content: sync load service: don't die when channels have unknown size (b=894586 r=ehsan r=jduell)
authorMook <marky+mozhg@activestate.com>
Tue, 30 Jul 2013 14:38:26 -0700
changeset 152899 3bc4bafd92a34f9448590521aa7eac361b376d25
parent 152898 d1606467afd4a8f781490f13791611f9a7612251
child 152900 e53429eddc5b0ae573296e6ee6a062c7a8e902be
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, 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=ehsan 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,116 @@
+/*
+ * 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 file = do_get_file("test_bug894586.js", false);
+    do_check_true(file.exists());
+    var url = Services.io.newFileURI(file);
+    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
@@ -73,16 +73,19 @@ tail =
 [test_bug654926_test_seek.js]
 [test_bug659569.js]
 [test_bug660066.js]
 [test_bug667907.js]
 [test_bug667818.js]
 [test_bug669001.js]
 [test_bug712914_secinfo_validation.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]