2013-06-09 1 views
8

Я только что обнаружил, что Node (протестирован: v0.8.23, текущий git: v0.11.3-pre) ignores any decoding errors в обработке буфера, молча заменяя любые символы не-utf8 '\ufffd' (Unicode REPLACEMENT CHARACTER) вместо того, чтобы бросать исключение из вход не-utf8. Как следствие, fs.readFile, process.stdin.setEncoding и друзья маскируют большой класс ошибок ввода для вас.Как записывать ошибки декодирования utf-8 в node.js?

Пример, который не подведет, но на самом деле должен:

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

'\ufffd' является вполне допустимым символом, который может произойти в правовом utf8 (как последовательность ef bf bd), поэтому он не является тривиальным monkey- патч в обработке ошибок на основе этого появляется в результате.

Копаем немного глубже, похоже, что это связано с тем, что узел просто откладывается на строки v8 и что те, в свою очередь, имеют вышеописанное поведение, v8 не имеют внешнего мира, заполненного чужими закодированными данными.

Существуют ли узловые модули или что-то еще, что позволяет мне поймать ошибки декодирования utf-8, предпочтительно с контекстом о том, где ошибка была обнаружена во входной строке или в буфере?

+0

Хотя я не уверен, но вы смотрели на модуль кодирования. Это может стать способом обойти вашу проблему. https://npmjs.org/package/encoding –

+0

Выполнение декодирования вручную (ну, как и в случае «не использовать примитивы узлов») должно быть безопасным; iconv через 'encoding', вероятно, является способом перехода туда, где это необходимо. – ecmanaut

ответ

6

Я надеюсь, что вы решили проблему в те годы я был похож один и в конце концов решил с этим уродливым трюком:

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

, который преобразует буфер взад-вперед и проверяет его на прежнем уровне.

Кодирование «utf8» может быть опущено.

Тогда мы имеем:

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

где '\ ufffd' символ правильно считается действительным utf8.

UPDATE: теперь это работает в JXcore тоже

+0

Спасибо - это решение, по крайней мере, охватывает все ситуации, когда разные формы нормализации не путают вещи.(Насколько я помню, я решил использовать инструментарий, над которым я работал в то время в Пайке, язык с очень твердой родословной Unicode. :-) – ecmanaut

0

Как сказал Джош С выше: «npmjs.org/package/encoding»

С сайта НПМ: «кодирование является простой оберткой узла-Iconv и Iconv-лайт для преобразования строк из одной кодировки в другой."

Скачать: $ npm install encoding

Пример

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

Посетите сайт:npm - encoding

 Смежные вопросы

  • Нет связанных вопросов^_^