Skip to content

Commit 98d32c5

Browse files
authored
browser(firefox): do not fail when decoding large responses (#2130)
String.fromCharCode cannot be used to convert very large arrays to strings. Use chunking in this case.
1 parent 7a01bb1 commit 98d32c5

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

browser_patches/firefox/BUILD_NUMBER

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1090
1+
1091

browser_patches/firefox/patches/bootstrap.diff

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,17 +1400,16 @@ index 0000000000000000000000000000000000000000..2b1fe7fa712ae210af3ebbccda084041
14001400
+
14011401
diff --git a/juggler/NetworkObserver.js b/juggler/NetworkObserver.js
14021402
new file mode 100644
1403-
index 0000000000000000000000000000000000000000..1a55b5498c18d2403eab21fe9149242f286157d4
1403+
index 0000000000000000000000000000000000000000..4ed81876c3e176cf07fdeab4ca3fc83874f865a3
14041404
--- /dev/null
14051405
+++ b/juggler/NetworkObserver.js
1406-
@@ -0,0 +1,794 @@
1406+
@@ -0,0 +1,833 @@
14071407
+"use strict";
14081408
+
14091409
+const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
14101410
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
14111411
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
14121412
+const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
1413-
+const {CommonUtils} = ChromeUtils.import("resource://services-common/utils.js");
14141413
+
14151414
+
14161415
+const Cc = Components.classes;
@@ -1978,7 +1977,7 @@ index 0000000000000000000000000000000000000000..1a55b5498c18d2403eab21fe9149242f
19781977
+ let result = response.body;
19791978
+ if (response.encodings && response.encodings.length) {
19801979
+ for (const encoding of response.encodings)
1981-
+ result = CommonUtils.convertString(result, encoding, 'uncompressed');
1980+
+ result = convertString(result, encoding, 'uncompressed');
19821981
+ }
19831982
+ return {base64body: btoa(result)};
19841983
+ }
@@ -2171,6 +2170,46 @@ index 0000000000000000000000000000000000000000..1a55b5498c18d2403eab21fe9149242f
21712170
+ }
21722171
+}
21732172
+
2173+
+function convertString(s, source, dest) {
2174+
+ const is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
2175+
+ Ci.nsIStringInputStream
2176+
+ );
2177+
+ is.setData(s, s.length);
2178+
+ const listener = Cc["@mozilla.org/network/stream-loader;1"].createInstance(
2179+
+ Ci.nsIStreamLoader
2180+
+ );
2181+
+ let result = [];
2182+
+ listener.init({
2183+
+ onStreamComplete: function onStreamComplete(
2184+
+ loader,
2185+
+ context,
2186+
+ status,
2187+
+ length,
2188+
+ data
2189+
+ ) {
2190+
+ const array = Array.from(data);
2191+
+ const kChunk = 100000;
2192+
+ for (let i = 0; i < length; i += kChunk) {
2193+
+ const len = Math.min(kChunk, length - i);
2194+
+ const chunk = String.fromCharCode.apply(this, array.slice(i, i + len));
2195+
+ result.push(chunk);
2196+
+ }
2197+
+ },
2198+
+ });
2199+
+ const converter = Cc["@mozilla.org/streamConverters;1"].getService(
2200+
+ Ci.nsIStreamConverterService
2201+
+ ).asyncConvertData(
2202+
+ source,
2203+
+ dest,
2204+
+ listener,
2205+
+ null
2206+
+ );
2207+
+ converter.onStartRequest(null, null);
2208+
+ converter.onDataAvailable(null, is, 0, s.length);
2209+
+ converter.onStopRequest(null, null, null);
2210+
+ return result.join('');
2211+
+}
2212+
+
21742213
+const errorMap = {
21752214
+ 'aborted': Cr.NS_ERROR_ABORT,
21762215
+ 'accessdenied': Cr.NS_ERROR_PORT_ACCESS_NOT_ALLOWED,

0 commit comments

Comments
 (0)