Commit e6cbbc3c authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

<meta>: Correct number parsing for meta refresh.

We should ignore trailing "." and digits after a number.
We should reject a leading "-", a leading "+", and scientific notation.

Bug: 742104
Change-Id: I4e5ed15e0a07f361fd86680a60430cb2d760dc83
Reviewed-on: https://chromium-review.googlesource.com/574973
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarTakayoshi Kochi <kochi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487446}
parent 8e043c4c
......@@ -838,8 +838,6 @@ crbug.com/108417 external/wpt/html/rendering/non-replaced-elements/tables/table-
crbug.com/490511 external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/color.html [ Failure ]
crbug.com/490511 external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/width.html [ Failure ]
crbug.com/742672 external/wpt/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/moving-documents.html [ Failure Pass ]
# [Slow] didn't help.
crbug.com/742104 external/wpt/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html [ Timeout ]
crbug.com/692560 external/wpt/html/semantics/document-metadata/styling/LinkStyle.html [ Failure Pass ]
crbug.com/627706 external/wpt/html/semantics/embedded-content/the-img-element/invalid-src.html [ Skip ]
......
This is a testharness.js-based test.
Found 64 tests; 63 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS ""
PASS "1"
PASS "1 "
PASS "1\t"
PASS "1\r"
PASS "1\n"
PASS "1\f"
PASS "1;"
PASS "1,"
PASS "1; url=foo"
PASS "1, url=foo"
PASS "1 url=foo"
PASS "1;\turl=foo"
PASS "1,\turl=foo"
PASS "1\turl=foo"
PASS "1;\rurl=foo"
PASS "1,\rurl=foo"
PASS "1\rurl=foo"
PASS "1;\nurl=foo"
PASS "1,\nurl=foo"
PASS "1\nurl=foo"
PASS "1;\furl=foo"
PASS "1,\furl=foo"
PASS "1\furl=foo"
PASS "1url=foo"
PASS "1x;url=foo"
PASS "1 x;url=foo"
PASS "1;;url=foo"
PASS " 1 ; url = foo"
PASS " 1 , url = foo"
PASS " 1 ; foo"
PASS " 1 , foo"
PASS " 1 url = foo"
PASS "1; url=foo "
PASS "1; url=f\to\no"
PASS "1; url=\"foo\"bar"
PASS "1; url='foo'bar"
PASS "1; url=\"foo'bar"
PASS "1; url foo"
PASS "1; urlfoo"
PASS "1; urfoo"
PASS "1; ufoo"
PASS "1; \"foo\"bar"
PASS "; foo"
PASS ", foo"
PASS "foo"
PASS "+1; url=foo"
PASS "-1; url=foo"
PASS "+0; url=foo"
PASS "-0; url=foo"
PASS "0; url=foo"
PASS "+1; foo"
PASS "-1; foo"
PASS "+0; foo"
PASS "-0; foo"
PASS "0; foo"
PASS "+1"
PASS "-1"
PASS "+0"
PASS "-0"
PASS "0"
PASS "1.9; url=foo"
PASS "1.9..5.; url=foo"
FAIL ".9; url=foo" assert_equals: expected "refresh.sub.html" but got "foo"
Harness: the test ran to completion.
......@@ -220,6 +220,27 @@ const UChar* ParseSuboriginPolicyOption(const UChar* begin,
return position + 1;
}
// Parse a number with ignoring trailing [0-9.].
// Returns NaN if the source contains invalid characters.
double ParseRefreshTime(const String& source) {
int full_stop_count = 0;
unsigned number_end = source.length();
for (unsigned i = 0; i < source.length(); ++i) {
UChar ch = source[i];
if (ch == kFullstopCharacter) {
// TODO(tkent): According to the HTML specification, we should support
// only integers. However we support fractional numbers.
if (++full_stop_count == 2)
number_end = i;
} else if (!IsASCIIDigit(ch)) {
return std::numeric_limits<double>::quiet_NaN();
}
}
bool ok;
double time = source.Left(number_end).ToDouble(&ok);
return ok ? time : std::numeric_limits<double>::quiet_NaN();
}
} // namespace
bool IsValidHTTPHeaderValue(const String& name) {
......@@ -248,6 +269,7 @@ bool IsContentDispositionAttachment(const String& content_disposition) {
return net::HttpContentDisposition(string, std::string()).is_attachment();
}
// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-refresh
bool ParseHTTPRefresh(const String& refresh,
WTF::CharacterMatchFunctionPtr matcher,
double& delay,
......@@ -265,13 +287,11 @@ bool ParseHTTPRefresh(const String& refresh,
if (pos == len) { // no URL
url = String();
bool ok;
delay = refresh.StripWhiteSpace().ToDouble(&ok);
return ok;
delay = ParseRefreshTime(refresh.StripWhiteSpace());
return std::isfinite(delay);
} else {
bool ok;
delay = refresh.Left(pos).StripWhiteSpace().ToDouble(&ok);
if (!ok)
delay = ParseRefreshTime(refresh.Left(pos).StripWhiteSpace());
if (!std::isfinite(delay))
return false;
SkipWhiteSpace(refresh, pos, matcher);
......
......@@ -393,6 +393,9 @@ TEST(HTTPParsersTest, ParseHTTPRefresh) {
String url;
EXPECT_FALSE(ParseHTTPRefresh("", nullptr, delay, url));
EXPECT_FALSE(ParseHTTPRefresh(" ", nullptr, delay, url));
EXPECT_FALSE(ParseHTTPRefresh("1.3xyz url=foo", nullptr, delay, url));
EXPECT_FALSE(ParseHTTPRefresh("1.3.4xyz url=foo", nullptr, delay, url));
EXPECT_FALSE(ParseHTTPRefresh("1e1 url=foo", nullptr, delay, url));
EXPECT_TRUE(ParseHTTPRefresh("123 ", nullptr, delay, url));
EXPECT_EQ(123.0, delay);
......@@ -417,6 +420,19 @@ TEST(HTTPParsersTest, ParseHTTPRefresh) {
ParseHTTPRefresh("10\nurl=dest", IsASCIISpace<UChar>, delay, url));
EXPECT_EQ(10, delay);
EXPECT_EQ("dest", url);
EXPECT_TRUE(
ParseHTTPRefresh("1.5; url=dest", IsASCIISpace<UChar>, delay, url));
EXPECT_EQ(1.5, delay);
EXPECT_EQ("dest", url);
EXPECT_TRUE(
ParseHTTPRefresh("1.5.9; url=dest", IsASCIISpace<UChar>, delay, url));
EXPECT_EQ(1.5, delay);
EXPECT_EQ("dest", url);
EXPECT_TRUE(
ParseHTTPRefresh("7..; url=dest", IsASCIISpace<UChar>, delay, url));
EXPECT_EQ(7, delay);
EXPECT_EQ("dest", url);
}
TEST(HTTPParsersTest, ParseMultipartHeadersResult) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment