mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21258845f0 | ||
|
|
96bcadd290 | ||
|
|
ee1030e044 | ||
|
|
11d1bfa071 | ||
|
|
131be8cefd |
@@ -1 +1 @@
|
||||
12.0.17
|
||||
12.0.18
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "12.0.17",
|
||||
"version": "12.0.18",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -144,3 +144,6 @@ cherry-pick-3feda0244490.patch
|
||||
cherry-pick-cd98d7c0dae9.patch
|
||||
replace_first_of_two_waitableevents_in_creditcardaccessmanager.patch
|
||||
cherry-pick-ac9dc1235e28.patch
|
||||
cherry-pick-4ce2abc17078.patch
|
||||
cherry-pick-e2123a8e0943.patch
|
||||
cherry-pick-1227933.patch
|
||||
|
||||
215
patches/chromium/cherry-pick-1227933.patch
Normal file
215
patches/chromium/cherry-pick-1227933.patch
Normal file
@@ -0,0 +1,215 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Koji Ishii <kojii@chromium.org>
|
||||
Date: Mon, 26 Jul 2021 07:09:18 +0000
|
||||
Subject: Fix nested inline box fragmentation
|
||||
|
||||
This patch fixes when nested inline boxes are fragmented in a
|
||||
line due to bidi reordering.
|
||||
|
||||
Before this change, the fragmented boxes are appended to the
|
||||
end of |box_data_list_|. Then when |NGInlineLayoutStateStack::
|
||||
CreateBoxFragments| creates inline boxes in the ascending
|
||||
order of |box_data_list_|, it failed to add the fragmented
|
||||
boxes into their parent inline boxes.
|
||||
|
||||
This is critical for out-of-flow positioned objects whose
|
||||
containing block is an inline box, because they expect to be
|
||||
propagated through all ancestor inline boxes.
|
||||
|
||||
|UpdateBoxDataFragmentRange| is a little tricky by appending
|
||||
to a vector it is iterating. Changing it to insert to the
|
||||
correct position makes the function even trickier. This patch
|
||||
changes it to add fragmented boxes to a separate vector, and
|
||||
let later process |UpdateFragmentedBoxDataEdges| to merge the
|
||||
vector to |box_data_list_|.
|
||||
|
||||
(cherry picked from commit 9c8a39c14a9c80556468593cddf436f5047a16ce)
|
||||
|
||||
Bug: 1227933, 1229999
|
||||
Change-Id: I7edcd209e1fdac06bab01b16d660383e7e9c37bd
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3038308
|
||||
Commit-Queue: Koji Ishii <kojii@chromium.org>
|
||||
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#903356}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3053212
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Koji Ishii <kojii@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4577@{#145}
|
||||
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
|
||||
index b257014513cb881d4531694b86c05fd21edb6732..9a3f6f3af7839ebed24f7d8a32b7f95fba66cd9a 100644
|
||||
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h"
|
||||
|
||||
+#include "base/containers/adapters.h"
|
||||
#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
|
||||
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
|
||||
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
|
||||
@@ -387,13 +388,14 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
|
||||
box_data.fragment_start = box_data.fragment_end = 0;
|
||||
|
||||
// Scan children and update start/end from their box_data_index.
|
||||
- unsigned box_count = box_data_list_.size();
|
||||
+ Vector<BoxData> fragmented_boxes;
|
||||
for (unsigned index = 0; index < line_box->size();)
|
||||
- index = UpdateBoxDataFragmentRange(line_box, index);
|
||||
+ index = UpdateBoxDataFragmentRange(line_box, index, &fragmented_boxes);
|
||||
|
||||
- // If any inline fragmentation due to BiDi reorder, adjust box edges.
|
||||
- if (box_count != box_data_list_.size())
|
||||
- UpdateFragmentedBoxDataEdges();
|
||||
+ // If any inline fragmentation occurred due to BiDi reorder, append them and
|
||||
+ // adjust box edges.
|
||||
+ if (UNLIKELY(!fragmented_boxes.IsEmpty()))
|
||||
+ UpdateFragmentedBoxDataEdges(&fragmented_boxes);
|
||||
|
||||
#if DCHECK_IS_ON()
|
||||
// Check all BoxData have ranges.
|
||||
@@ -410,7 +412,8 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
|
||||
|
||||
unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
|
||||
NGLogicalLineItems* line_box,
|
||||
- unsigned index) {
|
||||
+ unsigned index,
|
||||
+ Vector<BoxData>* fragmented_boxes) {
|
||||
// Find the first line box item that should create a box fragment.
|
||||
for (; index < line_box->size(); index++) {
|
||||
NGLogicalLineItem* start = &(*line_box)[index];
|
||||
@@ -438,7 +441,7 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
|
||||
// It also changes other BoxData, but not the one we're dealing with here
|
||||
// because the update is limited only when its |box_data_index| is lower.
|
||||
while (end->box_data_index && end->box_data_index < box_data_index) {
|
||||
- UpdateBoxDataFragmentRange(line_box, index);
|
||||
+ UpdateBoxDataFragmentRange(line_box, index, fragmented_boxes);
|
||||
}
|
||||
|
||||
if (box_data_index != end->box_data_index)
|
||||
@@ -453,14 +456,9 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
|
||||
} else {
|
||||
// This box is fragmented by BiDi reordering. Add a new BoxData for the
|
||||
// fragmented range.
|
||||
- box_data_list_[box_data_index - 1].fragmented_box_data_index =
|
||||
- box_data_list_.size();
|
||||
- // Do not use `emplace_back()` here because adding to |box_data_list_| may
|
||||
- // reallocate the buffer, but the `BoxData` ctor must run before the
|
||||
- // reallocation. Create a new instance and |push_back()| instead.
|
||||
- BoxData fragmented_box_data(box_data_list_[box_data_index - 1],
|
||||
- start_index, index);
|
||||
- box_data_list_.push_back(fragmented_box_data);
|
||||
+ BoxData& fragmented_box = fragmented_boxes->emplace_back(
|
||||
+ box_data_list_[box_data_index - 1], start_index, index);
|
||||
+ fragmented_box.fragmented_box_data_index = box_data_index;
|
||||
}
|
||||
// If this box has parent boxes, we need to process it again.
|
||||
if (box_data_list_[box_data_index - 1].parent_box_data_index)
|
||||
@@ -470,7 +468,43 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
|
||||
return index;
|
||||
}
|
||||
|
||||
-void NGInlineLayoutStateStack::UpdateFragmentedBoxDataEdges() {
|
||||
+void NGInlineLayoutStateStack::UpdateFragmentedBoxDataEdges(
|
||||
+ Vector<BoxData>* fragmented_boxes) {
|
||||
+ DCHECK(!fragmented_boxes->IsEmpty());
|
||||
+ // Append in the descending order of |fragmented_box_data_index| because the
|
||||
+ // indices will change as boxes are inserted into |box_data_list_|.
|
||||
+ std::sort(fragmented_boxes->begin(), fragmented_boxes->end(),
|
||||
+ [](const BoxData& a, const BoxData& b) {
|
||||
+ if (a.fragmented_box_data_index != b.fragmented_box_data_index) {
|
||||
+ return a.fragmented_box_data_index <
|
||||
+ b.fragmented_box_data_index;
|
||||
+ }
|
||||
+ DCHECK_NE(a.fragment_start, b.fragment_start);
|
||||
+ return a.fragment_start < b.fragment_start;
|
||||
+ });
|
||||
+ for (BoxData& fragmented_box : base::Reversed(*fragmented_boxes)) {
|
||||
+ // Insert the fragmented box to right after the box it was fragmented from.
|
||||
+ // The order in the |box_data_list_| is critical when propagating child
|
||||
+ // fragment data such as OOF to ancestors.
|
||||
+ const unsigned insert_at = fragmented_box.fragmented_box_data_index;
|
||||
+ DCHECK_GT(insert_at, 0u);
|
||||
+ fragmented_box.fragmented_box_data_index = 0;
|
||||
+ box_data_list_.insert(insert_at, fragmented_box);
|
||||
+
|
||||
+ // Adjust box data indices by the insertion.
|
||||
+ for (BoxData& box_data : box_data_list_) {
|
||||
+ if (box_data.fragmented_box_data_index >= insert_at)
|
||||
+ ++box_data.fragmented_box_data_index;
|
||||
+ }
|
||||
+
|
||||
+ // Set the index of the last fragment to the original box. This is needed to
|
||||
+ // update fragment edges.
|
||||
+ const unsigned fragmented_from = insert_at - 1;
|
||||
+ if (!box_data_list_[fragmented_from].fragmented_box_data_index)
|
||||
+ box_data_list_[fragmented_from].fragmented_box_data_index = insert_at;
|
||||
+ }
|
||||
+
|
||||
+ // Move the line-right edge to the last fragment.
|
||||
for (BoxData& box_data : box_data_list_) {
|
||||
if (box_data.fragmented_box_data_index)
|
||||
box_data.UpdateFragmentEdges(box_data_list_);
|
||||
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
|
||||
index 82ecfef8fe4d404d5713f0f67d83b38ecfbfca4c..9d079266efd7f2ccc43cef40d8d89e4fc6edda9e 100644
|
||||
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
|
||||
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
|
||||
@@ -156,17 +156,6 @@ class CORE_EXPORT NGInlineLayoutStateStack {
|
||||
// reordering.
|
||||
void UpdateAfterReorder(NGLogicalLineItems*);
|
||||
|
||||
- // Update start/end of the first BoxData found at |index|.
|
||||
- //
|
||||
- // If inline fragmentation is found, a new BoxData is added.
|
||||
- //
|
||||
- // Returns the index to process next. It should be given to the next call to
|
||||
- // this function.
|
||||
- unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*, unsigned index);
|
||||
-
|
||||
- // Update edges of inline fragmented boxes.
|
||||
- void UpdateFragmentedBoxDataEdges();
|
||||
-
|
||||
// Compute inline positions of fragments and boxes.
|
||||
LayoutUnit ComputeInlinePositions(NGLogicalLineItems*, LayoutUnit position);
|
||||
|
||||
@@ -259,6 +248,19 @@ class CORE_EXPORT NGInlineLayoutStateStack {
|
||||
scoped_refptr<const NGLayoutResult> CreateBoxFragment(NGLogicalLineItems*);
|
||||
};
|
||||
|
||||
+ // Update start/end of the first BoxData found at |index|.
|
||||
+ //
|
||||
+ // If inline fragmentation is found, a new BoxData is added.
|
||||
+ //
|
||||
+ // Returns the index to process next. It should be given to the next call to
|
||||
+ // this function.
|
||||
+ unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*,
|
||||
+ unsigned index,
|
||||
+ Vector<BoxData>* fragmented_boxes);
|
||||
+
|
||||
+ // Update edges of inline fragmented boxes.
|
||||
+ void UpdateFragmentedBoxDataEdges(Vector<BoxData>* fragmented_boxes);
|
||||
+
|
||||
Vector<NGInlineBoxState, 4> stack_;
|
||||
Vector<BoxData, 4> box_data_list_;
|
||||
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html b/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b701d2b5688ace54aa99530c12fa8143f1e6a508
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html
|
||||
@@ -0,0 +1,13 @@
|
||||
+<!DOCTYPE html>
|
||||
+<link rel="author" href="mailto:mstensho@chromium.org">
|
||||
+<link rel="help" href="https://crbug.com/1229999">
|
||||
+<div style="direction:rtl; width:500px">
|
||||
+ <span style="border:solid">
|
||||
+ <span style="position:relative">
|
||||
+ <div style="display:inline-block; width:1000%; height:10px"></div>
|
||||
+ <span dir="ltr">
|
||||
+ <div style="position:absolute"></div>
|
||||
+ </span>
|
||||
+ </span>
|
||||
+ </span>
|
||||
+</div>
|
||||
135
patches/chromium/cherry-pick-4ce2abc17078.patch
Normal file
135
patches/chromium/cherry-pick-4ce2abc17078.patch
Normal file
@@ -0,0 +1,135 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Flack <flackr@chromium.org>
|
||||
Date: Fri, 30 Jul 2021 18:51:38 +0000
|
||||
Subject: Forbid script execution for entire lifecycle update
|
||||
|
||||
We should not execute script during the lifecycle update except in cases where we we know it is safe to do so, either because we will rerun the lifecycle steps if anything is invalidated (resize observers, intersection observers) or because the script does not have access to invalidate the DOM (e.g. paint worklets).
|
||||
|
||||
(cherry picked from commit a73237da91de8aa49aaa5d9479bae51cf387f090)
|
||||
|
||||
Bug: 1196853
|
||||
Change-Id: Id1fdbbb25107cfdc6c234123f845406c28d32914
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2815619
|
||||
Reviewed-by: Stefan Zager <szager@chromium.org>
|
||||
Commit-Queue: Robert Flack <flackr@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#901110}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3058973
|
||||
Auto-Submit: Robert Flack <flackr@chromium.org>
|
||||
Commit-Queue: Stefan Zager <szager@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4472@{#1588}
|
||||
Cr-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
|
||||
index d3512edd4cad7b7dafbb1c3a6da5cd45ea367e79..69f8e8a598a4aefef652e603f1590c702e288b59 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
|
||||
@@ -96,6 +96,7 @@
|
||||
#include "third_party/blink/renderer/core/script/classic_script.h"
|
||||
#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
|
||||
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
|
||||
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
|
||||
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
|
||||
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
|
||||
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
|
||||
@@ -804,6 +805,8 @@ void WebPluginContainerImpl::Dispose() {
|
||||
}
|
||||
|
||||
if (web_plugin_) {
|
||||
+ // Plugins may execute script on being detached during the lifecycle update.
|
||||
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
|
||||
CHECK(web_plugin_->Container() == this);
|
||||
web_plugin_->Destroy();
|
||||
web_plugin_ = nullptr;
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
|
||||
index dd320dd900b7f556c9216c7faedc2ad35588b0d7..a9e724432440c05d1b3bb9863acb4345e07f77b4 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
|
||||
@@ -2484,6 +2484,7 @@ bool LocalFrameView::UpdateLifecyclePhases(
|
||||
|
||||
void LocalFrameView::UpdateLifecyclePhasesInternal(
|
||||
DocumentLifecycle::LifecycleState target_state) {
|
||||
+ ScriptForbiddenScope forbid_script;
|
||||
// RunScrollTimelineSteps must not run more than once.
|
||||
bool should_run_scroll_timeline_steps = true;
|
||||
|
||||
@@ -2564,6 +2565,10 @@ void LocalFrameView::UpdateLifecyclePhasesInternal(
|
||||
continue;
|
||||
}
|
||||
|
||||
+ // At this point in time, script is allowed to run as we will repeat the
|
||||
+ // lifecycle update if anything is invalidated.
|
||||
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
|
||||
+
|
||||
// ResizeObserver and post-layout IntersectionObserver observation
|
||||
// deliveries may dirty style and layout. RunResizeObserverSteps will return
|
||||
// true if any observer ran that may have dirtied style or layout;
|
||||
@@ -2816,6 +2821,7 @@ bool LocalFrameView::AnyFrameIsPrintingOrPaintingPreview() {
|
||||
}
|
||||
|
||||
void LocalFrameView::RunPaintLifecyclePhase(PaintBenchmarkMode benchmark_mode) {
|
||||
+ DCHECK(ScriptForbiddenScope::IsScriptForbidden());
|
||||
TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPaintLifecyclePhase");
|
||||
// While printing or capturing a paint preview of a document, the paint walk
|
||||
// is done into a special canvas. There is no point doing a normal paint step
|
||||
@@ -2850,17 +2856,11 @@ void LocalFrameView::RunPaintLifecyclePhase(PaintBenchmarkMode benchmark_mode) {
|
||||
for (PaintLayerScrollableArea* area : *animating_scrollable_areas)
|
||||
area->UpdateCompositorScrollAnimations();
|
||||
}
|
||||
- {
|
||||
- // Updating animations can notify ready promises which could mutate
|
||||
- // the DOM. We should delay these until we have finished the lifecycle
|
||||
- // update. https://crbug.com/1196781
|
||||
- ScriptForbiddenScope forbid_script;
|
||||
- frame_view.GetLayoutView()
|
||||
- ->GetDocument()
|
||||
- .GetDocumentAnimations()
|
||||
- .UpdateAnimations(DocumentLifecycle::kPaintClean,
|
||||
- paint_artifact_compositor_.get());
|
||||
- }
|
||||
+ frame_view.GetLayoutView()
|
||||
+ ->GetDocument()
|
||||
+ .GetDocumentAnimations()
|
||||
+ .UpdateAnimations(DocumentLifecycle::kPaintClean,
|
||||
+ paint_artifact_compositor_.get());
|
||||
Document& document = frame_view.GetLayoutView()->GetDocument();
|
||||
total_animations_count +=
|
||||
document.GetDocumentAnimations().GetAnimationsCount();
|
||||
@@ -4454,6 +4454,7 @@ void LocalFrameView::RenderThrottlingStatusChanged() {
|
||||
// so painting the tree should just clear the previous painted output.
|
||||
DCHECK(!IsUpdatingLifecycle());
|
||||
AllowThrottlingScope allow_throtting(*this);
|
||||
+ ScriptForbiddenScope forbid_script;
|
||||
RunPaintLifecyclePhase();
|
||||
}
|
||||
|
||||
@@ -4989,6 +4990,7 @@ void LocalFrameView::RunPaintBenchmark(int repeat_count,
|
||||
// quantization when the time is very small.
|
||||
base::LapTimer timer(kWarmupRuns, kTimeLimit, kTimeCheckInterval);
|
||||
do {
|
||||
+ ScriptForbiddenScope forbid_script;
|
||||
RunPaintLifecyclePhase(mode);
|
||||
timer.NextLap();
|
||||
} while (!timer.HasTimeLimitExpired());
|
||||
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
|
||||
index e6e0c5b909c4d073963bcbb074bfb091a6ccb83b..618e08fbb5157c06348feee5f0120bd28ed0bc44 100644
|
||||
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
|
||||
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h"
|
||||
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_id_generator.h"
|
||||
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h"
|
||||
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
|
||||
#include "third_party/blink/renderer/platform/graphics/paint_generated_image.h"
|
||||
|
||||
namespace blink {
|
||||
@@ -126,6 +127,10 @@ scoped_refptr<Image> PaintWorklet::Paint(const String& name,
|
||||
layout_object.GetDocument(), layout_object.StyleRef(),
|
||||
paint_definition->NativeInvalidationProperties(),
|
||||
paint_definition->CustomInvalidationProperties());
|
||||
+ // The PaintWorkletGlobalScope is sufficiently isolated that it is safe to
|
||||
+ // run during the lifecycle update without concern for it causing
|
||||
+ // invalidations to the lifecycle.
|
||||
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
|
||||
sk_sp<PaintRecord> paint_record = paint_definition->Paint(
|
||||
container_size, zoom, style_map, data, device_scale_factor);
|
||||
if (!paint_record)
|
||||
64
patches/chromium/cherry-pick-e2123a8e0943.patch
Normal file
64
patches/chromium/cherry-pick-e2123a8e0943.patch
Normal file
@@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tal Pressman <talp@chromium.org>
|
||||
Date: Wed, 21 Jul 2021 09:11:13 +0000
|
||||
Subject: Manually post task to bind FileUtilitiesHost.
|
||||
|
||||
The FileUtilitiesHost binder is posted to a separate sequence, and the
|
||||
ServiceWorkerHost may be destroyed by the time the it runs, causing a
|
||||
UAF.
|
||||
This CL changes it so that, when we try to bind a new receiver, the
|
||||
host's worker_process_id() is obtained first (on the service worker's
|
||||
core thread) and then a task is posted to do the actual binding on a
|
||||
USER_VISIBLE task runner.
|
||||
|
||||
Credit: This issue was first reported (with analysis) by
|
||||
soulchen8650@gmail.com.
|
||||
|
||||
Bug: 1229298
|
||||
Change-Id: I6d5c05a830ba30f6cb98bf2df70a3df3333f3dd9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3041006
|
||||
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
|
||||
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
|
||||
Commit-Queue: Tal Pressman <talp@google.com>
|
||||
Cr-Commit-Position: refs/heads/master@{#903832}
|
||||
|
||||
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
|
||||
index a45f9d3db09dbc4827c41c254b2b532968930e96..b6f69c1813fc9c66cc6a20205c02cb6e5d810fc5 100644
|
||||
--- a/content/browser/browser_interface_binders.cc
|
||||
+++ b/content/browser/browser_interface_binders.cc
|
||||
@@ -367,10 +367,22 @@ void BindTextSuggestionHostForFrame(
|
||||
}
|
||||
#endif
|
||||
|
||||
+// Get the service worker's worker process ID and post a task to bind the
|
||||
+// receiver on a USER_VISIBLE task runner.
|
||||
+// This is necessary because:
|
||||
+// - Binding the host itself and checking the ID on the task's thread may cause
|
||||
+// a UAF if the host has been deleted in the meantime.
|
||||
+// - The process ID is not yet populated at the time `PopulateInterfaceBinders`
|
||||
+// is called.
|
||||
void BindFileUtilitiesHost(
|
||||
- const ServiceWorkerHost* host,
|
||||
+ ServiceWorkerHost* host,
|
||||
mojo::PendingReceiver<blink::mojom::FileUtilitiesHost> receiver) {
|
||||
- FileUtilitiesHostImpl::Create(host->worker_process_id(), std::move(receiver));
|
||||
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
|
||||
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
|
||||
+ task_runner->PostTask(
|
||||
+ FROM_HERE,
|
||||
+ base::BindOnce(&FileUtilitiesHostImpl::Create, host->worker_process_id(),
|
||||
+ std::move(receiver)));
|
||||
}
|
||||
|
||||
template <typename WorkerHost, typename Interface>
|
||||
@@ -1122,9 +1134,7 @@ void PopulateServiceWorkerBinders(ServiceWorkerHost* host,
|
||||
|
||||
// static binders
|
||||
map->Add<blink::mojom::FileUtilitiesHost>(
|
||||
- base::BindRepeating(&BindFileUtilitiesHost, host),
|
||||
- base::ThreadPool::CreateSequencedTaskRunner(
|
||||
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE}));
|
||||
+ base::BindRepeating(&BindFileUtilitiesHost, host));
|
||||
map->Add<shape_detection::mojom::BarcodeDetectionProvider>(
|
||||
base::BindRepeating(&BindBarcodeDetectionProvider));
|
||||
map->Add<shape_detection::mojom::FaceDetectionProvider>(
|
||||
@@ -1230,31 +1230,29 @@ void WebContents::OnEnterFullscreenModeForTab(
|
||||
content::RenderFrameHost* requesting_frame,
|
||||
const blink::mojom::FullscreenOptions& options,
|
||||
bool allowed) {
|
||||
if (!allowed)
|
||||
return;
|
||||
if (!owner_window_)
|
||||
if (!allowed || !owner_window_)
|
||||
return;
|
||||
|
||||
auto* source = content::WebContents::FromRenderFrameHost(requesting_frame);
|
||||
if (IsFullscreenForTabOrPending(source)) {
|
||||
DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
|
||||
return;
|
||||
}
|
||||
|
||||
SetHtmlApiFullscreen(true);
|
||||
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
||||
|
||||
if (native_fullscreen_) {
|
||||
// Explicitly trigger a view resize, as the size is not actually changing if
|
||||
// the browser is fullscreened, too.
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
|
||||
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
|
||||
SetHtmlApiFullscreen(false);
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
|
||||
if (native_fullscreen_) {
|
||||
// Explicitly trigger a view resize, as the size is not actually changing if
|
||||
@@ -1262,7 +1260,6 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
|
||||
// `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
Emit("leave-html-full-screen");
|
||||
}
|
||||
|
||||
void WebContents::RendererUnresponsive(
|
||||
@@ -3585,7 +3582,7 @@ void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
||||
}
|
||||
|
||||
void WebContents::UpdateHtmlApiFullscreen(bool fullscreen) {
|
||||
if (fullscreen == html_fullscreen_)
|
||||
if (fullscreen == is_html_fullscreen())
|
||||
return;
|
||||
|
||||
html_fullscreen_ = fullscreen;
|
||||
@@ -3596,11 +3593,19 @@ void WebContents::UpdateHtmlApiFullscreen(bool fullscreen) {
|
||||
->GetWidget()
|
||||
->SynchronizeVisualProperties();
|
||||
|
||||
// The embedder WebContents is spearated from the frame tree of webview, so
|
||||
// The embedder WebContents is separated from the frame tree of webview, so
|
||||
// we must manually sync their fullscreen states.
|
||||
if (embedder_)
|
||||
embedder_->SetHtmlApiFullscreen(fullscreen);
|
||||
|
||||
if (fullscreen) {
|
||||
Emit("enter-html-full-screen");
|
||||
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
||||
} else {
|
||||
Emit("leave-html-full-screen");
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
}
|
||||
|
||||
// Make sure all child webviews quit html fullscreen.
|
||||
if (!fullscreen && !IsGuest()) {
|
||||
auto* manager = WebViewManager::GetWebViewManager(web_contents());
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 12,0,17,0
|
||||
PRODUCTVERSION 12,0,17,0
|
||||
FILEVERSION 12,0,18,0
|
||||
PRODUCTVERSION 12,0,18,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "12.0.17"
|
||||
VALUE "FileVersion", "12.0.18"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "12.0.17"
|
||||
VALUE "ProductVersion", "12.0.18"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -458,6 +458,34 @@ describe('<webview> tag', function () {
|
||||
await delay(0);
|
||||
expect(w.isFullScreen()).to.be.false();
|
||||
});
|
||||
|
||||
it('pressing ESC should emit the leave-html-full-screen event', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
webviewTag: true,
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
|
||||
const didAttachWebview = emittedOnce(w.webContents, 'did-attach-webview');
|
||||
w.loadFile(path.join(fixtures, 'pages', 'webview-did-attach-event.html'));
|
||||
|
||||
const [, webContents] = await didAttachWebview;
|
||||
|
||||
const enterFSWindow = emittedOnce(w, 'enter-html-full-screen');
|
||||
const enterFSWebview = emittedOnce(webContents, 'enter-html-full-screen');
|
||||
await webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
|
||||
await enterFSWindow;
|
||||
await enterFSWebview;
|
||||
|
||||
const leaveFSWindow = emittedOnce(w, 'leave-html-full-screen');
|
||||
const leaveFSWebview = emittedOnce(webContents, 'leave-html-full-screen');
|
||||
webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Escape' });
|
||||
await leaveFSWindow;
|
||||
await leaveFSWebview;
|
||||
});
|
||||
});
|
||||
|
||||
describe('nativeWindowOpen option', () => {
|
||||
|
||||
1
spec/fixtures/pages/a.html
vendored
1
spec/fixtures/pages/a.html
vendored
@@ -3,6 +3,7 @@
|
||||
<link rel="icon" type="image/png" href="http://test.com/favicon.png"/>
|
||||
<meta http-equiv="content-security-policy" content="script-src 'self' 'unsafe-inline'" />
|
||||
<body>
|
||||
<div id="div">Hello World</div>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
console.log('a');
|
||||
document.title = "test"
|
||||
|
||||
Reference in New Issue
Block a user