From d726d4fb2312a6a02691017a762555f9035a1481 Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Tue, 3 Jun 2014 20:45:37 +0400 Subject: [PATCH] Fixed #26 (iOS 5.1 Safary), closes #26 --- HISTORY.md | 6 ++++++ lib/utils/strings.js | 39 ++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a4e222c..91b00e2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +0.2.2 / WIP +------------------ + +- Fixed iOS 5.1 Safary issue with `apply(typed_array)`, #26. + + 0.2.1 / 2014-05-01 ------------------ diff --git a/lib/utils/strings.js b/lib/utils/strings.js index f03c4e6..d40b715 100644 --- a/lib/utils/strings.js +++ b/lib/utils/strings.js @@ -6,8 +6,15 @@ var utils = require('./common'); // Quick check if we can use fast array to bin string conversion +// +// - apply(Array) can fail on Android 2.2 +// - apply(Uint8Array) can fail on iOS 5.1 Safary +// var STR_APPLY_OK = true; +var STR_APPLY_UIA_OK = true; + try { String.fromCharCode.apply(null, [0]); } catch(__) { STR_APPLY_OK = false; } +try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch(__) { STR_APPLY_UIA_OK = false; } // Table with utf8 lengths (calculated by first byte of sequence) @@ -74,19 +81,26 @@ exports.string2buf = function (str) { return buf; }; - -// Convert byte array to binary string -exports.buf2binstring = function(buf) { +// Helper (used in 2 places) +function buf2binstring(buf, len) { // use fallback for big arrays to avoid stack overflow - if (STR_APPLY_OK && buf.length < 65537) { - return String.fromCharCode.apply(null, buf); + if (len < 65537) { + if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { + return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); + } } var result = ''; - for(var i=0, len=buf.length; i < len; i++) { + for(var i=0; i < len; i++) { result += String.fromCharCode(buf[i]); } return result; +} + + +// Convert byte array to binary string +exports.buf2binstring = function(buf) { + return buf2binstring(buf, buf.length); }; @@ -102,7 +116,7 @@ exports.binstring2buf = function(str) { // convert array to string exports.buf2string = function (buf, max) { - var str, i, out, c, c_len; + var i, out, c, c_len; var len = max || buf.length; // Reserve max possible length (2 words per char) @@ -139,16 +153,7 @@ exports.buf2string = function (buf, max) { } } - if (STR_APPLY_OK) { - return String.fromCharCode.apply(null, utils.shrinkBuf(utf16buf, out)); - } - - // Fallback, when String.fromCharCode.apply not available - str = ''; - for (i=0, len=out; i