Bug 1789128 - Always call LoadInfo::GetPerformanceStorage() r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D156825
This commit is contained in:
Valentin Gosu 2022-09-20 15:27:44 +00:00
parent 6e51ec685a
commit 56e1364da9
7 changed files with 39 additions and 31 deletions

View File

@ -4258,24 +4258,30 @@ mozilla::ipc::IPCResult ContentChild::RecvScriptError(
}
mozilla::ipc::IPCResult ContentChild::RecvReportFrameTimingData(
uint64_t innerWindowId, const nsString& entryName,
const mozilla::Maybe<LoadInfoArgs>& loadInfoArgs, const nsString& entryName,
const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData) {
if (!aData) {
return IPC_FAIL(this, "aData should not be null");
}
auto* innerWindow = nsGlobalWindowInner::GetInnerWindowWithId(innerWindowId);
if (!innerWindow) {
if (loadInfoArgs.isNothing()) {
return IPC_FAIL(this, "loadInfoArgs should not be null");
}
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(loadInfoArgs,
getter_AddRefs(loadInfo));
if (NS_FAILED(rv)) {
MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed");
return IPC_OK();
}
mozilla::dom::Performance* performance = innerWindow->GetPerformance();
if (!performance) {
return IPC_OK();
// It is important to call LoadInfo::GetPerformanceStorage instead of simply
// getting the performance object via the innerWindowID in order to perform
// necessary cross origin checks.
if (PerformanceStorage* storage = loadInfo->GetPerformanceStorage()) {
storage->AddEntry(entryName, initiatorType, std::move(aData));
}
performance->AsPerformanceStorage()->AddEntry(entryName, initiatorType,
std::move(aData));
return IPC_OK();
}

View File

@ -732,8 +732,9 @@ class ContentChild final : public PContentChild,
const uint64_t& aInnerWindowId, const bool& aFromChromeContext);
mozilla::ipc::IPCResult RecvReportFrameTimingData(
uint64_t innerWindowId, const nsString& entryName,
const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData);
const mozilla::Maybe<LoadInfoArgs>& loadInfoArgs,
const nsString& entryName, const nsString& initiatorType,
UniquePtr<PerformanceTimingData>&& aData);
mozilla::ipc::IPCResult RecvLoadURI(
const MaybeDiscarded<BrowsingContext>& aContext,

View File

@ -4883,14 +4883,19 @@ mozilla::ipc::IPCResult ContentParent::RecvConsoleMessage(
}
mozilla::ipc::IPCResult ContentParent::RecvReportFrameTimingData(
uint64_t aInnerWindowId, const nsAString& entryName,
const nsAString& initiatorType, UniquePtr<PerformanceTimingData>&& aData) {
const mozilla::Maybe<LoadInfoArgs>& loadInfoArgs,
const nsAString& entryName, const nsAString& initiatorType,
UniquePtr<PerformanceTimingData>&& aData) {
if (!aData) {
return IPC_FAIL(this, "aData should not be null");
}
if (loadInfoArgs.isNothing()) {
return IPC_FAIL(this, "loadInfoArgs should not be null");
}
RefPtr<WindowGlobalParent> parent =
WindowGlobalParent::GetByInnerWindowId(aInnerWindowId);
WindowGlobalParent::GetByInnerWindowId(loadInfoArgs->innerWindowID());
if (!parent || !parent->GetContentParent()) {
return IPC_OK();
}
@ -4899,7 +4904,7 @@ mozilla::ipc::IPCResult ContentParent::RecvReportFrameTimingData(
"No need to bounce around if in the same process");
Unused << parent->GetContentParent()->SendReportFrameTimingData(
aInnerWindowId, entryName, initiatorType, std::move(aData));
loadInfoArgs, entryName, initiatorType, std::move(aData));
return IPC_OK();
}

View File

@ -1073,8 +1073,9 @@ class ContentParent final : public PContentParent,
const uint64_t& aInnerWindowId, const bool& aIsFromChromeContext);
mozilla::ipc::IPCResult RecvReportFrameTimingData(
uint64_t innerWindowId, const nsAString& entryName,
const nsAString& initiatorType, UniquePtr<PerformanceTimingData>&& aData);
const mozilla::Maybe<LoadInfoArgs>& loadInfoArgs,
const nsAString& entryName, const nsAString& initiatorType,
UniquePtr<PerformanceTimingData>&& aData);
mozilla::ipc::IPCResult RecvScriptErrorWithStack(
const nsAString& aMessage, const nsAString& aSourceName,

View File

@ -1837,9 +1837,10 @@ both:
* another process. Child frame will send data to its ContentParent which
* will then identify the ContentParent for the innerWindowId and pass
* the data to the correct process.
* loadInfo is passed in order to enforce same-origin security checks
* aData must be non-null.
*/
async ReportFrameTimingData(uint64_t innerWindowId, nsString entryName,
async ReportFrameTimingData(LoadInfoArgs? loadInfo, nsString entryName,
nsString initiatorType,
UniquePtr<PerformanceTimingData> aData);

View File

@ -5270,29 +5270,22 @@ IMPL_TIMING_ATTR(RedirectEnd)
#undef IMPL_TIMING_ATTR
mozilla::dom::PerformanceStorage* HttpBaseChannel::GetPerformanceStorage() {
void HttpBaseChannel::MaybeReportTimingData() {
// If performance timing is disabled, there is no need for the Performance
// object anymore.
if (!LoadTimingEnabled()) {
return nullptr;
return;
}
// There is no point in continuing, since the performance object in the parent
// isn't the same as the one in the child which will be reporting resource
// performance.
if (XRE_IsE10sParentProcess()) {
return nullptr;
}
return mLoadInfo->GetPerformanceStorage();
}
void HttpBaseChannel::MaybeReportTimingData() {
if (XRE_IsE10sParentProcess()) {
return;
}
mozilla::dom::PerformanceStorage* documentPerformance =
GetPerformanceStorage();
mLoadInfo->GetPerformanceStorage();
if (documentPerformance) {
documentPerformance->AddEntry(this, this);
return;
@ -5315,8 +5308,10 @@ void HttpBaseChannel::MaybeReportTimingData() {
if (!performanceTimingData) {
return;
}
child->SendReportFrameTimingData(mLoadInfo->GetInnerWindowID(), entryName,
initiatorType,
Maybe<LoadInfoArgs> loadInfoArgs;
mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
child->SendReportFrameTimingData(loadInfoArgs, entryName, initiatorType,
std::move(performanceTimingData));
}
}

View File

@ -551,7 +551,6 @@ class HttpBaseChannel : public nsHashPropertyBag,
// was fired.
void NotifySetCookie(const nsACString& aCookie);
mozilla::dom::PerformanceStorage* GetPerformanceStorage();
void MaybeReportTimingData();
nsIURI* GetReferringPage();
nsPIDOMWindowInner* GetInnerDOMWindow();