diff --git a/netwerk/mime/nsMIMEHeaderParamImpl.cpp b/netwerk/mime/nsMIMEHeaderParamImpl.cpp index 3c3ec117b0b0..4bc5414a6486 100644 --- a/netwerk/mime/nsMIMEHeaderParamImpl.cpp +++ b/netwerk/mime/nsMIMEHeaderParamImpl.cpp @@ -144,22 +144,25 @@ void RemoveQuotedStringEscapes(char *src) class Continuation { public: Continuation(const char *aValue, PRUint32 aLength, - bool aNeedsPercentDecoding) { + bool aNeedsPercentDecoding, bool aWasQuotedString) { value = aValue; length = aLength; needsPercentDecoding = aNeedsPercentDecoding; + wasQuotedString = aWasQuotedString; } Continuation() { // empty constructor needed for nsTArray value = 0L; length = 0; needsPercentDecoding = false; + wasQuotedString = false; } ~Continuation() {} const char *value; PRUint32 length; bool needsPercentDecoding; + bool wasQuotedString; }; // combine segments into a single string, returning the allocated string @@ -192,6 +195,9 @@ char *combineContinuations(nsTArray& aArray) if (cont.needsPercentDecoding) { nsUnescape(c); } + if (cont.wasQuotedString) { + RemoveQuotedStringEscapes(c); + } } // return null if empty value @@ -210,7 +216,7 @@ char *combineContinuations(nsTArray& aArray) // add a continuation, return false on error if segment already has been seen bool addContinuation(nsTArray& aArray, PRUint32 aIndex, const char *aValue, PRUint32 aLength, - bool aNeedsPercentDecoding) + bool aNeedsPercentDecoding, bool aWasQuotedString) { if (aIndex < aArray.Length() && aArray[aIndex].value) { NS_WARNING("duplicate RC2231 continuation segment #\n"); @@ -222,7 +228,12 @@ bool addContinuation(nsTArray& aArray, PRUint32 aIndex, return false; } - Continuation cont (aValue, aLength, aNeedsPercentDecoding); + if (aNeedsPercentDecoding && aWasQuotedString) { + NS_WARNING("RC2231 continuation segment can't use percent encoding and quoted string form at the same time\n"); + return false; + } + + Continuation cont(aValue, aLength, aNeedsPercentDecoding, aWasQuotedString); if (aArray.Length() <= aIndex) { aArray.SetLength(aIndex + 1); @@ -578,7 +589,8 @@ nsMIMEHeaderParamImpl::DoParameterInternal(const char *aHeaderValue, } else { // caseC bool added = addContinuation(segments, 0, rawValStart, - rawValLength, needExtDecoding); + rawValLength, needExtDecoding, + isQuotedString); if (!added) { // continuation not added, stop processing them @@ -593,7 +605,8 @@ nsMIMEHeaderParamImpl::DoParameterInternal(const char *aHeaderValue, PRUint32 valueLength = valueEnd - valueStart; bool added = addContinuation(segments, segmentNumber, valueStart, - valueLength, needExtDecoding); + valueLength, needExtDecoding, + isQuotedString); if (!added) { // continuation not added, stop processing them diff --git a/netwerk/test/unit/test_MIME_params.js b/netwerk/test/unit/test_MIME_params.js index 0e53dbc80788..8fee955b6b63 100644 --- a/netwerk/test/unit/test_MIME_params.js +++ b/netwerk/test/unit/test_MIME_params.js @@ -385,6 +385,17 @@ var tests = [ ["attachment", "attachment", Cr.NS_ERROR_INVALID_ARG], + // Bug 730574: quoted-string in RFC2231-continuations not handled + + ['attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\r.html"', + "attachment", "foobar.html", + "attachment", "basic"], + + // unmatched escape char + ['attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\', + "attachment", "fooba\\", + "attachment", "basic"], + // Bug 732369: Content-Disposition parser does not require presence of ";" between params ["attachment; extension=bla filename=foo",