mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b48fa0318 | ||
|
|
be1c22ecab | ||
|
|
2c822ce4ac | ||
|
|
f4041c10cf | ||
|
|
60c84cbd77 | ||
|
|
523fa39765 | ||
|
|
d368492bfd | ||
|
|
3c269d74c9 | ||
|
|
5bbcc22b8d | ||
|
|
9abb7fb7e3 | ||
|
|
364390e039 | ||
|
|
b59963cf04 | ||
|
|
7a026ed3dc | ||
|
|
75b7a858ac |
@@ -54,7 +54,7 @@ executors:
|
||||
type: enum
|
||||
enum: ["macos.x86.medium.gen2", "large"]
|
||||
macos:
|
||||
xcode: 13.3.0
|
||||
xcode: 13.4.1
|
||||
resource_class: << parameters.size >>
|
||||
|
||||
# Electron Runners
|
||||
@@ -287,7 +287,7 @@ step-gclient-sync: &step-gclient-sync
|
||||
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
|
||||
if [ "$IS_RELEASE" != "true" ]; then
|
||||
# Re-export all the patches to check if there were changes.
|
||||
python src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
cd src/electron
|
||||
git update-index --refresh || true
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
@@ -341,8 +341,8 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
|
||||
third_party/goma/goma_ctl.py ensure_start
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
|
||||
python3 third_party/goma/goma_ctl.py ensure_start
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`python3 third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
|
||||
echo "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token."
|
||||
exit 1
|
||||
fi
|
||||
@@ -370,14 +370,14 @@ step-restore-brew-cache: &step-restore-brew-cache
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
keys:
|
||||
- v6-brew-cache-{{ arch }}
|
||||
- v7-brew-cache-{{ arch }}
|
||||
|
||||
step-save-brew-cache: &step-save-brew-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
key: v6-brew-cache-{{ arch }}
|
||||
key: v7-brew-cache-{{ arch }}
|
||||
name: Persisting brew cache
|
||||
|
||||
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
@@ -680,9 +680,9 @@ step-verify-mksnapshot: &step-verify-mksnapshot
|
||||
if [ "$IS_ASAN" != "1" ]; then
|
||||
cd src
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
|
||||
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
|
||||
else
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
|
||||
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -692,7 +692,7 @@ step-verify-chromedriver: &step-verify-chromedriver
|
||||
command: |
|
||||
if [ "$IS_ASAN" != "1" ]; then
|
||||
cd src
|
||||
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
|
||||
python3 electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
|
||||
fi
|
||||
|
||||
step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
|
||||
@@ -818,7 +818,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
|
||||
elif [ "`uname`" == "Darwin" ]; then
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.dylib" out/Default
|
||||
fi
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
|
||||
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
|
||||
mkdir cross-arch-snapshots
|
||||
cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
|
||||
# Clean up so that ninja does not get confused
|
||||
@@ -975,7 +975,6 @@ step-ts-compile: &step-ts-compile
|
||||
# List of all steps.
|
||||
steps-electron-gn-check: &steps-electron-gn-check
|
||||
steps:
|
||||
- install-python2-mac
|
||||
- *step-setup-goma-for-build
|
||||
- checkout-from-cache
|
||||
- *step-setup-env-for-build
|
||||
@@ -994,31 +993,6 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
||||
|
||||
# Command Aliases
|
||||
commands:
|
||||
install-python2-mac:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v2.7.18-python-cache-{{ arch }}
|
||||
name: Restore python cache
|
||||
- run:
|
||||
name: Install python2 on macos
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ] && [ "$IS_ELECTRON_RUNNER" != "1" ]; then
|
||||
if [ ! -f "python-downloads/python-2.7.18-macosx10.9.pkg" ]; then
|
||||
mkdir python-downloads
|
||||
echo 'Downloading Python 2.7.18'
|
||||
curl -O https://dev-cdn.electronjs.org/python/python-2.7.18-macosx10.9.pkg
|
||||
mv python-2.7.18-macosx10.9.pkg python-downloads
|
||||
else
|
||||
echo 'Using Python install from cache'
|
||||
fi
|
||||
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
|
||||
fi
|
||||
- save_cache:
|
||||
paths:
|
||||
- python-downloads
|
||||
key: v2.7.18-python-cache-{{ arch }}
|
||||
name: Persisting python cache
|
||||
maybe-restore-portaled-src-cache:
|
||||
parameters:
|
||||
halt-if-successful:
|
||||
@@ -1315,7 +1289,6 @@ commands:
|
||||
- run: rm -rf src/electron
|
||||
- *step-restore-brew-cache
|
||||
- *step-install-gnutar-on-mac
|
||||
- install-python2-mac
|
||||
- *step-save-brew-cache
|
||||
- when:
|
||||
condition: << parameters.build >>
|
||||
@@ -1476,7 +1449,6 @@ commands:
|
||||
- *step-setup-linux-for-headless-testing
|
||||
- *step-restore-brew-cache
|
||||
- *step-fix-known-hosts-linux
|
||||
- install-python2-mac
|
||||
- *step-install-signing-cert-on-mac
|
||||
|
||||
- run:
|
||||
@@ -1586,7 +1558,6 @@ commands:
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- install-python2-mac
|
||||
- *step-get-more-space-on-mac
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
|
||||
@@ -154,6 +154,39 @@ webContents.setWindowOpenHandler((details) => {
|
||||
})
|
||||
```
|
||||
|
||||
### Removed: `<webview>` `new-window` event
|
||||
|
||||
The `new-window` event of `<webview>` has been removed. There is no direct replacement.
|
||||
|
||||
```js
|
||||
// Removed in Electron 22
|
||||
webview.addEventListener('new-window', (event) => {})
|
||||
```
|
||||
|
||||
```javascript fiddle='docs/fiddles/ipc/webview-new-window'
|
||||
// Replace with
|
||||
|
||||
// main.js
|
||||
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
|
||||
wc.setWindowOpenHandler((details) => {
|
||||
mainWindow.webContents.send('webview-new-window', wc.id, details)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
})
|
||||
|
||||
// preload.js
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
|
||||
console.log('webview-new-window', webContentsId, details)
|
||||
document.getElementById('webview').dispatchEvent(new Event('new-window'))
|
||||
})
|
||||
|
||||
// renderer.js
|
||||
document.getElementById('webview').addEventListener('new-window', () => {
|
||||
console.log('got new-window event')
|
||||
})
|
||||
```
|
||||
|
||||
### Deprecated: BrowserWindow `scroll-touch-*` events
|
||||
|
||||
The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on
|
||||
|
||||
3
docs/fiddles/ipc/webview-new-window/child.html
Normal file
3
docs/fiddles/ipc/webview-new-window/child.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
<a href="child.html" target="_blank">new window</a>
|
||||
</body>
|
||||
4
docs/fiddles/ipc/webview-new-window/index.html
Normal file
4
docs/fiddles/ipc/webview-new-window/index.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<body>
|
||||
<webview id=webview src="child.html" allowpopups></webview>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
51
docs/fiddles/ipc/webview-new-window/main.js
Normal file
51
docs/fiddles/ipc/webview-new-window/main.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
webviewTag: true
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
|
||||
wc.setWindowOpenHandler((details) => {
|
||||
mainWindow.webContents.send('webview-new-window', wc.id, details)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', function () {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
6
docs/fiddles/ipc/webview-new-window/preload.js
Normal file
6
docs/fiddles/ipc/webview-new-window/preload.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const webview = document.getElementById('webview')
|
||||
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
|
||||
console.log('webview-new-window', webContentsId, details)
|
||||
webview.dispatchEvent(new Event('new-window'))
|
||||
})
|
||||
4
docs/fiddles/ipc/webview-new-window/renderer.js
Normal file
4
docs/fiddles/ipc/webview-new-window/renderer.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const webview = document.getElementById('webview')
|
||||
webview.addEventListener('new-window', () => {
|
||||
console.log('got new-window event')
|
||||
})
|
||||
@@ -1,3 +1,4 @@
|
||||
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
|
||||
cherry-pick-6da1a8953313.patch
|
||||
cherry-pick-aed05b609629.patch
|
||||
cherry-pick-d0ee0197ddff.patch
|
||||
|
||||
214
patches/angle/cherry-pick-d0ee0197ddff.patch
Normal file
214
patches/angle/cherry-pick-d0ee0197ddff.patch
Normal 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)
|
||||
@@ -141,3 +141,9 @@ 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
|
||||
base_do_not_use_va_args_twice_in_asprintf.patch
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benoit Lize <lizeb@chromium.org>
|
||||
Date: Fri, 9 Jun 2023 17:59:08 +0000
|
||||
Subject: Do not use va_args twice in asprintf()
|
||||
|
||||
(cherry picked from commit 3cff0cb19a6d01cbdd9932f43dabaaeda9c0330a)
|
||||
|
||||
Bug: 1450536
|
||||
Change-Id: Ib34d96935278869a63897f9a1c66afc98865d90f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4579347
|
||||
Reviewed-by: Egor Pasko <pasko@chromium.org>
|
||||
Commit-Queue: Benoit Lize <lizeb@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1151796}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604070
|
||||
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#1224}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
|
||||
index 621873126602463a09efca1bf1548ed10910d323..de2af6d7d54e254b9e7b8264b53d30a338fb13e8 100644
|
||||
--- a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
|
||||
+++ b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
|
||||
@@ -123,13 +123,21 @@ SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
|
||||
SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
|
||||
const char* fmt,
|
||||
va_list va_args) {
|
||||
+ // There are cases where we need to use the list of arguments twice, namely
|
||||
+ // when the original buffer is too small. It is not allowed to walk the list
|
||||
+ // twice, so make a copy for the second invocation of vsnprintf().
|
||||
+ va_list va_args_copy;
|
||||
+ va_copy(va_args_copy, va_args);
|
||||
+
|
||||
constexpr int kInitialSize = 128;
|
||||
*strp = static_cast<char*>(
|
||||
malloc(kInitialSize)); // Our malloc() doesn't return nullptr.
|
||||
|
||||
int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
|
||||
- if (actual_size < 0)
|
||||
+ if (actual_size < 0) {
|
||||
+ va_end(va_args_copy);
|
||||
return actual_size;
|
||||
+ }
|
||||
*strp =
|
||||
static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
|
||||
|
||||
@@ -139,9 +147,14 @@ SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
|
||||
//
|
||||
// This is very lightly used in Chromium in practice, see crbug.com/116558 for
|
||||
// details.
|
||||
- if (actual_size >= kInitialSize)
|
||||
- return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
|
||||
-
|
||||
+ if (actual_size >= kInitialSize) {
|
||||
+ int ret = vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt,
|
||||
+ va_args_copy);
|
||||
+ va_end(va_args_copy);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ va_end(va_args_copy);
|
||||
return actual_size;
|
||||
}
|
||||
|
||||
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
|
||||
index 59b4a2c915caa192346f3fa342c5a2852a2f7b9b..1f3d5956b198ddf89cdf6951739ef68a29a74936 100644
|
||||
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
|
||||
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
|
||||
@@ -726,6 +726,28 @@ TEST_F(AllocatorShimTest, InterceptVasprintf) {
|
||||
// Should not crash.
|
||||
}
|
||||
|
||||
+TEST_F(AllocatorShimTest, InterceptLongVasprintf) {
|
||||
+ char* str = nullptr;
|
||||
+ const char* lorem_ipsum =
|
||||
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. "
|
||||
+ "Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, "
|
||||
+ "ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula "
|
||||
+ "massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci "
|
||||
+ "nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit "
|
||||
+ "amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat "
|
||||
+ "in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero "
|
||||
+ "pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo "
|
||||
+ "in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue "
|
||||
+ "blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus "
|
||||
+ "et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed "
|
||||
+ "pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales "
|
||||
+ "hendrerit.";
|
||||
+ int err = asprintf(&str, "%s", lorem_ipsum);
|
||||
+ EXPECT_EQ(err, static_cast<int>(strlen(lorem_ipsum)));
|
||||
+ EXPECT_TRUE(str);
|
||||
+ free(str);
|
||||
+}
|
||||
+
|
||||
#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
|
||||
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
107
patches/chromium/cherry-pick-48785f698b1c.patch
Normal file
107
patches/chromium/cherry-pick-48785f698b1c.patch
Normal 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
|
||||
};
|
||||
|
||||
142
patches/chromium/cherry-pick-675562695049.patch
Normal file
142
patches/chromium/cherry-pick-675562695049.patch
Normal 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
|
||||
200
patches/chromium/cherry-pick-ea1cd76358e0.patch
Normal file
200
patches/chromium/cherry-pick-ea1cd76358e0.patch
Normal file
@@ -0,0 +1,200 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin McNee <mcnee@chromium.org>
|
||||
Date: Tue, 23 May 2023 15:46:16 +0000
|
||||
Subject: M114: Compute all webview find options before cloning them
|
||||
|
||||
Compute all webview find options before cloning them
|
||||
|
||||
In WebViewFindHelper::Find, we're cloning the find options before we've
|
||||
set the value for `new_session`. For requests that are part of the same
|
||||
session, in WebViewFindHelper::FindReply, we're using the incorrect
|
||||
value for `new_session` and we're destroying the FindInfo for what we
|
||||
think is a previous session but is actually for the request we're
|
||||
currently processing.
|
||||
|
||||
We now fully compute the options before cloning them.
|
||||
|
||||
(cherry picked from commit bb8e17b942b8b1de0a58b2dce34197e00a3b6525)
|
||||
|
||||
Bug: 1443401
|
||||
Change-Id: Ife6747aedabaf74f9a4855a173349ffe612b6f95
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4533923
|
||||
Reviewed-by: James Maclean <wjmaclean@chromium.org>
|
||||
Commit-Queue: James Maclean <wjmaclean@chromium.org>
|
||||
Auto-Submit: Kevin McNee <mcnee@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1145265}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4556646
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#941}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
index cebe56b9e79cbe0e5a58f73e68faf1b93b17ce5c..3748f8119bf1d4f37635bdb4fb87d825881de7f0 100644
|
||||
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
@@ -3888,6 +3888,11 @@ IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_testFindInMultipleWebViews) {
|
||||
TestHelper("testFindInMultipleWebViews", "web_view/shim", NO_TEST_SERVER);
|
||||
}
|
||||
|
||||
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAfterTerminate) {
|
||||
+ content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
|
||||
+ TestHelper("testFindAfterTerminate", "web_view/shim", NO_TEST_SERVER);
|
||||
+}
|
||||
+
|
||||
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) {
|
||||
TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
|
||||
|
||||
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
|
||||
index 5ed4f0223346b01d83cc04c8cda6c0e92e1a72e3..4a1543d1751cc817a511594d0123deacc0e61ebb 100644
|
||||
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
|
||||
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
|
||||
@@ -2859,6 +2859,20 @@ function testFindInMultipleWebViews() {
|
||||
});
|
||||
}
|
||||
|
||||
+function testFindAfterTerminate() {
|
||||
+ let webview = new WebView();
|
||||
+ webview.src = 'data:text/html,<body><iframe></iframe></body>';
|
||||
+ webview.addEventListener('loadstop', () => {
|
||||
+ webview.find('A');
|
||||
+ webview.terminate();
|
||||
+ webview.find('B', {'backward': true});
|
||||
+ webview.find('B', {'backward': true}, (results) => {
|
||||
+ embedder.test.succeed();
|
||||
+ });
|
||||
+ });
|
||||
+ document.body.appendChild(webview);
|
||||
+}
|
||||
+
|
||||
function testLoadDataAPI() {
|
||||
var webview = new WebView();
|
||||
webview.src = 'about:blank';
|
||||
@@ -3600,6 +3614,7 @@ embedder.test.testList = {
|
||||
'testFindAPI': testFindAPI,
|
||||
'testFindAPI_findupdate': testFindAPI_findupdate,
|
||||
'testFindInMultipleWebViews': testFindInMultipleWebViews,
|
||||
+ 'testFindAfterTerminate': testFindAfterTerminate,
|
||||
'testLoadDataAPI': testLoadDataAPI,
|
||||
'testLoadDataAPIAccessibleResources': testLoadDataAPIAccessibleResources,
|
||||
'testResizeEvents': testResizeEvents,
|
||||
diff --git a/extensions/browser/guest_view/web_view/web_view_find_helper.cc b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
|
||||
index 1e9148687f6871dff8a394cce53771e443775679..37630dc2f0a6365bbf33e765f4d126e2962fbb2a 100644
|
||||
--- a/extensions/browser/guest_view/web_view/web_view_find_helper.cc
|
||||
+++ b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
|
||||
@@ -36,12 +36,12 @@ void WebViewFindHelper::CancelAllFindSessions() {
|
||||
|
||||
void WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
|
||||
bool final_update) {
|
||||
- DCHECK(find_update_event_.get());
|
||||
+ CHECK(find_update_event_);
|
||||
base::Value::Dict args;
|
||||
find_update_event_->PrepareResults(args);
|
||||
args.Set(webview::kFindCanceled, canceled);
|
||||
args.Set(webview::kFindFinalUpdate, final_update);
|
||||
- DCHECK(webview_guest_);
|
||||
+ CHECK(webview_guest_);
|
||||
webview_guest_->DispatchEventToView(std::make_unique<GuestViewEvent>(
|
||||
webview::kEventFindReply, std::move(args)));
|
||||
}
|
||||
@@ -94,6 +94,17 @@ void WebViewFindHelper::Find(
|
||||
// Need a new request_id for each new find request.
|
||||
++current_find_request_id_;
|
||||
|
||||
+ if (current_find_session_) {
|
||||
+ const std::u16string& current_search_text =
|
||||
+ current_find_session_->search_text();
|
||||
+ bool current_match_case = current_find_session_->options()->match_case;
|
||||
+ options->new_session = current_search_text.empty() ||
|
||||
+ current_search_text != search_text ||
|
||||
+ current_match_case != options->match_case;
|
||||
+ } else {
|
||||
+ options->new_session = true;
|
||||
+ }
|
||||
+
|
||||
// Stores the find request information by request_id so that its callback
|
||||
// function can be called when the find results are available.
|
||||
std::pair<FindInfoMap::iterator, bool> insert_result =
|
||||
@@ -102,32 +113,19 @@ void WebViewFindHelper::Find(
|
||||
base::MakeRefCounted<FindInfo>(current_find_request_id_, search_text,
|
||||
options.Clone(), find_function)));
|
||||
// No duplicate insertions.
|
||||
- DCHECK(insert_result.second);
|
||||
-
|
||||
- blink::mojom::FindOptionsPtr full_options =
|
||||
- insert_result.first->second->options().Clone();
|
||||
-
|
||||
- if (current_find_session_) {
|
||||
- const std::u16string& current_search_text =
|
||||
- current_find_session_->search_text();
|
||||
- bool current_match_case = current_find_session_->options()->match_case;
|
||||
- full_options->new_session = current_search_text.empty() ||
|
||||
- current_search_text != search_text ||
|
||||
- current_match_case != options->match_case;
|
||||
- } else {
|
||||
- full_options->new_session = true;
|
||||
- }
|
||||
+ CHECK(insert_result.second);
|
||||
|
||||
// Link find requests that are a part of the same find session.
|
||||
- if (!full_options->new_session && current_find_session_) {
|
||||
- DCHECK(current_find_request_id_ != current_find_session_->request_id());
|
||||
+ if (!options->new_session && current_find_session_) {
|
||||
+ CHECK(current_find_request_id_ != current_find_session_->request_id());
|
||||
current_find_session_->AddFindNextRequest(
|
||||
insert_result.first->second->AsWeakPtr());
|
||||
}
|
||||
|
||||
// Update the current find session, if necessary.
|
||||
- if (full_options->new_session)
|
||||
+ if (options->new_session) {
|
||||
current_find_session_ = insert_result.first->second;
|
||||
+ }
|
||||
|
||||
// Handle the empty |search_text| case internally.
|
||||
if (search_text.empty()) {
|
||||
@@ -137,7 +135,7 @@ void WebViewFindHelper::Find(
|
||||
}
|
||||
|
||||
guest_web_contents->Find(current_find_request_id_, search_text,
|
||||
- std::move(full_options), /*skip_delay=*/true);
|
||||
+ std::move(options), /*skip_delay=*/true);
|
||||
}
|
||||
|
||||
void WebViewFindHelper::FindReply(int request_id,
|
||||
@@ -152,14 +150,14 @@ void WebViewFindHelper::FindReply(int request_id,
|
||||
return;
|
||||
|
||||
// This find request must be a part of an existing find session.
|
||||
- DCHECK(current_find_session_);
|
||||
+ CHECK(current_find_session_);
|
||||
|
||||
WebViewFindHelper::FindInfo* find_info = find_iterator->second.get();
|
||||
// Handle canceled find requests.
|
||||
if (find_info->options()->new_session &&
|
||||
find_info_map_.begin()->first < request_id) {
|
||||
- DCHECK_NE(current_find_session_->request_id(),
|
||||
- find_info_map_.begin()->first);
|
||||
+ CHECK_NE(current_find_session_->request_id(),
|
||||
+ find_info_map_.begin()->first);
|
||||
if (find_update_event_)
|
||||
DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
|
||||
EndFindSession(find_info_map_.begin()->first, true /* canceled */);
|
||||
@@ -174,11 +172,12 @@ void WebViewFindHelper::FindReply(int request_id,
|
||||
// Aggregate the find results.
|
||||
find_info->AggregateResults(number_of_matches, selection_rect,
|
||||
active_match_ordinal, final_update);
|
||||
- find_update_event_->AggregateResults(number_of_matches, selection_rect,
|
||||
- active_match_ordinal, final_update);
|
||||
-
|
||||
- // Propagate incremental results to the |findupdate| event.
|
||||
- DispatchFindUpdateEvent(false /* canceled */, final_update);
|
||||
+ if (find_update_event_) {
|
||||
+ find_update_event_->AggregateResults(number_of_matches, selection_rect,
|
||||
+ active_match_ordinal, final_update);
|
||||
+ // Propagate incremental results to the |findupdate| event.
|
||||
+ DispatchFindUpdateEvent(false /* canceled */, final_update);
|
||||
+ }
|
||||
|
||||
// Call the callback functions of completed find requests.
|
||||
if (final_update)
|
||||
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maggie Chen <magchen@chromium.org>
|
||||
Date: Thu, 18 May 2023 00:20:34 +0000
|
||||
Subject: Fix a crash caused by calling TRACE_EVENT
|
||||
|
||||
Now use literal constant for TRACE_EVENT. Passing a pointer instead of
|
||||
string content to TRACE_EVENT causes a crash in ScopedTracer.
|
||||
|
||||
(cherry picked from commit 6f2e587807aff2306309025db1c15fc59290eb6f)
|
||||
|
||||
Bug: 1444195
|
||||
Change-Id: I02aa1148d61e7596e9293ffc866135e99991e42e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4522164
|
||||
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Commit-Queue: Maggie Chen <magchen@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1144352}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4544885
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#749}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/ui/gl/swap_chain_presenter.cc b/ui/gl/swap_chain_presenter.cc
|
||||
index 54a8dfdd931a22c5acfe3613204ea3a89b842d13..1e76a1a655d0f9de1dd218ad4025a6210ceafc57 100644
|
||||
--- a/ui/gl/swap_chain_presenter.cc
|
||||
+++ b/ui/gl/swap_chain_presenter.cc
|
||||
@@ -1698,10 +1698,8 @@ bool SwapChainPresenter::ReallocateSwapChain(
|
||||
}
|
||||
}
|
||||
if (!use_yuv_swap_chain) {
|
||||
- std::ostringstream trace_event_stream;
|
||||
- trace_event_stream << "SwapChainPresenter::ReallocateSwapChain::"
|
||||
- << DxgiFormatToString(swap_chain_format);
|
||||
- TRACE_EVENT0("gpu", trace_event_stream.str().c_str());
|
||||
+ TRACE_EVENT1("gpu", "SwapChainPresenter::ReallocateSwapChain::BGRA",
|
||||
+ "format", DxgiFormatToString(swap_chain_format));
|
||||
|
||||
desc.Format = swap_chain_format;
|
||||
desc.Flags = DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO;
|
||||
51
patches/chromium/mojoipcz_copy_incoming_messages_early.patch
Normal file
51
patches/chromium/mojoipcz_copy_incoming_messages_early.patch
Normal file
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Mon, 3 Apr 2023 19:43:13 +0000
|
||||
Subject: MojoIpcz: Copy incoming messages early
|
||||
|
||||
Fixed: 1429720
|
||||
Change-Id: Id6cb7269d3a3e9118cc6ff1579b56e18bf911c07
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4390758
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1125510}
|
||||
|
||||
diff --git a/mojo/core/ipcz_driver/mojo_message.cc b/mojo/core/ipcz_driver/mojo_message.cc
|
||||
index 6194c0c2da8292b8229972eadf9fd6fa56ef0c86..b8372a6281ddcaf0990f55856a9e815fb9d78195 100644
|
||||
--- a/mojo/core/ipcz_driver/mojo_message.cc
|
||||
+++ b/mojo/core/ipcz_driver/mojo_message.cc
|
||||
@@ -112,23 +112,20 @@ void MojoMessage::SetParcel(ScopedIpczHandle parcel) {
|
||||
|
||||
// We always pass a parcel object in, so Begin/EndGet() must always succeed.
|
||||
DCHECK_EQ(result, IPCZ_RESULT_OK);
|
||||
+ if (num_bytes > 0) {
|
||||
+ data_storage_.reset(
|
||||
+ static_cast<uint8_t*>(base::AllocNonScannable(num_bytes)));
|
||||
+ memcpy(data_storage_.get(), data, num_bytes);
|
||||
+ } else {
|
||||
+ data_storage_.reset();
|
||||
+ }
|
||||
+ data_ = {data_storage_.get(), num_bytes};
|
||||
+ data_storage_size_ = num_bytes;
|
||||
|
||||
- // Grab only the handles.
|
||||
handles_.resize(num_handles);
|
||||
- result = GetIpczAPI().EndGet(parcel_.get(), 0, num_handles, IPCZ_NO_FLAGS,
|
||||
- nullptr, handles_.data());
|
||||
- DCHECK_EQ(result, IPCZ_RESULT_OK);
|
||||
-
|
||||
- // Now start a new two-phase get, which we'll leave active indefinitely for
|
||||
- // `data_` to reference.
|
||||
- result = GetIpczAPI().BeginGet(parcel_.get(), IPCZ_NO_FLAGS, nullptr, &data,
|
||||
- &num_bytes, &num_handles);
|
||||
+ result = GetIpczAPI().EndGet(parcel_.get(), num_bytes, num_handles,
|
||||
+ IPCZ_NO_FLAGS, nullptr, handles_.data());
|
||||
DCHECK_EQ(result, IPCZ_RESULT_OK);
|
||||
-
|
||||
- DCHECK_EQ(0u, num_handles);
|
||||
- data_ = base::make_span(static_cast<uint8_t*>(const_cast<void*>(data)),
|
||||
- num_bytes);
|
||||
-
|
||||
if (!FixUpDataPipeHandles(handles_)) {
|
||||
// The handle list was malformed. Although this is a validation error, it
|
||||
// is not safe to trigger MojoNotifyBadMessage from within MojoReadMessage,
|
||||
@@ -25,5 +25,9 @@
|
||||
|
||||
"src/electron/patches/webrtc": "src/third_party/webrtc",
|
||||
|
||||
"src/electron/patches/skia": "src/third_party/skia"
|
||||
"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
1
patches/dawn/.patches
Normal file
@@ -0,0 +1 @@
|
||||
change_d3d12_descriptor_allocator_to_invalidate_submitted_descriptors.patch
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
3
patches/pdfium/.patches
Normal file
3
patches/pdfium/.patches
Normal file
@@ -0,0 +1,3 @@
|
||||
m114_observe_cpwl_combobox_across_all_on_methods.patch
|
||||
m114_observe_widget_across_setoptionselection_calls.patch
|
||||
m114_always_check_return_code_from_cpwl_combobox_setpopup.patch
|
||||
@@ -0,0 +1,236 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Fri, 19 May 2023 18:41:31 +0000
|
||||
Subject: Always check return code from CPWL_ComboBox::SetPopup().
|
||||
|
||||
Operation must not continue when false is returned.
|
||||
|
||||
Bug: chromium:1444238
|
||||
Change-Id: Ic8c29653ac185ac80b6248203649ce05d0e10f06
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107390
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
(cherry picked from commit 3eb3c4d77d4f9372f77aa4895b85a1d4e4755c89)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107812
|
||||
|
||||
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
index 4cda2135433b07d641d773f184034b0f3dee7e58..f9a8550da29e7a7afca757167af257d95a67bd9f 100644
|
||||
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
@@ -400,7 +400,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
// options.
|
||||
switch (nChar) {
|
||||
case pdfium::ascii::kReturn:
|
||||
- SetPopup(!IsPopup());
|
||||
+ if (!SetPopup(!IsPopup())) {
|
||||
+ return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
return true;
|
||||
case pdfium::ascii::kSpace:
|
||||
@@ -408,7 +410,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
// editable
|
||||
if (!HasFlag(PCBS_ALLOWCUSTOMTEXT)) {
|
||||
if (!IsPopup()) {
|
||||
- SetPopup(/*bPopUp=*/true);
|
||||
+ if (!SetPopup(/*bPopUp=*/true)) {
|
||||
+ return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
}
|
||||
return true;
|
||||
@@ -438,7 +442,7 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
|
||||
void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
|
||||
if (child == m_pButton) {
|
||||
- SetPopup(!m_bPopup);
|
||||
+ (void)SetPopup(!m_bPopup);
|
||||
// Note, |this| may no longer be viable at this point. If more work needs to
|
||||
// be done, check the return value of SetPopup().
|
||||
}
|
||||
@@ -451,7 +455,7 @@ void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
|
||||
SetSelectText();
|
||||
SelectAllText();
|
||||
m_pEdit->SetFocus();
|
||||
- SetPopup(false);
|
||||
+ (void)SetPopup(false);
|
||||
// Note, |this| may no longer be viable at this point. If more work needs to
|
||||
// be done, check the return value of SetPopup().
|
||||
}
|
||||
diff --git a/fpdfsdk/pwl/cpwl_combo_box.h b/fpdfsdk/pwl/cpwl_combo_box.h
|
||||
index 480da52d7a65538dee190e2a609215f9c424bb38..b1ac3d9e8ac29e9433330ff86df7ef4b71a3fabd 100644
|
||||
--- a/fpdfsdk/pwl/cpwl_combo_box.h
|
||||
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
|
||||
@@ -64,7 +64,7 @@ class CPWL_ComboBox final : public CPWL_Wnd {
|
||||
void CreateListBox(const CreateParams& cp);
|
||||
|
||||
// Returns |true| iff this instance is still allocated.
|
||||
- bool SetPopup(bool bPopup);
|
||||
+ [[nodiscard]] bool SetPopup(bool bPopup);
|
||||
|
||||
UnownedPtr<CPWL_Edit> m_pEdit;
|
||||
UnownedPtr<CPWL_CBButton> m_pButton;
|
||||
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.evt b/testing/resources/javascript/xfa_specific/bug_1444238.evt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..adca35aa0d756e76eb395c5d60ba41b86c3d0090
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.evt
|
||||
@@ -0,0 +1,3 @@
|
||||
+mousedown,left,91,539
|
||||
+mouseup,left,91,539
|
||||
+charcode,32
|
||||
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.in b/testing/resources/javascript/xfa_specific/bug_1444238.in
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..675178c9446b0181c3633a4b5c9bc664bb4c127d
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.in
|
||||
@@ -0,0 +1,149 @@
|
||||
+{{header}}
|
||||
+{{object 1 0}} <<
|
||||
+ /Type /Catalog
|
||||
+ /Pages 2 0 R
|
||||
+ /AcroForm 4 0 R
|
||||
+ /OpenAction 40 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 2 0}} <<
|
||||
+ /Type /Pages
|
||||
+ /Count 2
|
||||
+ /Kids [
|
||||
+ 32 0 R
|
||||
+ 34 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Forms
|
||||
+{{object 4 0}} <<
|
||||
+ /XFA 43 0 R
|
||||
+ /Fields [
|
||||
+ 10 0 R
|
||||
+ 11 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 10 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Tx
|
||||
+ /T (MyField5)
|
||||
+ /V (myfield_5)
|
||||
+ /Rect [0 500 600 600]
|
||||
+>>
|
||||
+% Fields
|
||||
+{{object 11 0}} <<
|
||||
+ /T (MyField3)
|
||||
+ /Parent 4 0 R
|
||||
+ /Kids [12 0 R]
|
||||
+ /Opt [(a) (b) (c) (d)]
|
||||
+ /V [(a) (b) (c)]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 12 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Ch
|
||||
+ /Ff 131072
|
||||
+ /Parent 11 0 R
|
||||
+ /Kids [13 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 13 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /Parent 12 0 R
|
||||
+ /Rect [0 400 600 600]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 14 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /Parent 12 0 R
|
||||
+ /Rect [100 400 500 500]
|
||||
+>>
|
||||
+endobj
|
||||
+% Page number 2.
|
||||
+{{object 32 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [13 0 R]
|
||||
+
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 34 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [10 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+% Document JS Action
|
||||
+{{object 40 0}} <<
|
||||
+ /Type /Action
|
||||
+ /S /JavaScript
|
||||
+ /JS 41 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+% JS program to exexute
|
||||
+{{object 41 0}} <<
|
||||
+>>
|
||||
+stream
|
||||
+var f5 = this.getField("MyField5");
|
||||
+var f3 = this.getField("MyField3");
|
||||
+f3.setFocus();
|
||||
+this.__defineGetter__("pageNum",function o(){f5.setFocus(); f3.borderStyle="dashed"; f3.setFocus();});
|
||||
+endstream
|
||||
+endobj
|
||||
+{{object 43 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
|
||||
+<config></config>
|
||||
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.8/">
|
||||
+ <subform layout="tb" locale="en_US">
|
||||
+ <pageSet>
|
||||
+ <pageArea id="Page1" name="Page1">
|
||||
+ <contentArea h="268.939mm" w="203.2mm" x="6.35mm" y="6.35mm"/>
|
||||
+ <medium long="792pt" short="612pt" stock="default"/>
|
||||
+ </pageArea>
|
||||
+ </pageSet>
|
||||
+ <field h="9.0001mm" name="MyField3" w="47.625mm" x="120mm" y="120mm">
|
||||
+ <ui>
|
||||
+ <choiceList open="onEntry">
|
||||
+ <border>
|
||||
+ <edge/>
|
||||
+ </border>
|
||||
+ </choiceList>
|
||||
+ </ui>
|
||||
+ <items save="1">
|
||||
+ <text>apples</text>
|
||||
+ <text>bananas</text>
|
||||
+ <text>pears</text>
|
||||
+ </items>
|
||||
+ <value>
|
||||
+ <text>apples</text>
|
||||
+ </value>
|
||||
+ <event activity="preOpen">
|
||||
+ <script contentType="application/x-javascript">
|
||||
+ var aa = this.pageNum;
|
||||
+ </script>
|
||||
+ </event>
|
||||
+ </field>
|
||||
+ </subform>
|
||||
+</template>
|
||||
+</xdp:xdp>
|
||||
+endstream
|
||||
+endobj
|
||||
+{{xref}}
|
||||
+{{trailer}}
|
||||
+{{startxref}}
|
||||
+%%EOF
|
||||
@@ -0,0 +1,213 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Fri, 19 May 2023 20:05:10 +0000
|
||||
Subject: Observe CPWL_ComboBox across all On* methods
|
||||
|
||||
Bug: chromium:1445426
|
||||
Change-Id: I1d7ebf66fe170ca016c27a0df3ac4574e75c763c
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107650
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
(cherry picked from commit 29c665ea4c61b089746c3f502c30fcb5f4b11486)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107811
|
||||
|
||||
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
index dde76521a7c15070c1245938063830a003986a69..4cda2135433b07d641d773f184034b0f3dee7e58 100644
|
||||
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
@@ -339,31 +339,42 @@ bool CPWL_ComboBox::OnKeyDown(FWL_VKEYCODE nKeyCode,
|
||||
if (!m_pEdit)
|
||||
return false;
|
||||
|
||||
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
|
||||
m_nSelectItem = -1;
|
||||
|
||||
switch (nKeyCode) {
|
||||
case FWL_VKEY_Up:
|
||||
if (m_pList->GetCurSel() > 0) {
|
||||
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
|
||||
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
|
||||
+ }
|
||||
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
if (m_pList->IsMovementKey(nKeyCode)) {
|
||||
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
|
||||
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case FWL_VKEY_Down:
|
||||
if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
|
||||
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
|
||||
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
|
||||
+ }
|
||||
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
if (m_pList->IsMovementKey(nKeyCode)) {
|
||||
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
|
||||
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
}
|
||||
}
|
||||
@@ -411,10 +422,15 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
|
||||
return m_pEdit->OnChar(nChar, nFlag);
|
||||
|
||||
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
|
||||
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
|
||||
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
|
||||
+ }
|
||||
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
if (!m_pList->IsChar(nChar, nFlag))
|
||||
return false;
|
||||
return m_pList->OnCharNotify(nChar, nFlag);
|
||||
diff --git a/testing/resources/javascript/bug_1445426.evt b/testing/resources/javascript/bug_1445426.evt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..265e85b0471b33509568238ccae30d2395b4b4ab
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/bug_1445426.evt
|
||||
@@ -0,0 +1,3 @@
|
||||
+mousedown,left,202,697
|
||||
+mouseup,left,202,697
|
||||
+keycode,40
|
||||
diff --git a/testing/resources/javascript/bug_1445426.in b/testing/resources/javascript/bug_1445426.in
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1483da72f5759e9f2c8fdb538d5c6fa0cd1611c5
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/bug_1445426.in
|
||||
@@ -0,0 +1,114 @@
|
||||
+{{header}}
|
||||
+{{object 1 0}} <<
|
||||
+ /Type /Catalog
|
||||
+ /Pages 2 0 R
|
||||
+ /AcroForm 4 0 R
|
||||
+ /OpenAction 40 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 2 0}} <<
|
||||
+ /Type /Pages
|
||||
+ /Count 2
|
||||
+ /Kids [
|
||||
+ 32 0 R
|
||||
+ 34 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Forms
|
||||
+{{object 4 0}} <<
|
||||
+ /Fields [
|
||||
+ 10 0 R
|
||||
+ 11 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 10 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Tx
|
||||
+ /T (Field_TextEdit)
|
||||
+ /Rect [0 0 612 792]
|
||||
+>>
|
||||
+{{object 11 0}} <<
|
||||
+ /T (Field_ComboBox)
|
||||
+ /Parent 4 0 R
|
||||
+ /Kids [12 0 R]
|
||||
+ /Opt [(a) (b) (c) (d)]
|
||||
+ /V [(a)]
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 12 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Ch
|
||||
+ /Ff 131072
|
||||
+ /Parent 11 0 R
|
||||
+ /Kids [13 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 13 0}} <<
|
||||
+ /Parent 12 0 R
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /Rect [0 0 612 792]
|
||||
+ /AA << /K 20 0 R >>
|
||||
+>>
|
||||
+endobj
|
||||
+% Pages
|
||||
+{{object 32 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [13 0 R]
|
||||
+
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 34 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [10 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+% Document JS Action
|
||||
+{{object 40 0}} <<
|
||||
+ /Type /Action
|
||||
+ /S /JavaScript
|
||||
+ /JS 41 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+% JS program to exexute
|
||||
+{{object 41 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+var field_text = this.getField("Field_TextEdit");
|
||||
+var field_combobox = this.getField("Field_ComboBox");
|
||||
+field_combobox.setFocus();
|
||||
+this.__defineGetter__("filesize", function new_getter(){
|
||||
+ field_text.setFocus();
|
||||
+ field_combobox.borderStyle="dashed";
|
||||
+ field_combobox.setFocus();
|
||||
+ });
|
||||
+endstream
|
||||
+endobj
|
||||
+% OpenAction action
|
||||
+{{object 20 0}} <<
|
||||
+ /S /JavaScript
|
||||
+ /JS 21 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+% JS program to exexute
|
||||
+{{object 21 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+var t = this.filesize;
|
||||
+endstream
|
||||
+endobj
|
||||
+{{xref}}
|
||||
+{{trailer}}
|
||||
+{{startxref}}
|
||||
+%%EOF
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Thu, 18 May 2023 18:37:17 +0000
|
||||
Subject: Observe widget across SetOptionSelection() calls.
|
||||
|
||||
Call may re-enter JavaScript.
|
||||
|
||||
Bug: chromium:1444581
|
||||
Change-Id: Id7a2f17b3b81f822ca8f4496ac08c19b7794c48a
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107394
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
(cherry picked from commit a9ff918a86d700c3bdf9b5820faed35490c0cd25)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107735
|
||||
Auto-Submit: Tom Sepez <tsepez@chromium.org>
|
||||
|
||||
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
index ea119ec093c748c6c8bfb7b3c31b4ae97f959908..31134bb1e576003cc377eb90a61898f8097f080c 100644
|
||||
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
@@ -116,11 +116,18 @@ void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
|
||||
}
|
||||
if (m_pWidget->GetFieldFlags() & pdfium::form_flags::kChoiceMultiSelect) {
|
||||
for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
|
||||
- if (pListBox->IsItemSelected(i))
|
||||
+ if (pListBox->IsItemSelected(i)) {
|
||||
m_pWidget->SetOptionSelection(i);
|
||||
+ if (!observed_box) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
m_pWidget->SetOptionSelection(pListBox->GetCurSel());
|
||||
+ if (!observed_box) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget);
|
||||
ObservedPtr<CFFL_ListBox> observed_this(this);
|
||||
@@ -10,3 +10,10 @@ 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
|
||||
cherry-pick-9c6dfc733fce.patch
|
||||
cherry-pick-2e76270cf65e.patch
|
||||
|
||||
300
patches/v8/cherry-pick-2c8a019f39d2.patch
Normal file
300
patches/v8/cherry-pick-2c8a019f39d2.patch
Normal 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);
|
||||
45
patches/v8/cherry-pick-2e76270cf65e.patch
Normal file
45
patches/v8/cherry-pick-2e76270cf65e.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Mon, 5 Jun 2023 16:05:52 -0700
|
||||
Subject: Merged: Check for encoding when appending in string builder
|
||||
|
||||
Fixed: chromium:1450114
|
||||
(cherry picked from commit a7e2bef27b72f187a7dcdf95714df686f56d9e0b)
|
||||
|
||||
Change-Id: I5838383b6b12d137e84c8a36863ef88000e85c76
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4604652
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#41}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/strings/string-builder.cc b/src/strings/string-builder.cc
|
||||
index 9d1e3a95746b47b99c15f18ec593549d79e10b8c..c7e98e55763aba2d64f4070e25759489f850f589 100644
|
||||
--- a/src/strings/string-builder.cc
|
||||
+++ b/src/strings/string-builder.cc
|
||||
@@ -306,12 +306,21 @@ bool IncrementalStringBuilder::CanAppendByCopy(Handle<String> string) {
|
||||
void IncrementalStringBuilder::AppendStringByCopy(Handle<String> string) {
|
||||
DCHECK(CanAppendByCopy(string));
|
||||
|
||||
- Handle<SeqOneByteString> part =
|
||||
- Handle<SeqOneByteString>::cast(current_part());
|
||||
{
|
||||
DisallowGarbageCollection no_gc;
|
||||
- String::WriteToFlat(*string, part->GetChars(no_gc) + current_index_, 0,
|
||||
- string->length());
|
||||
+ if (encoding_ == String::ONE_BYTE_ENCODING) {
|
||||
+ String::WriteToFlat(
|
||||
+ *string,
|
||||
+ Handle<SeqOneByteString>::cast(current_part())->GetChars(no_gc) +
|
||||
+ current_index_,
|
||||
+ 0, string->length());
|
||||
+ } else {
|
||||
+ String::WriteToFlat(
|
||||
+ *string,
|
||||
+ Handle<SeqTwoByteString>::cast(current_part())->GetChars(no_gc) +
|
||||
+ current_index_,
|
||||
+ 0, string->length());
|
||||
+ }
|
||||
}
|
||||
current_index_ += string->length();
|
||||
DCHECK(current_index_ <= part_length_);
|
||||
186
patches/v8/cherry-pick-3b0607d14060.patch
Normal file
186
patches/v8/cherry-pick-3b0607d14060.patch
Normal file
@@ -0,0 +1,186 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Wed, 17 May 2023 13:47:36 +0200
|
||||
Subject: Merged: [runtime] Remove redundant calls to GetPropertyAttributes
|
||||
|
||||
... when defining properties in favour of CheckIfCanDefine.
|
||||
|
||||
Drive-by: move JSReceiver::CheckIfCanDefine to
|
||||
JSObject::CheckIfCanDefineAsConfigurable and fix handling of
|
||||
absent properties.
|
||||
|
||||
Bug: chromium:1443452
|
||||
(cherry picked from commit e98baa3526426c0219bb0474028ca301b8bd0677)
|
||||
|
||||
Change-Id: Ia1fd617778be608accee99dcee37f7d1ce3460b8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545762
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#22}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
||||
index 93939fa4702922f58e8e5bcc019e569f42ab198e..1190b3dedfabee414fb49038e31b3cf2bbce68ee 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -1816,14 +1816,14 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
|
||||
// been thrown if the private field already exists in the object.
|
||||
if (IsAnyDefineOwn() && !name->IsPrivateName() && !object->IsJSProxy() &&
|
||||
!Handle<JSObject>::cast(object)->HasNamedInterceptor()) {
|
||||
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
isolate(), &it, value, Nothing<ShouldThrow>());
|
||||
MAYBE_RETURN_NULL(can_define);
|
||||
if (!can_define.FromJust()) {
|
||||
return isolate()->factory()->undefined_value();
|
||||
}
|
||||
- // Restart the lookup iterator updated by CheckIfCanDefine() for
|
||||
- // UpdateCaches() to handle access checks.
|
||||
+ // Restart the lookup iterator updated by CheckIfCanDefineAsConfigurable()
|
||||
+ // for UpdateCaches() to handle access checks.
|
||||
if (use_ic && object->IsAccessCheckNeeded()) {
|
||||
it.Restart();
|
||||
}
|
||||
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
|
||||
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,
|
||||
return Just(true);
|
||||
}
|
||||
|
||||
-// static
|
||||
-Maybe<bool> JSReceiver::CheckIfCanDefine(Isolate* isolate, LookupIterator* it,
|
||||
- Handle<Object> value,
|
||||
- Maybe<ShouldThrow> should_throw) {
|
||||
- if (it->IsFound()) {
|
||||
- Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
|
||||
- MAYBE_RETURN(attributes, Nothing<bool>());
|
||||
- if ((attributes.FromJust() & DONT_DELETE) != 0) {
|
||||
- RETURN_FAILURE(
|
||||
- isolate, GetShouldThrow(isolate, should_throw),
|
||||
- NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
|
||||
- }
|
||||
- } else if (!JSObject::IsExtensible(
|
||||
- Handle<JSObject>::cast(it->GetReceiver()))) {
|
||||
- RETURN_FAILURE(
|
||||
- isolate, GetShouldThrow(isolate, should_throw),
|
||||
- NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
|
||||
- }
|
||||
- return Just(true);
|
||||
-}
|
||||
-
|
||||
namespace {
|
||||
|
||||
bool HasExcludedProperty(
|
||||
@@ -3643,7 +3622,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
|
||||
|
||||
if (semantics == EnforceDefineSemantics::kDefine) {
|
||||
it->Restart();
|
||||
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
it->isolate(), it, value, should_throw);
|
||||
if (can_define.IsNothing() || !can_define.FromJust()) {
|
||||
return can_define;
|
||||
@@ -4072,17 +4051,16 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
|
||||
Handle<Object> value,
|
||||
Maybe<ShouldThrow> should_throw) {
|
||||
DCHECK(it->GetReceiver()->IsJSObject());
|
||||
- MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
|
||||
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
|
||||
Isolate* isolate = receiver->GetIsolate();
|
||||
|
||||
- Maybe<bool> can_define =
|
||||
- JSReceiver::CheckIfCanDefine(isolate, it, value, should_throw);
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
+ isolate, it, value, should_throw);
|
||||
if (can_define.IsNothing() || !can_define.FromJust()) {
|
||||
return can_define;
|
||||
}
|
||||
|
||||
- RETURN_ON_EXCEPTION_VALUE(it->isolate(),
|
||||
+ RETURN_ON_EXCEPTION_VALUE(isolate,
|
||||
DefineOwnPropertyIgnoreAttributes(it, value, NONE),
|
||||
Nothing<bool>());
|
||||
|
||||
@@ -4708,19 +4686,42 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
|
||||
return it.factory()->undefined_value();
|
||||
}
|
||||
|
||||
- CHECK(GetPropertyAttributes(&it).IsJust());
|
||||
-
|
||||
- // ES5 forbids turning a property into an accessor if it's not
|
||||
- // configurable. See 8.6.1 (Table 5).
|
||||
- if (it.IsFound() && !it.IsConfigurable()) {
|
||||
- return it.factory()->undefined_value();
|
||||
- }
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
+ isolate, &it, info, Nothing<ShouldThrow>());
|
||||
+ MAYBE_RETURN_NULL(can_define);
|
||||
+ if (!can_define.FromJust()) return it.factory()->undefined_value();
|
||||
|
||||
it.TransitionToAccessorPair(info, attributes);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
+// static
|
||||
+Maybe<bool> JSObject::CheckIfCanDefineAsConfigurable(
|
||||
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
|
||||
+ Maybe<ShouldThrow> should_throw) {
|
||||
+ DCHECK(it->GetReceiver()->IsJSObject());
|
||||
+ if (it->IsFound()) {
|
||||
+ Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
|
||||
+ MAYBE_RETURN(attributes, Nothing<bool>());
|
||||
+ if (attributes.FromJust() != ABSENT) {
|
||||
+ if ((attributes.FromJust() & DONT_DELETE) != 0) {
|
||||
+ RETURN_FAILURE(
|
||||
+ isolate, GetShouldThrow(isolate, should_throw),
|
||||
+ NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
|
||||
+ }
|
||||
+ return Just(true);
|
||||
+ }
|
||||
+ // Property does not exist, check object extensibility.
|
||||
+ }
|
||||
+ if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
|
||||
+ RETURN_FAILURE(
|
||||
+ isolate, GetShouldThrow(isolate, should_throw),
|
||||
+ NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
|
||||
+ }
|
||||
+ return Just(true);
|
||||
+}
|
||||
+
|
||||
Object JSObject::SlowReverseLookup(Object value) {
|
||||
if (HasFastProperties()) {
|
||||
DescriptorArray descs = map().instance_descriptors();
|
||||
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
|
||||
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> {
|
||||
V8_WARN_UNUSED_RESULT static Maybe<bool> CheckPrivateNameStore(
|
||||
LookupIterator* it, bool is_define);
|
||||
|
||||
- // Check if a data property can be created on the object. It will fail with
|
||||
- // an error when it cannot.
|
||||
- V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefine(
|
||||
- Isolate* isolate, LookupIterator* it, Handle<Object> value,
|
||||
- Maybe<ShouldThrow> should_throw);
|
||||
-
|
||||
// ES6 7.3.4 (when passed kDontThrow)
|
||||
V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
|
||||
Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
|
||||
@@ -545,6 +539,12 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
|
||||
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
+ // Check if a data property can be created on the object. It will fail with
|
||||
+ // an error when it cannot.
|
||||
+ V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefineAsConfigurable(
|
||||
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
|
||||
+ Maybe<ShouldThrow> should_throw);
|
||||
+
|
||||
// The result must be checked first for exceptions. If there's no exception,
|
||||
// the output parameter |done| indicates whether the interceptor has a result
|
||||
// or not.
|
||||
257
patches/v8/cherry-pick-73af1a19a901.patch
Normal file
257
patches/v8/cherry-pick-73af1a19a901.patch
Normal file
@@ -0,0 +1,257 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Thu, 1 Jun 2023 10:59:39 +0200
|
||||
Subject: Merged: [lookup] Robustify LookupIterator against own lookups
|
||||
|
||||
... on non-JSReceiver objects.
|
||||
|
||||
Bug: chromium:1447430
|
||||
(cherry picked from commit 515f187ba067ee4a99fdf5198cca2c97abd342fd)
|
||||
|
||||
Change-Id: Ib9382d90ce19d6b55ee0b236dd299ded03ade04d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4575069
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#35}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
|
||||
index 44b8f9502e32a9a6fbbe60ebc5f8e0d184411b8f..782698bd7c488f5570288119e49784e16a93ddd2 100644
|
||||
--- a/src/objects/lookup-inl.h
|
||||
+++ b/src/objects/lookup-inl.h
|
||||
@@ -167,7 +167,7 @@ Handle<Name> PropertyKey::GetName(Isolate* isolate) {
|
||||
}
|
||||
|
||||
Handle<Name> LookupIterator::name() const {
|
||||
- DCHECK(!IsElement(*holder_));
|
||||
+ DCHECK_IMPLIES(!holder_.is_null(), !IsElement(*holder_));
|
||||
return name_;
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ void LookupIterator::UpdateProtector() {
|
||||
}
|
||||
|
||||
InternalIndex LookupIterator::descriptor_number() const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(has_property_);
|
||||
DCHECK(holder_->HasFastProperties(isolate_));
|
||||
@@ -264,6 +265,7 @@ InternalIndex LookupIterator::descriptor_number() const {
|
||||
}
|
||||
|
||||
InternalIndex LookupIterator::dictionary_entry() const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(has_property_);
|
||||
DCHECK(!holder_->HasFastProperties(isolate_));
|
||||
@@ -278,13 +280,14 @@ LookupIterator::Configuration LookupIterator::ComputeConfiguration(
|
||||
}
|
||||
|
||||
// static
|
||||
-Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
|
||||
- Handle<Object> lookup_start_object,
|
||||
- size_t index) {
|
||||
+MaybeHandle<JSReceiver> LookupIterator::GetRoot(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration) {
|
||||
if (lookup_start_object->IsJSReceiver(isolate)) {
|
||||
return Handle<JSReceiver>::cast(lookup_start_object);
|
||||
}
|
||||
- return GetRootForNonJSReceiver(isolate, lookup_start_object, index);
|
||||
+ return GetRootForNonJSReceiver(isolate, lookup_start_object, index,
|
||||
+ configuration);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
diff --git a/src/objects/lookup.cc b/src/objects/lookup.cc
|
||||
index 7c6f6c4a350fec92a3cc0a48a14c0b92f8d6021d..ce1502b859c0cce77fc054488e401ac82a073a7d 100644
|
||||
--- a/src/objects/lookup.cc
|
||||
+++ b/src/objects/lookup.cc
|
||||
@@ -42,27 +42,20 @@ PropertyKey::PropertyKey(Isolate* isolate, Handle<Object> key, bool* success) {
|
||||
}
|
||||
}
|
||||
|
||||
-LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
|
||||
- Handle<Name> name, Handle<Map> transition_map,
|
||||
- PropertyDetails details, bool has_property)
|
||||
- : configuration_(DEFAULT),
|
||||
- state_(TRANSITION),
|
||||
- has_property_(has_property),
|
||||
- interceptor_state_(InterceptorState::kUninitialized),
|
||||
- property_details_(details),
|
||||
- isolate_(isolate),
|
||||
- name_(name),
|
||||
- transition_(transition_map),
|
||||
- receiver_(receiver),
|
||||
- lookup_start_object_(receiver),
|
||||
- index_(kInvalidIndex) {
|
||||
- holder_ = GetRoot(isolate, lookup_start_object_);
|
||||
-}
|
||||
-
|
||||
template <bool is_element>
|
||||
void LookupIterator::Start() {
|
||||
// GetRoot might allocate if lookup_start_object_ is a string.
|
||||
- holder_ = GetRoot(isolate_, lookup_start_object_, index_);
|
||||
+ MaybeHandle<JSReceiver> maybe_holder =
|
||||
+ GetRoot(isolate_, lookup_start_object_, index_, configuration_);
|
||||
+ if (!maybe_holder.ToHandle(&holder_)) {
|
||||
+ // This is an attempt to perform an own property lookup on a non-JSReceiver
|
||||
+ // that doesn't have any properties.
|
||||
+ DCHECK(!lookup_start_object_->IsJSReceiver());
|
||||
+ DCHECK(!check_prototype_chain());
|
||||
+ has_property_ = false;
|
||||
+ state_ = NOT_FOUND;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
{
|
||||
DisallowGarbageCollection no_gc;
|
||||
@@ -135,19 +128,27 @@ template void LookupIterator::RestartInternal<true>(InterceptorState);
|
||||
template void LookupIterator::RestartInternal<false>(InterceptorState);
|
||||
|
||||
// static
|
||||
-Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
|
||||
- Isolate* isolate, Handle<Object> lookup_start_object, size_t index) {
|
||||
- // Strings are the only objects with properties (only elements) directly on
|
||||
- // the wrapper. Hence we can skip generating the wrapper for all other cases.
|
||||
- if (lookup_start_object->IsString(isolate) &&
|
||||
- index <
|
||||
- static_cast<size_t>(String::cast(*lookup_start_object).length())) {
|
||||
- // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native
|
||||
- // context, ensuring that we don't leak it into JS?
|
||||
- Handle<JSFunction> constructor = isolate->string_function();
|
||||
- Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
|
||||
- Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
|
||||
- return result;
|
||||
+MaybeHandle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration) {
|
||||
+ // Strings are the only non-JSReceiver objects with properties (only elements
|
||||
+ // and 'length') directly on the wrapper. Hence we can skip generating
|
||||
+ // the wrapper for all other cases.
|
||||
+ bool own_property_lookup = (configuration & kPrototypeChain) == 0;
|
||||
+ if (lookup_start_object->IsString(isolate)) {
|
||||
+ if (own_property_lookup ||
|
||||
+ index <
|
||||
+ static_cast<size_t>(String::cast(*lookup_start_object).length())) {
|
||||
+ // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the
|
||||
+ // native context, ensuring that we don't leak it into JS?
|
||||
+ Handle<JSFunction> constructor = isolate->string_function();
|
||||
+ Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
|
||||
+ Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
|
||||
+ return result;
|
||||
+ }
|
||||
+ } else if (own_property_lookup) {
|
||||
+ // Signal that the lookup will not find anything.
|
||||
+ return {};
|
||||
}
|
||||
Handle<HeapObject> root(
|
||||
lookup_start_object->GetPrototypeChainRootMap(isolate).prototype(isolate),
|
||||
@@ -901,6 +902,7 @@ Handle<Object> LookupIterator::FetchValue(
|
||||
}
|
||||
|
||||
bool LookupIterator::CanStayConst(Object value) const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(holder_->HasFastProperties(isolate_));
|
||||
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
|
||||
@@ -934,6 +936,7 @@ bool LookupIterator::CanStayConst(Object value) const {
|
||||
}
|
||||
|
||||
bool LookupIterator::DictCanStayConst(Object value) const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(!holder_->HasFastProperties(isolate_));
|
||||
DCHECK(!holder_->IsJSGlobalObject());
|
||||
@@ -980,6 +983,7 @@ int LookupIterator::GetAccessorIndex() const {
|
||||
|
||||
FieldIndex LookupIterator::GetFieldIndex() const {
|
||||
DCHECK(has_property_);
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(holder_->HasFastProperties(isolate_));
|
||||
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
@@ -987,6 +991,7 @@ FieldIndex LookupIterator::GetFieldIndex() const {
|
||||
}
|
||||
|
||||
Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
|
||||
return handle(holder->global_dictionary(isolate_, kAcquireLoad)
|
||||
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
|
||||
index 9adee79b3028c53e6481a07316d74aed616f01bd..ef90316295c98d51b61c118cf331731f991d93d0 100644
|
||||
--- a/src/objects/lookup.h
|
||||
+++ b/src/objects/lookup.h
|
||||
@@ -214,11 +214,6 @@ class V8_EXPORT_PRIVATE LookupIterator final {
|
||||
Handle<Object> lookup_start_object,
|
||||
Configuration configuration);
|
||||
|
||||
- // For |ForTransitionHandler|.
|
||||
- LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
|
||||
- Handle<Map> transition_map, PropertyDetails details,
|
||||
- bool has_property);
|
||||
-
|
||||
static void InternalUpdateProtector(Isolate* isolate, Handle<Object> receiver,
|
||||
Handle<Name> name);
|
||||
|
||||
@@ -278,12 +273,12 @@ class V8_EXPORT_PRIVATE LookupIterator final {
|
||||
Configuration configuration,
|
||||
Handle<Name> name);
|
||||
|
||||
- static Handle<JSReceiver> GetRootForNonJSReceiver(
|
||||
- Isolate* isolate, Handle<Object> lookup_start_object,
|
||||
- size_t index = kInvalidIndex);
|
||||
- static inline Handle<JSReceiver> GetRoot(Isolate* isolate,
|
||||
- Handle<Object> lookup_start_object,
|
||||
- size_t index = kInvalidIndex);
|
||||
+ static MaybeHandle<JSReceiver> GetRootForNonJSReceiver(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration);
|
||||
+ static inline MaybeHandle<JSReceiver> GetRoot(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration);
|
||||
|
||||
State NotFound(JSReceiver const holder) const;
|
||||
|
||||
diff --git a/test/mjsunit/regress/regress-crbug-1447430.js b/test/mjsunit/regress/regress-crbug-1447430.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c7bb3e72e3af1b9f8c2fa82faeeb2d813fe6ab3c
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-crbug-1447430.js
|
||||
@@ -0,0 +1,34 @@
|
||||
+// 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.
|
||||
+
|
||||
+// Flags: --allow-natives-syntax
|
||||
+
|
||||
+var s = %CreatePrivateSymbol('x');
|
||||
+
|
||||
+(function TestSmi() {
|
||||
+ function f(o, p) {
|
||||
+ o[p] = 153;
|
||||
+ }
|
||||
+ (1).__proto__[s] = 42;
|
||||
+ %PrepareFunctionForOptimization(f);
|
||||
+ assertEquals(f(42, s), undefined);
|
||||
+}());
|
||||
+
|
||||
+(function TestString() {
|
||||
+ function f(o, p) {
|
||||
+ o[p] = 153;
|
||||
+ }
|
||||
+ ('xyz').__proto__[s] = 42;
|
||||
+ %PrepareFunctionForOptimization(f);
|
||||
+ assertEquals(f('abc', s), undefined);
|
||||
+}());
|
||||
+
|
||||
+(function TestSymbol() {
|
||||
+ function f(o, p) {
|
||||
+ o[p] = 153;
|
||||
+ }
|
||||
+ Symbol('xyz').__proto__[s] = 42;
|
||||
+ %PrepareFunctionForOptimization(f);
|
||||
+ assertEquals(f(Symbol('abc'), s), undefined);
|
||||
+}());
|
||||
150
patches/v8/cherry-pick-9c6dfc733fce.patch
Normal file
150
patches/v8/cherry-pick-9c6dfc733fce.patch
Normal file
@@ -0,0 +1,150 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Tue, 16 May 2023 16:01:49 +0200
|
||||
Subject: Merged: [runtime] Fix handling of interceptors
|
||||
|
||||
Drive-by: simplify creation of LookupIterator copies.
|
||||
|
||||
Bug: chromium:1440695
|
||||
(cherry picked from commit d125c7329f6e22af4523de3c55de3a22f168acc9)
|
||||
|
||||
Change-Id: I58416531b9af3456f53264566ec1eb7457328f94
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545763
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#23}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
|
||||
index b3f7db7bd984e8524689c3060bfd0674840fa63b..8cc8af6c221a90cc6a6201faa46738ec80ffccdb 100644
|
||||
--- a/src/objects/js-objects.cc
|
||||
+++ b/src/objects/js-objects.cc
|
||||
@@ -3633,10 +3633,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
|
||||
// own property without the interceptor.
|
||||
Isolate* isolate = it->isolate();
|
||||
Handle<Object> receiver = it->GetReceiver();
|
||||
- LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
|
||||
- LookupIterator own_lookup =
|
||||
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
|
||||
- : LookupIterator(isolate, receiver, it->name(), c);
|
||||
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
|
||||
+ LookupIterator::OWN_SKIP_INTERCEPTOR);
|
||||
return JSObject::DefineOwnPropertyIgnoreAttributes(
|
||||
&own_lookup, value, attributes, should_throw, handling, semantics,
|
||||
store_origin);
|
||||
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
|
||||
index 782698bd7c488f5570288119e49784e16a93ddd2..35eaed8ffbc23248c33230868f428bc192c5b790 100644
|
||||
--- a/src/objects/lookup-inl.h
|
||||
+++ b/src/objects/lookup-inl.h
|
||||
@@ -130,6 +130,29 @@ PropertyKey::PropertyKey(Isolate* isolate, double index) {
|
||||
#endif
|
||||
}
|
||||
|
||||
+PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name, size_t index)
|
||||
+ : name_(name), index_(index) {
|
||||
+ DCHECK_IMPLIES(index_ == LookupIterator::kInvalidIndex, !name_.is_null());
|
||||
+#if V8_TARGET_ARCH_32_BIT
|
||||
+ DCHECK_IMPLIES(index_ != LookupIterator::kInvalidIndex,
|
||||
+ index_ <= JSObject::kMaxElementIndex);
|
||||
+#endif
|
||||
+#if DEBUG
|
||||
+ if (index_ != LookupIterator::kInvalidIndex && !name_.is_null()) {
|
||||
+ // If both valid index and name are given then the name is a string
|
||||
+ // representation of the same index.
|
||||
+ size_t integer_index;
|
||||
+ CHECK(name_->AsIntegerIndex(&integer_index));
|
||||
+ CHECK_EQ(index_, integer_index);
|
||||
+ } else if (index_ == LookupIterator::kInvalidIndex) {
|
||||
+ // If only name is given it must not be a string representing an integer
|
||||
+ // index.
|
||||
+ size_t integer_index;
|
||||
+ CHECK(!name_->AsIntegerIndex(&integer_index));
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name) {
|
||||
if (name->AsIntegerIndex(&index_)) {
|
||||
name_ = name;
|
||||
@@ -179,6 +202,10 @@ Handle<Name> LookupIterator::GetName() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
+PropertyKey LookupIterator::GetKey() const {
|
||||
+ return PropertyKey(isolate_, name_, index_);
|
||||
+}
|
||||
+
|
||||
bool LookupIterator::IsElement(JSReceiver object) const {
|
||||
return index_ <= JSObject::kMaxElementIndex ||
|
||||
(index_ != kInvalidIndex &&
|
||||
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
|
||||
index ef90316295c98d51b61c118cf331731f991d93d0..5d2d926b7e3dcecf8529f7d1c1e919033d9faa7f 100644
|
||||
--- a/src/objects/lookup.h
|
||||
+++ b/src/objects/lookup.h
|
||||
@@ -36,6 +36,11 @@ class PropertyKey {
|
||||
inline Handle<Name> GetName(Isolate* isolate);
|
||||
|
||||
private:
|
||||
+ friend LookupIterator;
|
||||
+
|
||||
+ // Shortcut for constructing PropertyKey from an active LookupIterator.
|
||||
+ inline PropertyKey(Isolate* isolate, Handle<Name> name, size_t index);
|
||||
+
|
||||
Handle<Name> name_;
|
||||
size_t index_;
|
||||
};
|
||||
@@ -108,6 +113,9 @@ class V8_EXPORT_PRIVATE LookupIterator final {
|
||||
return static_cast<uint32_t>(index_);
|
||||
}
|
||||
|
||||
+ // Helper method for creating a copy of of the iterator.
|
||||
+ inline PropertyKey GetKey() const;
|
||||
+
|
||||
// Returns true if this LookupIterator has an index in the range
|
||||
// [0, size_t::max).
|
||||
bool IsElement() const { return index_ != kInvalidIndex; }
|
||||
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
|
||||
index 01d826c43bf9ec8bb28aba0e59fd3fa8f5700bac..b57c68073e401bb34796689013213791d40af10a 100644
|
||||
--- a/src/objects/objects.cc
|
||||
+++ b/src/objects/objects.cc
|
||||
@@ -2668,11 +2668,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
|
||||
|
||||
// Note, the callers rely on the fact that this code is redoing the full own
|
||||
// lookup from scratch.
|
||||
- LookupIterator::Configuration c = LookupIterator::OWN;
|
||||
- LookupIterator own_lookup =
|
||||
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
|
||||
- : LookupIterator(isolate, receiver, it->name(), c);
|
||||
-
|
||||
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
|
||||
+ LookupIterator::OWN);
|
||||
for (; own_lookup.IsFound(); own_lookup.Next()) {
|
||||
switch (own_lookup.state()) {
|
||||
case LookupIterator::ACCESS_CHECK:
|
||||
@@ -2709,6 +2706,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
|
||||
JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
|
||||
MAYBE_RETURN(owned, Nothing<bool>());
|
||||
if (!owned.FromJust()) {
|
||||
+ // |own_lookup| might become outdated at this point anyway.
|
||||
+ own_lookup.Restart();
|
||||
if (!CheckContextualStoreToJSGlobalObject(&own_lookup,
|
||||
should_throw)) {
|
||||
return Nothing<bool>();
|
||||
diff --git a/test/unittests/api/interceptor-unittest.cc b/test/unittests/api/interceptor-unittest.cc
|
||||
index 635bf6a0b72f8d49591be333b1314846c9c47269..416f9bd1eb4c59160eb03031e6011ae02dcf021e 100644
|
||||
--- a/test/unittests/api/interceptor-unittest.cc
|
||||
+++ b/test/unittests/api/interceptor-unittest.cc
|
||||
@@ -174,8 +174,10 @@ TEST_F(InterceptorLoggingTest, DispatchTest) {
|
||||
EXPECT_EQ(Run("obj.foo"), "named getter");
|
||||
EXPECT_EQ(Run("obj[42]"), "indexed getter");
|
||||
|
||||
- EXPECT_EQ(Run("obj.foo = null"), "named setter, named descriptor");
|
||||
- EXPECT_EQ(Run("obj[42] = null"), "indexed setter, indexed descriptor");
|
||||
+ EXPECT_EQ(Run("obj.foo = null"),
|
||||
+ "named setter, named descriptor, named query");
|
||||
+ EXPECT_EQ(Run("obj[42] = null"),
|
||||
+ "indexed setter, indexed descriptor, indexed query");
|
||||
|
||||
EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
|
||||
"named descriptor");
|
||||
362
patches/v8/cherry-pick-bb90b9cfcbca.patch
Normal file
362
patches/v8/cherry-pick-bb90b9cfcbca.patch
Normal 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);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Fri, 2 Jun 2023 18:13:01 +0200
|
||||
Subject: Merged: [ic] Fix store handler selection for arguments objects
|
||||
|
||||
Drive-by: fix printing of handlers in --trace-feedback-updates mode.
|
||||
|
||||
(cherry picked from commit e144f3b71e64e01d6ffd247eb15ca1ff56f6287b)
|
||||
|
||||
Bug: chromium:1450481
|
||||
Change-Id: Ifbb97d694b8520584df0610aad30805713b29c00
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4584889
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.9@{#32}
|
||||
Cr-Branched-From: 8ade6bf1fa237ad30dd9a05cc6ffe548131699e8-refs/heads/10.9.194@{#1}
|
||||
Cr-Branched-From: 9ff2515271f11cab783f0e82678ae0b925d77dd0-refs/heads/main@{#84164}
|
||||
|
||||
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
|
||||
index b763468f58f8f0be294af50188dd69b99c9428dc..e4e206f2b52095c95ac4c667f32f0620c753967c 100644
|
||||
--- a/src/diagnostics/objects-printer.cc
|
||||
+++ b/src/diagnostics/objects-printer.cc
|
||||
@@ -1324,8 +1324,18 @@ void FeedbackNexus::Print(std::ostream& os) {
|
||||
case FeedbackSlotKind::kSetKeyedStrict: {
|
||||
os << InlineCacheState2String(ic_state());
|
||||
if (ic_state() == InlineCacheState::MONOMORPHIC) {
|
||||
- os << "\n " << Brief(GetFeedback()) << ": ";
|
||||
- StoreHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(), os);
|
||||
+ HeapObject feedback = GetFeedback().GetHeapObject();
|
||||
+ HeapObject feedback_extra = GetFeedbackExtra().GetHeapObject();
|
||||
+ if (feedback.IsName()) {
|
||||
+ os << " with name " << Brief(feedback);
|
||||
+ WeakFixedArray array = WeakFixedArray::cast(feedback_extra);
|
||||
+ os << "\n " << Brief(array.Get(0)) << ": ";
|
||||
+ Object handler = array.Get(1).GetHeapObjectOrSmi();
|
||||
+ StoreHandler::PrintHandler(handler, os);
|
||||
+ } else {
|
||||
+ os << "\n " << Brief(feedback) << ": ";
|
||||
+ StoreHandler::PrintHandler(feedback_extra, os);
|
||||
+ }
|
||||
} else if (ic_state() == InlineCacheState::POLYMORPHIC) {
|
||||
WeakFixedArray array =
|
||||
WeakFixedArray::cast(GetFeedback().GetHeapObject());
|
||||
diff --git a/src/ic/handler-configuration.cc b/src/ic/handler-configuration.cc
|
||||
index ece15ff24b9066158c85524ed0087f6804feb61c..ca49ed91db7b667fe3154a309e78130a9efe6d99 100644
|
||||
--- a/src/ic/handler-configuration.cc
|
||||
+++ b/src/ic/handler-configuration.cc
|
||||
@@ -593,8 +593,11 @@ void StoreHandler::PrintHandler(Object handler, std::ostream& os) {
|
||||
os << ", validity cell = ";
|
||||
store_handler.validity_cell().ShortPrint(os);
|
||||
os << ")" << std::endl;
|
||||
+ } else if (handler.IsMap()) {
|
||||
+ os << "StoreHandler(field transition to " << Brief(handler) << ")"
|
||||
+ << std::endl;
|
||||
} else {
|
||||
- os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")";
|
||||
+ os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
||||
index 0447e017fbedae66eac2ad9637d53121a008f5b0..93939fa4702922f58e8e5bcc019e569f42ab198e 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -2300,10 +2300,18 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
receiver_map->has_sealed_elements() ||
|
||||
receiver_map->has_nonextensible_elements() ||
|
||||
receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
|
||||
+ // TODO(jgruber): Update counter name.
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
|
||||
- code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
|
||||
- if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
|
||||
- return code;
|
||||
+ if (receiver_map->IsJSArgumentsObjectMap() &&
|
||||
+ receiver_map->has_fast_packed_elements()) {
|
||||
+ // Allow fast behaviour for in-bounds stores while making it miss and
|
||||
+ // properly handle the out of bounds store case.
|
||||
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), STANDARD_STORE);
|
||||
+ } else {
|
||||
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
|
||||
+ if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
|
||||
+ return code;
|
||||
+ }
|
||||
}
|
||||
} else if (IsStoreInArrayLiteralIC()) {
|
||||
// TODO(jgruber): Update counter name.
|
||||
@@ -2314,7 +2322,7 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
|
||||
DCHECK(DICTIONARY_ELEMENTS == receiver_map->elements_kind() ||
|
||||
receiver_map->has_frozen_elements());
|
||||
- code = StoreHandler::StoreSlow(isolate(), store_mode);
|
||||
+ return StoreHandler::StoreSlow(isolate(), store_mode);
|
||||
}
|
||||
|
||||
if (IsAnyDefineOwn() || IsStoreInArrayLiteralIC()) return code;
|
||||
diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h
|
||||
index a83a060337739878f258c50d8013d5ba6c2262d8..723a961521f26cdad66a484f39037f94109e2cac 100644
|
||||
--- a/src/objects/map-inl.h
|
||||
+++ b/src/objects/map-inl.h
|
||||
@@ -590,6 +590,10 @@ bool Map::has_fast_elements() const {
|
||||
return IsFastElementsKind(elements_kind());
|
||||
}
|
||||
|
||||
+bool Map::has_fast_packed_elements() const {
|
||||
+ return IsFastPackedElementsKind(elements_kind());
|
||||
+}
|
||||
+
|
||||
bool Map::has_sloppy_arguments_elements() const {
|
||||
return IsSloppyArgumentsElementsKind(elements_kind());
|
||||
}
|
||||
diff --git a/src/objects/map.h b/src/objects/map.h
|
||||
index 6914a51150f4235386f5dca7af0d8103bc64f9e2..8311850f82bc32b794873689789c510376f67233 100644
|
||||
--- a/src/objects/map.h
|
||||
+++ b/src/objects/map.h
|
||||
@@ -422,6 +422,7 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
|
||||
inline bool has_fast_smi_or_object_elements() const;
|
||||
inline bool has_fast_double_elements() const;
|
||||
inline bool has_fast_elements() const;
|
||||
+ inline bool has_fast_packed_elements() const;
|
||||
inline bool has_sloppy_arguments_elements() const;
|
||||
inline bool has_fast_sloppy_arguments_elements() const;
|
||||
inline bool has_fast_string_wrapper_elements() const;
|
||||
@@ -1 +1,2 @@
|
||||
fix_fallback_to_x11_capturer_on_wayland.patch
|
||||
m114_move_transceiver_iteration_loop_over_to_the_signaling_thread.patch
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tommi <tommi@webrtc.org>
|
||||
Date: Thu, 1 Jun 2023 16:08:52 +0200
|
||||
Subject: Move transceiver iteration loop over to the signaling thread.
|
||||
|
||||
This is required for ReportTransportStats since iterating over the
|
||||
transceiver list from the network thread is not safe.
|
||||
|
||||
(cherry picked from commit dba22d31909298161318e00d43a80cdb0abc940f)
|
||||
|
||||
No-Try: true
|
||||
Bug: chromium:1446274, webrtc:12692
|
||||
Change-Id: I7c514df9f029112c4b1da85826af91217850fb26
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307340
|
||||
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
|
||||
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#40197}
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308001
|
||||
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#3}
|
||||
Cr-Branched-From: df7df199abd619e75b9f1d9a7e12fc3f3f748775-refs/heads/main@{#39949}
|
||||
|
||||
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
|
||||
index 5de77fee9d2e5c76438b8612f29afc067bd02c13..7333bd59b99a618339413f0647562ed5ff5841d6 100644
|
||||
--- a/pc/peer_connection.cc
|
||||
+++ b/pc/peer_connection.cc
|
||||
@@ -727,9 +727,6 @@ JsepTransportController* PeerConnection::InitializeTransportController_n(
|
||||
transport_controller_->SubscribeIceConnectionState(
|
||||
[this](cricket::IceConnectionState s) {
|
||||
RTC_DCHECK_RUN_ON(network_thread());
|
||||
- if (s == cricket::kIceConnectionConnected) {
|
||||
- ReportTransportStats();
|
||||
- }
|
||||
signaling_thread()->PostTask(
|
||||
SafeTask(signaling_thread_safety_.flag(), [this, s]() {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
@@ -2390,6 +2387,20 @@ void PeerConnection::OnTransportControllerConnectionState(
|
||||
case cricket::kIceConnectionConnected:
|
||||
RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
|
||||
"all transports are writable.";
|
||||
+ {
|
||||
+ std::vector<RtpTransceiverProxyRefPtr> transceivers;
|
||||
+ if (ConfiguredForMedia()) {
|
||||
+ transceivers = rtp_manager()->transceivers()->List();
|
||||
+ }
|
||||
+
|
||||
+ network_thread()->PostTask(
|
||||
+ SafeTask(network_thread_safety_,
|
||||
+ [this, transceivers = std::move(transceivers)] {
|
||||
+ RTC_DCHECK_RUN_ON(network_thread());
|
||||
+ ReportTransportStats(std::move(transceivers));
|
||||
+ }));
|
||||
+ }
|
||||
+
|
||||
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
|
||||
NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
|
||||
break;
|
||||
@@ -2730,20 +2741,18 @@ void PeerConnection::OnTransportControllerGatheringState(
|
||||
}
|
||||
|
||||
// Runs on network_thread().
|
||||
-void PeerConnection::ReportTransportStats() {
|
||||
+void PeerConnection::ReportTransportStats(
|
||||
+ std::vector<RtpTransceiverProxyRefPtr> transceivers) {
|
||||
TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
|
||||
rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
|
||||
std::map<std::string, std::set<cricket::MediaType>>
|
||||
media_types_by_transport_name;
|
||||
- if (ConfiguredForMedia()) {
|
||||
- for (const auto& transceiver :
|
||||
- rtp_manager()->transceivers()->UnsafeList()) {
|
||||
- if (transceiver->internal()->channel()) {
|
||||
- std::string transport_name(
|
||||
- transceiver->internal()->channel()->transport_name());
|
||||
- media_types_by_transport_name[transport_name].insert(
|
||||
- transceiver->media_type());
|
||||
- }
|
||||
+ for (const auto& transceiver : transceivers) {
|
||||
+ if (transceiver->internal()->channel()) {
|
||||
+ std::string transport_name(
|
||||
+ transceiver->internal()->channel()->transport_name());
|
||||
+ media_types_by_transport_name[transport_name].insert(
|
||||
+ transceiver->media_type());
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
|
||||
index 39a240da4f3e601e8eea1a61dcab75369e51ac05..7f150822e9f224680fc4649a46f319ed97f9a171 100644
|
||||
--- a/pc/peer_connection.h
|
||||
+++ b/pc/peer_connection.h
|
||||
@@ -567,7 +567,8 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
|
||||
// Invoked when TransportController connection completion is signaled.
|
||||
// Reports stats for all transports in use.
|
||||
- void ReportTransportStats() RTC_RUN_ON(network_thread());
|
||||
+ void ReportTransportStats(std::vector<RtpTransceiverProxyRefPtr> transceivers)
|
||||
+ RTC_RUN_ON(network_thread());
|
||||
|
||||
// Gather the usage of IPv4/IPv6 as best connection.
|
||||
static void ReportBestConnectionState(const cricket::TransportStats& stats);
|
||||
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
|
||||
index 7fa94527f1002b6a3d17b9aa45211e51a51d7544..c12cbd4fcac2b110d875a1371d29ad54f48c8d71 100644
|
||||
--- a/pc/peer_connection_integrationtest.cc
|
||||
+++ b/pc/peer_connection_integrationtest.cc
|
||||
@@ -1836,6 +1836,10 @@ TEST_P(PeerConnectionIntegrationTest,
|
||||
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
|
||||
callee()->ice_connection_state(), kDefaultTimeout);
|
||||
|
||||
+ // Part of reporting the stats will occur on the network thread, so flush it
|
||||
+ // before checking NumEvents.
|
||||
+ SendTask(network_thread(), [] {});
|
||||
+
|
||||
EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
|
||||
"WebRTC.PeerConnection.CandidatePairType_UDP",
|
||||
webrtc::kIceCandidatePairHostNameHostName));
|
||||
@@ -1964,6 +1968,10 @@ TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
|
||||
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
|
||||
callee()->ice_connection_state(), kDefaultTimeout);
|
||||
|
||||
+ // Part of reporting the stats will occur on the network thread, so flush it
|
||||
+ // before checking NumEvents.
|
||||
+ SendTask(network_thread(), [] {});
|
||||
+
|
||||
// TODO(bugs.webrtc.org/9456): Fix it.
|
||||
const int num_best_ipv4 = webrtc::metrics::NumEvents(
|
||||
"WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);
|
||||
@@ -77,7 +77,7 @@ async function validateReleaseAssets (release, validatingRelease) {
|
||||
} else {
|
||||
await verifyShasumsForRemoteFiles(downloadUrls)
|
||||
.catch(err => {
|
||||
console.log(`${fail} error verifyingShasums`, err);
|
||||
console.error(`${fail} error verifyingShasums`, err);
|
||||
});
|
||||
}
|
||||
const azRemoteFiles = azRemoteFilesForVersion(release.tag_name);
|
||||
@@ -90,7 +90,7 @@ function check (condition, statement, exitIfFail = false) {
|
||||
console.log(`${pass} ${statement}`);
|
||||
} else {
|
||||
failureCount++;
|
||||
console.log(`${fail} ${statement}`);
|
||||
console.error(`${fail} ${statement}`);
|
||||
if (exitIfFail) process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ function runScript (scriptName, scriptArgs, cwd) {
|
||||
try {
|
||||
return execSync(scriptCommand, scriptOptions);
|
||||
} catch (err) {
|
||||
console.log(`${fail} Error running ${scriptName}`, err);
|
||||
console.error(`${fail} Error running ${scriptName}`, err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -266,7 +266,8 @@ async function createReleaseShasums (release) {
|
||||
repo: targetRepo,
|
||||
asset_id: existingAssets[0].id
|
||||
}).catch(err => {
|
||||
console.log(`${fail} Error deleting ${fileName} on GitHub:`, err);
|
||||
console.error(`${fail} Error deleting ${fileName} on GitHub:`, err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
console.log(`Creating and uploading the release ${fileName}.`);
|
||||
@@ -292,7 +293,7 @@ async function uploadShasumFile (filePath, fileName, releaseId) {
|
||||
data: fs.createReadStream(filePath),
|
||||
name: fileName
|
||||
}).catch(err => {
|
||||
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err);
|
||||
console.error(`${fail} Error uploading ${filePath} to GitHub:`, err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -301,13 +302,13 @@ function saveShaSumFile (checksums, fileName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
temp.open(fileName, (err, info) => {
|
||||
if (err) {
|
||||
console.log(`${fail} Could not create ${fileName} file`);
|
||||
console.error(`${fail} Could not create ${fileName} file`);
|
||||
process.exit(1);
|
||||
} else {
|
||||
fs.writeFileSync(info.fd, checksums);
|
||||
fs.close(info.fd, (err) => {
|
||||
if (err) {
|
||||
console.log(`${fail} Could close ${fileName} file`);
|
||||
console.error(`${fail} Could close ${fileName} file`);
|
||||
process.exit(1);
|
||||
}
|
||||
resolve(info.path);
|
||||
@@ -333,7 +334,7 @@ async function publishRelease (release) {
|
||||
draft: false,
|
||||
make_latest: makeLatest ? 'true' : 'false'
|
||||
}).catch(err => {
|
||||
console.log(`${fail} Error publishing release:`, err);
|
||||
console.error(`${fail} Error publishing release:`, err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -351,13 +352,17 @@ async function makeRelease (releaseToValidate) {
|
||||
} else {
|
||||
let draftRelease = await getDraftRelease();
|
||||
uploadNodeShasums();
|
||||
uploadIndexJson();
|
||||
|
||||
await createReleaseShasums(draftRelease);
|
||||
|
||||
// Fetch latest version of release before verifying
|
||||
draftRelease = await getDraftRelease(pkgVersion, true);
|
||||
await validateReleaseAssets(draftRelease);
|
||||
// index.json goes live once uploaded so do these uploads as
|
||||
// late as possible to reduce the chances it contains a release
|
||||
// which fails to publish. It has to be done before the final
|
||||
// publish to ensure there aren't published releases not contained
|
||||
// in index.json, which causes other problems in downstream projects
|
||||
uploadIndexJson();
|
||||
await publishRelease(draftRelease);
|
||||
console.log(`${pass} SUCCESS!!! Release has been published. Please run ` +
|
||||
'"npm run publish-to-npm" to publish release to npm.');
|
||||
@@ -403,7 +408,7 @@ async function verifyDraftGitHubReleaseAssets (release) {
|
||||
|
||||
return { url: response.headers.location, file: asset.name };
|
||||
})).catch(err => {
|
||||
console.log(`${fail} Error downloading files from GitHub`, err);
|
||||
console.error(`${fail} Error downloading files from GitHub`, err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ def main():
|
||||
chromedriver_name = {
|
||||
'darwin': 'chromedriver',
|
||||
'win32': 'chromedriver.exe',
|
||||
'linux': 'chromedriver',
|
||||
'linux2': 'chromedriver'
|
||||
}
|
||||
|
||||
|
||||
@@ -78,15 +78,20 @@ void StopTracing(gin_helper::Promise<base::FilePath> promise,
|
||||
}
|
||||
},
|
||||
std::move(promise), *file_path);
|
||||
if (file_path) {
|
||||
|
||||
auto* instance = TracingController::GetInstance();
|
||||
if (!instance->IsTracing()) {
|
||||
std::move(resolve_or_reject)
|
||||
.Run(absl::make_optional(
|
||||
"Failed to stop tracing - no trace in progress"));
|
||||
} else if (file_path) {
|
||||
auto split_callback = base::SplitOnceCallback(std::move(resolve_or_reject));
|
||||
auto endpoint = TracingController::CreateFileEndpoint(
|
||||
*file_path,
|
||||
base::BindOnce(std::move(split_callback.first), absl::nullopt));
|
||||
if (!TracingController::GetInstance()->StopTracing(endpoint)) {
|
||||
if (!instance->StopTracing(endpoint)) {
|
||||
std::move(split_callback.second)
|
||||
.Run(absl::make_optional(
|
||||
"Failed to stop tracing (was a trace in progress?)"));
|
||||
.Run(absl::make_optional("Failed to stop tracing"));
|
||||
}
|
||||
} else {
|
||||
std::move(resolve_or_reject)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
|
||||
namespace electron {
|
||||
@@ -36,7 +37,11 @@ void AutofillDriver::ShowAutofillPopup(
|
||||
v8::HandleScope scope(isolate);
|
||||
auto* web_contents = api::WebContents::From(
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host_));
|
||||
if (!web_contents || !web_contents->owner_window())
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
auto* owner_window = web_contents->owner_window();
|
||||
if (!owner_window)
|
||||
return;
|
||||
|
||||
auto* embedder = web_contents->embedder();
|
||||
@@ -55,9 +60,23 @@ void AutofillDriver::ShowAutofillPopup(
|
||||
embedder_frame_host = embedder->web_contents()->GetPrimaryMainFrame();
|
||||
}
|
||||
|
||||
// Ensure that if the WebContents belongs to a BrowserView,
|
||||
// the popup is positioned relative to the BrowserView's bounds.
|
||||
for (NativeBrowserView* bv : owner_window->browser_views()) {
|
||||
auto* iwc = bv->GetInspectableWebContents();
|
||||
if (!iwc)
|
||||
continue;
|
||||
|
||||
auto* awc = api::WebContents::From(iwc->GetWebContents());
|
||||
if (awc == web_contents) {
|
||||
auto bv_origin = bv->GetBounds().origin();
|
||||
popup_bounds.Offset(gfx::Vector2dF(bv_origin.x(), bv_origin.y()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
autofill_popup_->CreateView(render_frame_host_, embedder_frame_host, osr,
|
||||
web_contents->owner_window()->content_view(),
|
||||
popup_bounds);
|
||||
owner_window->content_view(), popup_bounds);
|
||||
autofill_popup_->SetItems(values, labels);
|
||||
}
|
||||
|
||||
|
||||
@@ -152,6 +152,9 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual std::string GetAlwaysOnTopLevel() = 0;
|
||||
virtual void SetActive(bool is_key) = 0;
|
||||
virtual bool IsActive() const = 0;
|
||||
virtual void RemoveChildWindow(NativeWindow* child) = 0;
|
||||
virtual void AttachChildren() = 0;
|
||||
virtual void DetachChildren() = 0;
|
||||
#endif
|
||||
|
||||
// Ability to augment the window title for the screen readers.
|
||||
@@ -382,6 +385,10 @@ class NativeWindow : public base::SupportsUserData,
|
||||
|
||||
int32_t window_id() const { return next_id_; }
|
||||
|
||||
void add_child_window(NativeWindow* child) {
|
||||
child_windows_.push_back(child);
|
||||
}
|
||||
|
||||
int NonClientHitTest(const gfx::Point& point);
|
||||
void AddDraggableRegionProvider(DraggableRegionProvider* provider);
|
||||
void RemoveDraggableRegionProvider(DraggableRegionProvider* provider);
|
||||
@@ -422,6 +429,8 @@ class NativeWindow : public base::SupportsUserData,
|
||||
FullScreenTransitionType fullscreen_transition_type_ =
|
||||
FullScreenTransitionType::NONE;
|
||||
|
||||
std::list<NativeWindow*> child_windows_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<views::Widget> widget_;
|
||||
|
||||
|
||||
@@ -154,6 +154,12 @@ class NativeWindowMac : public NativeWindow,
|
||||
void NotifyWindowLeaveFullScreen() override;
|
||||
void SetActive(bool is_key) override;
|
||||
bool IsActive() const override;
|
||||
// Remove the specified child window without closing it.
|
||||
void RemoveChildWindow(NativeWindow* child) override;
|
||||
// Attach child windows, if the window is visible.
|
||||
void AttachChildren() override;
|
||||
// Detach window from parent without destroying it.
|
||||
void DetachChildren() override;
|
||||
|
||||
void NotifyWindowWillEnterFullScreen();
|
||||
void NotifyWindowWillLeaveFullScreen();
|
||||
|
||||
@@ -473,14 +473,7 @@ void NativeWindowMac::Hide() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide all children of the current window before hiding the window.
|
||||
// components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
|
||||
// expects this when window visibility changes.
|
||||
if ([window_ childWindows]) {
|
||||
for (NSWindow* child in [window_ childWindows]) {
|
||||
[child orderOut:nil];
|
||||
}
|
||||
}
|
||||
DetachChildren();
|
||||
|
||||
// Detach the window from the parent before.
|
||||
if (parent())
|
||||
@@ -600,6 +593,37 @@ bool NativeWindowMac::HandleDeferredClose() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeWindowMac::RemoveChildWindow(NativeWindow* child) {
|
||||
child_windows_.remove_if([&child](NativeWindow* w) { return (w == child); });
|
||||
|
||||
[window_ removeChildWindow:child->GetNativeWindow().GetNativeNSWindow()];
|
||||
}
|
||||
|
||||
void NativeWindowMac::AttachChildren() {
|
||||
for (auto* child : child_windows_) {
|
||||
auto* child_nswindow = child->GetNativeWindow().GetNativeNSWindow();
|
||||
if ([child_nswindow parentWindow] == window_)
|
||||
continue;
|
||||
|
||||
// Attaching a window as a child window resets its window level, so
|
||||
// save and restore it afterwards.
|
||||
NSInteger level = window_.level;
|
||||
[window_ addChildWindow:child_nswindow ordered:NSWindowAbove];
|
||||
[window_ setLevel:level];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::DetachChildren() {
|
||||
DCHECK(child_windows_.size() == [[window_ childWindows] count]);
|
||||
|
||||
// Hide all children before hiding/minimizing the window.
|
||||
// NativeWidgetNSWindowBridge::NotifyVisibilityChangeDown()
|
||||
// will DCHECK otherwise.
|
||||
for (auto* child : child_windows_) {
|
||||
[child->GetNativeWindow().GetNativeNSWindow() orderOut:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetFullScreen(bool fullscreen) {
|
||||
if (!has_frame() && !HasStyleMask(NSWindowStyleMaskTitled))
|
||||
return;
|
||||
@@ -1765,18 +1789,12 @@ void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
|
||||
|
||||
// Remove current parent window.
|
||||
if ([window_ parentWindow])
|
||||
[[window_ parentWindow] removeChildWindow:window_];
|
||||
parent->RemoveChildWindow(this);
|
||||
|
||||
// Set new parent window.
|
||||
// Note that this method will force the window to become visible.
|
||||
if (parent && attach) {
|
||||
// Attaching a window as a child window resets its window level, so
|
||||
// save and restore it afterwards.
|
||||
NSInteger level = window_.level;
|
||||
[parent->GetNativeWindow().GetNativeNSWindow()
|
||||
addChildWindow:window_
|
||||
ordered:NSWindowAbove];
|
||||
[window_ setLevel:level];
|
||||
parent->add_child_window(this);
|
||||
parent->AttachChildren();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -718,10 +718,14 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
|
||||
gfx::Rect());
|
||||
|
||||
// Auto-hide menubar when in fullscreen.
|
||||
if (fullscreen)
|
||||
if (fullscreen) {
|
||||
menu_bar_visible_before_fullscreen_ = IsMenuBarVisible();
|
||||
SetMenuBarVisibility(false);
|
||||
else
|
||||
SetMenuBarVisibility(!IsMenuBarAutoHide());
|
||||
} else {
|
||||
SetMenuBarVisibility(!IsMenuBarAutoHide() &&
|
||||
menu_bar_visible_before_fullscreen_);
|
||||
menu_bar_visible_before_fullscreen_ = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -322,6 +322,9 @@ class NativeWindowViews : public NativeWindow,
|
||||
// Handles unhandled keyboard messages coming back from the renderer process.
|
||||
std::unique_ptr<views::UnhandledKeyboardEventHandler> keyboard_event_handler_;
|
||||
|
||||
// Whether the menubar is visible before the window enters fullscreen
|
||||
bool menu_bar_visible_before_fullscreen_ = false;
|
||||
|
||||
// Whether the window should be enabled based on user calls to SetEnabled()
|
||||
bool is_enabled_ = true;
|
||||
// How many modal children this window has;
|
||||
|
||||
@@ -239,6 +239,7 @@ using FullScreenTransitionState =
|
||||
level_ = [window level];
|
||||
shell_->SetWindowLevel(NSNormalWindowLevel);
|
||||
shell_->UpdateWindowOriginalFrame();
|
||||
shell_->DetachChildren();
|
||||
}
|
||||
|
||||
- (void)windowDidMiniaturize:(NSNotification*)notification {
|
||||
@@ -248,6 +249,7 @@ using FullScreenTransitionState =
|
||||
|
||||
- (void)windowDidDeminiaturize:(NSNotification*)notification {
|
||||
[super windowDidDeminiaturize:notification];
|
||||
shell_->AttachChildren();
|
||||
shell_->SetWindowLevel(level_);
|
||||
shell_->NotifyWindowRestore();
|
||||
}
|
||||
|
||||
@@ -4237,11 +4237,13 @@ describe('BrowserWindow module', () => {
|
||||
const c = new BrowserWindow({ show: false, parent: w });
|
||||
expect(c.getParentWindow()).to.equal(w);
|
||||
});
|
||||
|
||||
it('adds window to child windows of parent', () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const c = new BrowserWindow({ show: false, parent: w });
|
||||
expect(w.getChildWindows()).to.deep.equal([c]);
|
||||
});
|
||||
|
||||
it('removes from child windows of parent when window is closed', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const c = new BrowserWindow({ show: false, parent: w });
|
||||
@@ -4253,6 +4255,59 @@ describe('BrowserWindow module', () => {
|
||||
expect(w.getChildWindows().length).to.equal(0);
|
||||
});
|
||||
|
||||
ifit(process.platform === 'darwin')('child window matches visibility when visibility changes', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const c = new BrowserWindow({ show: false, parent: w });
|
||||
|
||||
const wShow = emittedOnce(w, 'show');
|
||||
const cShow = emittedOnce(c, 'show');
|
||||
|
||||
w.show();
|
||||
c.show();
|
||||
|
||||
await Promise.all([wShow, cShow]);
|
||||
|
||||
const minimized = emittedOnce(w, 'minimize');
|
||||
w.minimize();
|
||||
await minimized;
|
||||
|
||||
expect(w.isVisible()).to.be.false('parent is visible');
|
||||
expect(c.isVisible()).to.be.false('child is visible');
|
||||
|
||||
const restored = emittedOnce(w, 'restore');
|
||||
w.restore();
|
||||
await restored;
|
||||
|
||||
expect(w.isVisible()).to.be.true('parent is visible');
|
||||
expect(c.isVisible()).to.be.true('child is visible');
|
||||
});
|
||||
|
||||
ifit(process.platform === 'darwin')('matches child window visibility when visibility changes', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const c = new BrowserWindow({ show: false, parent: w });
|
||||
|
||||
const wShow = emittedOnce(w, 'show');
|
||||
const cShow = emittedOnce(c, 'show');
|
||||
|
||||
w.show();
|
||||
c.show();
|
||||
|
||||
await Promise.all([wShow, cShow]);
|
||||
|
||||
const minimized = emittedOnce(c, 'minimize');
|
||||
c.minimize();
|
||||
await minimized;
|
||||
|
||||
expect(c.isVisible()).to.be.false('child is visible');
|
||||
|
||||
const restored = emittedOnce(c, 'restore');
|
||||
c.restore();
|
||||
await restored;
|
||||
|
||||
expect(w.isVisible()).to.be.true('parent is visible');
|
||||
expect(c.isVisible()).to.be.true('child is visible');
|
||||
});
|
||||
|
||||
it('closes a grandchild window when a middle child window is destroyed', (done) => {
|
||||
const w = new BrowserWindow();
|
||||
|
||||
@@ -4863,6 +4918,48 @@ describe('BrowserWindow module', () => {
|
||||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform !== 'darwin')('when fullscreen state is changed', () => {
|
||||
it('correctly remembers state prior to fullscreen change', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
expect(w.isMenuBarVisible()).to.be.true('isMenuBarVisible');
|
||||
w.setMenuBarVisibility(false);
|
||||
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
|
||||
|
||||
const enterFS = emittedOnce(w, 'enter-full-screen');
|
||||
w.setFullScreen(true);
|
||||
await enterFS;
|
||||
expect(w.fullScreen).to.be.true('not fullscreen');
|
||||
|
||||
const exitFS = emittedOnce(w, 'leave-full-screen');
|
||||
w.setFullScreen(false);
|
||||
await exitFS;
|
||||
expect(w.fullScreen).to.be.false('not fullscreen');
|
||||
|
||||
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
|
||||
});
|
||||
|
||||
it('correctly remembers state prior to fullscreen change with autoHide', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
expect(w.autoHideMenuBar).to.be.false('autoHideMenuBar');
|
||||
w.autoHideMenuBar = true;
|
||||
expect(w.autoHideMenuBar).to.be.true('autoHideMenuBar');
|
||||
w.setMenuBarVisibility(false);
|
||||
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
|
||||
|
||||
const enterFS = emittedOnce(w, 'enter-full-screen');
|
||||
w.setFullScreen(true);
|
||||
await enterFS;
|
||||
expect(w.fullScreen).to.be.true('not fullscreen');
|
||||
|
||||
const exitFS = emittedOnce(w, 'leave-full-screen');
|
||||
w.setFullScreen(false);
|
||||
await exitFS;
|
||||
expect(w.fullScreen).to.be.false('not fullscreen');
|
||||
|
||||
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
|
||||
});
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin')('fullscreenable state', () => {
|
||||
it('with functions', () => {
|
||||
it('can be set with fullscreenable constructor option', () => {
|
||||
|
||||
@@ -113,7 +113,7 @@ ifdescribe(!(['arm', 'arm64', 'ia32'].includes(process.arch)))('contentTracing',
|
||||
});
|
||||
|
||||
it('rejects if no trace is happening', async () => {
|
||||
await expect(contentTracing.stopRecording()).to.be.rejected();
|
||||
await expect(contentTracing.stopRecording()).to.be.rejectedWith('Failed to stop tracing - no trace in progress');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -527,13 +527,13 @@
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/request@^6.0.0":
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.2.tgz#a2ba5ac22bddd5dcb3f539b618faa05115c5a255"
|
||||
integrity sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==
|
||||
version "6.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.5.tgz#7beef1065042998f7455973ef3f818e7b84d6ec2"
|
||||
integrity sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^7.0.0"
|
||||
"@octokit/request-error" "^3.0.0"
|
||||
"@octokit/types" "^8.0.0"
|
||||
"@octokit/types" "^9.0.0"
|
||||
is-plain-object "^5.0.0"
|
||||
node-fetch "^2.6.7"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
Reference in New Issue
Block a user