From a0d52c009403ce26131b73a1bcf5e2ec20555256 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Thu, 6 Apr 2023 21:20:33 +0800 Subject: [PATCH] Issue #2053 - Part 4b: Fix measure name to timestamp conversion Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1772417 --- dom/bindings/Errors.msg | 1 + dom/performance/Performance.cpp | 47 ++++++++++++++++++++++++--------- dom/performance/Performance.h | 3 +++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index 7f53a24966..0a9babdc73 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -108,3 +108,4 @@ MSG_DEF(MSG_PMO_UNKNOWN_MARK_NAME, 1, JSEXN_SYNTAXERR, "Given mark name, {0}, is MSG_DEF(MSG_PMO_CONSTRUCTOR_INACCESSIBLE, 0, JSEXN_TYPEERR, "Can't access PerformanceMark constructor, performance is null.") MSG_DEF(MSG_PMO_INVALID_TIMING_ATTR, 0, JSEXN_SYNTAXERR, "markName cannot be a performance timing attribute.") MSG_DEF(MSG_PMO_UNEXPECTED_START_TIME, 0, JSEXN_TYPEERR, "Expected startTime >= 0.") +MSG_DEF(MSG_PMO_INVALID_ATTR_FOR_NON_GLOBAL, 1, JSEXN_TYPEERR, "Cannot get PerformanceTiming attribute values for non-Window global object. Given: {0}.") diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp index bf36707be8..8e5851ceed 100755 --- a/dom/performance/Performance.cpp +++ b/dom/performance/Performance.cpp @@ -326,8 +326,11 @@ DOMHighResTimeStamp Performance::ConvertMarkToTimestampWithString(const nsAString& aName, ErrorResult& aRv) { + if (IsPerformanceTimingAttribute(aName)) { + return ConvertNameToTimestamp(aName, aRv); + } + AutoTArray, 1> arr; - DOMHighResTimeStamp ts; Optional typeParam; nsAutoString str; str.AssignLiteral("mark"); @@ -337,18 +340,8 @@ Performance::ConvertMarkToTimestampWithString(const nsAString& aName, return arr.LastElement()->StartTime(); } - if (!IsPerformanceTimingAttribute(aName)) { - aRv.ThrowTypeError(aName); - return 0; - } - - ts = GetPerformanceTimingFromString(aName); - if (!ts) { - aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); - return 0; - } - - return ts - CreationTime(); + aRv.ThrowTypeError(aName); + return 0; } DOMHighResTimeStamp @@ -390,6 +383,34 @@ Performance::ConvertMarkToTimestamp( aAttribute, aMarkNameOrTimestamp.GetAsDouble(), aRv); } +DOMHighResTimeStamp Performance::ConvertNameToTimestamp(const nsAString& aName, + ErrorResult& aRv) { + if (!IsGlobalObjectWindow()) { + aRv.ThrowTypeError(aName); + return 0; + } + + if (aName.EqualsASCII("navigationStart")) { + return 0; + } + + // We use GetPerformanceTimingFromString, rather than calling the + // navigationStart method timing function directly, because the former handles + // reducing precision against timing attacks. + const DOMHighResTimeStamp startTime = + GetPerformanceTimingFromString(NS_LITERAL_STRING("navigationStart")); + const DOMHighResTimeStamp endTime = + GetPerformanceTimingFromString(aName); + MOZ_ASSERT(endTime >= 0); + if (endTime == 0) { + // Was given a PerformanceTiming attribute which isn't available yet. + aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); + return 0; + } + + return endTime - startTime; +} + DOMHighResTimeStamp Performance::ResolveEndTimeForMeasure( const Optional& aEndMark, diff --git a/dom/performance/Performance.h b/dom/performance/Performance.h index 75d164c214..1b2bb5586c 100644 --- a/dom/performance/Performance.h +++ b/dom/performance/Performance.h @@ -190,6 +190,9 @@ private: const ResolveTimestampAttribute aAttribute, const OwningStringOrDouble& aMarkNameOrTimestamp, ErrorResult& aRv); + DOMHighResTimeStamp ConvertNameToTimestamp(const nsAString& aName, + ErrorResult& aRv); + DOMHighResTimeStamp ResolveEndTimeForMeasure( const Optional& aEndMark, const PerformanceMeasureOptions* aOptions,