chore: cherry-pick 7 changes from Release-1-M113 (#38331)

* chore: [23-x-y] cherry-pick 8 changes from Release-1-M113

* 91fce3345668 from v8
* 2c8a019f39d2 from v8
* b8020e1973d7 from v8
* d6272b794cbb from chromium
* 48785f698b1c from chromium
* d0ee0197ddff from angle
* 9b6ca211234b from chromium
* 675562695049 from chromium

* chore: clean up patches, delete bad patch

* chore: cherry-pick bb90b9cfcbca from v8

* build: fixup angle patch

* build: fixup v8 patches

* chore: fixup Handle empty ranges in unicode sets patch

* build: drop python2 from CI (#38303)

(cherry picked from commit a22e2a778e)
(cherry picked from commit 9bdd4738ae)

* chore: update patches for 110

* refactor: add WebViewGuestDelegate::GetGuestDelegateWeakPtr()

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/4515455

This approach copied from GuestViewBase::GetGuestDelegateWeakPtr() approach in that same commit.

(cherry picked from commit 3f3ab39e3a1077f71aa90319d7a81d53cfb3c55e)

* chore: cherry-pick bae60787d3e9 from dawn

* chore: delete unnecessary patches

* Revert "refactor: add WebViewGuestDelegate::GetGuestDelegateWeakPtr()"

This reverts commit 07a42e351e.

* chore: remove unneeded patch

* chore: update patches

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
This commit is contained in:
Keeley Hammond
2023-06-12 14:36:35 -07:00
committed by GitHub
parent f4041c10cf
commit 2c822ce4ac
13 changed files with 1183 additions and 8 deletions

View File

@@ -1,3 +1,4 @@
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
cherry-pick-6da1a8953313.patch
cherry-pick-aed05b609629.patch
cherry-pick-d0ee0197ddff.patch

View File

@@ -0,0 +1,214 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Wed, 3 May 2023 13:41:36 -0400
Subject: WebGL: Limit total size of private data
... not just individual arrays.
Bug: chromium:1431761
Change-Id: I721e29aeceeaf12c3f6a67b668abffb8dfbc89b0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4503753
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index c9607db74b53487950d31f6a56d55f3e834556a0..a05e857d7111528ad7f21799e3825b9d3f488dd3 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -23,6 +23,7 @@ namespace
// Arbitrarily enforce that types - even local variables' - declared
// with a size in bytes of over 2 GB will cause compilation failure.
constexpr size_t kMaxTypeSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
// Traverses intermediate tree to ensure that the shader does not
// exceed certain implementation-defined limits on the sizes of types.
@@ -31,7 +32,9 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
{
public:
ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
- : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mDiagnostics(diagnostics),
+ mTotalPrivateVariablesSize(0)
{
ASSERT(diagnostics);
}
@@ -85,11 +88,37 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
asSymbol->getName());
return false;
}
+
+ const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
+ variableType.getQualifier() == EvqGlobal ||
+ variableType.getQualifier() == EvqConst;
+ if (isPrivate)
+ {
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+ mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
+ }
}
return true;
}
+ void validateTotalPrivateVariableSize()
+ {
+ if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
+ {
+ mDiagnostics->error(
+ TSourceLoc{},
+ "Total size of declared private variables exceeds implementation-defined limit",
+ "");
+ }
+ }
+
private:
void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
{
@@ -198,6 +227,8 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
TDiagnostics *mDiagnostics;
std::vector<int> mLoopSymbolIds;
+
+ size_t mTotalPrivateVariablesSize;
};
} // namespace
@@ -208,6 +239,7 @@ bool ValidateTypeSizeLimitations(TIntermNode *root,
{
ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
root->traverse(&validate);
+ validate.validateTotalPrivateVariableSize();
return diagnostics->numErrors() == 0;
}
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 7dc56cddbc63add1aca6fca3bfd031f3da8d04fc..64287af5834607f6819f1197e2eed1a56f712ffe 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5271,11 +5271,12 @@ TEST_P(WebGLCompatibilityTest, ValidateArraySizes)
// fairly small array.
constexpr char kVSArrayOK[] =
R"(varying vec4 color;
-const int array_size = 1000;
+const int array_size = 500;
void main()
{
mat2 array[array_size];
- if (array[0][0][0] == 2.0)
+ mat2 array2[array_size];
+ if (array[0][0][0] + array2[0][0][0] == 2.0)
color = vec4(0.0, 1.0, 0.0, 1.0);
else
color = vec4(1.0, 0.0, 0.0, 1.0);
@@ -5353,6 +5354,103 @@ void main()
EXPECT_EQ(0u, program);
}
+// Reject attempts to allocate too much private memory.
+// This is an implementation-defined limit - crbug.com/1431761.
+TEST_P(WebGLCompatibilityTest, ValidateTotalPrivateSize)
+{
+ constexpr char kTooLargeGlobalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+vec4 array2[32769];
+
+void main()
+{
+ if (array[0].x + array[1].x == 0.)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32767];
+vec4 array2[32767];
+vec4 x, y, z;
+
+void main()
+{
+ if (array[0].x + array[1].x == x.w + y.w + z.w)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalAndLocalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+void main()
+{
+ vec4 array2[32769];
+ if (array[0].x + array[1].x == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ // Note: The call stack is not taken into account for the purposes of total memory calculation.
+ constexpr char kTooLargeGlobalAndLocalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+float f()
+{
+ vec4 array2[16384];
+ return array2[0].x;
+}
+
+float g()
+{
+ vec4 array3[16383];
+ return array3[0].x;
+}
+
+float h()
+{
+ vec4 value;
+ float value2
+ return value.x + value2;
+}
+
+void main()
+{
+ if (array[0].x + f() + g() + h() == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory2);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
+ EXPECT_EQ(0u, program);
+}
+
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
// qualifiers.
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)

View File

@@ -141,6 +141,8 @@ merge_m112_check_spdyproxyclientsocket_is_alive_after_write.patch
check_callback_availability_in.patch
m112_cherry_pick_libxml_cve_fix.patch
m112_fix_scopedobservation_uaf_in.patch
cherry-pick-48785f698b1c.patch
cherry-pick-675562695049.patch
cherry-pick-ea1cd76358e0.patch
m114_merge_fix_a_crash_caused_by_calling_trace_event.patch
mojoipcz_copy_incoming_messages_early.patch

View File

@@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Arthur Sonzogni <arthursonzogni@chromium.org>
Date: Tue, 2 May 2023 09:40:37 +0000
Subject: Avoid buffer overflow read in HFSReadNextNonIgnorableCodePoint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Unicode codepoints goes beyond 0xFFFF.
It exists upper and lower case characters there: `𞤡 `vs `𞥃`.
The buffer overflow occurred when using the lookup table:
```
lower_case_table[codepoint >> 8]
```
Bug: 1425115
Fixed: 1425115
Change-Id: I679da02dbe570283a68176fbd3c0c620caa4f9ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4481260
Reviewed-by: Alexander Timin <altimin@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1138234}
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index a43c09317da96332584286fdb67284b2bedd753f..3a7cca6fad051816d6d018857c8039594c51ec65 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -775,7 +775,7 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
#elif BUILDFLAG(IS_APPLE)
// Mac OS X specific implementation of file string comparisons.
-// cf. http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties
+// cf. https://developer.apple.com/library/archive/technotes/tn/tn1150.html#UnicodeSubtleties
//
// "When using CreateTextEncoding to create a text encoding, you should set
// the TextEncodingBase to kTextEncodingUnicodeV2_0, set the
@@ -801,11 +801,12 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
// Ignored characters are mapped to zero.
//
// cf. downloadable file linked in
-// http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm
+// https://developer.apple.com/library/archive/technotes/tn/tn1150.html#Downloads
namespace {
-const UInt16 lower_case_table[] = {
+// clang-format off
+const UInt16 lower_case_table[11 * 256] = {
// High-byte indices ( == 0 iff no case mapping and no ignorables )
/* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
@@ -1191,11 +1192,12 @@ const UInt16 lower_case_table[] = {
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
};
+// clang-format on
-// Returns the next non-ignorable codepoint within string starting from the
-// position indicated by index, or zero if there are no more.
-// The passed-in index is automatically advanced as the characters in the input
-// HFS-decomposed UTF-8 strings are read.
+// Returns the next non-ignorable codepoint within `string` starting from the
+// position indicated by `index`, or zero if there are no more.
+// The passed-in `index` is automatically advanced as the characters in the
+// input HFS-decomposed UTF-8 strings are read.
inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
size_t length,
size_t* index) {
@@ -1206,12 +1208,16 @@ inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
CBU8_NEXT(reinterpret_cast<const uint8_t*>(string), *index, length,
codepoint);
DCHECK_GT(codepoint, 0);
- if (codepoint > 0) {
+
+ // Note: Here, there are no lower case conversion implemented in the
+ // Supplementary Multilingual Plane (codepoint > 0xFFFF).
+
+ if (codepoint > 0 && codepoint <= 0xFFFF) {
// Check if there is a subtable for this upper byte.
int lookup_offset = lower_case_table[codepoint >> 8];
if (lookup_offset != 0)
codepoint = lower_case_table[lookup_offset + (codepoint & 0x00FF)];
- // Note: codepoint1 may be again 0 at this point if the character was
+ // Note: `codepoint` may be again 0 at this point if the character was
// an ignorable.
}
}
diff --git a/base/files/file_path_unittest.cc b/base/files/file_path_unittest.cc
index 3cfdcbe445c1f6e0d66e3798927131f94759fb3c..08c3e75b7e1ad55f5f81aed80f80081115f8f49c 100644
--- a/base/files/file_path_unittest.cc
+++ b/base/files/file_path_unittest.cc
@@ -1195,6 +1195,13 @@ TEST_F(FilePathTest, CompareIgnoreCase) {
{{FPL("K\u0301U\u032DO\u0304\u0301N"), FPL("\u1E31\u1E77\u1E53n")}, 0},
{{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("\u1E30\u1E76\u1E52n")}, 0},
{{FPL("k\u0301u\u032Do\u0304\u0302n"), FPL("\u1E30\u1E76\u1E52n")}, 1},
+
+ // Codepoints > 0xFFFF
+ // Here, we compare the `Adlam Letter Shu` in its capital and small version.
+ {{FPL("\U0001E921"), FPL("\U0001E943")}, -1},
+ {{FPL("\U0001E943"), FPL("\U0001E921")}, 1},
+ {{FPL("\U0001E921"), FPL("\U0001E921")}, 0},
+ {{FPL("\U0001E943"), FPL("\U0001E943")}, 0},
#endif
};

View File

@@ -0,0 +1,142 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Mon, 15 May 2023 03:21:49 +0000
Subject: Return after ReadyCommitNavigation call in CommitErrorPage if it
deletes NavigationRequest
NavigationRequest::ReadyToCommitNavigation() can cause deletion of the
NavigationRequest, so callers should check for that possibility after
calling the function. A caller in CommitErrorPage is missing that
check, which this CL adds, along with a regression test.
(cherry picked from commit 42db806805ef2be64ee92803d3a784631b2a7df0)
Bug: 1444360
Change-Id: I3964da4909a6709b7730d25d6497b19c098f4f21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4520493
Commit-Queue: Charlie Reis <creis@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1143298}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4531446
Reviewed-by: Prudhvikumar Bommana <pbommana@google.com>
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Commit-Queue: Prudhvikumar Bommana <pbommana@google.com>
Owners-Override: Prudhvikumar Bommana <pbommana@google.com>
Cr-Commit-Position: refs/branch-heads/5735@{#607}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index fd95d91a9a4efbfbbcfb117d9f2129b1b1c95011..c3f1bb989c30bf00750404995d080c3b8ee0e1c6 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -5034,7 +5034,13 @@ void NavigationRequest::CommitErrorPage(
}
}
+ base::WeakPtr<NavigationRequest> weak_self(weak_factory_.GetWeakPtr());
ReadyToCommitNavigation(true /* is_error */);
+ // The caller above might result in the deletion of `this`. Return immediately
+ // if so.
+ if (!weak_self) {
+ return;
+ }
PopulateDocumentTokenForCrossDocumentNavigation();
// Use a separate cache shard, and no cookies, for error pages.
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc
index 1213eb485a25a183ca23643941ae97ee6cfb596f..837af410e31d90769cb7e5d0f9c0bb9abf3035df 100644
--- a/content/browser/renderer_host/navigation_request_browsertest.cc
+++ b/content/browser/renderer_host/navigation_request_browsertest.cc
@@ -44,6 +44,7 @@
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_service.mojom.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
@@ -4032,4 +4033,84 @@ IN_PROC_BROWSER_TEST_P(NavigationRequestMPArchBrowserTest,
}
}
+// Tests that when trying to commit an error page for a failed navigation, but
+// the renderer process of the, the navigation won't commit and won't crash.
+// Regression test for https://crbug.com/1444360.
+IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest,
+ RendererCrashedBeforeCommitErrorPage) {
+ // Navigate to `url_a` first.
+ GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ ASSERT_TRUE(NavigateToURL(shell(), url_a));
+
+ // Set up an URLLoaderInterceptor which will cause future navigations to fail.
+ auto url_loader_interceptor = std::make_unique<URLLoaderInterceptor>(
+ base::BindRepeating([](URLLoaderInterceptor::RequestParams* params) {
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::ERR_NOT_IMPLEMENTED;
+ params->client->OnComplete(status);
+ return true;
+ }));
+
+ // Do a navigation to `url_b1` that will fail and commit an error page. This
+ // is important so that the next error page navigation won't need to create a
+ // speculative RenderFrameHost (unless RenderDocument is enabled) and won't
+ // get cancelled earlier than commit time due to speculative RFH deletion.
+ GURL url_b1(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ EXPECT_FALSE(NavigateToURL(shell(), url_b1));
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
+ EXPECT_TRUE(
+ shell()->web_contents()->GetPrimaryMainFrame()->IsErrorDocument());
+
+ // For the next navigation, set up a throttle that will be used to wait for
+ // WillFailRequest() and then defer the navigation, so that we can crash the
+ // error page process first.
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(),
+ NavigationThrottle::PROCEED /* will_start_result */,
+ NavigationThrottle::PROCEED /* will_redirect_result */,
+ NavigationThrottle::DEFER /* will_fail_result */,
+ NavigationThrottle::PROCEED /* will_process_result */,
+ NavigationThrottle::PROCEED /* will_commit_without_url_loader_result */);
+
+ // Start a navigation to `url_b2` that will also fail, but before it commits
+ // an error page, cause the error page process to crash.
+ GURL url_b2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ TestNavigationManager manager(shell()->web_contents(), url_b2);
+ shell()->LoadURL(url_b2);
+ EXPECT_TRUE(manager.WaitForRequestStart());
+
+ // Resume the navigation and wait for WillFailRequest(). After this point, we
+ // will have picked the final RenderFrameHost & RenderProcessHost for the
+ // failed navigation.
+ manager.ResumeNavigation();
+ installer.WaitForThrottleWillFail();
+
+ // Kill the error page process. This will cause for the navigation to `url_b2`
+ // to return early in `NavigationRequest::ReadyToCommitNavigation()` and not
+ // commit a new error page.
+ RenderProcessHost* process_to_kill =
+ manager.GetNavigationHandle()->GetRenderFrameHost()->GetProcess();
+ ASSERT_TRUE(process_to_kill->IsInitializedAndNotDead());
+ {
+ // Trigger a renderer kill by calling DoSomething() which will cause a bad
+ // message to be reported.
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(process_to_kill);
+ mojo::Remote<mojom::TestService> service;
+ process_to_kill->BindReceiver(service.BindNewPipeAndPassReceiver());
+ service->DoSomething(base::DoNothing());
+ EXPECT_EQ(bad_message::RPH_MOJO_PROCESS_ERROR, kill_waiter.Wait());
+ }
+ ASSERT_FALSE(process_to_kill->IsInitializedAndNotDead());
+
+ // Resume the navigation, which won't commit.
+ if (!ShouldCreateNewHostForAllFrames()) {
+ installer.navigation_throttle()->ResumeNavigation();
+ }
+ EXPECT_TRUE(manager.WaitForNavigationFinished());
+ EXPECT_FALSE(WaitForLoadStop(shell()->web_contents()));
+
+ // The tab stayed at `url_b1` as the `url_b2` navigation didn't commit.
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
+}
+
} // namespace content

View File

@@ -27,5 +27,7 @@
"src/electron/patches/skia": "src/third_party/skia",
"src/electron/patches/dawn": "src/third_party/dawn",
"src/electron/patches/pdfium": "src/third_party/pdfium"
}

1
patches/dawn/.patches Normal file
View File

@@ -0,0 +1 @@
change_d3d12_descriptor_allocator_to_invalidate_submitted_descriptors.patch

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brandon Jones <brandon1.jones@intel.com>
Date: Fri, 5 May 2023 18:02:42 +0000
Subject: Change D3D12 Descriptor Allocator To Invalidate Submitted Descriptors
Changes D3D12 descriptor allocator to invalidate existing descriptors
after the descriptor heap was submitted for use. This fixes a
synchonization issue where stale descriptors were seen as valid because
command list execution ran long.
Bug: dawn:1701
Bug: chromium:1442263
No-Try: true
Change-Id: Ibfd450b3be6cf91d66e8dce4ffd19ecf1a37f7f5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129920
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
(cherry picked from commit df6cb236493da101dad79fe50d4e6df0d5d1e915)
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131508
Kokoro: Austin Eng <enga@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
index fe99a63ac9d2d082c2c23eb7940a733a9d13846a..aedb28ad58a0a972879f07a6037499f901fcf04a 100644
--- a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
@@ -237,9 +237,11 @@ bool ShaderVisibleDescriptorAllocator::IsLastShaderVisibleHeapInLRUForTesting()
bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid(
const GPUDescriptorHeapAllocation& allocation) const {
- // Consider valid if allocated for the pending submit and the shader visible heaps
- // have not switched over.
- return (allocation.GetLastUsageSerial() > mDevice->GetCompletedCommandSerial() &&
+ // Descriptor allocations are only valid for the serial they were created for and are
+ // re-allocated every submit. For this reason, we view any descriptors allocated prior to the
+ // pending submit as invalid. We must also verify the descriptor heap has not switched (because
+ // a larger descriptor heap was needed).
+ return (allocation.GetLastUsageSerial() == mDevice->GetPendingCommandSerial() &&
allocation.GetHeapSerial() == mHeapSerial);
}

View File

@@ -10,6 +10,8 @@ force_cppheapcreateparams_to_be_noncopyable.patch
chore_allow_customizing_microtask_policy_per_context.patch
cherry-pick-c605df24af3c.patch
cherry-pick-f4b66ae451c2.patch
cherry-pick-2c8a019f39d2.patch
cherry-pick-bb90b9cfcbca.patch
merged_ic_fix_store_handler_selection_for_arguments_objects.patch
cherry-pick-73af1a19a901.patch
cherry-pick-3b0607d14060.patch

View File

@@ -0,0 +1,300 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Wed, 26 Apr 2023 10:56:03 -0700
Subject: Fix clobbered register in global Unicode special case
Bug: chromium:1439691
Change-Id: I53f22f484b226b5ad3eb9ffef8a9f44fe962beba
Fixed: chromium:1439691
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4477629
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#87288}
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.cc b/src/regexp/arm/regexp-macro-assembler-arm.cc
index 2658068b6f94b97f024b1400c8c0b20eefdc5143..5de110c8495ef5bd261df92ca8f459c5f0cc7e5b 100644
--- a/src/regexp/arm/regexp-macro-assembler-arm.cc
+++ b/src/regexp/arm/regexp-macro-assembler-arm.cc
@@ -877,19 +877,18 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
__ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
__ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare r0 to initialize registers with its value in the next run.
- __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), r2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// r4: capture start index
__ cmp(current_input_offset(), r4);
// Not a zero-length match, restart.
- __ b(ne, &load_char_start_regexp);
+ __ b(ne, &reload_string_start_minus_one);
// Offset from the end is zero if we already reached the end.
__ cmp(current_input_offset(), Operand::Zero());
__ b(eq, &exit_label_);
@@ -901,6 +900,11 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare r0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ b(&load_char_start_regexp);
} else {
__ mov(r0, Operand(SUCCESS));
diff --git a/src/regexp/ia32/regexp-macro-assembler-ia32.cc b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
index 600234542042ce9a06ceb3b415fece83f6f271bf..6c3df5da7d6c28619902b20419c9cf437325c1d1 100644
--- a/src/regexp/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
@@ -915,19 +915,18 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ add(Operand(ebp, kRegisterOutput),
Immediate(num_saved_registers_ * kSystemPointerSize));
- // Prepare eax to initialize registers with its value in the next run.
- __ mov(eax, Operand(ebp, kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), ebx);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// edx: capture start index
__ cmp(edi, edx);
// Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
+ __ j(not_equal, &reload_string_start_minus_one);
// edi (offset from the end) is zero if we already reached the end.
__ test(edi, edi);
__ j(zero, &exit_label_, Label::kNear);
@@ -941,6 +940,12 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
}
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+
+ __ bind(&reload_string_start_minus_one);
+ // Prepare eax to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ mov(eax, Operand(ebp, kStringStartMinusOne));
+
__ jmp(&load_char_start_regexp);
} else {
__ mov(eax, Immediate(SUCCESS));
diff --git a/src/regexp/loong64/regexp-macro-assembler-loong64.cc b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
index 35fd95bd0f2d210419b4057ced6e16ffd5aec051..d5c52b4134ccbfecef85328e181dae1bbda7bf63 100644
--- a/src/regexp/loong64/regexp-macro-assembler-loong64.cc
+++ b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
@@ -850,18 +850,17 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ Add_d(a2, a2, num_saved_registers_ * kIntSize);
__ St_d(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// t3: capture start index
// Not a zero-length match, restart.
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
Operand(t3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
@@ -874,6 +873,11 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(a0, Operand(SUCCESS));
diff --git a/src/regexp/mips64/regexp-macro-assembler-mips64.cc b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
index 456e166adefc72b7bcaa9245798f3885c2a4c2e7..6ee4c709cf96f68a32a0b3c1ebdc42817293bf29 100644
--- a/src/regexp/mips64/regexp-macro-assembler-mips64.cc
+++ b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
@@ -898,19 +898,18 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ Daddu(a2, a2, num_saved_registers_ * kIntSize);
__ Sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// t3: capture start index
// Not a zero-length match, restart.
- __ Branch(
- &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
+ Operand(t3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
Operand(zero_reg));
@@ -922,6 +921,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(v0, Operand(SUCCESS));
diff --git a/src/regexp/riscv/regexp-macro-assembler-riscv.cc b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
index c8f3eb551e05805003d30a1786acdd9aab96d906..7f79b1e02b145e56ac49d231f31555039c959c05 100644
--- a/src/regexp/riscv/regexp-macro-assembler-riscv.cc
+++ b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
@@ -869,18 +869,17 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
__ AddWord(a2, a2, num_saved_registers_ * kIntSize);
__ StoreWord(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ LoadWord(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// s3: capture start index
// Not a zero-length match, restart.
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
Operand(s3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
@@ -893,6 +892,12 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ LoadWord(a0,
+ MemOperand(frame_pointer(), kStringStartMinusOneOffset));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(a0, Operand(SUCCESS));
diff --git a/src/regexp/s390/regexp-macro-assembler-s390.cc b/src/regexp/s390/regexp-macro-assembler-s390.cc
index a61bc379ba6c265ecb0c5cd7aa8d7a2e35ca6c1e..de184b95862e7f2e64d69cff6b60d866eb212f36 100644
--- a/src/regexp/s390/regexp-macro-assembler-s390.cc
+++ b/src/regexp/s390/regexp-macro-assembler-s390.cc
@@ -947,19 +947,18 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
__ AddS64(r4, Operand(num_saved_registers_ * kIntSize));
__ StoreU64(r4, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare r2 to initialize registers with its value in the next run.
- __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), r4);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// r6: capture start index
__ CmpS64(current_input_offset(), r6);
// Not a zero-length match, restart.
- __ bne(&load_char_start_regexp);
+ __ bne(&reload_string_start_minus_one);
// Offset from the end is zero if we already reached the end.
__ CmpS64(current_input_offset(), Operand::Zero());
__ beq(&exit_label_);
@@ -970,6 +969,11 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare r2 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ b(&load_char_start_regexp);
} else {
__ mov(r2, Operand(SUCCESS));
diff --git a/src/regexp/x64/regexp-macro-assembler-x64.cc b/src/regexp/x64/regexp-macro-assembler-x64.cc
index 89fd2e34f1296113c43f16896d8f35d741782709..7c59534aa46c4c1c6fed151d7dad13070d133f47 100644
--- a/src/regexp/x64/regexp-macro-assembler-x64.cc
+++ b/src/regexp/x64/regexp-macro-assembler-x64.cc
@@ -951,19 +951,18 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ addq(Operand(rbp, kRegisterOutput),
Immediate(num_saved_registers_ * kIntSize));
- // Prepare rax to initialize registers with its value in the next run.
- __ movq(rax, Operand(rbp, kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), kScratchRegister);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// rdx: capture start index
__ cmpq(rdi, rdx);
// Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
+ __ j(not_equal, &reload_string_start_minus_one);
// rdi (offset from the end) is zero if we already reached the end.
__ testq(rdi, rdi);
__ j(zero, &exit_label_, Label::kNear);
@@ -978,6 +977,11 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare rax to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ movq(rax, Operand(rbp, kStringStartMinusOne));
+
__ jmp(&load_char_start_regexp);
} else {
__ Move(rax, SUCCESS);
diff --git a/test/mjsunit/regress/regress-crbug-1439691.js b/test/mjsunit/regress/regress-crbug-1439691.js
new file mode 100644
index 0000000000000000000000000000000000000000..6c55835535ab4f42ef0446abf863986962df9e9b
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1439691.js
@@ -0,0 +1,7 @@
+// Copyright 2023 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f0() {
+}
+/(?!(a))\1/gudyi[Symbol.replace]("f\uD83D\uDCA9ba\u2603", f0);

View File

@@ -43,7 +43,7 @@ index 93939fa4702922f58e8e5bcc019e569f42ab198e..1190b3dedfabee414fb49038e31b3cf2
it.Restart();
}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..3abfd10ee4ad64c67c490d3f9d24f8e6efe08a1f 100644
index 39cc83aacb5caf0791ce70212695f5016a22f274..b3f7db7bd984e8524689c3060bfd0674840fa63b 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -243,27 +243,6 @@ Maybe<bool> JSReceiver::CheckPrivateNameStore(LookupIterator* it,
@@ -74,7 +74,7 @@ index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..3abfd10ee4ad64c67c490d3f9d24f8e6
namespace {
bool HasExcludedProperty(
@@ -3642,7 +3621,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
@@ -3643,7 +3622,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
if (semantics == EnforceDefineSemantics::kDefine) {
it->Restart();
@@ -83,7 +83,7 @@ index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..3abfd10ee4ad64c67c490d3f9d24f8e6
it->isolate(), it, value, should_throw);
if (can_define.IsNothing() || !can_define.FromJust()) {
return can_define;
@@ -4071,17 +4050,16 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
@@ -4072,17 +4051,16 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
Handle<Object> value,
Maybe<ShouldThrow> should_throw) {
DCHECK(it->GetReceiver()->IsJSObject());
@@ -104,7 +104,7 @@ index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..3abfd10ee4ad64c67c490d3f9d24f8e6
DefineOwnPropertyIgnoreAttributes(it, value, NONE),
Nothing<bool>());
@@ -4710,19 +4688,42 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
@@ -4708,19 +4686,42 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
return it.factory()->undefined_value();
}
@@ -155,7 +155,7 @@ index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..3abfd10ee4ad64c67c490d3f9d24f8e6
if (HasFastProperties()) {
DescriptorArray descs = map().instance_descriptors();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index 06489c2b7bae61ecadbd8f020060e86ef50e11b6..f663af6ed8a445f8ef30a67bac176a1abe6c85f8 100644
index ff96bd4be2ff8d2fe03f75b6bca35a744e2084af..5e7326eb1c99115829c358cd4069e1f6835f972b 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -167,12 +167,6 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> {
@@ -171,7 +171,7 @@ index 06489c2b7bae61ecadbd8f020060e86ef50e11b6..f663af6ed8a445f8ef30a67bac176a1a
// ES6 7.3.4 (when passed kDontThrow)
V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
@@ -544,6 +538,12 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
@@ -545,6 +539,12 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
PropertyAttributes attributes);

View File

@@ -17,10 +17,10 @@ Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 3abfd10ee4ad64c67c490d3f9d24f8e6efe08a1f..4046b3d1d1e4a36a15c7f0e859c4e51cd29185e4 100644
index b3f7db7bd984e8524689c3060bfd0674840fa63b..8cc8af6c221a90cc6a6201faa46738ec80ffccdb 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -3632,10 +3632,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
@@ -3633,10 +3633,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
// own property without the interceptor.
Isolate* isolate = it->isolate();
Handle<Object> receiver = it->GetReceiver();

View File

@@ -0,0 +1,362 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Thu, 27 Apr 2023 11:11:32 +0200
Subject: Merged: [api] Fix v8::Object::SetAccessorProperty
... by using JavaScript spec compliant JSReceiver::DefineOwnProperty.
Drive-by:
- cleanup comments in include/v8-object.h, insert links to
respective pages of https://tc39.es/ecma262/ when referencing spec,
- rename JSObject::DefineAccessor() to
JSObject::DefineOwnAccessorIgnoreAttributes().
Bug: chromium:1433211
(cherry picked from commit b8020e1973d7d3a50b17c076cd948f079e59f9e5)
Change-Id: Ia4e0389e99b5a79987f59ca2a11ee7867b0c97e2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4502585
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.2@{#47}
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
diff --git a/include/v8-object.h b/include/v8-object.h
index d7332ba0c88d12e8086f56117631dfb3e1e514b4..dfeda2d39431d481dbeab6698c3d3e7f02a1b19c 100644
--- a/include/v8-object.h
+++ b/include/v8-object.h
@@ -247,13 +247,16 @@ class V8_EXPORT Object : public Value {
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
Local<Value> value);
- // Implements CreateDataProperty (ECMA-262, 7.3.4).
- //
- // Defines a configurable, writable, enumerable property with the given value
- // on the object unless the property already exists and is not configurable
- // or the object is not extensible.
- //
- // Returns true on success.
+ /**
+ * Implements CreateDataProperty(O, P, V), see
+ * https://tc39.es/ecma262/#sec-createdataproperty.
+ *
+ * Defines a configurable, writable, enumerable property with the given value
+ * on the object unless the property already exists and is not configurable
+ * or the object is not extensible.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
Local<Name> key,
Local<Value> value);
@@ -261,29 +264,35 @@ class V8_EXPORT Object : public Value {
uint32_t index,
Local<Value> value);
- // Implements DefineOwnProperty.
- //
- // In general, CreateDataProperty will be faster, however, does not allow
- // for specifying attributes.
- //
- // Returns true on success.
+ /**
+ * Implements [[DefineOwnProperty]] for data property case, see
+ * https://tc39.es/ecma262/#table-essential-internal-methods.
+ *
+ * In general, CreateDataProperty will be faster, however, does not allow
+ * for specifying attributes.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
Local<Context> context, Local<Name> key, Local<Value> value,
PropertyAttribute attributes = None);
- // Implements Object.DefineProperty(O, P, Attributes), see Ecma-262 19.1.2.4.
- //
- // The defineProperty function is used to add an own property or
- // update the attributes of an existing own property of an object.
- //
- // Both data and accessor descriptors can be used.
- //
- // In general, CreateDataProperty is faster, however, does not allow
- // for specifying attributes or an accessor descriptor.
- //
- // The PropertyDescriptor can change when redefining a property.
- //
- // Returns true on success.
+ /**
+ * Implements Object.defineProperty(O, P, Attributes), see
+ * https://tc39.es/ecma262/#sec-object.defineproperty.
+ *
+ * The defineProperty function is used to add an own property or
+ * update the attributes of an existing own property of an object.
+ *
+ * Both data and accessor descriptors can be used.
+ *
+ * In general, CreateDataProperty is faster, however, does not allow
+ * for specifying attributes or an accessor descriptor.
+ *
+ * The PropertyDescriptor can change when redefining a property.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
@@ -302,14 +311,15 @@ class V8_EXPORT Object : public Value {
Local<Context> context, Local<Value> key);
/**
- * Returns Object.getOwnPropertyDescriptor as per ES2016 section 19.1.2.6.
+ * Implements Object.getOwnPropertyDescriptor(O, P), see
+ * https://tc39.es/ecma262/#sec-object.getownpropertydescriptor.
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor(
Local<Context> context, Local<Name> key);
/**
- * Object::Has() calls the abstract operation HasProperty(O, P) described
- * in ECMA-262, 7.3.10. Has() returns
+ * Object::Has() calls the abstract operation HasProperty(O, P), see
+ * https://tc39.es/ecma262/#sec-hasproperty. Has() returns
* true, if the object has the property, either own or on the prototype chain.
* Interceptors, i.e., PropertyQueryCallbacks, are called if present.
*
@@ -347,7 +357,7 @@ class V8_EXPORT Object : public Value {
void SetAccessorProperty(Local<Name> name, Local<Function> getter,
Local<Function> setter = Local<Function>(),
- PropertyAttribute attribute = None,
+ PropertyAttribute attributes = None,
AccessControl settings = DEFAULT);
/**
diff --git a/src/api/api-natives.cc b/src/api/api-natives.cc
index d0b298723423e9ad4d151c463dcdde09d2400336..9f664a755e4b04d935d29b1be796a81ac3fe0c07 100644
--- a/src/api/api-natives.cc
+++ b/src/api/api-natives.cc
@@ -96,10 +96,10 @@ MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
Handle<CodeT> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
Handle<JSFunction>::cast(setter)->set_code(*trampoline);
}
- RETURN_ON_EXCEPTION(
- isolate,
- JSObject::DefineAccessor(object, name, getter, setter, attributes),
- Object);
+ RETURN_ON_EXCEPTION(isolate,
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, getter, setter, attributes),
+ Object);
return object;
}
diff --git a/src/api/api.cc b/src/api/api.cc
index d790bc0fd1b42a6b8107712d5c171751f83e5727..fbdbe4b5c7166e4dc1b2ad7b01aa911beed7f69c 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -5061,7 +5061,7 @@ Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
Local<Function> setter,
- PropertyAttribute attribute,
+ PropertyAttribute attributes,
AccessControl settings) {
// TODO(verwaest): Remove |settings|.
DCHECK_EQ(v8::DEFAULT, settings);
@@ -5073,9 +5073,20 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
if (setter_i.is_null()) setter_i = i_isolate->factory()->null_value();
- i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
- v8::Utils::OpenHandle(*name), getter_i, setter_i,
- static_cast<i::PropertyAttributes>(attribute));
+
+ i::PropertyDescriptor desc;
+ desc.set_enumerable(!(attributes & v8::DontEnum));
+ desc.set_configurable(!(attributes & v8::DontDelete));
+ desc.set_get(getter_i);
+ desc.set_set(setter_i);
+
+ i::Handle<i::Name> name_i = v8::Utils::OpenHandle(*name);
+ // DefineOwnProperty might still throw if the receiver is a JSProxy and it
+ // might fail if the receiver is non-extensible or already has this property
+ // as non-configurable.
+ Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
+ i_isolate, self, name_i, &desc, Just(i::kDontThrow));
+ USE(success);
}
Maybe<bool> Object::SetNativeDataProperty(
diff --git a/src/init/bootstrapper.cc b/src/init/bootstrapper.cc
index 3f5050e824c09ee2577dbd8471ac6b1bcc20755e..f7fdf90f0baeb3dd3516c565bb5e05fc7e8da550 100644
--- a/src/init/bootstrapper.cc
+++ b/src/init/bootstrapper.cc
@@ -631,7 +631,9 @@ V8_NOINLINE void SimpleInstallGetterSetter(Isolate* isolate,
Handle<JSFunction> setter =
SimpleCreateFunction(isolate, setter_name, call_setter, 1, true);
- JSObject::DefineAccessor(base, name, getter, setter, DONT_ENUM).Check();
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, name, getter, setter,
+ DONT_ENUM)
+ .Check();
}
void SimpleInstallGetterSetter(Isolate* isolate, Handle<JSObject> base,
@@ -655,7 +657,8 @@ V8_NOINLINE Handle<JSFunction> SimpleInstallGetter(Isolate* isolate,
Handle<Object> setter = isolate->factory()->undefined_value();
- JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM)
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, property_name, getter,
+ setter, DONT_ENUM)
.Check();
return getter;
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..39cc83aacb5caf0791ce70212695f5016a22f274 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -1519,7 +1519,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
? desc->set()
: Handle<Object>::cast(isolate->factory()->null_value()));
MaybeHandle<Object> result =
- JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
+ JSObject::DefineOwnAccessorIgnoreAttributes(it, getter, setter,
+ desc->ToAttributes());
if (result.is_null()) return Nothing<bool>();
}
}
@@ -1703,8 +1704,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
: current->has_set()
? current->set()
: Handle<Object>::cast(isolate->factory()->null_value()));
- MaybeHandle<Object> result =
- JSObject::DefineAccessor(it, getter, setter, attrs);
+ MaybeHandle<Object> result = JSObject::DefineOwnAccessorIgnoreAttributes(
+ it, getter, setter, attrs);
if (result.is_null()) return Nothing<bool>();
}
}
@@ -4638,22 +4639,19 @@ bool JSObject::HasEnumerableElements() {
UNREACHABLE();
}
-MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes) {
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
+ Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
+ Handle<Object> setter, PropertyAttributes attributes) {
Isolate* isolate = object->GetIsolate();
PropertyKey key(isolate, name);
LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
- return DefineAccessor(&it, getter, setter, attributes);
+ return DefineOwnAccessorIgnoreAttributes(&it, getter, setter, attributes);
}
-MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes) {
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
+ PropertyAttributes attributes) {
Isolate* isolate = it->isolate();
it->UpdateProtector();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index 06489c2b7bae61ecadbd8f020060e86ef50e11b6..ff96bd4be2ff8d2fe03f75b6bca35a744e2084af 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -531,13 +531,14 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
// Defines an AccessorPair property on the given object.
- V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor(
- Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
- Handle<Object> setter, PropertyAttributes attributes);
- static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes);
+ V8_EXPORT_PRIVATE static MaybeHandle<Object>
+ DefineOwnAccessorIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
+ Handle<Object> getter,
+ Handle<Object> setter,
+ PropertyAttributes attributes);
+ static MaybeHandle<Object> DefineOwnAccessorIgnoreAttributes(
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
+ PropertyAttributes attributes);
// Defines an AccessorInfo property on the given object.
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
index 5255ee26807ab13e93935b6c6d513184a12da7cd..f10e4649c6d078c3120063d53e54f4126b2d2fd5 100644
--- a/src/runtime/runtime-object.cc
+++ b/src/runtime/runtime-object.cc
@@ -1109,7 +1109,8 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
auto attrs = PropertyAttributesFromInt(args.smi_value_at(4));
RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
+ isolate, JSObject::DefineOwnAccessorIgnoreAttributes(obj, name, getter,
+ setter, attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1215,8 +1216,8 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::DefineAccessor(object, name, getter,
- isolate->factory()->null_value(), attrs));
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, getter, isolate->factory()->null_value(), attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1360,8 +1361,8 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
- setter, attrs));
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, isolate->factory()->null_value(), setter, attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
diff --git a/src/sandbox/testing.cc b/src/sandbox/testing.cc
index fead4aa222ceb81d76f6dfec7e7797e337e7ba94..aab72a18015bf7ac1d0949e9497e85d9d089b4b8 100644
--- a/src/sandbox/testing.cc
+++ b/src/sandbox/testing.cc
@@ -156,7 +156,8 @@ void InstallGetter(Isolate* isolate, Handle<JSObject> object,
Handle<String> property_name = factory->NewStringFromAsciiChecked(name);
Handle<JSFunction> getter = CreateFunc(isolate, func, property_name, false);
Handle<Object> setter = factory->null_value();
- JSObject::DefineAccessor(object, property_name, getter, setter, FROZEN);
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, property_name, getter,
+ setter, FROZEN);
}
void InstallFunction(Isolate* isolate, Handle<JSObject> holder,
diff --git a/test/cctest/test-code-stub-assembler.cc b/test/cctest/test-code-stub-assembler.cc
index c012e62016aca3a83975cd91216860ea9dc3d311..4c3402c7deec768931d07488cbbb79a0a7a7dd23 100644
--- a/test/cctest/test-code-stub-assembler.cc
+++ b/test/cctest/test-code-stub-assembler.cc
@@ -1178,7 +1178,9 @@ void AddProperties(Handle<JSObject> object, Handle<Name> names[],
Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value);
Handle<Object> getter(pair->getter(), isolate);
Handle<Object> setter(pair->setter(), isolate);
- JSObject::DefineAccessor(object, names[i], getter, setter, NONE).Check();
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, names[i], getter,
+ setter, NONE)
+ .Check();
} else {
JSObject::AddProperty(isolate, object, names[i], value, NONE);
}