2013-06-09 12 views
8

Ho appena scoperto quel nodo (testato: v0.8.23, git corrente: v0.11.3-pre) ignores any decoding errors nella sua gestione buffer, che sostituisce silenziosamente qualsiasi carattere non-utf8 con '\ufffd' (il PERSONALIZZATORE DI RICAMBIO Unicode) invece di generare un'eccezione l'input non-utf8. Di conseguenza, fs.readFile, process.stdin.setEncoding e gli amici mascherano una grande classe di errori di input non validi.Come posso catturare gli errori di decodifica utf-8 in node.js?

Esempio che non sicuro ma dovrebbe davvero:

> notValidUTF8 = new Buffer([ 128 ], 'binary') 
<Buffer 80> 
> decodedAsUTF8 = notValidUTF8.toString('utf8') // no exception thrown here! 
'�' 
> decodedAsUTF8 === '\ufffd' 
true 

'\ufffd' è un carattere perfettamente valido che può verificarsi in utf8 legale (come la sequenza ef bf bd), quindi è non banale scimmia- patch nella gestione degli errori in base a questo mostrando nel risultato.

Scavando un po 'più in profondità, sembra che questo provenga dal nodo che rimanda alle stringhe di v8 e che a loro volta hanno il comportamento sopra, v8 non ha alcun mondo esterno pieno di dati con codifica straniera.

Esistono moduli di nodi o altrimenti che mi consentono di rilevare gli errori di decodifica utf-8, preferibilmente con il contesto in cui è stato rilevato l'errore nella stringa di input o nel buffer?

+0

Anche se non sono sicuro, ma hai guardato il modulo di codifica. Potrebbe fornire un modo per aggirare il tuo problema. https://npmjs.org/package/encoding –

+0

Eseguire la decodifica a mano (beh, come in "non usare i primitivi del nodo") dovrebbe essere sicuro; iconv tramite 'encoding' probabilmente è la strada da percorrere dove esiste questa necessità. – ecmanaut

risposta

6

Spero che risolto il problema in quegli anni, ho avuto un simile uno e alla fine risolto con questo trucco brutto:

function isValidUTF8(buf){ 
    return Buffer.compare(new Buffer(buf.toString(),'utf8') , buf) === 0; 
    } 

che converte il buffer avanti e indietro e verifica che rimanga lo stesso.

La codifica 'utf8' può essere omessa.

allora abbiamo:

> isValidUTF8(new Buffer('this is valid, 指事字 eè we hope','utf8')) 
true 
> isValidUTF8(new Buffer([128])) 
false 
> isValidUTF8(new Buffer('\ufffd')) 
true 

dove il carattere '\ uFFFD' sia correttamente considerato come utf8 valida.

UPDATE: ora questo funziona in JXcore, anche

+0

Grazie - questa soluzione, per lo meno, copre tutte le situazioni in cui forme di normalizzazione diverse non confondono le cose.(Come ricordo, ho optato per il tooling su cui stavo lavorando in quel momento in Pike, una lingua con un pedigree Unicode molto solido. :-) – ecmanaut

0

Come Josh C. detto sopra: "npmjs.org/package/encoding"

Dal sito NPM: "encoding è un semplice wrapper nodo-iconv e iconv-lite per convertire le stringhe da una codifica a un altro."

download: $ npm install encoding

Esempio di utilizzo

var result = encoding.convert(new Buffer([ 128 ], 'binary'), "utf8"); 
console.log(result); //<Buffer 80> 

Visita il sito:npm - encoding

Problemi correlati