From a13f21b796cedae7062e0b9735546c733fe3a1fd Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Tue, 4 Sep 2012 21:01:57 -0400 Subject: [PATCH] Bug 784367 - Encode/decode document.cookie as UTF-8 per HTML5 spec. r=bz --- content/base/src/nsContentUtils.cpp | 32 ++++++++++++++---- content/html/document/src/nsHTMLDocument.cpp | 7 ++-- content/html/document/test/Makefile.in | 2 ++ .../document/test/test_non-ascii-cookie.html | 33 +++++++++++++++++++ .../test/test_non-ascii-cookie.html^headers^ | 1 + 5 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 content/html/document/test/test_non-ascii-cookie.html create mode 100644 content/html/document/test/test_non-ascii-cookie.html^headers^ diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 2347f204b455..b8a1810947a4 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -3598,21 +3598,39 @@ nsContentUtils::ConvertStringFromCharset(const nsACString& aCharset, return rv; nsPromiseFlatCString flatInput(aInput); - int32_t srcLen = flatInput.Length(); - int32_t dstLen; - rv = decoder->GetMaxLength(flatInput.get(), srcLen, &dstLen); + int32_t length = flatInput.Length(); + int32_t outLen; + rv = decoder->GetMaxLength(flatInput.get(), length, &outLen); if (NS_FAILED(rv)) return rv; - PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((dstLen + 1) * + PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((outLen + 1) * sizeof(PRUnichar)); if (!ustr) return NS_ERROR_OUT_OF_MEMORY; - rv = decoder->Convert(flatInput.get(), &srcLen, ustr, &dstLen); - if (NS_SUCCEEDED(rv)) { + const char* data = flatInput.get(); + aOutput.Truncate(); + for (;;) { + int32_t srcLen = length; + int32_t dstLen = outLen; + rv = decoder->Convert(data, &srcLen, ustr, &dstLen); + // Convert will convert the input partially even if the status + // indicates a failure. ustr[dstLen] = 0; - aOutput.Assign(ustr, dstLen); + aOutput.Append(ustr, dstLen); + if (rv != NS_ERROR_ILLEGAL_INPUT) { + break; + } + // Emit a decode error manually because some decoders + // do not support kOnError_Recover (bug 638379) + if (srcLen == -1) { + decoder->Reset(); + } else { + data += srcLen + 1; + length -= srcLen + 1; + aOutput.Append(static_cast(0xFFFD)); + } } nsMemory::Free(ustr); diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index d72540767930..20cd4b2cc61b 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -1246,7 +1246,10 @@ nsHTMLDocument::GetCookie(nsAString& aCookie) nsXPIDLCString cookie; service->GetCookieString(codebaseURI, mChannel, getter_Copies(cookie)); - CopyASCIItoUTF16(cookie, aCookie); + // CopyUTF8toUTF16 doesn't handle error + // because it assumes that the input is valid. + nsContentUtils::ConvertStringFromCharset(NS_LITERAL_CSTRING("utf-8"), + cookie, aCookie); } return NS_OK; @@ -1285,7 +1288,7 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie) return NS_OK; } - NS_LossyConvertUTF16toASCII cookie(aCookie); + NS_ConvertUTF16toUTF8 cookie(aCookie); service->SetCookieString(codebaseURI, prompt, cookie.get(), mChannel); } diff --git a/content/html/document/test/Makefile.in b/content/html/document/test/Makefile.in index 68c60c833c68..9fe1aa7a7633 100644 --- a/content/html/document/test/Makefile.in +++ b/content/html/document/test/Makefile.in @@ -72,6 +72,8 @@ MOCHITEST_FILES = test_bug1682.html \ test_bug677495.html \ test_bug677495-1.html \ test_bug741266.html \ + test_non-ascii-cookie.html \ + test_non-ascii-cookie.html^headers^ \ $(NULL) ifneq (mobile,$(MOZ_BUILD_APP)) diff --git a/content/html/document/test/test_non-ascii-cookie.html b/content/html/document/test/test_non-ascii-cookie.html new file mode 100644 index 000000000000..0f0a4bbb820f --- /dev/null +++ b/content/html/document/test/test_non-ascii-cookie.html @@ -0,0 +1,33 @@ + + + + + + Test for non-ASCII document.cookie + + + + +Mozilla Bug 784367 +

+ +
+
+
+ + diff --git a/content/html/document/test/test_non-ascii-cookie.html^headers^ b/content/html/document/test/test_non-ascii-cookie.html^headers^ new file mode 100644 index 000000000000..54aa6c3e721b --- /dev/null +++ b/content/html/document/test/test_non-ascii-cookie.html^headers^ @@ -0,0 +1 @@ +Set-Cookie: abc=012©ABC©DEF