Backed out changeset f82fd05e7699 (bug 1333899)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Wed, 22 Feb 2017 09:59:57 +0100
changeset 373251 65061c29c70cfacf1abd77d2429688941881b07d
parent 373250 d931cdfe0da3e6134e3398246c9b95a46eda61ae
child 373252 b593e365b72df20e16ae74994275cd228749e5e5
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1333899
milestone54.0a1
backs outf82fd05e7699aed68ad105fa9ecdd3fa7b7f689d
Backed out changeset f82fd05e7699 (bug 1333899)
netwerk/protocol/data/nsDataHandler.cpp
netwerk/protocol/data/nsDataHandler.h
--- a/netwerk/protocol/data/nsDataHandler.cpp
+++ b/netwerk/protocol/data/nsDataHandler.cpp
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDataChannel.h"
 #include "nsDataHandler.h"
 #include "nsNetCID.h"
 #include "nsError.h"
-#include "nsIOService.h"
 #include "DataChannelChild.h"
 #include "plstr.h"
 
 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 nsDataHandler::nsDataHandler() {
@@ -153,140 +152,99 @@ NS_IMETHODIMP
 nsDataHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) {
     // don't override anything.  
     *_retval = false;
     return NS_OK;
 }
 
 #define BASE64_EXTENSION ";base64"
 
-/**
- * Helper that performs a case insensitive match to find the offset of a given
- * pattern in a nsACString.
- */
-bool
-FindOffsetOf(const nsACString& aPattern, const nsACString& aSrc,
-             nsACString::size_type& aOffset)
+nsresult
+nsDataHandler::ParseURI(nsCString& spec,
+                        nsCString& contentType,
+                        nsCString* contentCharset,
+                        bool&    isBase64,
+                        nsCString* dataBuffer)
 {
-    static const nsCaseInsensitiveCStringComparator kComparator;
-
-    nsACString::const_iterator begin, end;
-    aSrc.BeginReading(begin);
-    aSrc.EndReading(end);
-    if (!FindInReadable(aPattern, begin, end, kComparator)) {
-        return false;
-    }
+    isBase64 = false;
 
-    // FindInReadable updates |begin| and |end| to the match coordinates.
-    aOffset = nsACString::size_type(begin.get() - aSrc.Data());
-    return true;
-}
-
-nsresult
-nsDataHandler::ParsePathWithoutRef(
-    const nsACString& aPath,
-    nsCString& aContentType,
-    nsCString* aContentCharset,
-    bool& aIsBase64,
-    nsDependentCSubstring* aDataBuffer)
-{
-    static NS_NAMED_LITERAL_CSTRING(kBase64Ext, BASE64_EXTENSION);
-    static NS_NAMED_LITERAL_CSTRING(kCharset, "charset=");
-
-    aIsBase64 = false;
+    // move past "data:"
+    const char* roBuffer = (const char*) PL_strcasestr(spec.get(), "data:");
+    if (!roBuffer) {
+        // malformed uri
+        return NS_ERROR_MALFORMED_URI;
+    }
+    roBuffer += sizeof("data:") - 1;
 
     // First, find the start of the data
-    int32_t commaIdx = aPath.FindChar(',');
-    if (commaIdx == kNotFound) {
+    const char* roComma = strchr(roBuffer, ',');
+    const char* roHash = strchr(roBuffer, '#');
+    if (!roComma || (roHash && roHash < roComma)) {
         return NS_ERROR_MALFORMED_URI;
     }
 
-    if (commaIdx == 0) {
-        // Nothing but data.
-        aContentType.AssignLiteral("text/plain");
-        if (aContentCharset) {
-            aContentCharset->AssignLiteral("US-ASCII");
+    if (roComma == roBuffer) {
+        // nothing but data
+        contentType.AssignLiteral("text/plain");
+        if (contentCharset) {
+            contentCharset->AssignLiteral("US-ASCII");
         }
     } else {
-        auto mediaType = Substring(aPath, 0, commaIdx);
+        // Make a copy of the non-data part so we can null out parts of it as
+        // we go. This copy will be a small number of chars, in contrast to the
+        // data which may be large.
+        char* buffer = PL_strndup(roBuffer, roComma - roBuffer);
 
-        // Determine if the data is base64 encoded.
-        nsACString::size_type base64;
-        if (FindOffsetOf(kBase64Ext, mediaType, base64)) {
-            nsACString::size_type offset = base64 + kBase64Ext.Length();
+        // determine if the data is base64 encoded.
+        char* base64 = PL_strcasestr(buffer, BASE64_EXTENSION);
+        if (base64) {
+            char *beyond = base64 + sizeof(BASE64_EXTENSION) - 1;
             // Per the RFC 2397 grammar, "base64" MUST be at the end of the
             // non-data part.
             //
             // But we also allow it in between parameters so a subsequent ";"
             // is ok as well (this deals with *broken* data URIs, see bug
             // 781693 for an example). Anything after "base64" in the non-data
             // part will be discarded in this case, however.
-            if (offset == mediaType.Length() || mediaType[offset] == ';') {
-                aIsBase64 = true;
-                // Trim the base64 part off.
-                mediaType.Rebind(aPath, 0, base64);
+            if (*beyond == '\0' || *beyond == ';') {
+                isBase64 = true;
+                *base64 = '\0';
             }
         }
 
-        // Everything else is content type.
-        int32_t semiColon = mediaType.FindChar(';');
+        // everything else is content type
+        char *semiColon = (char *) strchr(buffer, ';');
+        if (semiColon)
+            *semiColon = '\0';
 
-        if (semiColon == 0 || mediaType.IsEmpty()) {
-            // There is no content type, but there are other parameters.
-            aContentType.AssignLiteral("text/plain");
+        if (semiColon == buffer || base64 == buffer) {
+            // there is no content type, but there are other parameters
+            contentType.AssignLiteral("text/plain");
         } else {
-            aContentType = Substring(mediaType, 0, semiColon);
-            ToLowerCase(aContentType);
-            aContentType.StripWhitespace();
+            contentType.Assign(buffer);
+            ToLowerCase(contentType);
+            contentType.StripWhitespace();
         }
 
-        if (semiColon != kNotFound && aContentCharset) {
-            auto afterSemi = Substring(mediaType, semiColon + 1);
-            nsACString::size_type charset;
-            if (FindOffsetOf(kCharset, afterSemi, charset)) {
-                *aContentCharset =
-                        Substring(afterSemi, charset + kCharset.Length());
-                aContentCharset->StripWhitespace();
+        if (semiColon && contentCharset) {
+            char *charset = PL_strcasestr(semiColon + 1, "charset=");
+            if (charset) {
+                contentCharset->Assign(charset + sizeof("charset=") - 1);
+                contentCharset->StripWhitespace();
             }
         }
+
+        free(buffer);
     }
 
-    if (aDataBuffer) {
-        aDataBuffer->Rebind(aPath, commaIdx + 1);
+    if (dataBuffer) {
+        // Split encoded data from terminal "#ref" (if present)
+        const char* roData = roComma + 1;
+        bool ok = !roHash
+                ? dataBuffer->Assign(roData, mozilla::fallible)
+                : dataBuffer->Assign(roData, roHash - roData, mozilla::fallible);
+        if (!ok) {
+            return NS_ERROR_OUT_OF_MEMORY;
+        }
     }
 
     return NS_OK;
 }
-
-nsresult
-nsDataHandler::ParseURI(nsCString& spec,
-                        nsCString& contentType,
-                        nsCString* contentCharset,
-                        bool&    isBase64,
-                        nsCString* dataBuffer)
-{
-    static NS_NAMED_LITERAL_CSTRING(kDataScheme, "data:");
-
-    // move past "data:"
-    int32_t scheme = spec.Find(kDataScheme, /* aIgnoreCase = */ true);
-    if (scheme == kNotFound) {
-        // malformed uri
-        return NS_ERROR_MALFORMED_URI;
-    }
-
-    scheme += kDataScheme.Length();
-
-    // Find the start of the hash ref if present.
-    int32_t hash = spec.FindChar('#', scheme);
-
-    auto pathWithoutRef = Substring(spec, scheme,
-                                    hash != kNotFound ? hash : -1);
-    nsDependentCSubstring dataRange;
-    nsresult rv = ParsePathWithoutRef(pathWithoutRef, contentType,
-                                      contentCharset, isBase64, &dataRange);
-    if (NS_SUCCEEDED(rv) && dataBuffer) {
-        if (!dataBuffer->Assign(dataRange, mozilla::fallible)) {
-            rv = NS_ERROR_OUT_OF_MEMORY;
-        }
-    }
-
-    return rv;
-}
--- a/netwerk/protocol/data/nsDataHandler.h
+++ b/netwerk/protocol/data/nsDataHandler.h
@@ -31,28 +31,11 @@ public:
     // (the given spec will temporarily be modified but will be returned
     //  to the original before returning)
     // contentCharset and dataBuffer can be nullptr if they are not needed.
     static MOZ_MUST_USE nsresult ParseURI(nsCString& spec,
                                           nsCString& contentType,
                                           nsCString* contentCharset,
                                           bool& isBase64,
                                           nsCString* dataBuffer);
-
-    // Parse the path portion of a data: URI and return the individual parts.
-    //
-    // Note: The path is assumed *not* to have a ref portion.
-    //
-    // @arg aPath The path portion of the spec. Must not have ref portion.
-    // @arg aContentType Out param, will hold the parsed content type.
-    // @arg aContentCharset Optional, will hold the charset if specified.
-    // @arg aIsBase64 Out param, indicates if the data is base64 encoded.
-    // @arg aDataBuffer Optional, will reference the substring in |aPath| that
-    //  contains the data portion of the path. No copy is made.
-    static MOZ_MUST_USE nsresult ParsePathWithoutRef(
-        const nsACString& aPath,
-        nsCString& aContentType,
-        nsCString* aContentCharset,
-        bool& aIsBase64,
-        nsDependentCSubstring* aDataBuffer);
 };
 
 #endif /* nsDataHandler_h___ */