mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 02:57:38 +00:00
Bug 1032511 - URLSearchParam should decode any non-unicode input correctly, r=hsivonen
This commit is contained in:
parent
aeabb8d6b0
commit
298752138d
@ -5,6 +5,7 @@
|
||||
|
||||
#include "URLSearchParams.h"
|
||||
#include "mozilla/dom/URLSearchParamsBinding.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -98,30 +99,31 @@ URLSearchParams::ParseInput(const nsACString& aInput,
|
||||
name.Assign(string);
|
||||
}
|
||||
|
||||
nsAutoCString decodedName;
|
||||
nsAutoString decodedName;
|
||||
DecodeString(name, decodedName);
|
||||
|
||||
nsAutoCString decodedValue;
|
||||
nsAutoString decodedValue;
|
||||
DecodeString(value, decodedValue);
|
||||
|
||||
AppendInternal(NS_ConvertUTF8toUTF16(decodedName),
|
||||
NS_ConvertUTF8toUTF16(decodedValue));
|
||||
AppendInternal(decodedName, decodedValue);
|
||||
}
|
||||
|
||||
NotifyObservers(aObserver);
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::DecodeString(const nsACString& aInput, nsACString& aOutput)
|
||||
URLSearchParams::DecodeString(const nsACString& aInput, nsAString& aOutput)
|
||||
{
|
||||
nsACString::const_iterator start, end;
|
||||
aInput.BeginReading(start);
|
||||
aInput.EndReading(end);
|
||||
|
||||
nsCString unescaped;
|
||||
|
||||
while (start != end) {
|
||||
// replace '+' with U+0020
|
||||
if (*start == '+') {
|
||||
aOutput.Append(' ');
|
||||
unescaped.Append(' ');
|
||||
++start;
|
||||
continue;
|
||||
}
|
||||
@ -148,20 +150,62 @@ URLSearchParams::DecodeString(const nsACString& aInput, nsACString& aOutput)
|
||||
|
||||
if (first != end && second != end &&
|
||||
ASCII_HEX_DIGIT(*first) && ASCII_HEX_DIGIT(*second)) {
|
||||
aOutput.Append(HEX_DIGIT(first) * 16 + HEX_DIGIT(second));
|
||||
unescaped.Append(HEX_DIGIT(first) * 16 + HEX_DIGIT(second));
|
||||
start = ++second;
|
||||
continue;
|
||||
|
||||
} else {
|
||||
aOutput.Append('%');
|
||||
unescaped.Append('%');
|
||||
++start;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
aOutput.Append(*start);
|
||||
unescaped.Append(*start);
|
||||
++start;
|
||||
}
|
||||
|
||||
ConvertString(unescaped, aOutput);
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::ConvertString(const nsACString& aInput, nsAString& aOutput)
|
||||
{
|
||||
aOutput.Truncate();
|
||||
|
||||
if (!mDecoder) {
|
||||
mDecoder = EncodingUtils::DecoderForEncoding("UTF-8");
|
||||
if (!mDecoder) {
|
||||
MOZ_ASSERT(mDecoder, "Failed to create a decoder.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsACString::const_iterator iter;
|
||||
aInput.BeginReading(iter);
|
||||
|
||||
int32_t inputLength = aInput.Length();
|
||||
int32_t outputLength = 0;
|
||||
|
||||
nsresult rv = mDecoder->GetMaxLength(iter.get(), inputLength,
|
||||
&outputLength);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mozilla::fallible_t fallible = mozilla::fallible_t();
|
||||
nsAutoArrayPtr<char16_t> buf(new (fallible) char16_t[outputLength + 1]);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = mDecoder->Convert(iter.get(), &inputLength, buf, &outputLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
buf[outputLength] = 0;
|
||||
if (!aOutput.Assign(buf, outputLength, mozilla::fallible_t())) {
|
||||
aOutput.Truncate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -83,7 +84,8 @@ private:
|
||||
|
||||
void DeleteAll();
|
||||
|
||||
void DecodeString(const nsACString& aInput, nsACString& aOutput);
|
||||
void DecodeString(const nsACString& aInput, nsAString& aOutput);
|
||||
void ConvertString(const nsACString& aInput, nsAString& aOutput);
|
||||
|
||||
void NotifyObservers(URLSearchParamsObserver* aExceptObserver);
|
||||
|
||||
@ -98,6 +100,7 @@ private:
|
||||
nsClassHashtable<nsStringHashKey, nsTArray<nsString>> mSearchParams;
|
||||
|
||||
nsTArray<nsRefPtr<URLSearchParamsObserver>> mObservers;
|
||||
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -74,6 +74,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
|
||||
[test_url_malformedHost.html]
|
||||
[test_urlExceptions.html]
|
||||
[test_urlSearchParams.html]
|
||||
[test_urlSearchParams_utf8.html]
|
||||
[test_urlutils_stringify.html]
|
||||
[test_window_constructor.html]
|
||||
[test_window_cross_origin_props.html]
|
||||
|
40
dom/base/test/test_urlSearchParams_utf8.html
Normal file
40
dom/base/test/test_urlSearchParams_utf8.html
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1032511
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1032511</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1032511">Mozilla Bug 1032511</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe name="x" id="x"></iframe>
|
||||
<iframe name="y" id="y"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<a href="http://www.example.net?a=b&c=d" id="anchor">foobar</a>
|
||||
<area href="http://www.example.net?a=b&c=d" id="area">foobar</area>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1032511 **/
|
||||
var a = new URLSearchParams("%e2");
|
||||
ok(a, "a exists");
|
||||
is(a.toString(), '=', "The value should be here.");
|
||||
|
||||
a = new URLSearchParams("a%e2");
|
||||
// This is a known decoder bug that fails to emit a REPLACEMENT CHARACTER.
|
||||
is(a.toString(), 'a=', "The value should be here.");
|
||||
|
||||
a = new URLSearchParams("a%e2b");
|
||||
is(a.toString(), 'a%EF%BF%BDb=', "The value should be here.");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user