content: sync load service: don't die when channels have unknown size (b=894586 r=jst r=jduell)
☠☠ backed out by 009130768e09 ☠ ☠
authorMook <marky+mozhg@activestate.com>
Fri, 26 Jul 2013 15:25:27 -0700
changeset 140226 f570fc641c5f087fc00e87708ecda8053495c3ad
parent 140225 2ee2dc1d2bcc0d8210fcf1dfe61e66284cec4026
child 140227 2287b266756501af9cedfe42082b3525969be655
push id31654
push usermook.moz@gmail.com
push dateFri, 26 Jul 2013 22:26:25 +0000
treeherdermozilla-inbound@f570fc641c5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst, jduell
bugs894586
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
content: sync load service: don't die when channels have unknown size (b=894586 r=jst r=jduell)
content/base/src/nsSyncLoadService.cpp
netwerk/test/unit/test_bug894586.js
netwerk/test/unit/xpcshell.ini
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -335,17 +335,17 @@ nsSyncLoadService::PushSyncStreamToListe
                                             nsIChannel* aChannel)
 {
     // Set up buffering stream
     nsresult rv;
     nsCOMPtr<nsIInputStream> bufferedStream;
     if (!NS_InputStreamIsBuffered(aIn)) {
         int64_t chunkSize;
         rv = aChannel->GetContentLength(&chunkSize);
-        if (NS_FAILED(rv)) {
+        if (NS_FAILED(rv) || chunkSize < 1) {
             chunkSize = 4096;
         }
         chunkSize = std::min(int64_t(UINT16_MAX), chunkSize);
 
         rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), aIn,
                                        chunkSize);
         NS_ENSURE_SUCCESS(rv, rv);
 
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_bug894586.js
@@ -0,0 +1,115 @@
+/*
+ * Tests for bug 894586: nsSyncLoadService::PushSyncStreamToListener
+ * should not fail for channels of unknown size
+ */
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function ProtocolHandler() {
+  this.uri = Cc["@mozilla.org/network/simple-uri;1"].
+               createInstance(Ci.nsIURI);
+  this.uri.spec = this.scheme + ":dummy";
+  this.uri.QueryInterface(Ci.nsIMutable).mutable = false;
+}
+
+ProtocolHandler.prototype = {
+  /** nsIProtocolHandler */
+  get scheme() "x-bug894586",
+  get defaultPort() -1,
+  get protocolFlags() Ci.nsIProtocolHandler.URI_NORELATIVE |
+                      Ci.nsIProtocolHandler.URI_NOAUTH |
+                      Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE |
+                      Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
+                      Ci.nsIProtocolHandler.URI_NON_PERSISTABLE |
+                      Ci.nsIProtocolHandler.URI_SYNC_LOAD_IS_OK,
+  newURI: function(aSpec, aOriginCharset, aBaseURI) this.uri,
+  newChannel: function(aURI) this,
+  allowPort: function(port, scheme) port != -1,
+
+  /** nsIChannel */
+  get originalURI() this.uri,
+  get URI() this.uri,
+  owner: null,
+  notificationCallbacks: null,
+  get securityInfo() null,
+  get contentType() "text/css",
+  set contentType(val) void(0),
+  contentCharset: "UTF-8",
+  get contentLength() -1,
+  set contentLength(val) {
+    throw Components.Exception("Setting content length", NS_ERROR_NOT_IMPLEMENTED);
+  },
+  open: function() {
+    var url = Services.io.newURI("resource://app/chrome.manifest", null, null);
+    do_check_true(url.QueryInterface(Ci.nsIFileURL).file.exists());
+    return Services.io.newChannelFromURI(url).open();
+  },
+  asyncOpen: function(aListener, aContext) {
+    throw Components.Exception("Not implemented",
+                               Cr.NS_ERROR_NOT_IMPLEMENTED);
+  },
+  contentDisposition: Ci.nsIChannel.DISPOSITION_INLINE,
+  get contentDispositionFilename() {
+    throw Components.Exception("No file name",
+                               Cr.NS_ERROR_NOT_AVAILABLE);
+  },
+  get contentDispositionHeader() {
+    throw Components.Exception("No header",
+                               Cr.NS_ERROR_NOT_AVAILABLE);
+  },
+
+  /** nsIRequest */
+  get name() this.uri.spec,
+  isPending: function() false,
+  get status() Cr.NS_OK,
+  cancel: function(status) {},
+  loadGroup: null,
+  loadFlags: Ci.nsIRequest.LOAD_NORMAL |
+             Ci.nsIRequest.INHIBIT_CACHING |
+             Ci.nsIRequest.LOAD_BYPASS_CACHE,
+
+  /** nsIFactory */
+  createInstance: function(aOuter, aIID) {
+    if (aOuter) {
+      throw Components.Exception("createInstance no aggregation",
+                                 Cr.NS_ERROR_NO_AGGREGATION);
+    }
+    return this.QueryInterface(aIID);
+  },
+  lockFactory: function() {},
+
+  /** nsISupports */
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler,
+                                         Ci.nsIRequest,
+                                         Ci.nsIChannel,
+                                         Ci.nsIFactory]),
+  classID: Components.ID("{16d594bc-d9d8-47ae-a139-ea714dc0c35c}")
+};
+
+/**
+ * Attempt a sync load; we use the stylesheet service to do this for us,
+ * based on the knowledge that it forces a sync load under the hood.
+ */
+function run_test()
+{
+  var handler = new ProtocolHandler();
+  var registrar = Components.manager.
+                             QueryInterface(Ci.nsIComponentRegistrar);
+  registrar.registerFactory(handler.classID, "",
+                            "@mozilla.org/network/protocol;1?name=" + handler.scheme,
+                            handler);
+  try {
+    var ss = Cc["@mozilla.org/content/style-sheet-service;1"].
+               getService(Ci.nsIStyleSheetService);
+    ss.loadAndRegisterSheet(handler.uri, Ci.nsIStyleSheetService.AGENT_SHEET);
+    do_check_true(ss.sheetRegistered(handler.uri, Ci.nsIStyleSheetService.AGENT_SHEET));
+  } finally {
+    registrar.unregisterFactory(handler.classID, handler);
+  }
+}
+
+// vim: set et ts=2 :
+
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -74,16 +74,19 @@ tail =
 [test_bug659569.js]
 [test_bug660066.js]
 [test_bug667907.js]
 [test_bug667818.js]
 [test_bug669001.js]
 [test_bug712914_secinfo_validation.js]
 [test_bug722299.js]
 [test_bug770243.js]
+[test_bug894586.js]
+# Allocating 4GB might actually succeed on 64 bit machines
+skip-if = bits != 32
 [test_doomentry.js]
 [test_cacheflags.js]
 [test_cache_jar.js]
 [test_channel_close.js]
 [test_compareURIs.js]
 [test_compressappend.js]
 [test_content_encoding_gzip.js]
 [test_content_sniffer.js]