Bug 272541: Empty disposition type treated as 'attachment'. r=jduell
authorjulian.reschke@greenbytes.de
Mon, 12 Sep 2011 20:14:16 -0700
changeset 77944 ddb49b079701d0a44947b087eda139a2401a6c73
parent 77943 1a84481f69875da535508041e90041f06bd2deae
child 77945 091bdb10d01717a68c730b2625d3d02a443ce1bf
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell
bugs272541
milestone9.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
Bug 272541: Empty disposition type treated as 'attachment'. r=jduell
js/src/xpconnect/src/xpc.msg
netwerk/base/public/nsNetError.h
netwerk/base/public/nsNetUtil.h
netwerk/mime/nsMIMEHeaderParamImpl.cpp
netwerk/test/unit/test_bug272541.js
netwerk/test/unit/xpcshell.ini
--- a/js/src/xpconnect/src/xpc.msg
+++ b/js/src/xpconnect/src/xpc.msg
@@ -170,16 +170,17 @@ XPC_MSG_DEF(NS_BINDING_REDIRECTED       
 XPC_MSG_DEF(NS_BINDING_RETARGETED                   , "The async request has been retargeted to a different handler")
 XPC_MSG_DEF(NS_ERROR_MALFORMED_URI                  , "The URI is malformed")
 XPC_MSG_DEF(NS_ERROR_UNKNOWN_PROTOCOL               , "The URI scheme corresponds to an unknown protocol handler")
 XPC_MSG_DEF(NS_ERROR_NO_CONTENT                     , "Channel opened successfully but no data will be returned")
 XPC_MSG_DEF(NS_ERROR_IN_PROGRESS                    , "The requested action could not be completed while the object is busy")
 XPC_MSG_DEF(NS_ERROR_ALREADY_OPENED                 , "Channel is already open")
 XPC_MSG_DEF(NS_ERROR_INVALID_CONTENT_ENCODING       , "The content encoding of the source document is incorrect")
 XPC_MSG_DEF(NS_ERROR_CORRUPTED_CONTENT              , "Corrupted content was received from server")
+XPC_MSG_DEF(NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "Couldn't extract first component from potentially corrupted header field")
 XPC_MSG_DEF(NS_ERROR_ALREADY_CONNECTED              , "The connection is already established")
 XPC_MSG_DEF(NS_ERROR_NOT_CONNECTED                  , "The connection does not exist")
 XPC_MSG_DEF(NS_ERROR_CONNECTION_REFUSED             , "The connection was refused")
 XPC_MSG_DEF(NS_ERROR_PROXY_CONNECTION_REFUSED       , "The connection to the proxy server was refused")
 XPC_MSG_DEF(NS_ERROR_NET_TIMEOUT                    , "The connection has timed out")
 XPC_MSG_DEF(NS_ERROR_OFFLINE                        , "The requested action could not be completed in the offline state")
 XPC_MSG_DEF(NS_ERROR_PORT_ACCESS_NOT_ALLOWED        , "Establishing a connection to an unsafe or otherwise banned port was prohibited")
 XPC_MSG_DEF(NS_ERROR_NET_RESET                      , "The connection was established, but no data was ever received")
--- a/netwerk/base/public/nsNetError.h
+++ b/netwerk/base/public/nsNetError.h
@@ -147,16 +147,27 @@
 /**
  * A transport level corruption was found in the source document. for example
  * a document with a calculated checksum that does not match the Content-MD5
  * http header.
  */
 #define NS_ERROR_CORRUPTED_CONTENT \
     NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 29)
 
+/**
+ * While parsing for the first component of a header field using
+ * syntax as in Content-Disposition or Content-Type, the first component
+ * was found to be empty, such as in:
+ *
+ * Content-Disposition: ; filename=foo
+ */
+#define NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY \
+    NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 34)
+
+
 /******************************************************************************
  * Connectivity error codes:
  */
 
 /**
  * The connection is already established.
  * XXX currently unused - consider removing.
  */
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -1938,18 +1938,23 @@ NS_GetContentDispositionFromHeader(const
     aChan->GetURI(getter_AddRefs(uri));
     if (uri)
       uri->GetOriginCharset(fallbackCharset);
   }
 
   nsAutoString dispToken;
   rv = mimehdrpar->GetParameter(aHeader, "", fallbackCharset, PR_TRUE, nsnull,
                                 dispToken);
-  if (NS_FAILED(rv))
-    return nsIChannel::DISPOSITION_ATTACHMENT;
+
+  if (NS_FAILED(rv)) {
+    // special case (see bug 272541): empty disposition type handled as "inline"
+    return rv == NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY
+                 ? nsIChannel::DISPOSITION_INLINE
+                 : nsIChannel::DISPOSITION_ATTACHMENT;
+  }
 
   return NS_GetContentDispositionFromToken(dispToken);
 }
 
 /** Extracts the filename out of a content-disposition header
  * @param aFilename [out] The filename. Can be empty on error.
  * @param aDisposition Value of a Content-Disposition header
  * @param aURI Optional. Will be used to get a fallback charset for the
--- a/netwerk/mime/nsMIMEHeaderParamImpl.cpp
+++ b/netwerk/mime/nsMIMEHeaderParamImpl.cpp
@@ -52,16 +52,17 @@
 #include "nsCOMPtr.h"
 #include "nsEscape.h"
 #include "nsIUTF8ConverterService.h"
 #include "nsUConvCID.h"
 #include "nsIServiceManager.h"
 #include "nsMIMEHeaderParamImpl.h"
 #include "nsReadableUtils.h"
 #include "nsNativeCharsetUtils.h"
+#include "nsNetError.h"
 
 // static functions declared below are moved from mailnews/mime/src/comi18n.cpp
   
 static char *DecodeQ(const char *, PRUint32);
 static PRBool Is7bitNonAsciiString(const char *, PRUint32);
 static void CopyRawHeader(const char *, PRUint32, const char *, nsACString &);
 static nsresult DecodeRFC2047Str(const char *, const char *, PRBool, nsACString&);
 
@@ -176,17 +177,18 @@ nsMIMEHeaderParamImpl::GetParameterInter
   // aParamName is empty. return the first (possibly) _unnamed_ 'parameter'
   // For instance, return 'inline' in the following case:
   // Content-Disposition: inline; filename=.....
   if (!aParamName || !*aParamName) 
     {
       for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str)
         ;
       if (str == start)
-        return NS_ERROR_UNEXPECTED;
+        return NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY;
+
       *aResult = (char *) nsMemory::Clone(start, (str - start) + 1);
       NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
       (*aResult)[str - start] = '\0';  // null-terminate
       return NS_OK;
     }
 
   /* Skip forward to first ';' */
   for (; *str && *str != ';' && *str != ','; ++str)
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_bug272541.js
@@ -0,0 +1,37 @@
+/**
+ * Test for bug 272541: - Empty disposition type treated as "attachment" 
+ */
+
+const Cr = Components.results
+
+var tests = [
+                 [ /* the actual bug */
+                  "; filename=foo.html", 
+                  Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY],
+                 [ /* regression check, but see bug 671204 */
+                  "filename=foo.html", 
+                  "filename=foo.html"],
+                 [ /* sanity check */
+                  "attachment; filename=foo.html", 
+                  "attachment"],
+                ];
+
+function run_test() {
+
+  var mhp = Components.classes["@mozilla.org/network/mime-hdrparam;1"]
+                      .getService(Components.interfaces.nsIMIMEHeaderParam);
+
+  var unused = { value : null };
+
+  for (var i = 0; i < tests.length; ++i) {
+    dump("Testing " + tests[i] + "\n");
+    try {
+      do_check_eq(mhp.getParameter(tests[i][0], "", "UTF-8", true, unused),
+                  tests[i][1]);
+    }
+    catch (e) {
+      do_check_eq(e.result, tests[i][1]);
+    }
+  }
+}
+
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -11,16 +11,17 @@ tail =
 # Bug 675039: test hangs consistently on Android
 skip-if = os == "android"
 [test_authpromptwrapper.js]
 [test_bug203271.js]
 [test_bug248970_cache.js]
 [test_bug248970_cookie.js]
 [test_bug261425.js]
 [test_bug263127.js]
+[test_bug272541.js]
 [test_bug321706.js]
 [test_bug331825.js]
 [test_bug336501.js]
 [test_bug337744.js]
 [test_bug365133.js]
 [test_bug368702.js]
 [test_bug369787.js]
 [test_bug371473.js]