Commit e2deca61 authored by Batalov Vladislav's avatar Batalov Vladislav Committed by Commit Bot

Fix the crash in the Get Installed Related Apps API.

There is a moment between requesting manifest and providing the answer
when destroying (detaching) of execution context leds to crash.
E.g. without waiting for the promise to be triggered,
detach the frame by navigating to a different URL.

Change-Id: I6cfcfc26daac62d76aa0323f68d315315799a67e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2358739Reviewed-by: default avatarRayan Kanso <rayankans@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799077}
parent b7df216f
......@@ -319,6 +319,7 @@ source_set("unit_tests") {
"indexeddb/mock_web_idb_transaction.h",
"indexeddb/web_idb_cursor_impl_unittest.cc",
"indexeddb/web_idb_transaction_impl_unittest.cc",
"installedapp/installed_app_controller_test.cc",
"manifest/image_resource_type_converters_test.cc",
"manifest/manifest_manager_unittest.cc",
"manifest/manifest_parser_unittest.cc",
......
......@@ -60,6 +60,10 @@ void InstalledAppController::OnGetManifestForRelatedApps(
std::unique_ptr<AppInstalledCallbacks> callbacks,
const KURL& url,
mojom::blink::ManifestPtr manifest) {
if (!GetExecutionContext()) {
callbacks->OnError();
return;
}
Vector<mojom::blink::RelatedApplicationPtr> mojo_related_apps;
for (const auto& related_application : manifest->related_applications) {
auto application = mojom::blink::RelatedApplication::New();
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/installedapp/installed_app_controller.h"
#include <memory>
#include <utility>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_head_element.h"
#include "third_party/blink/renderer/core/html/html_link_element.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/modules/manifest/manifest_manager.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
namespace blink {
class InstalledAppControllerTest : public testing::Test {
public:
InstalledAppControllerTest()
: holder_(std::make_unique<DummyPageHolder>()),
handle_scope_(GetScriptState()->GetIsolate()),
context_(GetScriptState()->GetContext()),
context_scope_(context_) {}
Document& GetDocument() { return holder_->GetDocument(); }
LocalFrame& GetFrame() { return holder_->GetFrame(); }
ScriptState* GetScriptState() const {
return ToScriptStateForMainWorld(&holder_->GetFrame());
}
void ResetContext() { holder_.reset(); }
protected:
void SetUp() override {
url_test_helpers::RegisterMockedURLLoad(
KURL("https://example.com/manifest.json"), "", "");
GetFrame().Loader().CommitNavigation(
WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(),
KURL("https://example.com")),
nullptr /* extra_data */);
test::RunPendingTasks();
auto* link_manifest = MakeGarbageCollected<HTMLLinkElement>(
GetDocument(), CreateElementFlags());
link_manifest->setAttribute(blink::html_names::kRelAttr, "manifest");
GetDocument().head()->AppendChild(link_manifest);
link_manifest->setAttribute(html_names::kHrefAttr,
"https://example.com/manifest.json");
ManifestManager::From(*GetFrame().DomWindow())->DidChangeManifest();
}
private:
std::unique_ptr<DummyPageHolder> holder_;
v8::HandleScope handle_scope_;
v8::Local<v8::Context> context_;
v8::Context::Scope context_scope_;
};
TEST_F(InstalledAppControllerTest, DestroyContextBeforeCallback) {
auto* controller = InstalledAppController::From(*GetFrame().DomWindow());
auto* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(GetScriptState());
ScriptPromise promise = resolver->Promise();
controller->GetInstalledRelatedApps(
std::make_unique<
CallbackPromiseAdapter<HeapVector<Member<RelatedApplication>>, void>>(
resolver));
ExecutionContext::From(GetScriptState())->NotifyContextDestroyed();
test::RunPendingTasks();
// Not to crash is enough.
}
} // namespace blink
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