Commit 0df68e0e authored by Liquan(Max) Gu's avatar Liquan(Max) Gu Committed by Commit Bot

[UserTimingL3] Throw TypeError on negative time stamp

According to the spec (https://w3c.github.io/user-timing/):
1. "If markOptions's startTime is negative, throw a TypeError.",
2. "If mark is negative, throw a TypeError." when "Convert a mark to a timestamp"

The CL is to add these two checks accordingly.

Bug: 953865
Change-Id: I8475870cc883dc8c3d3d4f3e65a9d5a0a2189a58
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1691871Reviewed-by: default avatarLiquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarNicolás Peña Moreno <npm@chromium.org>
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676266}
parent d23ff3f3
...@@ -110,6 +110,11 @@ PerformanceMark* UserTiming::CreatePerformanceMark( ...@@ -110,6 +110,11 @@ PerformanceMark* UserTiming::CreatePerformanceMark(
DOMHighResTimeStamp start = 0.0; DOMHighResTimeStamp start = 0.0;
if (mark_options && mark_options->hasStartTime()) { if (mark_options && mark_options->hasStartTime()) {
start = mark_options->startTime(); start = mark_options->startTime();
if (start < 0.0) {
exception_state.ThrowTypeError("'" + mark_name +
"' cannot have a negative start time.");
return nullptr;
}
} else { } else {
start = performance_->now(); start = performance_->now();
} }
...@@ -192,14 +197,20 @@ double UserTiming::FindExistingMarkStartTime(const AtomicString& mark_name, ...@@ -192,14 +197,20 @@ double UserTiming::FindExistingMarkStartTime(const AtomicString& mark_name,
return value - timing->navigationStart(); return value - timing->navigationStart();
} }
double UserTiming::GetTimeOrFindMarkTime(const StringOrDouble& mark_or_time, double UserTiming::GetTimeOrFindMarkTime(const AtomicString& measure_name,
const StringOrDouble& mark_or_time,
ExceptionState& exception_state) { ExceptionState& exception_state) {
if (mark_or_time.IsString()) { if (mark_or_time.IsString()) {
return FindExistingMarkStartTime(AtomicString(mark_or_time.GetAsString()), return FindExistingMarkStartTime(AtomicString(mark_or_time.GetAsString()),
exception_state); exception_state);
} }
DCHECK(mark_or_time.IsDouble()); DCHECK(mark_or_time.IsDouble());
return mark_or_time.GetAsDouble(); const double time = mark_or_time.GetAsDouble();
if (time < 0.0) {
exception_state.ThrowTypeError("'" + measure_name +
"' cannot have a negative time stamp.");
}
return time;
} }
PerformanceMeasure* UserTiming::Measure(ScriptState* script_state, PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
...@@ -209,12 +220,15 @@ PerformanceMeasure* UserTiming::Measure(ScriptState* script_state, ...@@ -209,12 +220,15 @@ PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
const ScriptValue& detail, const ScriptValue& detail,
ExceptionState& exception_state) { ExceptionState& exception_state) {
double start_time = double start_time =
start.IsNull() ? 0.0 : GetTimeOrFindMarkTime(start, exception_state); start.IsNull()
? 0.0
: GetTimeOrFindMarkTime(measure_name, start, exception_state);
if (exception_state.HadException()) if (exception_state.HadException())
return nullptr; return nullptr;
double end_time = end.IsNull() ? performance_->now() double end_time =
: GetTimeOrFindMarkTime(end, exception_state); end.IsNull() ? performance_->now()
: GetTimeOrFindMarkTime(measure_name, end, exception_state);
if (exception_state.HadException()) if (exception_state.HadException())
return nullptr; return nullptr;
......
...@@ -71,7 +71,8 @@ class UserTiming final : public GarbageCollected<UserTiming> { ...@@ -71,7 +71,8 @@ class UserTiming final : public GarbageCollected<UserTiming> {
private: private:
double FindExistingMarkStartTime(const AtomicString& mark_name, double FindExistingMarkStartTime(const AtomicString& mark_name,
ExceptionState&); ExceptionState&);
double GetTimeOrFindMarkTime(const StringOrDouble& mark_or_time, double GetTimeOrFindMarkTime(const AtomicString& measure_name,
const StringOrDouble& mark_or_time,
ExceptionState&); ExceptionState&);
Member<Performance> performance_; Member<Performance> performance_;
......
...@@ -96,10 +96,16 @@ ...@@ -96,10 +96,16 @@
test(function() { test(function() {
this.add_cleanup(cleanupPerformanceTimeline); this.add_cleanup(cleanupPerformanceTimeline);
assert_throws(new TypeError(), function() { assert_throws(new TypeError(), function() {
self.performance.measure("wrongUsage2", {'start': 2}, 12); self.performance.measure("optionsAndNumberEnd", {'start': 2}, 12);
}, "measure should throw a TypeError when passed an options object and an end time"); }, "measure should throw a TypeError when passed an options object and an end time");
assert_throws(new TypeError(), function() { assert_throws(new TypeError(), function() {
self.performance.measure("wrongUsage3", {'start': 2}, 'mark1'); self.performance.measure("optionsAndMarkEnd", {'start': 2}, 'mark1');
}, "measure should throw a TypeError when passed an options object and an end mark"); }, "measure should throw a TypeError when passed an options object and an end mark");
assert_throws(new TypeError(), function() {
self.performance.measure("negativeStartInOptions", {'start': -1});
}, "measure cannot have a negative time stamp.");
assert_throws(new TypeError(), function() {
self.performance.measure("negativeEndInOptions", {'end': -1});
}, "measure cannot have a negative time stamp for end.");
}, "measure should throw a TypeError when passed an invalid argument combination"); }, "measure should throw a TypeError when passed an invalid argument combination");
</script> </script>
This is a testharness.js-based test. This is a testharness.js-based test.
FAIL measure entries' detail and start/end are customizable Cannot read property 'name' of null FAIL measure entries' detail and start/end are customizable Cannot read property 'name' of null
FAIL measure should throw a TypeError when passed an invalid argument combination assert_throws: measure should throw a TypeError when passed an options object and an end time function "function() { FAIL measure should throw a TypeError when passed an invalid argument combination assert_throws: measure should throw a TypeError when passed an options object and an end time function "function() {
self.performance.measure("wrongUsage2", {'start': 2}, 12); self.performance.measure("optionsAndNumberEnd", {'start': 2}, 12);
}" threw object "SyntaxError: Failed to execute 'measure' on 'Performance': The mark '12' does not exist." ("SyntaxError") expected object "TypeError" ("TypeError") }" threw object "SyntaxError: Failed to execute 'measure' on 'Performance': The mark '12' does not exist." ("SyntaxError") expected object "TypeError" ("TypeError")
Harness: the test ran to completion. Harness: the test ran to completion.
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