Bug 1271955 - Strip leading and trailing C0 controls and space for urls passed to new URL() r=mcmanus

MozReview-Commit-ID: B7BiKE6P7GA
This commit is contained in:
Valentin Gosu 2016-05-25 16:23:37 +02:00
parent b8472acaf5
commit 78d21aba95
5 changed files with 76 additions and 76 deletions

View File

@ -197,16 +197,12 @@ nsSimpleURI::SetSpec(const nsACString &aSpec)
NS_ENSURE_STATE(mMutable);
const nsAFlatCString& flat = PromiseFlatCString(aSpec);
const char* specPtr = flat.get();
// filter out unexpected chars "\r\n\t" if necessary
nsAutoCString filteredSpec;
int32_t specLen;
if (net_FilterURIString(specPtr, filteredSpec)) {
specPtr = filteredSpec.get();
specLen = filteredSpec.Length();
} else
specLen = flat.Length();
net_FilterURIString(flat, filteredSpec);
const char* specPtr = filteredSpec.get();
int32_t specLen = filteredSpec.Length();
// nsSimpleURI currently restricts the charset to US-ASCII
nsAutoCString spec;

View File

@ -1293,21 +1293,22 @@ nsStandardURL::SetSpec(const nsACString &input)
ENSURE_MUTABLE();
const nsPromiseFlatCString &flat = PromiseFlatCString(input);
const char *spec = flat.get();
int32_t specLength = flat.Length();
LOG(("nsStandardURL::SetSpec [spec=%s]\n", spec));
if (!spec || !*spec)
return NS_ERROR_MALFORMED_URI;
LOG(("nsStandardURL::SetSpec [spec=%s]\n", flat.get()));
if (input.Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
// NUL characters aren't allowed
// \r\n\t are stripped out instead of returning error(see below)
if (input.Contains('\0')) {
// filter out unexpected chars "\r\n\t" if necessary
nsAutoCString filteredURI;
net_FilterURIString(flat, filteredURI);
if (filteredURI.Length() == 0) {
return NS_ERROR_MALFORMED_URI;
}
// NUL characters aren't allowed in the filtered URI.
if (filteredURI.Contains('\0')) {
return NS_ERROR_MALFORMED_URI;
}
@ -1316,14 +1317,6 @@ nsStandardURL::SetSpec(const nsACString &input)
prevURL.CopyMembers(this, eHonorRef);
Clear();
// filter out unexpected chars "\r\n\t" if necessary
nsAutoCString filteredURI;
if (!net_FilterURIString(spec, filteredURI)) {
// Copy the content into filteredURI even if no whitespace was stripped.
// We need a non-const buffer to perform backslash replacement.
filteredURI = input;
}
if (IsSpecialProtocol(filteredURI)) {
// Bug 652186: Replace all backslashes with slashes when parsing paths
// Stop when we reach the query or the hash.
@ -1342,9 +1335,8 @@ nsStandardURL::SetSpec(const nsACString &input)
}
}
spec = filteredURI.get();
specLength = filteredURI.Length();
const char *spec = filteredURI.get();
int32_t specLength = filteredURI.Length();
// parse the given URL...
nsresult rv = ParseURL(spec, specLength);
@ -2122,19 +2114,12 @@ NS_IMETHODIMP
nsStandardURL::Resolve(const nsACString &in, nsACString &out)
{
const nsPromiseFlatCString &flat = PromiseFlatCString(in);
const char *relpath = flat.get();
// filter out unexpected chars "\r\n\t" if necessary
nsAutoCString buf;
int32_t relpathLen;
if (!net_FilterURIString(relpath, buf)) {
// Copy the content into filteredURI even if no whitespace was stripped.
// We need a non-const buffer to perform backslash replacement.
buf = in;
}
net_FilterURIString(flat, buf);
relpath = buf.get();
relpathLen = buf.Length();
const char *relpath = buf.get();
int32_t relpathLen = buf.Length();
char *result = nullptr;

View File

@ -475,12 +475,19 @@ nsresult
net_ExtractURLScheme(const nsACString &inURI,
nsACString& scheme)
{
Tokenizer p(inURI, "\r\n\t");
nsACString::const_iterator start, end;
inURI.BeginReading(start);
inURI.EndReading(end);
while (p.CheckWhite() || p.CheckChar(' ')) {
// Skip leading whitespace
// Strip C0 and space from begining
while (start != end) {
if ((uint8_t) *start > 0x20) {
break;
}
start++;
}
Tokenizer p(Substring(start, end), "\r\n\t");
p.Record();
if (!p.CheckChar(isAsciiAlpha)) {
// First char must be alpha
@ -523,12 +530,20 @@ net_IsValidScheme(const char *scheme, uint32_t schemeLen)
bool
net_IsAbsoluteURL(const nsACString& uri)
{
Tokenizer p(uri, "\r\n\t");
nsACString::const_iterator start, end;
uri.BeginReading(start);
uri.EndReading(end);
while (p.CheckWhite() || p.CheckChar(' ')) {
// Skip leading whitespace
// Strip C0 and space from begining
while (start != end) {
if ((uint8_t) *start > 0x20) {
break;
}
start++;
}
Tokenizer p(Substring(start, end), "\r\n\t");
// First char must be alpha
if (!p.CheckChar(isAsciiAlpha)) {
return false;
@ -554,39 +569,39 @@ net_IsAbsoluteURL(const nsACString& uri)
return false;
}
bool
net_FilterURIString(const char *str, nsACString& result)
void
net_FilterURIString(const nsACString& input, nsACString& result)
{
NS_PRECONDITION(str, "Must have a non-null string!");
result.Truncate();
const char *p = str;
// Figure out if we need to filter anything.
bool writing = false;
while (*p) {
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
writing = true;
nsACString::const_iterator start, end;
input.BeginReading(start);
input.EndReading(end);
// Strip C0 and space from begining
while (start != end) {
if ((uint8_t) *start > 0x20) {
break;
}
p++;
start++;
}
if (!writing) {
// Nothing to strip or filter
return false;
MOZ_ASSERT(!*end, "input should null terminated");
// Strip C0 and space from end
while (end != start) {
end--;
if ((uint8_t) *end > 0x20) {
end++;
break;
}
}
nsAutoCString temp;
temp.Assign(str);
temp.Trim("\r\n\t ");
nsAutoCString temp(Substring(start, end));
temp.StripChars("\r\n\t");
result.Assign(temp);
return true;
}
#if defined(XP_WIN)
bool
net_NormalizeFileURL(const nsACString &aURL, nsCString &aResultBuf)

View File

@ -105,21 +105,15 @@ inline bool net_IsValidScheme(const nsAFlatCString &scheme)
}
/**
* Filter out whitespace from a URI string. The input is the |str|
* pointer. |result| is written to if and only if there is whitespace that has
* to be filtered out. The return value is true if and only if |result| is
* written to.
* This function strips out all C0 controls and space at the beginning and end
* of the URL and filters out \r, \n, \t from the middle of the URL. This makes
* it safe to call on things like javascript: urls or data: urls, where we may
* in fact run into whitespace that is not properly encoded.
*
* This function strips out all whitespace at the beginning and end of the URL
* and strips out \r, \n, \t from the middle of the URL. This makes it safe to
* call on things like javascript: urls or data: urls, where we may in fact run
* into whitespace that is not properly encoded.
*
* @param str the pointer to the string to filter. Must be non-null.
* @param input the URL spec we want to filter
* @param result the out param to write to if filtering happens
* @return whether result was written to
*/
bool net_FilterURIString(const char *str, nsACString& result);
void net_FilterURIString(const nsACString& input, nsACString& result);
#if defined(XP_WIN)
/**

View File

@ -346,3 +346,13 @@ add_test(function test_backslashReplacement()
run_next_test();
});
add_test(function test_trim_C0_and_space()
{
var url = stringToURL("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f http://example.com/ \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ");
do_check_eq(url.spec, "http://example.com/");
url.spec = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f http://test.com/ \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ";
do_check_eq(url.spec, "http://test.com/");
Assert.throws(() => { url.spec = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19 "; }, "set empty spec");
run_next_test();
});