2013-06-09 16 views
8

Tôi vừa phát hiện ra rằng Node (được kiểm tra: v0.8.23, git hiện tại: v0.11.3-pre) ignores any decoding errors trong việc xử lý Bộ đệm, âm thầm thay thế bất kỳ ký tự không phải utf8 nào bằng '\ufffd' (Unicode REPLACEMENT CHARACTER) thay vì ném một ngoại lệ về đầu vào không phải là utf8. Kết quả là, fs.readFile, process.stdin.setEncoding và bạn bè che dấu một lớp lớn các lỗi nhập sai cho bạn.Làm cách nào để ghi lại các lỗi giải mã utf-8 trong node.js?

Ví dụ mà không thất bại nhưng thực sự nên:

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

'\ufffd' là một nhân vật hoàn toàn hợp lệ có thể xảy ra trong utf8 quy phạm pháp luật (như chuỗi ef bf bd), vì vậy nó là không tầm thường để monkey- vá lỗi xử lý dựa trên điều này hiển thị trong kết quả.

Đào sâu hơn một chút, có vẻ như nó xuất phát từ nút chỉ trì hoãn chuỗi của v8 và lần lượt có hành vi trên, v8 không có bất kỳ thế giới bên ngoài nào có đầy đủ dữ liệu được mã hóa nước ngoài.

Có mô-đun nút hay cách khác cho phép tôi nắm bắt lỗi giải mã utf-8, tốt nhất là với ngữ cảnh về nơi phát hiện lỗi trong chuỗi đầu vào hoặc bộ đệm?

+0

Trong khi tôi không chắc chắn, nhưng có bạn nhìn vào các mô-đun mã hóa. Nó có thể cung cấp một cách để phá vỡ vấn đề của bạn. https://npmjs.org/package/encoding –

+0

Thực hiện giải mã bằng tay (tốt, như trong "không sử dụng các nút nguyên thủy") phải an toàn; iconv thông qua 'encoding' có lẽ là cách để đi đến nơi mà nhu cầu này tồn tại. – ecmanaut

Trả lời

6

Tôi hy vọng bạn giải quyết vấn đề trong những năm đó, tôi đã có một tương tự một và cuối cùng được giải quyết với thủ thuật xấu xí này:

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

chuyển đổi bộ đệm qua lại và kiểm tra xem nó vẫn giữ nguyên.

Có thể bỏ qua mã hóa 'utf8'.

Sau đó, chúng ta có:

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

nơi '\ ufffd' nhân vật được chính xác coi là utf8 hợp lệ.

CẬP NHẬT: hiện đang làm việc này trong JXcore, quá

+0

Cảm ơn - giải pháp này ít nhất bao gồm tất cả các tình huống mà các hình thức bình thường hóa khác nhau không làm lẫn lộn mọi thứ.(Như tôi nhớ lại, tôi đã chọn làm công cụ mà tôi đang làm vào thời điểm đó ở Pike, một ngôn ngữ có phả hệ Unicode rất chắc chắn .--) – ecmanaut

0

Như Josh C. nói ở trên: "npmjs.org/package/encoding"

Từ trang web NPM: "mã hóa là một wrapper đơn giản xung quanh nút-iconv và iconv-lite để chuyển đổi chuỗi từ một mã hóa để khác."

Download: $ npm install encoding

Ví dụ cách dùng

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

thăm trang web:npm - encoding

Các vấn đề liên quan