Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #19912 from kamituel/Bug_1019169_byte_str_conv
Browse files Browse the repository at this point in the history
Bug 1019169: Fixed UTF <-> Uint8Array conversions
  • Loading branch information
rvandermeulen committed Jun 5, 2014
2 parents 763b7f6 + 6283093 commit 0f5dc07
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 51 deletions.
2 changes: 1 addition & 1 deletion apps/system/js/nfc_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ var NfcManager = {
text = NfcUtils.toUTF8(record.payload.subarray(langLen + 1));
encodingString = 'UTF-8';
} else if (encoding === NDEF.RTD_TEXT_UTF16) {
text = NfcUtils.UTF16BytesToString(record.payload.subarray(langLen + 1));
text = NfcUtils.UTF16BytesToStr(record.payload.subarray(langLen + 1));
encodingString = 'UTF-16';
}

Expand Down
55 changes: 39 additions & 16 deletions apps/system/test/unit/nfc_utils_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ suite('NFC Utils', function() {
var uint8array1;

setup(function() {
string1 = 'StringTestString ABCDEFGHIJKLMNOPQRSTUVWXYZ';
string1 = 'StringTestString ABCDEFGHIJKLMNOPQRSTUVWXYZ ą嗨è©';
uint8array1 = new Uint8Array([0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x54, 0x65, 0x73, 0x74,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
Expand All @@ -29,7 +29,10 @@ suite('NFC Utils', function() {
0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a]);
0x59, 0x5a,
0x20,
0xC4, 0x85, 0xE5, 0x97, 0xA8, 0xC3,
0xA8, 0xC2, 0xA9]);
});

test('equalArrays', function() {
Expand Down Expand Up @@ -64,20 +67,40 @@ suite('NFC Utils', function() {
});

suite('String <> byte conversions', function() {
test('UTF16BytesToString', function() {
assert.equal('©', NfcUtils.UTF16BytesToString([0xFE, 0xFF, 0x00, 0xA9]));
assert.equal('©', NfcUtils.UTF16BytesToString([0xFF, 0xFE, 0xA9, 0x00]));
assert.equal('ą', NfcUtils.UTF16BytesToString([0x01, 0x05]));

var foxArr = [0x00, 0x42, 0x00, 0x69, 0x00, 0x67, 0x00, 0x20, 0x00, 0x62,
0x00, 0x72, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x6E, 0x00, 0x20,
0x00, 0x66, 0x00, 0x6F, 0x00, 0x78, 0x00, 0x21, 0x00, 0x20,
0x00, 0x44, 0x00, 0x75, 0x01, 0x7C, 0x00, 0x79, 0x00, 0x20,
0x00, 0x62, 0x00, 0x72, 0x01, 0x05, 0x00, 0x7A, 0x00, 0x6F,
0x00, 0x77, 0x00, 0x79, 0x00, 0x20, 0x00, 0x6C, 0x00, 0x69,
0x00, 0x73, 0x00, 0x3F];
var foxTxt = 'Big brown fox! Duży brązowy lis?';
assert.equal(foxTxt, NfcUtils.UTF16BytesToString(foxArr));
var cprght = '©';
var cprghtUTF16BE = new Uint8Array([0x00, 0xA9]);
var cprghtUTF16BEBOM = new Uint8Array([0xFE, 0xFF, 0x00, 0xA9]);
var cprghtUTF16LEBOM = new Uint8Array([0xFF, 0xFE, 0xA9, 0x00]);

var plchr = 'ą';
var plchrUTF16BE = new Uint8Array([0x01, 0x05]);

var hai = '嗨';
var haiUTF16BE = new Uint8Array([0x55, 0xE8]);

var foxTxt = 'Big brown fox! 大棕狐狸?';
var foxTxtUTF16BE = new Uint8Array(
[0x00, 0x42, 0x00, 0x69, 0x00, 0x67, 0x00, 0x20, 0x00, 0x62, 0x00, 0x72,
0x00, 0x6F, 0x00, 0x77, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6F,
0x00, 0x78, 0x00, 0x21, 0x00, 0x20, 0x59, 0x27, 0x68, 0xD5, 0x72, 0xD0,
0x72, 0xF8, 0x00, 0x3F]
);

test('UTF16BytesToStr', function() {
assert.equal(cprght, NfcUtils.UTF16BytesToStr(cprghtUTF16BE));
assert.equal(cprght, NfcUtils.UTF16BytesToStr(cprghtUTF16BEBOM));
assert.equal(cprght, NfcUtils.UTF16BytesToStr(cprghtUTF16LEBOM));

assert.equal(plchr, NfcUtils.UTF16BytesToStr(plchrUTF16BE));
assert.equal(hai, NfcUtils.UTF16BytesToStr(haiUTF16BE));
assert.equal(foxTxt, NfcUtils.UTF16BytesToStr(foxTxtUTF16BE));
});

test('strToUTF16Bytes', function() {
assert.deepEqual(cprghtUTF16BE, NfcUtils.strToUTF16Bytes(cprght));
assert.deepEqual(plchrUTF16BE, NfcUtils.strToUTF16Bytes(plchr));
assert.deepEqual(haiUTF16BE, NfcUtils.strToUTF16Bytes(hai));
assert.deepEqual(foxTxtUTF16BE, NfcUtils.strToUTF16Bytes(foxTxt));
});
});

Expand Down
73 changes: 39 additions & 34 deletions shared/js/nfc_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/* Copyright © 2013, Deutsche Telekom, Inc. */

/* globals dump, MozNDEFRecord */
/* globals dump, MozNDEFRecord, TextEncoder, TextDecoder */
/* exported NDEF, NfcBuffer, NfcUtils */
'use strict';

Expand Down Expand Up @@ -198,11 +198,8 @@ NfcUtils = {
return null;
}

var buf = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
buf[i] = str.charCodeAt(i);
}
return buf;
var enc = new TextEncoder('utf-8');
return enc.encode(str);
},

/**
Expand Down Expand Up @@ -235,46 +232,54 @@ NfcUtils = {
return null;
}

var str = '';
for (var i = 0; i < a.length; i++) {
str += String.fromCharCode(a[i]);
// BOM removal
if (this.equalArrays(a.subarray(0, 3), [0xEF, 0xBB, 0xBF])) {
a = a.subarray(3);
}
return str;
var dec = new TextDecoder('utf-8');
return dec.decode(a);
},

/**
* Decodes UTF-16 bytes array into a String
*
* @param {Array} array containing UTF-16 encoded bytes
* @return {String}
* @param {Uint8Array} array containing UTF-16 encoded bytes
* @return {string}
*/
UTF16BytesToString: function UTF16BytesToString(array) {
UTF16BytesToStr: function UTF16BytesToStr(array) {
if (!array) {
return null;
}

// if BOM not present Big-endian should be used
// NFCForum-TS-RTD_Text_1.0
var offset1 = 0, offset2 = 1, i = 0;

if (array[0] === 0xFE && array[1] === 0xFF) {
i = 2;
} else if (array[0] === 0xFF && array[1] === 0xFE) {
i = 2;
offset1 = 1;
offset2 = 0;
var le = false;

var possibleBom = array.subarray(0, 2);
if (this.equalArrays(possibleBom, [0xFF, 0xFE])) {
array = array.subarray(2);
le = true;
} else if (this.equalArrays(possibleBom, [0xFE, 0xFF])) {
array = array.subarray(2);
}

var str = '';
for (var len = array.length; i < len; i += 2) {
var b1 = array[i + offset1];
if (b1 < 0xD8 || b1 >= 0xE0) {
var b2 = array[i + offset2];
var word = (b1 << 8) + b2;
str += String.fromCharCode(word);
} else {
i += 2;
// as for now we handle only BMP characters
}
}
var encoding = (le) ? 'utf-16le' : 'utf-16be';
var dec = new TextDecoder(encoding);
return dec.decode(array);
},

/**
* Ecodes string into Uint8Array conating UTF-16 BE bytes without BOM
* @param {string}
* @return {Uint8Array}
*/
strToUTF16Bytes: function strToUTF16Bytes(str) {
if (!str) {
return null;
}

return str;
var enc = new TextEncoder('utf-16be');
return enc.encode(str);
},

/*****************************************************************************
Expand Down

0 comments on commit 0f5dc07

Please sign in to comment.