mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5955d53c48 | ||
|
|
3a5479aab6 | ||
|
|
7b3143cc84 | ||
|
|
d7816993b9 | ||
|
|
01f11a9169 | ||
|
|
d53ed0bcd7 | ||
|
|
999860f569 | ||
|
|
b8a8fe115f | ||
|
|
c50fa5486e | ||
|
|
3ad0eb0027 | ||
|
|
6619ad79d0 | ||
|
|
b74089153a | ||
|
|
9fec618788 | ||
|
|
55fd99488f | ||
|
|
ff3d3e6944 | ||
|
|
e39c0f9dae | ||
|
|
35b75e2285 | ||
|
|
5e9a959eae | ||
|
|
0a340b7f31 | ||
|
|
b3e5978c27 | ||
|
|
bce144aaf3 | ||
|
|
5910d3f090 | ||
|
|
b91a920128 | ||
|
|
a1342720ec | ||
|
|
53a6765fd6 | ||
|
|
3b45a30d2a | ||
|
|
1ec867c8a1 | ||
|
|
ec272f1e53 | ||
|
|
1914b92b8e | ||
|
|
59e3c0b9aa | ||
|
|
67e49b202c | ||
|
|
549e1a22e2 | ||
|
|
6a5ab8aa35 | ||
|
|
81dbdeb832 | ||
|
|
0dd76c79a8 | ||
|
|
b362e26261 | ||
|
|
d8b20376f9 | ||
|
|
e5237eb2ce | ||
|
|
fb5aa4660b | ||
|
|
78279119e2 | ||
|
|
bc12c6938a |
2
.github/actions/build-electron/action.yml
vendored
2
.github/actions/build-electron/action.yml
vendored
@@ -36,7 +36,7 @@ runs:
|
||||
shell: bash
|
||||
if: ${{ inputs.target-arch == 'x64' && inputs.target-platform == 'macos' }}
|
||||
run: |
|
||||
GN_APPENDED_ARGS="$GN_EXTRA_ARGS v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\""
|
||||
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"x64\" v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\""
|
||||
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
|
||||
- name: Build Electron ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
|
||||
1
.github/actions/checkout/action.yml
vendored
1
.github/actions/checkout/action.yml
vendored
@@ -100,6 +100,7 @@ runs:
|
||||
echo "There were changes to the patches when applying."
|
||||
echo "Check the CI artifacts for a patch you can apply to fix it."
|
||||
echo "======================================================================"
|
||||
cat ../../patches/update-patches.patch
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -136,6 +136,7 @@ jobs:
|
||||
needs: checkout-macos
|
||||
with:
|
||||
build-runs-on: macos-14-xlarge
|
||||
check-runs-on: macos-14
|
||||
test-runs-on: macos-13
|
||||
target-platform: macos
|
||||
target-arch: x64
|
||||
@@ -154,6 +155,7 @@ jobs:
|
||||
needs: checkout-macos
|
||||
with:
|
||||
build-runs-on: macos-14-xlarge
|
||||
check-runs-on: macos-14
|
||||
test-runs-on: macos-14
|
||||
target-platform: macos
|
||||
target-arch: arm64
|
||||
@@ -172,6 +174,7 @@ jobs:
|
||||
needs: checkout-linux
|
||||
with:
|
||||
build-runs-on: electron-arc-linux-amd64-32core
|
||||
check-runs-on: electron-arc-linux-amd64-8core
|
||||
test-runs-on: electron-arc-linux-amd64-4core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
|
||||
@@ -192,6 +195,7 @@ jobs:
|
||||
needs: checkout-linux
|
||||
with:
|
||||
build-runs-on: electron-arc-linux-amd64-32core
|
||||
check-runs-on: electron-arc-linux-amd64-8core
|
||||
test-runs-on: electron-arc-linux-amd64-4core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
|
||||
@@ -213,6 +217,7 @@ jobs:
|
||||
needs: checkout-linux
|
||||
with:
|
||||
build-runs-on: electron-arc-linux-amd64-32core
|
||||
check-runs-on: electron-arc-linux-amd64-8core
|
||||
test-runs-on: electron-arc-linux-arm64-4core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
|
||||
@@ -233,6 +238,7 @@ jobs:
|
||||
needs: checkout-linux
|
||||
with:
|
||||
build-runs-on: electron-arc-linux-amd64-32core
|
||||
check-runs-on: electron-arc-linux-amd64-8core
|
||||
test-runs-on: electron-arc-linux-arm64-4core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
|
||||
|
||||
@@ -15,6 +15,10 @@ on:
|
||||
type: string
|
||||
description: 'What host to run the build'
|
||||
required: true
|
||||
check-runs-on:
|
||||
type: string
|
||||
description: 'What host to run the gn-check'
|
||||
required: true
|
||||
test-runs-on:
|
||||
type: string
|
||||
description: 'What host to run the tests on'
|
||||
@@ -77,7 +81,7 @@ jobs:
|
||||
with:
|
||||
target-platform: ${{ inputs.target-platform }}
|
||||
target-arch: ${{ inputs.target-arch }}
|
||||
check-runs-on: ${{ inputs.build-runs-on }}
|
||||
check-runs-on: ${{ inputs.check-runs-on }}
|
||||
check-container: ${{ inputs.build-container }}
|
||||
gn-build-type: ${{ inputs.gn-build-type }}
|
||||
is-asan: ${{ inputs.is-asan }}
|
||||
|
||||
@@ -15,6 +15,10 @@ on:
|
||||
type: string
|
||||
description: 'What host to run the build'
|
||||
required: true
|
||||
check-runs-on:
|
||||
type: string
|
||||
description: 'What host to run the gn-check'
|
||||
required: true
|
||||
test-runs-on:
|
||||
type: string
|
||||
description: 'What host to run the tests on'
|
||||
@@ -83,7 +87,7 @@ jobs:
|
||||
with:
|
||||
target-platform: ${{ inputs.target-platform }}
|
||||
target-arch: ${{ inputs.target-arch }}
|
||||
check-runs-on: ${{ inputs.build-runs-on }}
|
||||
check-runs-on: ${{ inputs.check-runs-on }}
|
||||
check-container: ${{ inputs.build-container }}
|
||||
gn-build-type: ${{ inputs.gn-build-type }}
|
||||
is-asan: ${{ inputs.is-asan }}
|
||||
|
||||
@@ -82,6 +82,12 @@ jobs:
|
||||
with:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
- name: Free up space (macOS)
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: ./src/electron/.github/actions/free-space-macos
|
||||
- name: Check disk space after freeing up space
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
run: df -h
|
||||
- name: Setup Node.js/npm
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
|
||||
|
||||
@@ -54,6 +54,23 @@ jobs:
|
||||
with:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
- name: Cleanup disk space on macOS
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
shell: bash
|
||||
run: |
|
||||
sudo mkdir -p $TMPDIR/del-target
|
||||
|
||||
tmpify() {
|
||||
if [ -d "$1" ]; then
|
||||
sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
|
||||
fi
|
||||
}
|
||||
tmpify /Library/Developer/CoreSimulator
|
||||
tmpify ~/Library/Developer/CoreSimulator
|
||||
sudo rm -rf $TMPDIR/del-target
|
||||
- name: Check disk space after freeing up space
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
run: df -h
|
||||
- name: Install Build Tools
|
||||
uses: ./src/electron/.github/actions/install-build-tools
|
||||
- name: Init Build Tools
|
||||
|
||||
2
DEPS
2
DEPS
@@ -4,7 +4,7 @@ vars = {
|
||||
'chromium_version':
|
||||
'124.0.6367.243',
|
||||
'node_version':
|
||||
'v20.15.1',
|
||||
'v20.16.0',
|
||||
'nan_version':
|
||||
'e14bdcd1f72d62bca1d541b66da43130384ec213',
|
||||
'squirrel.mac_version':
|
||||
|
||||
@@ -95,6 +95,8 @@ for:
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: |
|
||||
Set-Content -Path $pwd\depot_tools\build_telemetry.cfg -Value '{"user": "info@electronjs.org", "status": "opt-out", "countdown": 10, "version": 1}'
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
@@ -115,6 +117,13 @@ for:
|
||||
$env:RBE_experimental_credentials_helper = $env:RECLIENT_HELPER
|
||||
- ps: >-
|
||||
$env:RBE_experimental_credentials_helper_args = "print"
|
||||
- ps: >-
|
||||
if ($env:ELECTRON_RBE_JWT -eq '') {
|
||||
$env:RBE_fail_early_min_action_count = "0"
|
||||
$env:RBE_fail_early_min_fallback_ratio = "0"
|
||||
$env:RBE_exec_strategy = "local"
|
||||
$env:RBE_remote_update_cache= "false"
|
||||
}
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
@@ -166,8 +175,8 @@ for:
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
autoninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( autoninja -C out/Default electron:electron_symbols )
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python3 electron\script\zip-symbols.py
|
||||
|
||||
11
appveyor.yml
11
appveyor.yml
@@ -93,6 +93,8 @@ for:
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: |
|
||||
Set-Content -Path $pwd\depot_tools\build_telemetry.cfg -Value '{"user": "info@electronjs.org", "status": "opt-out", "countdown": 10, "version": 1}'
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
@@ -113,6 +115,13 @@ for:
|
||||
$env:RBE_experimental_credentials_helper = $env:RECLIENT_HELPER
|
||||
- ps: >-
|
||||
$env:RBE_experimental_credentials_helper_args = "print"
|
||||
- ps: >-
|
||||
if ($env:ELECTRON_RBE_JWT -eq '') {
|
||||
$env:RBE_fail_early_min_action_count = "0"
|
||||
$env:RBE_fail_early_min_fallback_ratio = "0"
|
||||
$env:RBE_exec_strategy = "local"
|
||||
$env:RBE_remote_update_cache= "false"
|
||||
}
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
@@ -163,8 +172,8 @@ for:
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
autoninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( autoninja -C out/Default electron:electron_symbols )
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python3 electron\script\zip-symbols.py
|
||||
|
||||
@@ -1357,7 +1357,7 @@ Show the app's about panel options. These options can be overridden with `app.se
|
||||
* `credits` string (optional) _macOS_ _Windows_ - Credit information.
|
||||
* `authors` string[] (optional) _Linux_ - List of app authors.
|
||||
* `website` string (optional) _Linux_ - The app's website.
|
||||
* `iconPath` string (optional) _Linux_ _Windows_ - Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
|
||||
* `iconPath` string (optional) _Linux_ _Windows_ - Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as 64x64 pixels while retaining aspect ratio. On Windows, a 48x48 PNG will result in the best visual quality.
|
||||
|
||||
Set the about panel options. This will override the values defined in the app's `.plist` file on macOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.
|
||||
|
||||
|
||||
@@ -690,6 +690,8 @@ Sets whether the window should be in fullscreen mode.
|
||||
|
||||
Returns `boolean` - Whether the window is in fullscreen mode.
|
||||
|
||||
**Note:** On macOS, fullscreen transitions take place asynchronously. When querying for a BrowserWindow's fullscreen status, you should ensure that either the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events have been emitted.
|
||||
|
||||
#### `win.setSimpleFullScreen(flag)` _macOS_
|
||||
|
||||
* `flag` boolean
|
||||
|
||||
@@ -9,80 +9,66 @@ The following example shows how to capture video from a desktop window whose
|
||||
title is `Electron`:
|
||||
|
||||
```js
|
||||
// In the main process.
|
||||
const { BrowserWindow, desktopCapturer } = require('electron')
|
||||
// main.js
|
||||
const { app, BrowserWindow, desktopCapturer, session } = require('electron')
|
||||
|
||||
const mainWindow = new BrowserWindow()
|
||||
app.whenReady().then(() => {
|
||||
const mainWindow = new BrowserWindow()
|
||||
|
||||
desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {
|
||||
for (const source of sources) {
|
||||
if (source.name === 'Electron') {
|
||||
mainWindow.webContents.send('SET_SOURCE', source.id)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
```js @ts-nocheck
|
||||
// In the preload script.
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.on('SET_SOURCE', async (event, sourceId) => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: sourceId,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
|
||||
desktopCapturer.getSources({ types: ['screen'] }).then((sources) => {
|
||||
// Grant access to the first screen found.
|
||||
callback({ video: sources[0], audio: 'loopback' })
|
||||
})
|
||||
handleStream(stream)
|
||||
} catch (e) {
|
||||
handleError(e)
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.loadFile('index.html')
|
||||
})
|
||||
|
||||
function handleStream (stream) {
|
||||
const video = document.querySelector('video')
|
||||
video.srcObject = stream
|
||||
video.onloadedmetadata = (e) => video.play()
|
||||
}
|
||||
|
||||
function handleError (e) {
|
||||
console.log(e)
|
||||
}
|
||||
```
|
||||
|
||||
To capture video from a source provided by `desktopCapturer` the constraints
|
||||
passed to [`navigator.mediaDevices.getUserMedia`][] must include
|
||||
`chromeMediaSource: 'desktop'`, and `audio: false`.
|
||||
|
||||
To capture both audio and video from the entire desktop the constraints passed
|
||||
to [`navigator.mediaDevices.getUserMedia`][] must include `chromeMediaSource: 'desktop'`,
|
||||
for both `audio` and `video`, but should not include a `chromeMediaSourceId` constraint.
|
||||
|
||||
```js
|
||||
const constraints = {
|
||||
audio: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop'
|
||||
// renderer.js
|
||||
const startButton = document.getElementById('startButton')
|
||||
const stopButton = document.getElementById('stopButton')
|
||||
const video = document.querySelector('video')
|
||||
|
||||
startButton.addEventListener('click', () => {
|
||||
navigator.mediaDevices.getDisplayMedia({
|
||||
audio: true,
|
||||
video: {
|
||||
width: 320,
|
||||
height: 240,
|
||||
frameRate: 30
|
||||
}
|
||||
},
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop'
|
||||
}
|
||||
}
|
||||
}
|
||||
}).then(stream => {
|
||||
video.srcObject = stream
|
||||
video.onloadedmetadata = (e) => video.play()
|
||||
}).catch(e => console.log(e))
|
||||
})
|
||||
|
||||
stopButton.addEventListener('click', () => {
|
||||
video.pause()
|
||||
})
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<html>
|
||||
<meta http-equiv="content-security-policy" content="script-src 'self' 'unsafe-inline'" />
|
||||
<body>
|
||||
<button id="startButton" class="button">Start</button>
|
||||
<button id="stopButton" class="button">Stop</button>
|
||||
<video width="320" height="240" autoplay></video>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
See [`navigator.mediaDevices.getDisplayMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia) for more information.
|
||||
|
||||
**Note:** `navigator.mediaDevices.getDisplayMedia` does not permit the use of `deviceId` for
|
||||
selection of a source - see [specification](https://w3c.github.io/mediacapture-screen-share/#constraints).
|
||||
|
||||
## Methods
|
||||
|
||||
The `desktopCapturer` module has the following methods:
|
||||
|
||||
@@ -72,3 +72,7 @@ or is being instructed to use an inverted color scheme.
|
||||
|
||||
A `boolean` indicating whether Chromium is in forced colors mode, controlled by system accessibility settings.
|
||||
Currently, Windows high contrast is the only system setting that triggers forced colors mode.
|
||||
|
||||
### `nativeTheme.prefersReducedTransparency` _Readonly_
|
||||
|
||||
A `boolean` that indicates the whether the user has chosen via system accessibility settings to reduce transparency at the OS level.
|
||||
|
||||
@@ -143,6 +143,71 @@ Returns:
|
||||
Emitted after an extension is loaded and all necessary browser state is
|
||||
initialized to support the start of the extension's background page.
|
||||
|
||||
#### Event: 'file-system-access-restricted'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `origin` string - The origin that initiated access to the blocked path.
|
||||
* `isDirectory` boolean - Whether or not the path is a directory.
|
||||
* `path` string - The blocked path attempting to be accessed.
|
||||
* `callback` Function
|
||||
* `action` string - The action to take as a result of the restricted path access attempt.
|
||||
* `allow` - This will allow `path` to be accessed despite restricted status.
|
||||
* `deny` - This will block the access request and trigger an [`AbortError`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort).
|
||||
* `tryAgain` - This will open a new file picker and allow the user to choose another path.
|
||||
|
||||
```js
|
||||
const { app, dialog, BrowserWindow, session } = require('electron')
|
||||
|
||||
async function createWindow () {
|
||||
const mainWindow = new BrowserWindow()
|
||||
|
||||
await mainWindow.loadURL('https://buzzfeed.com')
|
||||
|
||||
session.defaultSession.on('file-system-access-restricted', async (e, details, callback) => {
|
||||
const { origin, path } = details
|
||||
const { response } = await dialog.showMessageBox({
|
||||
message: `Are you sure you want ${origin} to open restricted path ${path}?`,
|
||||
title: 'File System Access Restricted',
|
||||
buttons: ['Choose a different folder', 'Allow', 'Cancel'],
|
||||
cancelId: 2
|
||||
})
|
||||
|
||||
if (response === 0) {
|
||||
callback('tryAgain')
|
||||
} else if (response === 1) {
|
||||
callback('allow')
|
||||
} else {
|
||||
callback('deny')
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.executeJavaScript(`
|
||||
window.showDirectoryPicker({
|
||||
id: 'electron-demo',
|
||||
mode: 'readwrite',
|
||||
startIn: 'downloads',
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})`, true
|
||||
)
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
```
|
||||
|
||||
#### Event: 'preconnect'
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -97,19 +97,12 @@ is as follows:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nodejs/Release/main/schedule.svg?sanitize=true" alt="Releases">
|
||||
|
||||
As a rule, stable branches of Electron do not receive Node.js upgrades after they have been cut.
|
||||
If Electron has recently updated its `main` branch to a new major version of Node.js, the next stable
|
||||
branch to be cut will be released with the new version.
|
||||
|
||||
Patch upgrades of Node that contain significant security or bug fixes, and are submitted
|
||||
more than 2 weeks prior to a stable release date, will be accepted into an Electron alpha
|
||||
or beta release branch.
|
||||
|
||||
Minor upgrades of Node that contain significant security or bug fixes, and are submitted
|
||||
more than 2 weeks prior to a stable release date may be accepted into an Electron alpha or
|
||||
beta release branch on a case-by-case basis. These requests will be reviewed and voted on
|
||||
by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases),
|
||||
to ensure minimal disruption for developers who may be consuming alpha or beta releases.
|
||||
Stable release lines of Electron will receive minor and patch bumps of Node.js after they are released.
|
||||
Patch bumps to Node.js will be released in patch releases of Electron, and minor bumps to Node.js will result in a minor release of Electron.
|
||||
Security-only release branches will receive security-related changes from Node.js releases, but not the full release.
|
||||
|
||||
### Breaking API changes
|
||||
|
||||
|
||||
@@ -547,7 +547,6 @@ filenames = {
|
||||
"shell/common/api/electron_api_clipboard.h",
|
||||
"shell/common/api/electron_api_command_line.cc",
|
||||
"shell/common/api/electron_api_environment.cc",
|
||||
"shell/common/api/electron_api_key_weak_map.h",
|
||||
"shell/common/api/electron_api_native_image.cc",
|
||||
"shell/common/api/electron_api_native_image.h",
|
||||
"shell/common/api/electron_api_net.cc",
|
||||
@@ -559,8 +558,6 @@ filenames = {
|
||||
"shell/common/api/electron_bindings.cc",
|
||||
"shell/common/api/electron_bindings.h",
|
||||
"shell/common/api/features.cc",
|
||||
"shell/common/api/object_life_monitor.cc",
|
||||
"shell/common/api/object_life_monitor.h",
|
||||
"shell/common/application_info.cc",
|
||||
"shell/common/application_info.h",
|
||||
"shell/common/asar/archive.cc",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import type { BaseWindow as TLWT } from 'electron/main';
|
||||
import { TouchBar } from 'electron/main';
|
||||
|
||||
const { BaseWindow } = process._linkedBinding('electron_browser_base_window') as { BaseWindow: typeof TLWT };
|
||||
|
||||
Object.setPrototypeOf(BaseWindow.prototype, EventEmitter.prototype);
|
||||
@@ -15,6 +17,10 @@ BaseWindow.prototype._init = function (this: TLWT) {
|
||||
}
|
||||
};
|
||||
|
||||
BaseWindow.prototype.setTouchBar = function (touchBar) {
|
||||
(TouchBar as any)._setOnWindow(touchBar, this);
|
||||
};
|
||||
|
||||
// Properties
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'autoHideMenuBar', {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BaseWindow, WebContents, TouchBar, BrowserView } from 'electron/main';
|
||||
import { BaseWindow, WebContents, BrowserView } from 'electron/main';
|
||||
import type { BrowserWindow as BWT } from 'electron/main';
|
||||
const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };
|
||||
|
||||
@@ -100,10 +100,6 @@ BrowserWindow.fromBrowserView = (browserView: BrowserView) => {
|
||||
return BrowserWindow.fromWebContents(browserView.webContents);
|
||||
};
|
||||
|
||||
BrowserWindow.prototype.setTouchBar = function (touchBar) {
|
||||
(TouchBar as any)._setOnWindow(touchBar, this);
|
||||
};
|
||||
|
||||
// Forwarded to webContents:
|
||||
|
||||
BrowserWindow.prototype.loadURL = function (...args) {
|
||||
|
||||
@@ -284,7 +284,7 @@ const escapeItemSymbol = Symbol('escape item');
|
||||
|
||||
class TouchBar extends EventEmitter implements Electron.TouchBar {
|
||||
// Bind a touch bar to a window
|
||||
static _setOnWindow (touchBar: TouchBar | Electron.TouchBarConstructorOptions['items'], window: Electron.BrowserWindow) {
|
||||
static _setOnWindow (touchBar: TouchBar | Electron.TouchBarConstructorOptions['items'], window: Electron.BaseWindow) {
|
||||
if (window._touchBar != null) {
|
||||
window._touchBar._removeFromWindow(window);
|
||||
}
|
||||
@@ -383,7 +383,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
|
||||
return this[escapeItemSymbol];
|
||||
}
|
||||
|
||||
_addToWindow (window: Electron.BrowserWindow) {
|
||||
_addToWindow (window: Electron.BaseWindow) {
|
||||
const { id } = window;
|
||||
|
||||
// Already added to window
|
||||
@@ -439,7 +439,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
|
||||
escapeItemListener(this.escapeItem);
|
||||
}
|
||||
|
||||
_removeFromWindow (window: Electron.BrowserWindow) {
|
||||
_removeFromWindow (window: Electron.BaseWindow) {
|
||||
const removeListeners = this.windowListeners.get(window.id);
|
||||
if (removeListeners != null) removeListeners();
|
||||
}
|
||||
|
||||
@@ -4,3 +4,4 @@ cherry-pick-b845fed99111.patch
|
||||
cherry-pick-771e74ab497d.patch
|
||||
cherry-pick-8f07d39227f6.patch
|
||||
cherry-pick-b3c64851765c.patch
|
||||
cherry-pick-9463ce9cd8d9.patch
|
||||
|
||||
261
patches/DirectXShaderCompiler/cherry-pick-9463ce9cd8d9.patch
Normal file
261
patches/DirectXShaderCompiler/cherry-pick-9463ce9cd8d9.patch
Normal file
@@ -0,0 +1,261 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Neto <dneto@google.com>
|
||||
Date: Tue, 16 Jul 2024 16:34:52 -0400
|
||||
Subject: Add CMake option DXC_CODEGEN_EXCEPTIONS_TRAP (#6764)
|
||||
|
||||
When enabled, any hlsl::Exception thrown during code generation and
|
||||
optimization will cause the process to trap.
|
||||
|
||||
Bug: 346618785
|
||||
Change-Id: I9ac966d339ec3090e3455d51a9d7516cc5a3f153
|
||||
|
||||
HLMatrixLower: allow exceptions to propagate out (#6710)
|
||||
|
||||
If an exception is thrown, don't block it in the TempOverloadPool
|
||||
destructor. Allow it to propagate out as a user-visible error.
|
||||
|
||||
Explicitly clear the TempOverloadPool before returning from the
|
||||
HLMatrixLowerPass::runOnModule. In the normal case, when no exception is
|
||||
thrown, that will still verify that all the overloads actually have been
|
||||
lowered, and will assert out if they aren't.
|
||||
|
||||
Bug: 346618785
|
||||
Change-Id: Id421ca324e4d799477a41abb14b966e8f39be482
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5715228
|
||||
Reviewed-by: Natalie Chouinard <chouinard@google.com>
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 15097b8473bf9f6c2b6c28ac095936616aa917f6..ac35ebd1a6afd55934da502ddb0e0c286da10db8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -104,6 +104,9 @@ endif()
|
||||
option(DXC_DISABLE_ALLOCATOR_OVERRIDES "Disable usage of allocator overrides" OFF)
|
||||
mark_as_advanced(DXC_DISABLE_ALLOCATOR_OVERRIDES)
|
||||
|
||||
+option(DXC_CODEGEN_EXCEPTIONS_TRAP "An exception in code generation generates a trap, ending the compiler process" OFF)
|
||||
+mark_as_advanced(DXC_CODEGEN_EXCEPTIONS_TRAP)
|
||||
+
|
||||
# adjust link option to enable debugging from kernel mode; not compatible with incremental linking
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.13" AND WIN32 AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64EC")
|
||||
add_link_options(/DEBUGTYPE:CV,FIXUP,PDATA /INCREMENTAL:NO)
|
||||
diff --git a/include/dxc/config.h.cmake b/include/dxc/config.h.cmake
|
||||
index 6d7450323ec864ef5f6e8796c46423d49f278b76..7226ed75a108f63c3c894b59eb7e0dbc5fb66002 100644
|
||||
--- a/include/dxc/config.h.cmake
|
||||
+++ b/include/dxc/config.h.cmake
|
||||
@@ -1,2 +1,4 @@
|
||||
/* Disable overriding memory allocators. */
|
||||
#cmakedefine DXC_DISABLE_ALLOCATOR_OVERRIDES
|
||||
+/* Generate a trap if an hlsl::Exception is thrown during code generation */
|
||||
+#cmakedefine DXC_CODEGEN_EXCEPTIONS_TRAP
|
||||
diff --git a/lib/HLSL/HLMatrixLowerPass.cpp b/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
index d5959eb9335465f67d8e7ef7d7ab4eb720274226..3bb9f65834ecfd0c7a25c8a176f62c124e9967e5 100644
|
||||
--- a/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
+++ b/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
@@ -60,7 +60,12 @@ class TempOverloadPool {
|
||||
public:
|
||||
TempOverloadPool(llvm::Module &Module, const char *BaseName)
|
||||
: Module(Module), BaseName(BaseName) {}
|
||||
- ~TempOverloadPool() { clear(); }
|
||||
+ ~TempOverloadPool() {
|
||||
+ if (!Funcs.empty()) {
|
||||
+ // The flow has thrown an exception. Let that exception
|
||||
+ // propagate out and be reported as a compile error.
|
||||
+ }
|
||||
+ }
|
||||
|
||||
Function *get(FunctionType *Ty);
|
||||
bool contains(FunctionType *Ty) const { return Funcs.count(Ty) != 0; }
|
||||
@@ -248,12 +253,15 @@ bool HLMatrixLowerPass::runOnModule(Module &M) {
|
||||
m_matToVecStubs = nullptr;
|
||||
m_vecToMatStubs = nullptr;
|
||||
|
||||
- // If you hit an assert during TempOverloadPool destruction,
|
||||
+ // If you hit an assert while clearing TempOverloadPool,
|
||||
// it means that either a matrix producer was lowered,
|
||||
// causing a translation stub to be created,
|
||||
// but the consumer of that matrix was never (properly) lowered.
|
||||
// Or the opposite: a matrix consumer was lowered and not its producer.
|
||||
|
||||
+ matToVecStubs.clear();
|
||||
+ vecToMatStubs.clear();
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/tools/clang/lib/CodeGen/BackendUtil.cpp b/tools/clang/lib/CodeGen/BackendUtil.cpp
|
||||
index 294ca05946eed6d87a3ad4e2b56a641d24065760..1e9adb40f4bae4cada42b5581582d50dc3676594 100644
|
||||
--- a/tools/clang/lib/CodeGen/BackendUtil.cpp
|
||||
+++ b/tools/clang/lib/CodeGen/BackendUtil.cpp
|
||||
@@ -8,6 +8,10 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/CodeGen/BackendUtil.h"
|
||||
+#include "dxc/HLSL/DxilGenerationPass.h" // HLSL Change
|
||||
+#include "dxc/HLSL/HLMatrixLowerPass.h" // HLSL Change
|
||||
+#include "dxc/Support/Global.h" // HLSL Change
|
||||
+#include "dxc/config.h" // HLSL Change
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
@@ -41,10 +45,8 @@
|
||||
#include "llvm/Transforms/ObjCARC.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Utils/SymbolRewriter.h"
|
||||
+#include <cstdio>
|
||||
#include <memory>
|
||||
-#include "dxc/HLSL/DxilGenerationPass.h" // HLSL Change
|
||||
-#include "dxc/HLSL/HLMatrixLowerPass.h" // HLSL Change
|
||||
-#include "dxc/Support/Global.h" // HLSL Change
|
||||
|
||||
using namespace clang;
|
||||
using namespace llvm;
|
||||
@@ -780,6 +782,13 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
|
||||
} catch (const ::hlsl::Exception &hlslException) {
|
||||
Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0\n"))
|
||||
<< StringRef(hlslException.what());
|
||||
+#if defined(DXC_CODEGEN_EXCEPTIONS_TRAP)
|
||||
+ // llvm::errs() doesn't work in release builds on Linux.
|
||||
+ // Use C-style fprintf because it works everywhere.
|
||||
+ fprintf(stderr, "internal codegen error: %s\n", hlslException.what());
|
||||
+ fflush(stderr);
|
||||
+ LLVM_BUILTIN_TRAP;
|
||||
+#endif
|
||||
} // HLSL Change Ends
|
||||
|
||||
// If an optional clang TargetInfo description string was passed in, use it to
|
||||
diff --git a/tools/clang/test/DXC/Passes/HLMatrixLower/dont_crash_on_invalid_cast.ll b/tools/clang/test/DXC/Passes/HLMatrixLower/dont_crash_on_invalid_cast.ll
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fca52d11595d3ac99dedb28219f0746a26add6c9
|
||||
--- /dev/null
|
||||
+++ b/tools/clang/test/DXC/Passes/HLMatrixLower/dont_crash_on_invalid_cast.ll
|
||||
@@ -0,0 +1,130 @@
|
||||
+; RUN: not %dxopt %s -hlsl-passes-resume -hlmatrixlower -S | FileCheck %s
|
||||
+
|
||||
+
|
||||
+; The HL matrix lowering pass can sometimes throw an exception
|
||||
+; due to an invalid LLVM-level cast<Ty> call. Make sure that
|
||||
+; propagates out to a user-level error.
|
||||
+
|
||||
+; Note: There is still a bug in the compiler here. Not all matrix
|
||||
+; lowerings are covered by the pass.
|
||||
+
|
||||
+; TODO: Fix the underlying bug https://github.com/microsoft/DirectXShaderCompiler/issues/6723
|
||||
+; Once that is fixed, this test changes or should be deleted.
|
||||
+
|
||||
+
|
||||
+; CHECK: Operation failed - error code
|
||||
+
|
||||
+;
|
||||
+; Buffer Definitions:
|
||||
+;
|
||||
+; cbuffer $Globals
|
||||
+; {
|
||||
+;
|
||||
+; [0 x i8] (type annotation not present)
|
||||
+;
|
||||
+; }
|
||||
+;
|
||||
+;
|
||||
+; Resource Bindings:
|
||||
+;
|
||||
+; Name Type Format Dim ID HLSL Bind Count
|
||||
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
|
||||
+; $Globals cbuffer NA NA CB0 cb4294967295 1
|
||||
+;
|
||||
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
|
||||
+target triple = "dxil-ms-dx"
|
||||
+
|
||||
+%ConstantBuffer = type opaque
|
||||
+%class.matrix.float.2.4 = type { [2 x <4 x float>] }
|
||||
+%struct.e = type { [1 x %struct.d], [1 x %struct.d] }
|
||||
+%struct.d = type { %struct.a }
|
||||
+%struct.a = type { float, %class.matrix.float.2.4 }
|
||||
+
|
||||
+@"$Globals" = external constant %ConstantBuffer
|
||||
+@g.0.0.0 = internal global [1 x float] undef, align 4
|
||||
+@g.0.0.1 = internal global [1 x %class.matrix.float.2.4] undef, align 4
|
||||
+@g.1.0.0 = internal global [1 x float] undef, align 4
|
||||
+@g.1.0.1 = internal global [1 x %class.matrix.float.2.4] undef, align 4
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+define void @main() #0 {
|
||||
+entry:
|
||||
+ %h.0.1 = alloca %class.matrix.float.2.4, !dbg !26 ; line:13 col:17
|
||||
+ store float 0.000000e+00, float* getelementptr inbounds ([1 x float], [1 x float]* @g.0.0.0, i32 0, i32 0), !dbg !26 ; line:13 col:17
|
||||
+ %0 = call %class.matrix.float.2.4 @"dx.hl.init.rn.%class.matrix.float.2.4 (i32, <8 x float>)"(i32 0, <8 x float> zeroinitializer) #0, !dbg !26 ; line:13 col:17
|
||||
+ %1 = call %class.matrix.float.2.4 @"dx.hl.cast.rowMatToColMat.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4)"(i32 7, %class.matrix.float.2.4 %0) #0, !dbg !26 ; line:13 col:17
|
||||
+ %2 = call %class.matrix.float.2.4 @"dx.hl.matldst.colStore.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4*, %class.matrix.float.2.4)"(i32 1, %class.matrix.float.2.4* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.0.0.1, i32 0, i32 0), %class.matrix.float.2.4 %1) #0, !dbg !26 ; line:13 col:17
|
||||
+ store float 0.000000e+00, float* getelementptr inbounds ([1 x float], [1 x float]* @g.1.0.0, i32 0, i32 0), !dbg !26 ; line:13 col:17
|
||||
+ %3 = call %class.matrix.float.2.4 @"dx.hl.init.rn.%class.matrix.float.2.4 (i32, <8 x float>)"(i32 0, <8 x float> zeroinitializer) #0, !dbg !26 ; line:13 col:17
|
||||
+ %4 = call %class.matrix.float.2.4 @"dx.hl.cast.rowMatToColMat.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4)"(i32 7, %class.matrix.float.2.4 %3) #0, !dbg !26 ; line:13 col:17
|
||||
+ %5 = call %class.matrix.float.2.4 @"dx.hl.matldst.colStore.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4*, %class.matrix.float.2.4)"(i32 1, %class.matrix.float.2.4* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.1.0.1, i32 0, i32 0), %class.matrix.float.2.4 %4) #0, !dbg !26 ; line:13 col:17
|
||||
+ %6 = load float, float* getelementptr inbounds ([1 x float], [1 x float]* @g.1.0.0, i32 0, i32 0), !dbg !32 ; line:17 col:9
|
||||
+ %7 = getelementptr inbounds %class.matrix.float.2.4, %class.matrix.float.2.4* %h.0.1, i32 0, i32 0, i32 0, !dbg !32 ; line:17 col:9
|
||||
+ %8 = load <4 x float>, <4 x float>* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.1.0.1, i32 0, i32 0, i32 0, i32 0), !dbg !32 ; line:17 col:9
|
||||
+ store <4 x float> %8, <4 x float>* %7, !dbg !32 ; line:17 col:9
|
||||
+ %9 = getelementptr inbounds %class.matrix.float.2.4, %class.matrix.float.2.4* %h.0.1, i32 0, i32 0, i32 1, !dbg !32 ; line:17 col:9
|
||||
+ %10 = load <4 x float>, <4 x float>* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.1.0.1, i32 0, i32 0, i32 0, i32 1), !dbg !32 ; line:17 col:9
|
||||
+ store <4 x float> %10, <4 x float>* %9, !dbg !32 ; line:17 col:9
|
||||
+ ret void, !dbg !33 ; line:18 col:3
|
||||
+}
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0
|
||||
+
|
||||
+; Function Attrs: nounwind readnone
|
||||
+declare %class.matrix.float.2.4 @"dx.hl.init.rn.%class.matrix.float.2.4 (i32, <8 x float>)"(i32, <8 x float>) #1
|
||||
+
|
||||
+; Function Attrs: nounwind readnone
|
||||
+declare %class.matrix.float.2.4 @"dx.hl.cast.rowMatToColMat.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4)"(i32, %class.matrix.float.2.4) #1
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+declare %class.matrix.float.2.4 @"dx.hl.matldst.colStore.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4*, %class.matrix.float.2.4)"(i32, %class.matrix.float.2.4*, %class.matrix.float.2.4) #0
|
||||
+
|
||||
+attributes #0 = { nounwind }
|
||||
+attributes #1 = { nounwind readnone }
|
||||
+
|
||||
+!llvm.module.flags = !{!0}
|
||||
+!pauseresume = !{!1}
|
||||
+!llvm.ident = !{!2}
|
||||
+!dx.version = !{!3}
|
||||
+!dx.valver = !{!4}
|
||||
+!dx.shaderModel = !{!5}
|
||||
+!dx.typeAnnotations = !{!6, !15}
|
||||
+!dx.entryPoints = !{!19}
|
||||
+!dx.fnprops = !{!23}
|
||||
+!dx.options = !{!24, !25}
|
||||
+
|
||||
+!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
+!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
|
||||
+!2 = !{!"dxc(private) 1.8.0.4640 (issue-785, 45018c752d)"}
|
||||
+!3 = !{i32 1, i32 0}
|
||||
+!4 = !{i32 1, i32 8}
|
||||
+!5 = !{!"cs", i32 6, i32 0}
|
||||
+!6 = !{i32 0, %struct.e undef, !7, %struct.d undef, !10, %struct.a undef, !11}
|
||||
+!7 = !{i32 152, !8, !9}
|
||||
+!8 = !{i32 6, !"c", i32 3, i32 0}
|
||||
+!9 = !{i32 6, !"f", i32 3, i32 80}
|
||||
+!10 = !{i32 72, !8}
|
||||
+!11 = !{i32 72, !12, !13}
|
||||
+!12 = !{i32 6, !"b", i32 3, i32 0, i32 7, i32 9}
|
||||
+!13 = !{i32 6, !"c", i32 2, !14, i32 3, i32 16, i32 7, i32 9}
|
||||
+!14 = !{i32 2, i32 4, i32 2}
|
||||
+!15 = !{i32 1, void ()* @main, !16}
|
||||
+!16 = !{!17}
|
||||
+!17 = !{i32 1, !18, !18}
|
||||
+!18 = !{}
|
||||
+!19 = !{void ()* @main, !"main", null, !20, null}
|
||||
+!20 = !{null, null, !21, null}
|
||||
+!21 = !{!22}
|
||||
+!22 = !{i32 0, %ConstantBuffer* @"$Globals", !"$Globals", i32 0, i32 -1, i32 1, i32 0, null}
|
||||
+!23 = !{void ()* @main, i32 5, i32 1, i32 1, i32 1}
|
||||
+!24 = !{i32 64}
|
||||
+!25 = !{i32 -1}
|
||||
+!26 = !DILocation(line: 13, column: 17, scope: !27, inlinedAt: !30)
|
||||
+!27 = !DISubprogram(name: "??__Eg@@YAXXZ", scope: !28, file: !28, line: 13, type: !29, isLocal: true, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: false)
|
||||
+!28 = !DIFile(filename: "a.hlsl", directory: "")
|
||||
+!29 = !DISubroutineType(types: !18)
|
||||
+!30 = distinct !DILocation(line: 16, scope: !31)
|
||||
+!31 = !DISubprogram(name: "main", scope: !28, file: !28, line: 16, type: !29, isLocal: false, isDefinition: true, scopeLine: 16, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
|
||||
+!32 = !DILocation(line: 17, column: 9, scope: !31)
|
||||
+!33 = !DILocation(line: 18, column: 3, scope: !31)
|
||||
@@ -137,3 +137,11 @@ fix_font_face_resolution_when_renderer_is_blocked.patch
|
||||
x11_use_localized_display_label_only_for_browser_process.patch
|
||||
feat_enable_passing_exit_code_on_service_process_crash.patch
|
||||
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
|
||||
cherry-pick-44b7fbf35b10.patch
|
||||
cherry-pick-d54105311590.patch
|
||||
cherry-pick-43b8b682d05c.patch
|
||||
cherry-pick-c5dd8839bfaf.patch
|
||||
cherry-pick-38e4483e47f9.patch
|
||||
cherry-pick-1b9040817119.patch
|
||||
cherry-pick-99cafbf4b4b9.patch
|
||||
cherry-pick-d9f7652c867c.patch
|
||||
|
||||
84
patches/chromium/cherry-pick-1b9040817119.patch
Normal file
84
patches/chromium/cherry-pick-1b9040817119.patch
Normal file
@@ -0,0 +1,84 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bryant Chandler <bryantchandler@chromium.org>
|
||||
Date: Mon, 24 Jun 2024 17:28:53 +0000
|
||||
Subject: Fix pointer tear down order problem
|
||||
|
||||
Holding a RenderFrameHost* in the `OnceBinding` isn't safe,
|
||||
because the `RenderFrameHost` can be destroyed before the
|
||||
binding. This CL changes the task strategy so that the
|
||||
RenderFrameHost* doesn't need to be bound in a callback.
|
||||
|
||||
Tested using the repro steps in the bug and this change stops
|
||||
it from reproducing.
|
||||
|
||||
Fixed: 347373236
|
||||
Change-Id: Id639f317b0f37a508833aba9fe52ffc5c0ed590c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5640501
|
||||
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
|
||||
Commit-Queue: Bryant Chandler <bryantchandler@chromium.org>
|
||||
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1318653}
|
||||
|
||||
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
|
||||
index 65bee7132f6583cb64d774756423942382c8eed6..2c27db7ee49193cbf91158d576e29bb255378a3e 100644
|
||||
--- a/content/browser/renderer_host/media/media_stream_manager.cc
|
||||
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
|
||||
@@ -2887,25 +2887,19 @@ void MediaStreamManager::GetRawDeviceIdsOpenedForFrame(
|
||||
RenderFrameHost* render_frame_host,
|
||||
blink::mojom::MediaStreamType type,
|
||||
GetRawDeviceIdsOpenedForFrameCallback callback) const {
|
||||
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
- CHECK(render_frame_host);
|
||||
- auto collect_all_render_frame_host_ids = base::BindOnce(
|
||||
- [](RenderFrameHost* render_frame_host) {
|
||||
- base::flat_set<GlobalRenderFrameHostId> all_render_frame_host_ids;
|
||||
- render_frame_host->ForEachRenderFrameHost(
|
||||
- [&all_render_frame_host_ids](RenderFrameHost* render_frame_host) {
|
||||
- all_render_frame_host_ids.insert(
|
||||
- render_frame_host->GetGlobalId());
|
||||
- });
|
||||
- return all_render_frame_host_ids;
|
||||
- },
|
||||
- render_frame_host);
|
||||
-
|
||||
- GetUIThreadTaskRunner()->PostTaskAndReplyWithResult(
|
||||
- FROM_HERE, std::move(collect_all_render_frame_host_ids),
|
||||
- base::BindPostTaskToCurrentDefault(
|
||||
- base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds,
|
||||
- base::Unretained(this), type, std::move(callback))));
|
||||
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
+
|
||||
+ base::flat_set<GlobalRenderFrameHostId> all_render_frame_host_ids;
|
||||
+ render_frame_host->ForEachRenderFrameHost(
|
||||
+ [&all_render_frame_host_ids](RenderFrameHost* render_frame_host) {
|
||||
+ all_render_frame_host_ids.insert(render_frame_host->GetGlobalId());
|
||||
+ });
|
||||
+
|
||||
+ GetIOThreadTaskRunner()->PostTask(
|
||||
+ FROM_HERE,
|
||||
+ base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds,
|
||||
+ base::Unretained(this), type, std::move(callback),
|
||||
+ all_render_frame_host_ids));
|
||||
}
|
||||
|
||||
void MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds(
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index b0b1d0aea5bf251411d0cab06562fd77d8d7c549..819c73370d6e6fc5e6ab24e78646a206b6a5873d 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -10808,12 +10808,9 @@ void WebContentsImpl::GetMediaCaptureRawDeviceIdsOpened(
|
||||
return;
|
||||
}
|
||||
|
||||
- GetIOThreadTaskRunner({})->PostTask(
|
||||
- FROM_HERE,
|
||||
- base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrame,
|
||||
- base::Unretained(media_stream_manager),
|
||||
- GetPrimaryMainFrame(), type,
|
||||
- base::BindPostTaskToCurrentDefault(std::move(callback))));
|
||||
+ media_stream_manager->GetRawDeviceIdsOpenedForFrame(
|
||||
+ GetPrimaryMainFrame(), type,
|
||||
+ base::BindPostTaskToCurrentDefault(std::move(callback)));
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
88
patches/chromium/cherry-pick-38e4483e47f9.patch
Normal file
88
patches/chromium/cherry-pick-38e4483e47f9.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Kron <kron@chromium.org>
|
||||
Date: Wed, 19 Jun 2024 20:59:48 +0000
|
||||
Subject: Use BindPostTask() + weak pointer in callback handler
|
||||
|
||||
The callback handler incorrectly accessed member objects directly which may
|
||||
cause UAF. Avoid this by using BindPostTask() together with a weak pointer.
|
||||
|
||||
Fixed: 346898524
|
||||
Change-Id: I9d03d6decfd0212af88d3d0d8d70f83f1081d2e3
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5639016
|
||||
Reviewed-by: Avi Drissman <avi@chromium.org>
|
||||
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
|
||||
Commit-Queue: Johannes Kron <kron@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1317142}
|
||||
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
index 4fb3e8eb5f34a7ee9e8b0f22a7c842129cdc31eb..e2710fba1a8d7a4cee6023558898c74706a9c189 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -326,13 +326,18 @@ void OnStreamSample(gfx::ScopedInUseIOSurface io_surface,
|
||||
destRectInFrame:dest_rect_in_frame
|
||||
frameRate:requested_capture_format_->
|
||||
frame_rate];
|
||||
+
|
||||
+ __block base::OnceCallback<void()> on_update_configuration_error =
|
||||
+ base::BindPostTask(
|
||||
+ device_task_runner_,
|
||||
+ base::BindOnce(
|
||||
+ &ScreenCaptureKitDeviceMac::OnUpdateConfigurationError,
|
||||
+ weak_factory_.GetWeakPtr()));
|
||||
[stream_
|
||||
updateConfiguration:config
|
||||
completionHandler:^(NSError* _Nullable error) {
|
||||
if (error) {
|
||||
- client()->OnError(
|
||||
- media::VideoCaptureError::kScreenCaptureKitStreamError,
|
||||
- FROM_HERE, "Error on updateConfiguration");
|
||||
+ std::move(on_update_configuration_error).Run();
|
||||
}
|
||||
}];
|
||||
}
|
||||
@@ -361,6 +366,21 @@ void OnStreamError() {
|
||||
FROM_HERE, "Stream delegate called didStopWithError");
|
||||
}
|
||||
}
|
||||
+ void OnUpdateContentFilterCompleted(NSError* _Nullable error) {
|
||||
+ DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
+ is_resetting_ = false;
|
||||
+
|
||||
+ if (error) {
|
||||
+ client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
|
||||
+ FROM_HERE,
|
||||
+ "Error on updateContentFilter (fullscreen window).");
|
||||
+ }
|
||||
+ }
|
||||
+ void OnUpdateConfigurationError() {
|
||||
+ DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
+ client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
|
||||
+ FROM_HERE, "Error on updateConfiguration");
|
||||
+ }
|
||||
|
||||
// IOSurfaceCaptureDeviceBase:
|
||||
void OnStart() override {
|
||||
@@ -411,15 +431,16 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
SCContentFilter* filter =
|
||||
[[SCContentFilter alloc] initWithDesktopIndependentWindow:window];
|
||||
|
||||
+ __block base::OnceCallback<void(NSError*)>
|
||||
+ on_update_content_filter_completed = base::BindPostTask(
|
||||
+ device_task_runner_,
|
||||
+ base::BindOnce(
|
||||
+ &ScreenCaptureKitDeviceMac::OnUpdateContentFilterCompleted,
|
||||
+ weak_factory_.GetWeakPtr()));
|
||||
+
|
||||
[stream_ updateContentFilter:filter
|
||||
completionHandler:^(NSError* _Nullable error) {
|
||||
- is_resetting_ = false;
|
||||
- if (error) {
|
||||
- client()->OnError(
|
||||
- media::VideoCaptureError::kScreenCaptureKitStreamError,
|
||||
- FROM_HERE,
|
||||
- "Error on updateContentFilter (fullscreen window).");
|
||||
- }
|
||||
+ std::move(on_update_content_filter_completed).Run(error);
|
||||
}];
|
||||
}
|
||||
|
||||
264
patches/chromium/cherry-pick-43b8b682d05c.patch
Normal file
264
patches/chromium/cherry-pick-43b8b682d05c.patch
Normal file
@@ -0,0 +1,264 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Philip Pfaffe <pfaffe@chromium.org>
|
||||
Date: Tue, 18 Jun 2024 10:04:45 +0000
|
||||
Subject: Prevent script injection on reload when racing with a navigation
|
||||
|
||||
DevTools passes the loaderId now when calling Page.reload, in order to
|
||||
prevent accidentally reloading the wrong page when a navigation occurred
|
||||
concurrently. It can still happen that the navigation kicks in in between the reload iniated in the browser and the script injection that happens in the renderer, which would run the injected script on the wrong target. We need to check the loaderId also on the renderer side.
|
||||
|
||||
Fixed: 341136300
|
||||
Change-Id: I891fb37fa10e6789c8697a0f29bf7118788a9319
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5625857
|
||||
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
|
||||
Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1316330}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/inspector/build.gni b/third_party/blink/renderer/core/inspector/build.gni
|
||||
index 2e9feebe066f938506d63d157be65828aa2a27c9..39de006f5f97f9e2a84ee4d38f7bb98e99c41924 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/build.gni
|
||||
+++ b/third_party/blink/renderer/core/inspector/build.gni
|
||||
@@ -138,6 +138,7 @@ blink_core_tests_inspector = [
|
||||
"inspector_emulation_agent_test.cc",
|
||||
"inspector_highlight_test.cc",
|
||||
"inspector_history_test.cc",
|
||||
+ "inspector_page_agent_unittest.cc",
|
||||
"inspector_preload_agent_unittest.cc",
|
||||
"inspector_media_context_impl_unittest.cc",
|
||||
"inspector_session_state_test.cc",
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
|
||||
index 1825080b32ab6d7adb86236a389c08caf0b90c5c..f17565a6178c3f47037378faf965cd0f52cb0d26 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
|
||||
@@ -479,6 +479,42 @@ String InspectorPageAgent::CachedResourceTypeJson(
|
||||
return ResourceTypeJson(ToResourceType(cached_resource.GetType()));
|
||||
}
|
||||
|
||||
+InspectorPageAgent::PageReloadScriptInjection::PageReloadScriptInjection(
|
||||
+ InspectorAgentState& agent_state)
|
||||
+ : pending_script_to_evaluate_on_load_once_(&agent_state,
|
||||
+ /*default_value=*/{}),
|
||||
+ target_url_for_pending_script_(&agent_state,
|
||||
+ /*default_value=*/{}) {}
|
||||
+
|
||||
+void InspectorPageAgent::PageReloadScriptInjection::clear() {
|
||||
+ script_to_evaluate_on_load_once_ = {};
|
||||
+ pending_script_to_evaluate_on_load_once_.Set({});
|
||||
+ target_url_for_pending_script_.Set({});
|
||||
+}
|
||||
+
|
||||
+void InspectorPageAgent::PageReloadScriptInjection::SetPending(
|
||||
+ String script,
|
||||
+ const KURL& target_url) {
|
||||
+ pending_script_to_evaluate_on_load_once_.Set(script);
|
||||
+ target_url_for_pending_script_.Set(target_url.GetString().GetString());
|
||||
+}
|
||||
+
|
||||
+void InspectorPageAgent::PageReloadScriptInjection::PromoteToLoadOnce() {
|
||||
+ script_to_evaluate_on_load_once_ =
|
||||
+ pending_script_to_evaluate_on_load_once_.Get();
|
||||
+ target_url_for_active_script_ = target_url_for_pending_script_.Get();
|
||||
+ pending_script_to_evaluate_on_load_once_.Set({});
|
||||
+ target_url_for_pending_script_.Set({});
|
||||
+}
|
||||
+
|
||||
+String InspectorPageAgent::PageReloadScriptInjection::GetScriptForInjection(
|
||||
+ const KURL& target_url) {
|
||||
+ if (target_url_for_active_script_ == target_url.GetString()) {
|
||||
+ return script_to_evaluate_on_load_once_;
|
||||
+ }
|
||||
+ return {};
|
||||
+}
|
||||
+
|
||||
InspectorPageAgent::InspectorPageAgent(
|
||||
InspectedFrames* inspected_frames,
|
||||
Client* client,
|
||||
@@ -495,8 +531,6 @@ InspectorPageAgent::InspectorPageAgent(
|
||||
screencast_enabled_(&agent_state_, /*default_value=*/false),
|
||||
lifecycle_events_enabled_(&agent_state_, /*default_value=*/false),
|
||||
bypass_csp_enabled_(&agent_state_, /*default_value=*/false),
|
||||
- pending_script_to_evaluate_on_load_once_(&agent_state_,
|
||||
- /*default_value=*/String()),
|
||||
scripts_to_evaluate_on_load_(&agent_state_,
|
||||
/*default_value=*/String()),
|
||||
worlds_to_evaluate_on_load_(&agent_state_,
|
||||
@@ -506,7 +540,8 @@ InspectorPageAgent::InspectorPageAgent(
|
||||
/*default_value=*/false),
|
||||
standard_font_size_(&agent_state_, /*default_value=*/0),
|
||||
fixed_font_size_(&agent_state_, /*default_value=*/0),
|
||||
- script_font_families_cbor_(&agent_state_, std::vector<uint8_t>()) {}
|
||||
+ script_font_families_cbor_(&agent_state_, std::vector<uint8_t>()),
|
||||
+ script_injection_on_load_(agent_state_) {}
|
||||
|
||||
void InspectorPageAgent::Restore() {
|
||||
if (enabled_.Get())
|
||||
@@ -545,8 +580,7 @@ protocol::Response InspectorPageAgent::enable() {
|
||||
protocol::Response InspectorPageAgent::disable() {
|
||||
agent_state_.ClearAllFields();
|
||||
pending_isolated_worlds_.clear();
|
||||
- script_to_evaluate_on_load_once_ = String();
|
||||
- pending_script_to_evaluate_on_load_once_.Set(String());
|
||||
+ script_injection_on_load_.clear();
|
||||
instrumenting_agents_->RemoveInspectorPageAgent(this);
|
||||
inspector_resource_content_loader_->Cancel(
|
||||
resource_content_loader_client_id_);
|
||||
@@ -672,8 +706,9 @@ protocol::Response InspectorPageAgent::setAdBlockingEnabled(bool enable) {
|
||||
protocol::Response InspectorPageAgent::reload(
|
||||
Maybe<bool> optional_bypass_cache,
|
||||
Maybe<String> optional_script_to_evaluate_on_load) {
|
||||
- pending_script_to_evaluate_on_load_once_.Set(
|
||||
- optional_script_to_evaluate_on_load.value_or(""));
|
||||
+ script_injection_on_load_.SetPending(
|
||||
+ optional_script_to_evaluate_on_load.value_or(""),
|
||||
+ inspected_frames_->Root()->Loader().GetDocumentLoader()->Url());
|
||||
v8_session_->setSkipAllPauses(true);
|
||||
v8_session_->resume(true /* terminate on resume */);
|
||||
return protocol::Response::Success();
|
||||
@@ -989,7 +1024,9 @@ void InspectorPageAgent::DidCreateMainWorldContext(LocalFrame* frame) {
|
||||
EvaluateScriptOnNewDocument(*frame, key);
|
||||
}
|
||||
|
||||
- if (script_to_evaluate_on_load_once_.empty()) {
|
||||
+ String script = script_injection_on_load_.GetScriptForInjection(
|
||||
+ frame->Loader().GetDocumentLoader()->Url());
|
||||
+ if (script.empty()) {
|
||||
return;
|
||||
}
|
||||
ScriptState* script_state = ToScriptStateForMainWorld(frame);
|
||||
@@ -997,9 +1034,8 @@ void InspectorPageAgent::DidCreateMainWorldContext(LocalFrame* frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
- v8_session_->evaluate(
|
||||
- script_state->GetContext(),
|
||||
- ToV8InspectorStringView(script_to_evaluate_on_load_once_));
|
||||
+ v8_session_->evaluate(script_state->GetContext(),
|
||||
+ ToV8InspectorStringView(script));
|
||||
}
|
||||
|
||||
void InspectorPageAgent::EvaluateScriptOnNewDocument(
|
||||
@@ -1049,9 +1085,7 @@ void InspectorPageAgent::LoadEventFired(LocalFrame* frame) {
|
||||
|
||||
void InspectorPageAgent::WillCommitLoad(LocalFrame*, DocumentLoader* loader) {
|
||||
if (loader->GetFrame() == inspected_frames_->Root()) {
|
||||
- script_to_evaluate_on_load_once_ =
|
||||
- pending_script_to_evaluate_on_load_once_.Get();
|
||||
- pending_script_to_evaluate_on_load_once_.Set(String());
|
||||
+ script_injection_on_load_.PromoteToLoadOnce();
|
||||
}
|
||||
GetFrontend()->frameNavigated(BuildObjectForFrame(loader->GetFrame()),
|
||||
protocol::Page::NavigationTypeEnum::Navigation);
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
|
||||
index 6e6263beee810946d03934e7f707bb49a3177a2f..e7003baa895494bf61ad06f875d825ac9f53aec2 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.h
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
|
||||
@@ -94,6 +94,22 @@ class CORE_EXPORT InspectorPageAgent final
|
||||
kOtherResource
|
||||
};
|
||||
|
||||
+ class CORE_EXPORT PageReloadScriptInjection {
|
||||
+ private:
|
||||
+ String script_to_evaluate_on_load_once_;
|
||||
+ String target_url_for_active_script_;
|
||||
+ InspectorAgentState::String pending_script_to_evaluate_on_load_once_;
|
||||
+ InspectorAgentState::String target_url_for_pending_script_;
|
||||
+
|
||||
+ public:
|
||||
+ explicit PageReloadScriptInjection(InspectorAgentState&);
|
||||
+
|
||||
+ void clear();
|
||||
+ void SetPending(String script, const KURL& target_url);
|
||||
+ void PromoteToLoadOnce();
|
||||
+ String GetScriptForInjection(const KURL& target_url);
|
||||
+ };
|
||||
+
|
||||
static bool CachedResourceContent(const Resource*,
|
||||
String* result,
|
||||
bool* base64_encoded);
|
||||
@@ -307,7 +323,6 @@ class CORE_EXPORT InspectorPageAgent final
|
||||
ad_script_identifiers_;
|
||||
v8_inspector::V8InspectorSession* v8_session_;
|
||||
Client* client_;
|
||||
- String script_to_evaluate_on_load_once_;
|
||||
Member<InspectorResourceContentLoader> inspector_resource_content_loader_;
|
||||
int resource_content_loader_client_id_;
|
||||
InspectorAgentState::Boolean intercept_file_chooser_;
|
||||
@@ -315,7 +330,6 @@ class CORE_EXPORT InspectorPageAgent final
|
||||
InspectorAgentState::Boolean screencast_enabled_;
|
||||
InspectorAgentState::Boolean lifecycle_events_enabled_;
|
||||
InspectorAgentState::Boolean bypass_csp_enabled_;
|
||||
- InspectorAgentState::String pending_script_to_evaluate_on_load_once_;
|
||||
InspectorAgentState::StringMap scripts_to_evaluate_on_load_;
|
||||
InspectorAgentState::StringMap worlds_to_evaluate_on_load_;
|
||||
InspectorAgentState::BooleanMap
|
||||
@@ -323,6 +337,7 @@ class CORE_EXPORT InspectorPageAgent final
|
||||
InspectorAgentState::Integer standard_font_size_;
|
||||
InspectorAgentState::Integer fixed_font_size_;
|
||||
InspectorAgentState::Bytes script_font_families_cbor_;
|
||||
+ PageReloadScriptInjection script_injection_on_load_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b81f6b4735392f3f542ccbb2a114c2def185be1c
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc
|
||||
@@ -0,0 +1,57 @@
|
||||
+// Copyright 2024 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#include "third_party/blink/renderer/core/inspector/inspector_page_agent.h"
|
||||
+
|
||||
+#include "testing/gtest/include/gtest/gtest.h"
|
||||
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
|
||||
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
|
||||
+
|
||||
+class PageReloadScriptInjectionTest : public testing::Test {
|
||||
+ protected:
|
||||
+ blink::mojom::blink::DevToolsSessionStatePtr session_state_cookie_;
|
||||
+ blink::InspectorAgentState agent_state_;
|
||||
+ blink::InspectorPageAgent::PageReloadScriptInjection injection_;
|
||||
+ blink::InspectorSessionState state_;
|
||||
+
|
||||
+ public:
|
||||
+ PageReloadScriptInjectionTest()
|
||||
+ : agent_state_("page"),
|
||||
+ injection_(agent_state_),
|
||||
+ state_(session_state_cookie_.Clone()) {}
|
||||
+
|
||||
+ void SetUp() override { agent_state_.InitFrom(&state_); }
|
||||
+};
|
||||
+
|
||||
+TEST_F(PageReloadScriptInjectionTest, PromotesScript) {
|
||||
+ blink::KURL url("http://example.com");
|
||||
+ injection_.SetPending("script", url);
|
||||
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
|
||||
+ injection_.PromoteToLoadOnce();
|
||||
+ ASSERT_EQ(injection_.GetScriptForInjection(url), "script");
|
||||
+ injection_.PromoteToLoadOnce();
|
||||
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
|
||||
+}
|
||||
+
|
||||
+TEST_F(PageReloadScriptInjectionTest, ClearsScript) {
|
||||
+ blink::KURL url("http://example.com");
|
||||
+ injection_.SetPending("script", url);
|
||||
+ injection_.clear();
|
||||
+ injection_.PromoteToLoadOnce();
|
||||
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
|
||||
+
|
||||
+ injection_.SetPending("script", url);
|
||||
+ injection_.PromoteToLoadOnce();
|
||||
+ ASSERT_EQ(injection_.GetScriptForInjection(url), "script");
|
||||
+ injection_.clear();
|
||||
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
|
||||
+}
|
||||
+
|
||||
+TEST_F(PageReloadScriptInjectionTest, ChecksLoaderId) {
|
||||
+ blink::KURL url("http://example.com");
|
||||
+ blink::KURL url2("about:blank");
|
||||
+ injection_.SetPending("script", url);
|
||||
+ injection_.PromoteToLoadOnce();
|
||||
+ ASSERT_TRUE(injection_.GetScriptForInjection(url2).empty());
|
||||
+}
|
||||
288
patches/chromium/cherry-pick-44b7fbf35b10.patch
Normal file
288
patches/chromium/cherry-pick-44b7fbf35b10.patch
Normal file
@@ -0,0 +1,288 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hiroshige Hayashizaki <hiroshige@chromium.org>
|
||||
Date: Tue, 16 Jul 2024 03:44:29 +0000
|
||||
Subject: Handle ThrottlingURLLoader deletion during throttle calls
|
||||
|
||||
Theoretically `ThrottlingURLLoader` can be deleted during
|
||||
throttle calls and some call sites have already protection
|
||||
for such cases. This CL adds the protection for more call sites.
|
||||
|
||||
This CL also adds more unit tests for cancelling/deleting
|
||||
`ThrottlingURLLoader` during throttle calls.
|
||||
|
||||
(cherry picked from commit c40f8866cfd6438725cc58e5db2d792e6d9f869b)
|
||||
|
||||
Bug: 349342289
|
||||
Change-Id: I80d64be9ba1a3ac920315f5b4012b29c9737e414
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5665925
|
||||
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
|
||||
Reviewed-by: Tsuyoshi Horo <horo@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1323986}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5710951
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6533@{#1515}
|
||||
Cr-Branched-From: 7e0b87ec6b8cb5cb2969e1479fc25776e582721d-refs/heads/main@{#1313161}
|
||||
|
||||
diff --git a/third_party/blink/common/loader/throttling_url_loader.cc b/third_party/blink/common/loader/throttling_url_loader.cc
|
||||
index d2de163172880bd23f7478c6743c2608a5f04d94..28f55e1b3867cbd1ff3817c21c1f648fef4fcbc7 100644
|
||||
--- a/third_party/blink/common/loader/throttling_url_loader.cc
|
||||
+++ b/third_party/blink/common/loader/throttling_url_loader.cc
|
||||
@@ -660,8 +660,12 @@ void ThrottlingURLLoader::OnReceiveResponse(
|
||||
for (auto& entry : throttles_) {
|
||||
auto* throttle = entry.throttle.get();
|
||||
base::Time start = base::Time::Now();
|
||||
+ auto weak_ptr = weak_factory_.GetWeakPtr();
|
||||
throttle->BeforeWillProcessResponse(response_url_, *response_head,
|
||||
&has_pending_restart);
|
||||
+ if (!weak_ptr) {
|
||||
+ return;
|
||||
+ }
|
||||
RecordExecutionTimeHistogram("BeforeWillProcessResponse", start);
|
||||
if (!HandleThrottleResult(throttle)) {
|
||||
return;
|
||||
@@ -681,8 +685,12 @@ void ThrottlingURLLoader::OnReceiveResponse(
|
||||
auto* throttle = entry.throttle.get();
|
||||
bool throttle_deferred = false;
|
||||
base::Time start = base::Time::Now();
|
||||
+ auto weak_ptr = weak_factory_.GetWeakPtr();
|
||||
throttle->WillProcessResponse(response_url_, response_head.get(),
|
||||
&throttle_deferred);
|
||||
+ if (!weak_ptr) {
|
||||
+ return;
|
||||
+ }
|
||||
RecordExecutionTimeHistogram(GetStageNameForHistogram(DEFERRED_RESPONSE),
|
||||
start);
|
||||
if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
|
||||
@@ -852,7 +860,11 @@ void ThrottlingURLLoader::OnComplete(
|
||||
for (auto& entry : throttles_) {
|
||||
auto* throttle = entry.throttle.get();
|
||||
base::Time start = base::Time::Now();
|
||||
+ auto weak_ptr = weak_factory_.GetWeakPtr();
|
||||
throttle->WillOnCompleteWithError(status);
|
||||
+ if (!weak_ptr) {
|
||||
+ return;
|
||||
+ }
|
||||
RecordExecutionTimeHistogram("WillOnCompleteWithError", start);
|
||||
if (!HandleThrottleResult(throttle)) {
|
||||
return;
|
||||
diff --git a/third_party/blink/common/loader/throttling_url_loader_unittest.cc b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
|
||||
index 2c73705d12445c13067e937b4bfae1c99290da09..a7e037b2dde9390d9cc15d863ed926809f9afccf 100644
|
||||
--- a/third_party/blink/common/loader/throttling_url_loader_unittest.cc
|
||||
+++ b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
|
||||
@@ -338,9 +338,9 @@ class TestURLLoaderThrottle : public blink::URLLoaderThrottle {
|
||||
network::mojom::URLResponseHead* response_head,
|
||||
bool* defer) override {
|
||||
will_process_response_called_++;
|
||||
+ response_url_ = response_url;
|
||||
if (will_process_response_callback_)
|
||||
will_process_response_callback_.Run(delegate_.get(), defer);
|
||||
- response_url_ = response_url;
|
||||
}
|
||||
|
||||
void BeforeWillProcessResponse(
|
||||
@@ -422,6 +422,11 @@ class ThrottlingURLLoaderTest : public testing::Test {
|
||||
factory_.factory_remote().FlushForTesting();
|
||||
}
|
||||
|
||||
+ void ResetLoader() {
|
||||
+ ResetThrottleRawPointer();
|
||||
+ loader_.reset();
|
||||
+ }
|
||||
+
|
||||
void ResetThrottleRawPointer() { throttle_ = nullptr; }
|
||||
|
||||
// Be the first member so it is destroyed last.
|
||||
@@ -467,6 +472,25 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeStart) {
|
||||
EXPECT_EQ(1u, client_.on_complete_called());
|
||||
}
|
||||
|
||||
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeStart) {
|
||||
+ base::RunLoop run_loop;
|
||||
+ throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
|
||||
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
|
||||
+ bool* defer) {
|
||||
+ ResetLoader();
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(1u, factory_.create_loader_and_start_called());
|
||||
+
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(0u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
TEST_F(ThrottlingURLLoaderTest, DeferBeforeStart) {
|
||||
throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
|
||||
[](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
|
||||
@@ -667,6 +691,88 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeRedirect) {
|
||||
EXPECT_EQ(1u, client_.on_complete_called());
|
||||
}
|
||||
|
||||
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeRedirect) {
|
||||
+ base::RunLoop run_loop;
|
||||
+ throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
|
||||
+ [this, &run_loop](
|
||||
+ blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
|
||||
+ std::vector<std::string>* /* removed_headers */,
|
||||
+ net::HttpRequestHeaders* /* modified_headers */,
|
||||
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
|
||||
+ ResetLoader();
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+
|
||||
+ factory_.NotifyClientOnReceiveRedirect();
|
||||
+
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(0u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillRedirect) {
|
||||
+ throttle_->set_before_will_redirect_request_callback(
|
||||
+ base::BindLambdaForTesting(
|
||||
+ [](blink::URLLoaderThrottle::Delegate* delegate,
|
||||
+ RestartWithURLReset* restart_with_url_reset,
|
||||
+ std::vector<std::string>* /* removed_headers */,
|
||||
+ net::HttpRequestHeaders* /* modified_headers */,
|
||||
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
|
||||
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
|
||||
+ }));
|
||||
+
|
||||
+ base::RunLoop run_loop;
|
||||
+ client_.set_on_complete_callback(
|
||||
+ base::BindLambdaForTesting([&run_loop](int error) {
|
||||
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+
|
||||
+ factory_.NotifyClientOnReceiveRedirect();
|
||||
+
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
|
||||
+ EXPECT_EQ(1u, throttle_->will_redirect_request_called());
|
||||
+ EXPECT_EQ(0u, throttle_->before_will_process_response_called());
|
||||
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
|
||||
+
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(1u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillRedirect) {
|
||||
+ base::RunLoop run_loop;
|
||||
+ throttle_->set_before_will_redirect_request_callback(
|
||||
+ base::BindLambdaForTesting(
|
||||
+ [this, &run_loop](
|
||||
+ blink::URLLoaderThrottle::Delegate* delegate,
|
||||
+ RestartWithURLReset* restart_with_url_reset,
|
||||
+ std::vector<std::string>* /* removed_headers */,
|
||||
+ net::HttpRequestHeaders* /* modified_headers */,
|
||||
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
|
||||
+ ResetLoader();
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+
|
||||
+ factory_.NotifyClientOnReceiveRedirect();
|
||||
+
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(0u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
TEST_F(ThrottlingURLLoaderTest, DeferBeforeRedirect) {
|
||||
base::RunLoop run_loop1;
|
||||
throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
|
||||
@@ -880,6 +986,77 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) {
|
||||
EXPECT_EQ(1u, client_.on_complete_called());
|
||||
}
|
||||
|
||||
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeResponse) {
|
||||
+ base::RunLoop run_loop;
|
||||
+ throttle_->set_will_process_response_callback(base::BindLambdaForTesting(
|
||||
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
|
||||
+ bool* defer) {
|
||||
+ ResetLoader();
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+
|
||||
+ factory_.NotifyClientOnReceiveResponse();
|
||||
+
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(0u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillProcessResponse) {
|
||||
+ throttle_->set_before_will_process_response_callback(
|
||||
+ base::BindLambdaForTesting(
|
||||
+ [](blink::URLLoaderThrottle::Delegate* delegate,
|
||||
+ RestartWithURLReset* restart_with_url_reset) {
|
||||
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
|
||||
+ }));
|
||||
+
|
||||
+ base::RunLoop run_loop;
|
||||
+ client_.set_on_complete_callback(
|
||||
+ base::BindLambdaForTesting([&run_loop](int error) {
|
||||
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+
|
||||
+ factory_.NotifyClientOnReceiveResponse();
|
||||
+
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
|
||||
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
|
||||
+ EXPECT_EQ(1u, throttle_->before_will_process_response_called());
|
||||
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(1u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillProcessResponse) {
|
||||
+ base::RunLoop run_loop;
|
||||
+ throttle_->set_before_will_process_response_callback(
|
||||
+ base::BindLambdaForTesting(
|
||||
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
|
||||
+ RestartWithURLReset* restart_with_url_reset) {
|
||||
+ ResetLoader();
|
||||
+ run_loop.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ CreateLoaderAndStart();
|
||||
+
|
||||
+ factory_.NotifyClientOnReceiveResponse();
|
||||
+
|
||||
+ run_loop.Run();
|
||||
+
|
||||
+ EXPECT_EQ(0u, client_.on_received_response_called());
|
||||
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
|
||||
+ EXPECT_EQ(0u, client_.on_complete_called());
|
||||
+}
|
||||
+
|
||||
TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
|
||||
base::RunLoop run_loop1;
|
||||
throttle_->set_will_process_response_callback(base::BindRepeating(
|
||||
166
patches/chromium/cherry-pick-99cafbf4b4b9.patch
Normal file
166
patches/chromium/cherry-pick-99cafbf4b4b9.patch
Normal file
@@ -0,0 +1,166 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yann Dago <ydago@chromium.org>
|
||||
Date: Mon, 8 Jul 2024 16:20:32 +0000
|
||||
Subject: Ensure chrome://policy/test messages ignored when not supported
|
||||
|
||||
It was possible to go to chrome://policy and in the dev tools and send
|
||||
the right message to set test policies even if the policy test page was disabled and/or unavailable because both pages share the same handler.
|
||||
|
||||
Bug: 338248595
|
||||
Change-Id: If689325999cb108b2b71b2821d905e42efd3390d
|
||||
Low-Coverage-Reason: TRIVIAL_CHANGE
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5679162
|
||||
Auto-Submit: Yann Dago <ydago@chromium.org>
|
||||
Reviewed-by: Rohit Rao <rohitrao@chromium.org>
|
||||
Reviewed-by: Sergey Poromov <poromov@chromium.org>
|
||||
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1324277}
|
||||
|
||||
diff --git a/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
|
||||
index e27325a18087c8a01d21111f2fa0dd6e6da60023..a03c639b8654a5cbedccc3c38de4007dba084bf8 100644
|
||||
--- a/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
|
||||
+++ b/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
+#include "chrome/browser/enterprise/browser_management/browser_management_service.h"
|
||||
#include "chrome/browser/enterprise/browser_management/management_service_factory.h"
|
||||
#include "chrome/browser/lifetime/application_lifetime.h"
|
||||
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
|
||||
@@ -270,6 +271,57 @@ class PolicyTestHandlerTest : public PlatformBrowserTest {
|
||||
#endif
|
||||
};
|
||||
|
||||
+IN_PROC_BROWSER_TEST_F(PolicyTestHandlerTest,
|
||||
+ HandleSetLocalTestPoliciesNotSupported) {
|
||||
+ // Ensure chrome://policy/test not supported.
|
||||
+ policy::ScopedManagementServiceOverrideForTesting profile_management(
|
||||
+ policy::ManagementServiceFactory::GetForProfile(GetProfile()),
|
||||
+ policy::EnterpriseManagementAuthority::CLOUD);
|
||||
+ std::unique_ptr<PolicyUIHandler> handler = SetUpHandler();
|
||||
+ const std::string jsonString =
|
||||
+ R"([
|
||||
+ {"level": 0,"scope": 0,"source": 0, "namespace": "chrome",
|
||||
+ "name": "AutofillAddressEnabled","value": false},
|
||||
+ {"level": 1,"scope": 1,"source": 2, "namespace": "chrome",
|
||||
+ "name": "CloudReportingEnabled","value": true}
|
||||
+ ])";
|
||||
+ const std::string revertAppliedPoliciesButtonDisabledJs =
|
||||
+ R"(
|
||||
+ document
|
||||
+ .querySelector('#revert-applied-policies')
|
||||
+ .disabled;
|
||||
+ )";
|
||||
+
|
||||
+ base::Value::List list_args;
|
||||
+
|
||||
+ list_args.Append("setLocalTestPolicies");
|
||||
+ list_args.Append(jsonString);
|
||||
+ list_args.Append("{}");
|
||||
+
|
||||
+ // Open chrome://policy
|
||||
+ ASSERT_TRUE(
|
||||
+ content::NavigateToURL(web_contents(), GURL(chrome::kChromeUIPolicyURL)));
|
||||
+ web_ui()->HandleReceivedMessage("setLocalTestPolicies", list_args);
|
||||
+
|
||||
+ base::RunLoop().RunUntilIdle();
|
||||
+
|
||||
+ const policy::PolicyNamespace chrome_namespace(policy::POLICY_DOMAIN_CHROME,
|
||||
+ std::string());
|
||||
+ policy::PolicyService* policy_service =
|
||||
+ GetProfile()->GetProfilePolicyConnector()->policy_service();
|
||||
+
|
||||
+ // Check policies not applied
|
||||
+ const policy::PolicyMap* policy_map =
|
||||
+ &policy_service->GetPolicies(chrome_namespace);
|
||||
+ ASSERT_TRUE(policy_map);
|
||||
+
|
||||
+ {
|
||||
+ const policy::PolicyMap::Entry* entry =
|
||||
+ policy_map->Get(policy::key::kAutofillAddressEnabled);
|
||||
+ ASSERT_FALSE(entry);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
IN_PROC_BROWSER_TEST_F(PolicyTestHandlerTest,
|
||||
HandleSetAndRevertLocalTestPolicies) {
|
||||
if (!policy::utils::IsPolicyTestingEnabled(/*pref_service=*/nullptr,
|
||||
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
|
||||
index 0d13979009fc4df379432d5eea1a394607203615..1dc6ecc6bed91115be10021c0661f8d81456161b 100644
|
||||
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc
|
||||
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "chrome/browser/ui/chrome_select_file_policy.h"
|
||||
#include "chrome/browser/ui/webui/policy/policy_ui.h"
|
||||
#include "chrome/browser/ui/webui/webui_util.h"
|
||||
+#include "chrome/common/channel_info.h"
|
||||
#include "chrome/grit/branded_strings.h"
|
||||
#include "components/crx_file/id_util.h"
|
||||
#include "components/enterprise/browser/controller/browser_dm_token_storage.h"
|
||||
@@ -69,6 +70,7 @@
|
||||
#include "components/policy/core/common/policy_pref_names.h"
|
||||
#include "components/policy/core/common/policy_scheduler.h"
|
||||
#include "components/policy/core/common/policy_types.h"
|
||||
+#include "components/policy/core/common/policy_utils.h"
|
||||
#include "components/policy/core/common/remote_commands/remote_commands_service.h"
|
||||
#include "components/policy/core/common/schema.h"
|
||||
#include "components/policy/core/common/schema_map.h"
|
||||
@@ -316,6 +318,12 @@ void PolicyUIHandler::HandleCopyPoliciesJson(const base::Value::List& args) {
|
||||
void PolicyUIHandler::HandleSetLocalTestPolicies(
|
||||
const base::Value::List& args) {
|
||||
std::string policies = args[1].GetString();
|
||||
+ AllowJavascript();
|
||||
+
|
||||
+ if (!PolicyUI::ShouldLoadTestPage(Profile::FromWebUI(web_ui()))) {
|
||||
+ ResolveJavascriptCallback(args[0], true);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
policy::LocalTestPolicyProvider* local_test_provider =
|
||||
static_cast<policy::LocalTestPolicyProvider*>(
|
||||
@@ -338,12 +346,14 @@ void PolicyUIHandler::HandleSetLocalTestPolicies(
|
||||
->UseLocalTestPolicyProvider();
|
||||
|
||||
local_test_provider->LoadJsonPolicies(policies);
|
||||
- AllowJavascript();
|
||||
ResolveJavascriptCallback(args[0], true);
|
||||
}
|
||||
|
||||
void PolicyUIHandler::HandleRevertLocalTestPolicies(
|
||||
const base::Value::List& args) {
|
||||
+ if (!PolicyUI::ShouldLoadTestPage(Profile::FromWebUI(web_ui()))) {
|
||||
+ return;
|
||||
+ }
|
||||
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
|
||||
Profile::FromWebUI(web_ui())->GetPrefs()->ClearPref(
|
||||
prefs::kUserCloudSigninPolicyResponseFromPolicyTestPage);
|
||||
diff --git a/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm b/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
|
||||
index 577caf2012e0cdcdcf5baa4c5a288119da40cabd..94466842c2faeb13fd0ae33ba619362f8a43cd06 100644
|
||||
--- a/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
|
||||
+++ b/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
|
||||
@@ -220,6 +220,12 @@
|
||||
const base::Value::List& args) {
|
||||
std::string json_policies_string = args[1].GetString();
|
||||
|
||||
+ if (!PolicyUI::ShouldLoadTestPage(
|
||||
+ ChromeBrowserState::FromWebUIIOS(web_ui()))) {
|
||||
+ web_ui()->ResolveJavascriptCallback(args[0], true);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
policy::LocalTestPolicyProvider* local_test_provider =
|
||||
static_cast<policy::LocalTestPolicyProvider*>(
|
||||
GetApplicationContext()
|
||||
@@ -238,6 +244,11 @@
|
||||
|
||||
void PolicyUIHandler::HandleRevertLocalTestPolicies(
|
||||
const base::Value::List& args) {
|
||||
+ if (!PolicyUI::ShouldLoadTestPage(
|
||||
+ ChromeBrowserState::FromWebUIIOS(web_ui()))) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ChromeBrowserState::FromWebUIIOS(web_ui())
|
||||
->GetPolicyConnector()
|
||||
->RevertUseLocalTestPolicyProvider();
|
||||
32
patches/chromium/cherry-pick-c5dd8839bfaf.patch
Normal file
32
patches/chromium/cherry-pick-c5dd8839bfaf.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rakina Zata Amni <rakina@chromium.org>
|
||||
Date: Wed, 19 Jun 2024 02:49:58 +0000
|
||||
Subject: Destruct controller before referenced WebUI in CreateWebUIIfNeeded
|
||||
|
||||
Reset `controller` first before resetting `web_ui_`, since the
|
||||
controller still has a pointer to `web_ui_`, to avoid referencing to
|
||||
the already deleted `web_ui_` object from `controller`'s destructor.
|
||||
|
||||
Bug: 345640549
|
||||
Change-Id: Ie9c193436b593845d8269605f68bf94bc75beed7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5624749
|
||||
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
|
||||
Reviewed-by: Nasko Oskov <nasko@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1316830}
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
|
||||
index 8a9beaf3bfb9fe5eca8ca6675c7c45b4b880db03..85041c38c8d2e84d780948a4dab94013ce39dfbe 100644
|
||||
--- a/content/browser/renderer_host/navigation_request.cc
|
||||
+++ b/content/browser/renderer_host/navigation_request.cc
|
||||
@@ -10268,6 +10268,11 @@ void NavigationRequest::CreateWebUIIfNeeded(RenderFrameHostImpl* frame_host) {
|
||||
bindings() != web_ui_->GetBindings()) {
|
||||
RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
|
||||
base::WeakPtr<NavigationRequest> self = GetWeakPtr();
|
||||
+ // Reset `controller` first before resetting `web_ui_`, since the controller
|
||||
+ // still has a pointer to `web_ui_`, to avoid referencing to the already
|
||||
+ // deleted `web_ui_` object from `controller`'s destructor. See also
|
||||
+ // https://crbug.com/345640549.
|
||||
+ controller.reset();
|
||||
web_ui_.reset();
|
||||
// Resetting the WebUI may indirectly call content's embedders and delete
|
||||
// `this`. There are no known occurrences of it, so we assume this never
|
||||
37
patches/chromium/cherry-pick-d54105311590.patch
Normal file
37
patches/chromium/cherry-pick-d54105311590.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "mark a. foltz" <mfoltz@chromium.org>
|
||||
Date: Mon, 17 Jun 2024 23:07:32 +0000
|
||||
Subject: Retain refptr to shared helper to prevent UAF.
|
||||
|
||||
Capture a reference to the shared helper in the onerror handler to
|
||||
prevent a UAF that can occur when the browser drops the mojo
|
||||
connection.
|
||||
|
||||
Bug: 346692546
|
||||
Change-Id: Ifb264488a6fa8417c134a34d902605d2c141720b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5634908
|
||||
Reviewed-by: Avi Drissman <avi@chromium.org>
|
||||
Commit-Queue: Mark Foltz <mfoltz@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1316145}
|
||||
|
||||
diff --git a/media/audio/mac/audio_loopback_input_mac_impl.mm b/media/audio/mac/audio_loopback_input_mac_impl.mm
|
||||
index 7b301492f17a3f1da96b8ff990f6deeb4a19b6e3..f90c00e668f58c2389e622466422ae7aa237c94d 100644
|
||||
--- a/media/audio/mac/audio_loopback_input_mac_impl.mm
|
||||
+++ b/media/audio/mac/audio_loopback_input_mac_impl.mm
|
||||
@@ -394,12 +394,15 @@ - (void)stream:(SCStream*)stream
|
||||
base::BindRepeating(&SCKAudioInputStream::OnStreamError,
|
||||
base::Unretained(this)));
|
||||
|
||||
+ // Make a local copy of the shared_refptr in case the error handler is called
|
||||
+ // after `this` is destroyed.
|
||||
+ auto local_shared_helper = shared_helper_;
|
||||
[stream_ startCaptureWithCompletionHandler:^(NSError* error) {
|
||||
if (!error) {
|
||||
return;
|
||||
}
|
||||
|
||||
- shared_helper_->OnStreamError(error);
|
||||
+ local_shared_helper->OnStreamError(error);
|
||||
}];
|
||||
}
|
||||
|
||||
159
patches/chromium/cherry-pick-d9f7652c867c.patch
Normal file
159
patches/chromium/cherry-pick-d9f7652c867c.patch
Normal file
@@ -0,0 +1,159 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Rice <ricea@chromium.org>
|
||||
Date: Thu, 25 Jul 2024 05:28:45 +0000
|
||||
Subject: Don't allocate WebTransportCloseInfo on stack
|
||||
|
||||
blink::WebTransport::OnClosed() was allocating a WebTransportCloseInfo
|
||||
object on the stack. Since it is a garbage-collected object, this is
|
||||
wrong. Allocate it with MakeGarbageCollected<>() instead.
|
||||
|
||||
(cherry picked from commit 84c1481d8a8d5e7f51316b648d1bf71f2ae52122)
|
||||
|
||||
Fixed: 352872238
|
||||
Change-Id: I83484021d5f3f6d49d3c222c8f2dc34219f2d240
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5725413
|
||||
Commit-Queue: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Reviewed-by: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Auto-Submit: Adam Rice <ricea@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1331525}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5740536
|
||||
Commit-Queue: Adam Rice <ricea@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6478@{#1848}
|
||||
Cr-Branched-From: e6143acc03189c5e52959545b110d6d17ecd5286-refs/heads/main@{#1300313}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport.cc b/third_party/blink/renderer/modules/webtransport/web_transport.cc
|
||||
index bcfa17448f3051dc2b292aa3e19dbfb915cf692a..4922359605b53c6b9ac5339f6ce6b3613bfe275b 100644
|
||||
--- a/third_party/blink/renderer/modules/webtransport/web_transport.cc
|
||||
+++ b/third_party/blink/renderer/modules/webtransport/web_transport.cc
|
||||
@@ -1092,17 +1092,17 @@ void WebTransport::OnClosed(
|
||||
|
||||
latest_stats_ = ConvertStatsFromMojom(std::move(final_stats));
|
||||
|
||||
- WebTransportCloseInfo idl_close_info;
|
||||
+ auto* idl_close_info = MakeGarbageCollected<WebTransportCloseInfo>();
|
||||
if (close_info) {
|
||||
- idl_close_info.setCloseCode(close_info->code);
|
||||
- idl_close_info.setReason(close_info->reason);
|
||||
+ idl_close_info->setCloseCode(close_info->code);
|
||||
+ idl_close_info->setReason(close_info->reason);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> error = WebTransportError::Create(
|
||||
isolate, /*stream_error_code=*/std::nullopt, "The session is closed.",
|
||||
WebTransportError::Source::kSession);
|
||||
|
||||
- Cleanup(&idl_close_info, error, /*abruptly=*/false);
|
||||
+ Cleanup(idl_close_info, error, /*abruptly=*/false);
|
||||
}
|
||||
|
||||
void WebTransport::OnOutgoingStreamClosed(uint32_t stream_id) {
|
||||
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport_test.cc b/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
|
||||
index 01f5a0fca58d88e342298e03231dd2263ca5a678..fc05ad637888df648f8692683f8a626c8d6a38dd 100644
|
||||
--- a/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
|
||||
+++ b/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
|
||||
@@ -1959,6 +1959,21 @@ TEST_F(WebTransportTest, OnClosed) {
|
||||
EXPECT_EQ(close_info->reason(), "reason");
|
||||
}
|
||||
|
||||
+// Regression test for https://crbug.com/347710668.
|
||||
+TEST_F(WebTransportTest, ClosedAccessorCalledAfterOnClosed) {
|
||||
+ V8TestingScope scope;
|
||||
+
|
||||
+ auto* web_transport =
|
||||
+ CreateAndConnectSuccessfully(scope, "https://example.com");
|
||||
+
|
||||
+ web_transport->OnClosed(
|
||||
+ network::mojom::blink::WebTransportCloseInfo::New(99, "reason"),
|
||||
+ network::mojom::blink::WebTransportStats::New());
|
||||
+
|
||||
+ // If this doesn't crash then the test passed.
|
||||
+ EXPECT_FALSE(web_transport->closed(scope.GetScriptState()).IsEmpty());
|
||||
+}
|
||||
+
|
||||
TEST_F(WebTransportTest, OnClosedWithNull) {
|
||||
V8TestingScope scope;
|
||||
v8::Isolate* isolate = scope.GetIsolate();
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt
|
||||
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt
|
||||
@@ -1,4 +1,5 @@
|
||||
This is a testharness.js-based test.
|
||||
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
|
||||
[FAIL] opening unidirectional stream before ready
|
||||
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
|
||||
[FAIL] opening bidirectional stream before ready
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js
|
||||
index 0d8579584fbb21e74595588f663ef21c3b028c63..d69967ba70bb716f8664f973fe83d4158ba6da89 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js
|
||||
@@ -163,3 +163,24 @@ promise_test(async t => {
|
||||
const wt = new WebTransport(webtransport_url('server-close.py'));
|
||||
promise_rejects_dom(t, "InvalidStateError", wt.createBidirectionalStream());
|
||||
}, 'server initiated closure while opening bidirectional stream before ready');
|
||||
+
|
||||
+// Regression test for https://crbug.com/347710668.
|
||||
+promise_test(async t => {
|
||||
+ const wt = new WebTransport(webtransport_url('server-read-then-close.py'));
|
||||
+ add_completion_callback(() => wt.close());
|
||||
+ await wt.ready;
|
||||
+
|
||||
+ const bidi_reader = wt.incomingBidirectionalStreams.getReader();
|
||||
+ const { value: bidi } = await bidi_reader.read();
|
||||
+
|
||||
+ bidi.writable.getWriter().write(new TextEncoder().encode('some data'));
|
||||
+ const reader = bidi.readable.getReader();
|
||||
+ await reader.closed.catch(t.step_func(
|
||||
+ e => assert_true(e instanceof WebTransportError)));
|
||||
+
|
||||
+ // The WebTransport session will already be closed.
|
||||
+ const {reason, closeCode} = await wt.closed;
|
||||
+
|
||||
+ assert_equals(reason, '', 'reason should be default');
|
||||
+ assert_equals(closeCode, 0, 'closeCode should be default');
|
||||
+}, 'reading closed property after close should work');
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt
|
||||
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt
|
||||
@@ -1,4 +1,5 @@
|
||||
This is a testharness.js-based test.
|
||||
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
|
||||
[FAIL] opening unidirectional stream before ready
|
||||
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
|
||||
[FAIL] opening bidirectional stream before ready
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt
|
||||
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt
|
||||
@@ -1,4 +1,5 @@
|
||||
This is a testharness.js-based test.
|
||||
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
|
||||
[FAIL] opening unidirectional stream before ready
|
||||
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
|
||||
[FAIL] opening bidirectional stream before ready
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt
|
||||
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt
|
||||
@@ -1,4 +1,5 @@
|
||||
This is a testharness.js-based test.
|
||||
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
|
||||
[FAIL] opening unidirectional stream before ready
|
||||
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
|
||||
[FAIL] opening bidirectional stream before ready
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/handlers/server-read-then-close.py b/third_party/blink/web_tests/external/wpt/webtransport/handlers/server-read-then-close.py
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7f992e0dcca3ae62277cac0fa39355fce3e57be0
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webtransport/handlers/server-read-then-close.py
|
||||
@@ -0,0 +1,9 @@
|
||||
+def session_established(session):
|
||||
+ stream_id = session.create_bidirectional_stream()
|
||||
+
|
||||
+
|
||||
+def stream_data_received(session,
|
||||
+ stream_id: int,
|
||||
+ data: bytes,
|
||||
+ stream_ended: bool):
|
||||
+ session.close(None)
|
||||
@@ -1 +1,2 @@
|
||||
dawn_dxc_disable_dxc_pass_structurize-loop-exits-for-unroll.patch
|
||||
deps_update_dxc_to_patched_branch.patch
|
||||
|
||||
28
patches/dawn/deps_update_dxc_to_patched_branch.patch
Normal file
28
patches/dawn/deps_update_dxc_to_patched_branch.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Neto <dneto@google.com>
|
||||
Date: Wed, 17 Jul 2024 14:09:26 +0000
|
||||
Subject: DEPS: Update DXC to patched branch
|
||||
|
||||
Also, add DXC_CODEGEN_EXCEPTIONS_TRAP=1 to DXC gn config.
|
||||
|
||||
Bug: chromium:346618785, chromium:350696474
|
||||
Change-Id: I4c1ac753d824c4790e78d8f36231c8f2fe0e2722
|
||||
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/198756
|
||||
Reviewed-by: Natalie Chouinard <chouinard@google.com>
|
||||
|
||||
diff --git a/third_party/gn/dxc/BUILD.gn b/third_party/gn/dxc/BUILD.gn
|
||||
index aadb64eeb4fba2f2da442a8a7f4b285a469c5cdd..0060484cefcf1835138b111258c33e09fab1279c 100644
|
||||
--- a/third_party/gn/dxc/BUILD.gn
|
||||
+++ b/third_party/gn/dxc/BUILD.gn
|
||||
@@ -453,7 +453,10 @@ cmake_configure_file("clang-config-h") {
|
||||
cmake_configure_file("dxc-config-h") {
|
||||
input = "$dawn_dxc_dir/include/dxc/config.h.cmake"
|
||||
output = "$target_gen_dir/include/dxc/config.h"
|
||||
- values = [ "DXC_DISABLE_ALLOCATOR_OVERRIDES=1" ]
|
||||
+ values = [
|
||||
+ "DXC_DISABLE_ALLOCATOR_OVERRIDES=1",
|
||||
+ "DXC_CODEGEN_EXCEPTIONS_TRAP=1",
|
||||
+ ]
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
@@ -41,3 +41,6 @@ test_match_wpt_streams_transferable_transform-stream-members_any_js.patch
|
||||
build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch
|
||||
fix_revert_src_lb_reducing_c_calls_of_esm_legacy_main_resolve.patch
|
||||
deprecate_vector_v8_local_in_v8.patch
|
||||
src_account_for_openssl_unexpected_version.patch
|
||||
windows_32bit_config_change_callback_needs_to_be_stdcall.patch
|
||||
fix_building_with_unicode.patch
|
||||
|
||||
@@ -537,10 +537,10 @@ index 0e69d7383762f6b81c5b57698aa9d121d5a9c401..35bbeb37acc7ccb14b4b8a644ec3d4c7
|
||||
cflags_c = [
|
||||
"-mavx512vl",
|
||||
diff --git a/deps/cares/BUILD.gn b/deps/cares/BUILD.gn
|
||||
index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de001bd8947e 100644
|
||||
index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..087e27424f3997575e4e089a57955d04b8802321 100644
|
||||
--- a/deps/cares/BUILD.gn
|
||||
+++ b/deps/cares/BUILD.gn
|
||||
@@ -1,14 +1,163 @@
|
||||
@@ -1,14 +1,170 @@
|
||||
-##############################################################################
|
||||
-# #
|
||||
-# DO NOT EDIT THIS FILE! #
|
||||
@@ -582,6 +582,8 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de00
|
||||
+ "src/lib/ares__htable_strvp.h",
|
||||
+ "src/lib/ares__htable_szvp.c",
|
||||
+ "src/lib/ares__htable_szvp.h",
|
||||
+ "src/lib/ares__htable_vpvp.c",
|
||||
+ "src/lib/ares__htable_vpvp.h",
|
||||
+ "src/lib/ares__iface_ips.c",
|
||||
+ "src/lib/ares__iface_ips.h",
|
||||
+ "src/lib/ares__llist.c",
|
||||
@@ -607,6 +609,7 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de00
|
||||
+ "src/lib/ares_dns_record.c",
|
||||
+ "src/lib/ares_dns_private.h",
|
||||
+ "src/lib/ares_dns_write.c",
|
||||
+ "src/lib/ares_event_configchg.c",
|
||||
+ "src/lib/ares_event.h",
|
||||
+ "src/lib/ares_event_win32.h",
|
||||
+ "src/lib/ares_event_epoll.c",
|
||||
@@ -711,7 +714,11 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de00
|
||||
-cares_gn_build("cares") {
|
||||
+ if (is_mac) {
|
||||
+ include_dirs += [ "config/darwin" ]
|
||||
+ sources += [ "config/darwin/ares_config.h" ]
|
||||
+ sources += [
|
||||
+ "config/darwin/ares_config.h",
|
||||
+ "src/lib/ares_sysconfig_mac.c",
|
||||
+ "src/lib/thirdparty/apple/dnsinfo.h",
|
||||
+ ]
|
||||
+ }
|
||||
}
|
||||
diff --git a/deps/googletest/BUILD.gn b/deps/googletest/BUILD.gn
|
||||
@@ -1256,10 +1263,10 @@ index 0000000000000000000000000000000000000000..af9cbada10203b387fb9732b346583b1
|
||||
+}
|
||||
diff --git a/filenames.json b/filenames.json
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d18a59b6629849588e31f977e8d537ff5b11f7e4
|
||||
index 0000000000000000000000000000000000000000..7fed188f922a6754907411046ba4a977049394ea
|
||||
--- /dev/null
|
||||
+++ b/filenames.json
|
||||
@@ -0,0 +1,738 @@
|
||||
@@ -0,0 +1,740 @@
|
||||
+// This file is automatically generated by generate_gn_filenames_json.py
|
||||
+// DO NOT EDIT
|
||||
+{
|
||||
@@ -1846,6 +1853,7 @@ index 0000000000000000000000000000000000000000..d18a59b6629849588e31f977e8d537ff
|
||||
+ "src/permission/fs_permission.cc",
|
||||
+ "src/permission/inspector_permission.cc",
|
||||
+ "src/permission/permission.cc",
|
||||
+ "src/permission/wasi_permission.cc",
|
||||
+ "src/permission/worker_permission.cc",
|
||||
+ "src/pipe_wrap.cc",
|
||||
+ "src/process_wrap.cc",
|
||||
@@ -1967,6 +1975,7 @@ index 0000000000000000000000000000000000000000..d18a59b6629849588e31f977e8d537ff
|
||||
+ "src/permission/fs_permission.h",
|
||||
+ "src/permission/inspector_permission.h",
|
||||
+ "src/permission/permission.h",
|
||||
+ "src/permission/wasi_permission.h",
|
||||
+ "src/permission/worker_permission.h",
|
||||
+ "src/pipe_wrap.h",
|
||||
+ "src/req_wrap.h",
|
||||
|
||||
@@ -33,10 +33,10 @@ index 7d201bb6b822f0401c3be2bc52d65bc71463748b..38f4b5afb9e667f0958008847224fa7a
|
||||
node_platform = "win32"
|
||||
} else if (target_os == "mac") {
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index 7bd5edf61c339daa1e1b0df8e2e91680948641de..401bc2fc819b85baba2509de6cd4dbcde5f67559 100644
|
||||
index ea0ae4e08ec7dd98721bc89d2fe80fa47eaddfec..cad55dc4458cc64d701b53975f817b1552660d73 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -557,7 +557,8 @@ IsolateData::IsolateData(Isolate* isolate,
|
||||
@@ -569,7 +569,8 @@ IsolateData::IsolateData(Isolate* isolate,
|
||||
// for embedder ID, V8 could accidentally enable cppgc on them. So
|
||||
// safe guard against this.
|
||||
DCHECK_NE(descriptor.wrappable_type_index, BaseObject::kSlot);
|
||||
@@ -46,7 +46,7 @@ index 7bd5edf61c339daa1e1b0df8e2e91680948641de..401bc2fc819b85baba2509de6cd4dbcd
|
||||
cpp_heap_ = CppHeap::Create(
|
||||
platform,
|
||||
CppHeapCreateParams{
|
||||
@@ -565,6 +566,7 @@ IsolateData::IsolateData(Isolate* isolate,
|
||||
@@ -577,6 +578,7 @@ IsolateData::IsolateData(Isolate* isolate,
|
||||
WrapperDescriptor(
|
||||
BaseObject::kEmbedderType, BaseObject::kSlot, cppgc_id)});
|
||||
isolate->AttachCppHeap(cpp_heap_.get());
|
||||
|
||||
@@ -26,7 +26,7 @@ index 155485dbab0d46bb225fa40e99f555d805659c4f..8183cffe9d7060571c08f696abb7c090
|
||||
try {
|
||||
resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index 16e291484bfe85d5614557f070ab0d2ae59655d4..b4272f01e84d7fec263dcad444d92459743780a8 100644
|
||||
index 8fad2fe617e4f8d2364b8c9d3cfb27c265f08b5b..710af646aaf97f88ac2ee003d8f83388ccf9a84f 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -244,12 +244,14 @@ function patchProcessObject(expandArgv1) {
|
||||
|
||||
@@ -45,10 +45,10 @@ index f995c170540ffaa80b1b5f8b95dbd8f52bbd5431..6455dbdd015477e16c414b6d21131393
|
||||
fixtures.path(name),
|
||||
transform ?? defaultTransform,
|
||||
diff --git a/test/parallel/test-node-output-errors.mjs b/test/parallel/test-node-output-errors.mjs
|
||||
index c0acee2bfc8c124e9d9b254041589a49c8301b8f..0e266899ffc0918b2f94e8f636043a6ec5f0870f 100644
|
||||
index 84f20a77dda367fe1ada8d616c7b6813d39efd43..27d16d74884a006ba01b777f5a20339b4906197b 100644
|
||||
--- a/test/parallel/test-node-output-errors.mjs
|
||||
+++ b/test/parallel/test-node-output-errors.mjs
|
||||
@@ -61,21 +61,22 @@ describe('errors output', { concurrency: true }, () => {
|
||||
@@ -59,21 +59,22 @@ describe('errors output', { concurrency: true }, () => {
|
||||
{ name: 'errors/events_unhandled_error_subclass.js', transform: errTransform },
|
||||
{ name: 'errors/if-error-has-good-stack.js', transform: errTransform },
|
||||
{ name: 'errors/throw_custom_error.js', transform: errTransform },
|
||||
@@ -69,11 +69,11 @@ index c0acee2bfc8c124e9d9b254041589a49c8301b8f..0e266899ffc0918b2f94e8f636043a6e
|
||||
- { skip: skipForceColors, name: 'errors/force_colors.js',
|
||||
- transform: forceColorsTransform, env: { FORCE_COLOR: 1 } },
|
||||
+ // { skip: skipForceColors, name: 'errors/force_colors.js',
|
||||
+ // transform: forceColorsTransform, env: { FORCE_COLOR: 1 } },
|
||||
+ // transform: forceColorsTransform, env: { FORCE_COLOR: 1 } },
|
||||
];
|
||||
for (const { name, transform = defaultTransform, env, skip = false } of tests) {
|
||||
it(name, { skip }, async () => {
|
||||
+ if (env) env.ELECTRON_RUN_AS_NODE = 1;
|
||||
await snapshot.spawnAndAssert(fixtures.path(name), transform, { env });
|
||||
await snapshot.spawnAndAssert(fixtures.path(name), transform, { env: { ...env, ...process.env } });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ In file included from ../../third_party/electron_node/src/env-inl.h:32:
|
||||
1 error generated.
|
||||
|
||||
diff --git a/src/util.h b/src/util.h
|
||||
index cd4fe2e422a7843f5a3f0f4b336a8625a0b24bcf..8edd50e598d8612144b8da9236e63f9079b99156 100644
|
||||
index 3ae876e5484f0ebacfae6749cc336f42cd69bf14..8e9e8289de249119d6b8078abe32db6b885dfaab 100644
|
||||
--- a/src/util.h
|
||||
+++ b/src/util.h
|
||||
@@ -146,9 +146,9 @@ void DumpJavaScriptBacktrace(FILE* fp);
|
||||
|
||||
@@ -58,10 +58,10 @@ index f9d29f0065b1de63a62cfdce74a9705c22dd87d7..3f44160f1bd40fc2d4658f10edf0d0b3
|
||||
}
|
||||
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index 753311e15f161547be4277016efe11cc57d351db..8e98b76e29824565739010b885375d63c992bdf8 100644
|
||||
index 28fbd93c5d4a6f379844e10e556920b7614910d8..53cf93719bea001db09697b56f197815549dc953 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -1317,6 +1317,11 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -1321,6 +1321,11 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
|
||||
Local<Context> context = env->context();
|
||||
Local<Object> ret = Object::New(isolate);
|
||||
|
||||
|
||||
33
patches/node/fix_building_with_unicode.patch
Normal file
33
patches/node/fix_building_with_unicode.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Keeley Hammond <khammond@slack-corp.com>
|
||||
Date: Thu, 25 Jul 2024 15:29:12 -0700
|
||||
Subject: fix: building with UNICODE
|
||||
|
||||
Use the unicode version of 'RegOpenKeyEx' to avoid compilation error on string type.
|
||||
|
||||
Backport of https://github.com/c-ares/c-ares/pull/802.
|
||||
|
||||
diff --git a/deps/cares/src/lib/ares_event_configchg.c b/deps/cares/src/lib/ares_event_configchg.c
|
||||
index c9b39f7b3358f37e61fb95e440695a9b590c2090..b33141ce3a30dd92509de8a4aff1a7fc76a5b915 100644
|
||||
--- a/deps/cares/src/lib/ares_event_configchg.c
|
||||
+++ b/deps/cares/src/lib/ares_event_configchg.c
|
||||
@@ -319,15 +319,15 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
|
||||
/* Monitor HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces
|
||||
* and HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
|
||||
* for changes via RegNotifyChangeKeyValue() */
|
||||
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
- "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
|
||||
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
|
||||
0, KEY_NOTIFY, &c->regip4) != ERROR_SUCCESS) {
|
||||
status = ARES_ESERVFAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
- "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces",
|
||||
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces",
|
||||
0, KEY_NOTIFY, &c->regip6) != ERROR_SUCCESS) {
|
||||
status = ARES_ESERVFAIL;
|
||||
goto done;
|
||||
@@ -24,7 +24,7 @@ index 69e2a389f9e1480a1a4ba37f5df5356b42f7d52d..0c29b00298b44b97f88a63aa5b89f1c2
|
||||
wrap->object()->Has(env->context(), env->handle_onclose_symbol())
|
||||
.FromMaybe(false)) {
|
||||
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
|
||||
index ca8575e9a21b9a0b8089484a04abe702b2fe6d4e..df1d9cb4fd0442ec6ce6164a136b7a5fbcbe5b67 100644
|
||||
index d873792ab95e41d54579f552c6c1fa43447ca4cd..708fa03d088e67a50dc4e69bb3f2cc14529dc3f1 100644
|
||||
--- a/src/node_contextify.cc
|
||||
+++ b/src/node_contextify.cc
|
||||
@@ -460,6 +460,7 @@ bool ContextifyContext::IsStillInitializing(const ContextifyContext* ctx) {
|
||||
|
||||
@@ -31,7 +31,7 @@ index 4e3c32fdcd23fbe3e74bd5e624b739d224689f33..19d65aae7fa8ec9f9b907733ead17a20
|
||||
// Test Parallel Execution w/ KeyObject is threadsafe in openssl3
|
||||
{
|
||||
diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js
|
||||
index 6178445adbc634160c3c3ca699a36868f894e544..ff4dc2f7d527b5eb1fa442ba6b0f9ba04af39357 100644
|
||||
index 59dd3b69c4bdf6dbd7b5e4f03df74caac551d459..1e0f9ce4c979683530afdf83ac3dc095acad2eb8 100644
|
||||
--- a/test/parallel/test-crypto-authenticated.js
|
||||
+++ b/test/parallel/test-crypto-authenticated.js
|
||||
@@ -48,7 +48,9 @@ const errMessages = {
|
||||
@@ -381,7 +381,7 @@ index fcf1922bcdba733af6c22f142db4f7b099947757..9f72ae4e41a113e752f40795103c2af5
|
||||
assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex);
|
||||
assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex);
|
||||
diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js
|
||||
index 3b738b7f47ec59ba718a92e3a0024fed45a9c87c..fabf5775a263804f5974b10cf73c6886d59bf1fa 100644
|
||||
index fb580e1b315445182538c56fc114742ce896bf4c..36014fe7cb411016d72a7f4ab118923d12e97898 100644
|
||||
--- a/test/parallel/test-crypto-dh.js
|
||||
+++ b/test/parallel/test-crypto-dh.js
|
||||
@@ -55,18 +55,17 @@ const crypto = require('crypto');
|
||||
@@ -594,6 +594,19 @@ index 5f4fafdfffbf726b7cb39c472baa3df25c9794cf..73bb53b0405b20f51b13326cc70e5275
|
||||
assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
|
||||
}
|
||||
+*/
|
||||
diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js
|
||||
index 61bd65fc92678c24baa3c0eb9ffb1ead64ace70b..cb690351696a811210b9d990ee4cde3cfb2a3446 100644
|
||||
--- a/test/parallel/test-crypto-scrypt.js
|
||||
+++ b/test/parallel/test-crypto-scrypt.js
|
||||
@@ -178,7 +178,7 @@ for (const options of bad) {
|
||||
|
||||
for (const options of toobig) {
|
||||
const expected = {
|
||||
- message: /Invalid scrypt params:.*memory limit exceeded/,
|
||||
+ message: /Invalid scrypt params/,
|
||||
code: 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS',
|
||||
};
|
||||
assert.throws(() => crypto.scrypt('pass', 'salt', 1, options, () => {}),
|
||||
diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js
|
||||
index 56e5c16c2867f019caccf42f228193cae6167150..dc585c44db9894ae57a5e11d453af03e1ea4f211 100644
|
||||
--- a/test/parallel/test-crypto-sign-verify.js
|
||||
|
||||
@@ -48,10 +48,10 @@ index 67cd4f2adf15e7d8511f561c54163b1842e971af..7e0e1a62289289b8362870ba4869c974
|
||||
|
||||
const EVP_MD* digest = nullptr;
|
||||
diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc
|
||||
index ee1c7931a5c83eec00fe05807ddb97572fe70cc9..8e297e57fdbc9fd42beb6e4a33cc91b9dd7316b8 100644
|
||||
index 962018583360a137639682d4aec8b0ebad2f3070..f8ec40885905abbbe0da0f285ff9e83694c2b620 100644
|
||||
--- a/src/crypto/crypto_common.cc
|
||||
+++ b/src/crypto/crypto_common.cc
|
||||
@@ -158,7 +158,7 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
|
||||
@@ -166,7 +166,7 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
|
||||
const unsigned char* buf;
|
||||
size_t len;
|
||||
size_t rem;
|
||||
@@ -60,7 +60,7 @@ index ee1c7931a5c83eec00fe05807ddb97572fe70cc9..8e297e57fdbc9fd42beb6e4a33cc91b9
|
||||
if (!SSL_client_hello_get0_ext(
|
||||
ssl.get(),
|
||||
TLSEXT_TYPE_application_layer_protocol_negotiation,
|
||||
@@ -171,13 +171,15 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
|
||||
@@ -179,13 +179,15 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
|
||||
len = (buf[0] << 8) | buf[1];
|
||||
if (len + 2 != rem) return nullptr;
|
||||
return reinterpret_cast<const char*>(buf + 3);
|
||||
@@ -77,7 +77,7 @@ index ee1c7931a5c83eec00fe05807ddb97572fe70cc9..8e297e57fdbc9fd42beb6e4a33cc91b9
|
||||
if (!SSL_client_hello_get0_ext(
|
||||
ssl.get(),
|
||||
TLSEXT_TYPE_server_name,
|
||||
@@ -199,6 +201,8 @@ const char* GetClientHelloServerName(const SSLPointer& ssl) {
|
||||
@@ -207,6 +209,8 @@ const char* GetClientHelloServerName(const SSLPointer& ssl) {
|
||||
if (len + 2 > rem)
|
||||
return nullptr;
|
||||
return reinterpret_cast<const char*>(buf + 5);
|
||||
@@ -86,7 +86,7 @@ index ee1c7931a5c83eec00fe05807ddb97572fe70cc9..8e297e57fdbc9fd42beb6e4a33cc91b9
|
||||
}
|
||||
|
||||
const char* GetServerName(SSL* ssl) {
|
||||
@@ -206,7 +210,10 @@ const char* GetServerName(SSL* ssl) {
|
||||
@@ -214,7 +218,10 @@ const char* GetServerName(SSL* ssl) {
|
||||
}
|
||||
|
||||
bool SetGroups(SecureContext* sc, const char* groups) {
|
||||
@@ -116,8 +116,21 @@ index ee1c7931a5c83eec00fe05807ddb97572fe70cc9..8e297e57fdbc9fd42beb6e4a33cc91b9
|
||||
Local<Object> obj = Object::New(env->isolate());
|
||||
if (!Set(env->context(),
|
||||
obj,
|
||||
@@ -1104,8 +1111,11 @@ MaybeLocal<Object> GetEphemeralKey(Environment* env, const SSLPointer& ssl) {
|
||||
|
||||
EscapableHandleScope scope(env->isolate());
|
||||
Local<Object> info = Object::New(env->isolate());
|
||||
+#ifndef OPENSSL_IS_BORINGSSL
|
||||
if (!SSL_get_peer_tmp_key(ssl.get(), &raw_key)) return scope.Escape(info);
|
||||
-
|
||||
+#else
|
||||
+ if (!SSL_get_server_tmp_key(ssl.get(), &raw_key)) return scope.Escape(info);
|
||||
+#endif
|
||||
Local<Context> context = env->context();
|
||||
crypto::EVPKeyPointer key(raw_key);
|
||||
|
||||
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
||||
index 6e5bbe07d0c337b36f3157c2e6404fdc91849fd1..7ec682833213de9054a8c30751436d12baaea235 100644
|
||||
index e26e64834bee7fd9cd4e18bfe69a4f41d51fa8e9..a5b1ec5ea6284ab9892d5a2e576f369ae3bbac91 100644
|
||||
--- a/src/crypto/crypto_context.cc
|
||||
+++ b/src/crypto/crypto_context.cc
|
||||
@@ -63,7 +63,7 @@ inline X509_STORE* GetOrCreateRootCertStore() {
|
||||
@@ -253,7 +266,7 @@ index 3fa4a415dc911a13afd90dfb31c1ed4ad0fd268f..fa48dffc31342c44a1c1207b9d4c3dc7
|
||||
return EVPKeyCtxPointer();
|
||||
|
||||
diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc
|
||||
index c5dd2fb8fce40f2bf6f9a8543047ffb50cc08084..d850af9257cc194ee385130ce3cd2c0101b2455f 100644
|
||||
index a4979cf5586a7be6308a917eb020bedafa17f683..e4705482c6d45138deac84c59d8192bb2a284a76 100644
|
||||
--- a/src/crypto/crypto_keys.cc
|
||||
+++ b/src/crypto/crypto_keys.cc
|
||||
@@ -1241,6 +1241,7 @@ void KeyObjectHandle::GetAsymmetricKeyType(
|
||||
@@ -369,7 +382,7 @@ index 5734d8fdc5505e1586f571c19b840bd56e9c9f1f..3034b114e081e2b32dd5b71653927a41
|
||||
} // namespace
|
||||
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index 3b3724d6c7156b87555be31470e75b1cf28b5e3f..910c69b6d1d17ef25201dbb39d3d074f4f3f011f 100644
|
||||
index cd8db07919dc4d00675bbaae976e8fa1fcc16028..2310c89227f08cdcca6c4965cc163031af303626 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -49,7 +49,7 @@
|
||||
@@ -381,7 +394,7 @@ index 3b3724d6c7156b87555be31470e75b1cf28b5e3f..910c69b6d1d17ef25201dbb39d3d074f
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
|
||||
@@ -1036,7 +1036,7 @@ class Environment : public MemoryRetainer {
|
||||
@@ -1038,7 +1038,7 @@ class Environment : public MemoryRetainer {
|
||||
kExitInfoFieldCount
|
||||
};
|
||||
|
||||
@@ -391,7 +404,7 @@ index 3b3724d6c7156b87555be31470e75b1cf28b5e3f..910c69b6d1d17ef25201dbb39d3d074f
|
||||
// We declare another alias here to avoid having to include crypto_util.h
|
||||
using EVPMDPointer = DeleteFnPtr<EVP_MD, EVP_MD_free>;
|
||||
diff --git a/src/node_metadata.cc b/src/node_metadata.cc
|
||||
index 844c5ac2c2b948b3be35cb3e447717a510a463a6..72a75ee0bf391ea508441f49413f85c5b735b259 100644
|
||||
index 985d44b3cd1f1aa5c09f99e868083f2e48c7e32b..5856292b5450f697cdb57de30bafd3e907a7964d 100644
|
||||
--- a/src/node_metadata.cc
|
||||
+++ b/src/node_metadata.cc
|
||||
@@ -21,7 +21,7 @@
|
||||
@@ -400,7 +413,7 @@ index 844c5ac2c2b948b3be35cb3e447717a510a463a6..72a75ee0bf391ea508441f49413f85c5
|
||||
|
||||
-#if HAVE_OPENSSL
|
||||
+#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
#if NODE_OPENSSL_HAS_QUIC
|
||||
#include <openssl/quic.h>
|
||||
diff --git a/src/node_metadata.h b/src/node_metadata.h
|
||||
@@ -417,7 +430,7 @@ index cf051585e779e2b03bd7b95fe5008b89cc7f8162..9de49c6828468fdf846dcd4ad445390f
|
||||
#if NODE_OPENSSL_HAS_QUIC
|
||||
#include <openssl/quic.h>
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index 7110b4d984b72fa8c9bef2cbe6e37b1871e14d08..753311e15f161547be4277016efe11cc57d351db 100644
|
||||
index 1ba0bfcd9b3096c4bffe518ad08973edb895e8c3..28fbd93c5d4a6f379844e10e556920b7614910d8 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -6,7 +6,7 @@
|
||||
@@ -430,7 +443,7 @@ index 7110b4d984b72fa8c9bef2cbe6e37b1871e14d08..753311e15f161547be4277016efe11cc
|
||||
#endif
|
||||
|
||||
diff --git a/src/node_options.h b/src/node_options.h
|
||||
index 3c67c3680b045786dafb8435f5b311c3f386a943..546c3979e2c8d7498aa92df4c89ee867c6485080 100644
|
||||
index 1357e5b42869e8e3a30d2bf6db0faed565d99754..49c6d8b4162977a926e36bad7183a10502b2beaf 100644
|
||||
--- a/src/node_options.h
|
||||
+++ b/src/node_options.h
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
@@ -7,7 +7,7 @@ We use this to allow node's 'fs' module to read from ASAR files as if they were
|
||||
a real filesystem.
|
||||
|
||||
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
|
||||
index d42e766555a83ec7421b13c2bf75bfd28f086102..57125a271394dda0d3aa3a261ba087c978582c29 100644
|
||||
index 12262f40ce123440a9a0f974386cfbe8511f4459..f3c15b61d33bdae44de528e106fcc6f930f1c388 100644
|
||||
--- a/lib/internal/bootstrap/node.js
|
||||
+++ b/lib/internal/bootstrap/node.js
|
||||
@@ -134,6 +134,10 @@ process.domain = null;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 25 Jul 2024 12:19:41 +0200
|
||||
Subject: src: account for OpenSSL unexpected version
|
||||
|
||||
Fixes a crash that occurs because the logic to parse for an OpenSSL
|
||||
version didn't account for OpenSSL_version returning a value that
|
||||
doesn't match the expected pattern of OpenSSL 1.1.0i 14 Aug 2018.
|
||||
In Electron's case, OpenSSL_version returns just BoringSSL, which in
|
||||
combination with the search logic not accounting for the delimiter not
|
||||
being present caused an out-of-bounds crash:
|
||||
|
||||
out_of_range was thrown in -fno-exceptions mode with message "basic_string"
|
||||
|
||||
This fixes that by checking for the null terminator and returning 0.0.0
|
||||
when the target delimiter isn't present.
|
||||
|
||||
Upstreamed at https://github.com/nodejs/node/pull/54038
|
||||
|
||||
diff --git a/src/node_metadata.cc b/src/node_metadata.cc
|
||||
index 5856292b5450f697cdb57de30bafd3e907a7964d..6cb32b187151b0416fbe29cf4b61543e828cea20 100644
|
||||
--- a/src/node_metadata.cc
|
||||
+++ b/src/node_metadata.cc
|
||||
@@ -48,14 +48,19 @@ Metadata metadata;
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
static constexpr size_t search(const char* s, char c, size_t n = 0) {
|
||||
- return *s == c ? n : search(s + 1, c, n + 1);
|
||||
+ return *s == '\0' ? n : (*s == c ? n : search(s + 1, c, n + 1));
|
||||
}
|
||||
|
||||
static inline std::string GetOpenSSLVersion() {
|
||||
// sample openssl version string format
|
||||
// for reference: "OpenSSL 1.1.0i 14 Aug 2018"
|
||||
const char* version = OpenSSL_version(OPENSSL_VERSION);
|
||||
- const size_t start = search(version, ' ') + 1;
|
||||
+ const size_t first_space = search(version, ' ');
|
||||
+ if (version[first_space] == '\0') {
|
||||
+ return std::string("0.0.0");
|
||||
+ }
|
||||
+
|
||||
+ const size_t start = first_space + 1;
|
||||
const size_t len = search(&version[start], ' ');
|
||||
return std::string(version, start, len);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ Instead of disabling the tests, flag them as flaky so they still run
|
||||
but don't cause CI failures on flakes.
|
||||
|
||||
diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
|
||||
index 8840bd004ba87aa4a310b381310bb9612b96d861..892980bb90e433b16756f33c554b299ecc185eb4 100644
|
||||
index c2b988f9b2f76940c1c6b05af13898ba2062ba72..d45260cee87349cc8642d814dd11b904bdcf3762 100644
|
||||
--- a/test/parallel/parallel.status
|
||||
+++ b/test/parallel/parallel.status
|
||||
@@ -5,6 +5,16 @@ prefix parallel
|
||||
@@ -24,9 +24,9 @@ index 8840bd004ba87aa4a310b381310bb9612b96d861..892980bb90e433b16756f33c554b299e
|
||||
+test-cluster-bind-privileged-port: PASS, FLAKY
|
||||
+test-cluster-shared-handle-bind-privileged-port: PASS, FLAKY
|
||||
+test-debugger-random-port-with-inspect-port: PASS, FLAKY
|
||||
|
||||
# https://github.com/nodejs/node/issues/51862
|
||||
test-fs-read-stream-concurrent-reads: PASS, FLAKY
|
||||
# https://github.com/nodejs/node/issues/52273
|
||||
test-net-write-fully-async-hex-string: PASS, FLAKY
|
||||
# https://github.com/nodejs/node/issues/52273
|
||||
diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status
|
||||
index ccab879b6e5fcdcc0d3a4b790b97db94d92f1a59..11339325697ae98f6996101163679590451c0b81 100644
|
||||
--- a/test/sequential/sequential.status
|
||||
|
||||
@@ -7,7 +7,7 @@ Subject: test: match wpt/streams/transferable/transform-stream-members.any.js
|
||||
All four of this calls should fail - see third_party/blink/web_tests/external/wpt/streams/transferable/transform-stream-members.any-expected.txt
|
||||
|
||||
diff --git a/test/wpt/status/streams.json b/test/wpt/status/streams.json
|
||||
index 8d6a4c6d2fe27b349ca8a4cbcdc51c3eec06ede9..1e7af48a149ba2c8bed01cd6584e59dc0bc6b676 100644
|
||||
index 3b6e0ce6429f9dddb0b1a6882ce9e3a5158300e5..7ec49a378bfc84728b473d5df69675fff1dfdfef 100644
|
||||
--- a/test/wpt/status/streams.json
|
||||
+++ b/test/wpt/status/streams.json
|
||||
@@ -50,7 +50,9 @@
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Keeley Hammond <khammond@slack-corp.com>
|
||||
Date: Thu, 25 Jul 2024 15:26:37 -0700
|
||||
Subject: windows 32bit: config change callback needs to be stdcall
|
||||
|
||||
Patch of upstream fix: https://github.com/c-ares/c-ares/commit/8f265c9d5109e5665136396d347c0a93ea78999e
|
||||
|
||||
diff --git a/deps/cares/src/lib/ares_event_configchg.c b/deps/cares/src/lib/ares_event_configchg.c
|
||||
index b7c5ad8c75b6218cf36283fb6d0f8cd702224b87..c9b39f7b3358f37e61fb95e440695a9b590c2090 100644
|
||||
--- a/deps/cares/src/lib/ares_event_configchg.c
|
||||
+++ b/deps/cares/src/lib/ares_event_configchg.c
|
||||
@@ -239,9 +239,10 @@ void ares_event_configchg_destroy(ares_event_configchg_t *configchg)
|
||||
|
||||
|
||||
# ifndef __WATCOMC__
|
||||
-static void ares_event_configchg_ip_cb(PVOID CallerContext,
|
||||
- PMIB_IPINTERFACE_ROW Row,
|
||||
- MIB_NOTIFICATION_TYPE NotificationType)
|
||||
+static void NETIOAPI_API_
|
||||
+ ares_event_configchg_ip_cb(PVOID CallerContext,
|
||||
+ PMIB_IPINTERFACE_ROW Row,
|
||||
+ MIB_NOTIFICATION_TYPE NotificationType)
|
||||
{
|
||||
ares_event_configchg_t *configchg = CallerContext;
|
||||
(void)Row;
|
||||
@@ -308,7 +309,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
|
||||
* that didn't get triggered either.
|
||||
*/
|
||||
if (NotifyIpInterfaceChange(
|
||||
- AF_UNSPEC, (PIPINTERFACE_CHANGE_CALLBACK)ares_event_configchg_ip_cb,
|
||||
+ AF_UNSPEC, ares_event_configchg_ip_cb,
|
||||
*configchg, FALSE, &c->ifchg_hnd) != NO_ERROR) {
|
||||
status = ARES_ESERVFAIL;
|
||||
goto done;
|
||||
@@ -3,3 +3,9 @@ deps_add_v8_object_setinternalfieldfornodecore.patch
|
||||
cherry-pick-8b400f9b7d66.patch
|
||||
cherry-pick-ba6cab40612d.patch
|
||||
merged_wasm_add_missing_type_canonicalization_for_exceptions_js.patch
|
||||
cherry-pick-cdbc1d9684a3.patch
|
||||
cherry-pick-70d2fe6b7c47.patch
|
||||
cherry-pick-901377bb2f3b.patch
|
||||
cherry-pick-bb28367eed73.patch
|
||||
cherry-pick-bc545b15a0ee.patch
|
||||
spill_all_loop_inputs_before_entering_loop.patch
|
||||
|
||||
32
patches/v8/cherry-pick-70d2fe6b7c47.patch
Normal file
32
patches/v8/cherry-pick-70d2fe6b7c47.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Leszek Swirski <leszeks@chromium.org>
|
||||
Date: Fri, 21 Jun 2024 15:11:40 +0200
|
||||
Subject: Allow reduced hasInstance to abort
|
||||
|
||||
Fixed: 343507800
|
||||
Change-Id: I579041fe82e975d83a72e4744013cb04c4d3dc70
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5644891
|
||||
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
|
||||
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#94585}
|
||||
|
||||
diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
|
||||
index efcdd6d2028a5e0f0ec1149925ab2e1fe5f90412..78f4dd57d339eaad8b265721ef37137291da7940 100644
|
||||
--- a/src/maglev/maglev-graph-builder.cc
|
||||
+++ b/src/maglev/maglev-graph-builder.cc
|
||||
@@ -8639,10 +8639,9 @@ ReduceResult MaglevGraphBuilder::TryBuildFastInstanceOf(
|
||||
|
||||
if (has_instance_field->IsJSFunction()) {
|
||||
SaveCallSpeculationScope saved(this);
|
||||
- ReduceResult result =
|
||||
- ReduceCallForConstant(has_instance_field->AsJSFunction(), args);
|
||||
- DCHECK(!result.IsDoneWithAbort());
|
||||
- call_result = result.value();
|
||||
+ GET_VALUE_OR_ABORT(
|
||||
+ call_result,
|
||||
+ ReduceCallForConstant(has_instance_field->AsJSFunction(), args));
|
||||
} else {
|
||||
call_result = BuildGenericCall(GetConstant(*has_instance_field),
|
||||
Call::TargetType::kAny, args);
|
||||
221
patches/v8/cherry-pick-901377bb2f3b.patch
Normal file
221
patches/v8/cherry-pick-901377bb2f3b.patch
Normal file
@@ -0,0 +1,221 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Thibaud Michaud <thibaudm@chromium.org>
|
||||
Date: Fri, 21 Jun 2024 16:31:15 +0200
|
||||
Subject: Fix scanning of wasm-to-js params
|
||||
|
||||
Wasm-to-js wrappers are sometimes compiled as on-heap Code objects, for
|
||||
example when tiering-up from a WasmFuncRef call origin. The frames of
|
||||
these functions are mapped to a subclass of TypedFrame, however
|
||||
TypedFrame::Iterate() only supports iterating the generic wasm-to-js
|
||||
wrapper.
|
||||
|
||||
Add support for iterating the tagged parameters of optimized wasm-to-js
|
||||
wrappers in TypedFrame::Iterate. For this we also add two 16-bit fields
|
||||
in the Code object to encode the incoming tagged parameter region, which
|
||||
we would normally find in the WasmCode data.
|
||||
|
||||
R=jkummerow@chromium.org
|
||||
|
||||
Fixed: 346597059
|
||||
Change-Id: I425619fca86c38f91f1ca9cbeb70e7b5a7b2d6c1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5639725
|
||||
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#94589}
|
||||
|
||||
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
|
||||
index 0181588337df73bfa97220d895733c40b92bd40b..033469e626ffb35846ae5114632f3dc000400935 100644
|
||||
--- a/src/compiler/pipeline.cc
|
||||
+++ b/src/compiler/pipeline.cc
|
||||
@@ -2295,6 +2295,14 @@ CompilationJob::Status FinalizeWrapperCompilation(
|
||||
Handle<AbstractCode>::cast(code),
|
||||
info->GetDebugName().get()));
|
||||
}
|
||||
+ // Set the wasm-to-js specific code fields needed to scan the incoming stack
|
||||
+ // parameters.
|
||||
+ if (code->kind() == CodeKind::WASM_TO_JS_FUNCTION) {
|
||||
+ code->set_wasm_js_tagged_parameter_count(
|
||||
+ call_descriptor->GetTaggedParameterSlots() & 0xffff);
|
||||
+ code->set_wasm_js_first_tagged_parameter(
|
||||
+ call_descriptor->GetTaggedParameterSlots() >> 16);
|
||||
+ }
|
||||
return CompilationJob::SUCCEEDED;
|
||||
}
|
||||
return CompilationJob::FAILED;
|
||||
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
|
||||
index 7677022ce31c1b8ead0cc2eb37fb505b750639be..12bd5b8fd27f67c73938550acc4af1857eace59a 100644
|
||||
--- a/src/diagnostics/objects-printer.cc
|
||||
+++ b/src/diagnostics/objects-printer.cc
|
||||
@@ -2102,7 +2102,14 @@ void Code::CodePrint(std::ostream& os, const char* name, Address current_pc) {
|
||||
os << "\n - instruction_size: " << instruction_size();
|
||||
os << "\n - metadata_size: " << metadata_size();
|
||||
|
||||
- os << "\n - inlined_bytecode_size: " << inlined_bytecode_size();
|
||||
+ if (kind() != CodeKind::WASM_TO_JS_FUNCTION) {
|
||||
+ os << "\n - inlined_bytecode_size: " << inlined_bytecode_size();
|
||||
+ } else {
|
||||
+ os << "\n - wasm_js_tagged_parameter_count: "
|
||||
+ << wasm_js_tagged_parameter_count();
|
||||
+ os << "\n - wasm_js_first_tagged_parameter: "
|
||||
+ << wasm_js_first_tagged_parameter();
|
||||
+ }
|
||||
os << "\n - osr_offset: " << osr_offset();
|
||||
os << "\n - handler_table_offset: " << handler_table_offset();
|
||||
os << "\n - unwinding_info_offset: " << unwinding_info_offset();
|
||||
diff --git a/src/execution/frames.cc b/src/execution/frames.cc
|
||||
index 92dff2f7e8c8f72e38eef4feb5b10ace9fe2535c..2693fb2a859dc7489ef802c3064beace88608415 100644
|
||||
--- a/src/execution/frames.cc
|
||||
+++ b/src/execution/frames.cc
|
||||
@@ -1562,7 +1562,7 @@ void WasmFrame::Iterate(RootVisitor* v) const {
|
||||
frame_header_limit);
|
||||
}
|
||||
|
||||
-void TypedFrame::IterateParamsOfWasmToJSWrapper(RootVisitor* v) const {
|
||||
+void TypedFrame::IterateParamsOfGenericWasmToJSWrapper(RootVisitor* v) const {
|
||||
Tagged<Object> maybe_signature = Tagged<Object>(
|
||||
Memory<Address>(fp() + WasmToJSWrapperConstants::kSignatureOffset));
|
||||
if (IsSmi(maybe_signature)) {
|
||||
@@ -1678,6 +1678,18 @@ void TypedFrame::IterateParamsOfWasmToJSWrapper(RootVisitor* v) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+void TypedFrame::IterateParamsOfOptimizedWasmToJSWrapper(RootVisitor* v) const {
|
||||
+ Tagged<GcSafeCode> code = GcSafeLookupCode();
|
||||
+ if (code->wasm_js_tagged_parameter_count() > 0) {
|
||||
+ FullObjectSlot tagged_parameter_base(&Memory<Address>(caller_sp()));
|
||||
+ tagged_parameter_base += code->wasm_js_first_tagged_parameter();
|
||||
+ FullObjectSlot tagged_parameter_limit =
|
||||
+ tagged_parameter_base + code->wasm_js_tagged_parameter_count();
|
||||
+ v->VisitRootPointers(Root::kStackRoots, nullptr, tagged_parameter_base,
|
||||
+ tagged_parameter_limit);
|
||||
+ }
|
||||
+}
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
void TypedFrame::Iterate(RootVisitor* v) const {
|
||||
@@ -1709,10 +1721,13 @@ void TypedFrame::Iterate(RootVisitor* v) const {
|
||||
CHECK(entry->code.has_value());
|
||||
Tagged<GcSafeCode> code = entry->code.value();
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
- bool is_wasm_to_js =
|
||||
+ bool is_generic_wasm_to_js =
|
||||
code->is_builtin() && code->builtin_id() == Builtin::kWasmToJsWrapperCSA;
|
||||
- if (is_wasm_to_js) {
|
||||
- IterateParamsOfWasmToJSWrapper(v);
|
||||
+ bool is_optimized_wasm_to_js = this->type() == WASM_TO_JS_FUNCTION;
|
||||
+ if (is_generic_wasm_to_js) {
|
||||
+ IterateParamsOfGenericWasmToJSWrapper(v);
|
||||
+ } else if (is_optimized_wasm_to_js) {
|
||||
+ IterateParamsOfOptimizedWasmToJSWrapper(v);
|
||||
}
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
DCHECK(code->is_turbofanned());
|
||||
@@ -1745,10 +1760,14 @@ void TypedFrame::Iterate(RootVisitor* v) const {
|
||||
// wrapper switched to before pushing the outgoing stack parameters and
|
||||
// calling the target. It marks the limit of the stack param area, and is
|
||||
// distinct from the beginning of the spill area.
|
||||
- Address central_stack_sp =
|
||||
- Memory<Address>(fp() + WasmToJSWrapperConstants::kCentralStackSPOffset);
|
||||
+ int central_stack_sp_offset =
|
||||
+ is_generic_wasm_to_js
|
||||
+ ? WasmToJSWrapperConstants::kCentralStackSPOffset
|
||||
+ : WasmImportWrapperFrameConstants::kCentralStackSPOffset;
|
||||
+ Address central_stack_sp = Memory<Address>(fp() + central_stack_sp_offset);
|
||||
FullObjectSlot parameters_limit(
|
||||
- is_wasm_to_js && central_stack_sp != kNullAddress
|
||||
+ (is_generic_wasm_to_js || is_optimized_wasm_to_js) &&
|
||||
+ central_stack_sp != kNullAddress
|
||||
? central_stack_sp
|
||||
: frame_header_base.address() - spill_slots_size);
|
||||
#else
|
||||
diff --git a/src/execution/frames.h b/src/execution/frames.h
|
||||
index 081c74bf124ccfa57e4b40f75cbe42b00c771b2e..908239b4161235aeda04fe5526ddea8d56b09425 100644
|
||||
--- a/src/execution/frames.h
|
||||
+++ b/src/execution/frames.h
|
||||
@@ -634,7 +634,8 @@ class TypedFrame : public CommonFrame {
|
||||
Tagged<HeapObject> unchecked_code() const override { return {}; }
|
||||
void Iterate(RootVisitor* v) const override;
|
||||
|
||||
- void IterateParamsOfWasmToJSWrapper(RootVisitor* v) const;
|
||||
+ void IterateParamsOfGenericWasmToJSWrapper(RootVisitor* v) const;
|
||||
+ void IterateParamsOfOptimizedWasmToJSWrapper(RootVisitor* v) const;
|
||||
|
||||
protected:
|
||||
inline explicit TypedFrame(StackFrameIteratorBase* iterator);
|
||||
diff --git a/src/objects/code-inl.h b/src/objects/code-inl.h
|
||||
index baaced29afdbc87eae1c34b8df779e17e41410c4..1e1d66a87ee633cbdb49265444f53b5db790d9dd 100644
|
||||
--- a/src/objects/code-inl.h
|
||||
+++ b/src/objects/code-inl.h
|
||||
@@ -48,6 +48,8 @@ GCSAFE_CODE_FWD_ACCESSOR(bool, has_tagged_outgoing_params)
|
||||
GCSAFE_CODE_FWD_ACCESSOR(bool, marked_for_deoptimization)
|
||||
GCSAFE_CODE_FWD_ACCESSOR(Tagged<Object>, raw_instruction_stream)
|
||||
GCSAFE_CODE_FWD_ACCESSOR(int, stack_slots)
|
||||
+GCSAFE_CODE_FWD_ACCESSOR(uint16_t, wasm_js_tagged_parameter_count)
|
||||
+GCSAFE_CODE_FWD_ACCESSOR(uint16_t, wasm_js_first_tagged_parameter)
|
||||
GCSAFE_CODE_FWD_ACCESSOR(Address, constant_pool)
|
||||
GCSAFE_CODE_FWD_ACCESSOR(Address, safepoint_table_address)
|
||||
#undef GCSAFE_CODE_FWD_ACCESSOR
|
||||
@@ -428,6 +430,31 @@ void Code::set_inlined_bytecode_size(unsigned size) {
|
||||
RELAXED_WRITE_UINT_FIELD(*this, kInlinedBytecodeSizeOffset, size);
|
||||
}
|
||||
|
||||
+// For optimized on-heap wasm-js wrappers, we repurpose the (otherwise unused)
|
||||
+// 32-bit InlinedBytecodeSize field to encode two 16 values needed for scanning
|
||||
+// the frame: the count and starting offset of incoming tagged parameters.
|
||||
+// TODO(wasm): Eventually the wrappers should be managed off-heap by the wasm
|
||||
+// engine. Remove these accessors when that is the case.
|
||||
+void Code::set_wasm_js_tagged_parameter_count(uint16_t count) {
|
||||
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
|
||||
+ RELAXED_WRITE_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset, count);
|
||||
+}
|
||||
+
|
||||
+uint16_t Code::wasm_js_tagged_parameter_count() const {
|
||||
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
|
||||
+ return RELAXED_READ_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset);
|
||||
+}
|
||||
+
|
||||
+void Code::set_wasm_js_first_tagged_parameter(uint16_t count) {
|
||||
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
|
||||
+ RELAXED_WRITE_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset + 2, count);
|
||||
+}
|
||||
+
|
||||
+uint16_t Code::wasm_js_first_tagged_parameter() const {
|
||||
+ DCHECK_EQ(kind(), CodeKind::WASM_TO_JS_FUNCTION);
|
||||
+ return RELAXED_READ_UINT16_FIELD(*this, kInlinedBytecodeSizeOffset + 2);
|
||||
+}
|
||||
+
|
||||
BytecodeOffset Code::osr_offset() const {
|
||||
return BytecodeOffset(RELAXED_READ_INT32_FIELD(*this, kOsrOffsetOffset));
|
||||
}
|
||||
diff --git a/src/objects/code.h b/src/objects/code.h
|
||||
index 9a079a94ba0126b24532362a0ce233477f42c221..1da011899807125d6dc9ffb6d56622f5f15ad465 100644
|
||||
--- a/src/objects/code.h
|
||||
+++ b/src/objects/code.h
|
||||
@@ -124,6 +124,15 @@ class Code : public ExposedTrustedObject {
|
||||
// [deoptimization_data]: Array containing data for deopt for non-baseline
|
||||
// code.
|
||||
DECL_ACCESSORS(deoptimization_data, Tagged<TrustedFixedArray>)
|
||||
+ // [parameter_count]: The number of formal parameters, including the
|
||||
+ // receiver. Currently only available for optimized functions.
|
||||
+ // TODO(saelo): make this always available. This is just a matter of figuring
|
||||
+ // out how to obtain the parameter count during code generation when no
|
||||
+ // BytecodeArray is available from which it can be copied.
|
||||
+ DECL_PRIMITIVE_ACCESSORS(parameter_count, uint16_t)
|
||||
+ inline uint16_t parameter_count_without_receiver() const;
|
||||
+ DECL_PRIMITIVE_ACCESSORS(wasm_js_tagged_parameter_count, uint16_t)
|
||||
+ DECL_PRIMITIVE_ACCESSORS(wasm_js_first_tagged_parameter, uint16_t)
|
||||
|
||||
// Whether this type of Code uses deoptimization data, in which case the
|
||||
// deoptimization_data field will be populated.
|
||||
@@ -503,6 +512,10 @@ class GcSafeCode : public HeapObject {
|
||||
inline bool CanDeoptAt(Isolate* isolate, Address pc) const;
|
||||
inline Tagged<Object> raw_instruction_stream(
|
||||
PtrComprCageBase code_cage_base) const;
|
||||
+ // The two following accessors repurpose the InlinedBytecodeSize field, see
|
||||
+ // comment in code-inl.h.
|
||||
+ inline uint16_t wasm_js_tagged_parameter_count() const;
|
||||
+ inline uint16_t wasm_js_first_tagged_parameter() const;
|
||||
|
||||
private:
|
||||
OBJECT_CONSTRUCTORS(GcSafeCode, HeapObject);
|
||||
64
patches/v8/cherry-pick-bb28367eed73.patch
Normal file
64
patches/v8/cherry-pick-bb28367eed73.patch
Normal file
@@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Olivier=20Fl=C3=BCckiger?= <olivf@chromium.org>
|
||||
Date: Mon, 24 Jun 2024 16:22:09 +0200
|
||||
Subject: Fix skipped smi check due to phi hoisting
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Given we have a phi (29) assumed to be smi at graph building time, we
|
||||
must not untag it's input phis (10,12) to float64.
|
||||
|
||||
╭─────►Block b2
|
||||
│ 10: φᵀ r0 (n4, n29) (compressed) → (x), 3 uses
|
||||
│ 12: φᵀ r2 (n6, n39) (compressed) → (x), 6 uses
|
||||
...
|
||||
│ 13: CheckedSmiUntag [n10:(x)] → (x), 2 uses
|
||||
│ 14: CheckedSmiUntag [n12:(x)] → (x), 1 uses
|
||||
...
|
||||
│╭──────17: BranchIfToBooleanTrue [n16:(x)] b3 b9
|
||||
...
|
||||
││ │ 29: φᵀ <accumulator> (n10, n12) (compressed) → (x), 4 uses
|
||||
...
|
||||
││ │ 33: UnsafeSmiUntag [n29:(x)] → (x), 1 uses
|
||||
|
||||
Doing so could invalidate the `UnsafeSmiUntag` instruction.
|
||||
|
||||
This can only happen when hoisting the untagging out of the loop, as
|
||||
this will remove the original `CheckedSmiUntag` instruction.
|
||||
|
||||
Fixed: 348567825
|
||||
Change-Id: I2d7f2c3b544f991be9850d44bf11c3f632a0bb46
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5645901
|
||||
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
|
||||
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
|
||||
Auto-Submit: Olivier Flückiger <olivf@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#94615}
|
||||
|
||||
diff --git a/src/maglev/maglev-phi-representation-selector.cc b/src/maglev/maglev-phi-representation-selector.cc
|
||||
index 02e030bcb543287433c944e5f298998cdc5b7ce9..cabe3a29383b111fc0f1568a40d439e1513bc154 100644
|
||||
--- a/src/maglev/maglev-phi-representation-selector.cc
|
||||
+++ b/src/maglev/maglev-phi-representation-selector.cc
|
||||
@@ -285,6 +285,14 @@ MaglevPhiRepresentationSelector::ProcessPhi(Phi* node) {
|
||||
ValueRepresentation::kHoleyFloat64};
|
||||
}
|
||||
|
||||
+ // When hoisting we must ensure that we don't turn a tagged flowing into
|
||||
+ // CheckedSmiUntag into a float64. This would cause us to loose the smi check
|
||||
+ // which in turn can invalidate assumptions on aliasing values.
|
||||
+ if (hoist_untagging.size() && node->uses_require_31_bit_value()) {
|
||||
+ allowed_inputs_for_uses.Remove(
|
||||
+ {ValueRepresentation::kFloat64, ValueRepresentation::kHoleyFloat64});
|
||||
+ }
|
||||
+
|
||||
auto intersection = possible_inputs & allowed_inputs_for_uses;
|
||||
|
||||
TRACE_UNTAGGING(" + intersection reprs: " << intersection);
|
||||
@@ -615,6 +623,7 @@ void MaglevPhiRepresentationSelector::ConvertTaggedPhiTo(
|
||||
TaggedToFloat64ConversionType::kOnlyNumber),
|
||||
block, NewNodePosition::kEnd);
|
||||
} else {
|
||||
+ DCHECK(!phi->uses_require_31_bit_value());
|
||||
untagged = AddNode(NodeBase::New<CheckedNumberOrOddballToFloat64>(
|
||||
builder_->zone(), {input},
|
||||
TaggedToFloat64ConversionType::kOnlyNumber),
|
||||
39
patches/v8/cherry-pick-bc545b15a0ee.patch
Normal file
39
patches/v8/cherry-pick-bc545b15a0ee.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Date: Thu, 11 Jul 2024 16:34:00 +0200
|
||||
Subject: Fix cast of memory index
|
||||
|
||||
"uint8_t" must have been a typo.
|
||||
|
||||
Fixed: 351327767
|
||||
Bug: 42203854
|
||||
Change-Id: I196c961ec2f2ed16acfe16bf304d7eae6551aacc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5695665
|
||||
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
|
||||
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
|
||||
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#94981}
|
||||
|
||||
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
|
||||
index 16f1f1470b782ce3584ba4bb6626501c9f9551b7..02364fdf5d3d17fa0f03fd48d21523a4bae3f21e 100644
|
||||
--- a/src/compiler/wasm-compiler.cc
|
||||
+++ b/src/compiler/wasm-compiler.cc
|
||||
@@ -3395,7 +3395,7 @@ Node* WasmGraphBuilder::MemStart(uint32_t mem_index) {
|
||||
DCHECK_NOT_NULL(instance_cache_);
|
||||
V8_ASSUME(cached_memory_index_ == kNoCachedMemoryIndex ||
|
||||
cached_memory_index_ >= 0);
|
||||
- if (mem_index == static_cast<uint8_t>(cached_memory_index_)) {
|
||||
+ if (mem_index == static_cast<uint32_t>(cached_memory_index_)) {
|
||||
return instance_cache_->mem_start;
|
||||
}
|
||||
return LoadMemStart(mem_index);
|
||||
@@ -3405,7 +3405,7 @@ Node* WasmGraphBuilder::MemSize(uint32_t mem_index) {
|
||||
DCHECK_NOT_NULL(instance_cache_);
|
||||
V8_ASSUME(cached_memory_index_ == kNoCachedMemoryIndex ||
|
||||
cached_memory_index_ >= 0);
|
||||
- if (mem_index == static_cast<uint8_t>(cached_memory_index_)) {
|
||||
+ if (mem_index == static_cast<uint32_t>(cached_memory_index_)) {
|
||||
return instance_cache_->mem_size;
|
||||
}
|
||||
|
||||
112
patches/v8/cherry-pick-cdbc1d9684a3.patch
Normal file
112
patches/v8/cherry-pick-cdbc1d9684a3.patch
Normal file
@@ -0,0 +1,112 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darius Mercadier <dmercadier@chromium.org>
|
||||
Date: Tue, 18 Jun 2024 16:10:26 +0200
|
||||
Subject: Lower LoadStackArgument to a Tagged load
|
||||
|
||||
If we start with a graph that looks like
|
||||
|
||||
```
|
||||
x = LoadStackArgument(a, 40)
|
||||
...
|
||||
Allocate()
|
||||
...
|
||||
y = LoadStackArgument(a, 40)
|
||||
```
|
||||
|
||||
This used to be lowered to
|
||||
|
||||
```
|
||||
x1 = Load<WordPtr>(a, 40)
|
||||
x2 = TaggedBitcast(x1, WordPtr->Tagged)
|
||||
...
|
||||
Allocate()
|
||||
...
|
||||
y1 = Load<WordPtr>(a, 40)
|
||||
y2 = TaggedBitcast(y1, WordPtr->Tagged)
|
||||
```
|
||||
|
||||
And then, Load Elimination would remove the second Load, and we'd get:
|
||||
|
||||
```
|
||||
x1 = Load<WordPtr>(a, 40)
|
||||
x2 = TaggedBitcast(x1, WordPtr->Tagged)
|
||||
...
|
||||
Allocate()
|
||||
...
|
||||
y2 = TaggedBitcast(x1, WordPtr->Tagged)
|
||||
```
|
||||
|
||||
And now we would be in trouble: if the allocation in the middle
|
||||
triggers a GC, then `x1` could move, and thus `y2` could refer to a
|
||||
stale pointer. In theory, Turbofan knows where tagged values are, and
|
||||
can thus update them when the GC moves things, but here, `x1` is not
|
||||
marked as Tagged (but rather as a raw WordPtr).
|
||||
|
||||
This CL fixes this issue by doing a Tagged load from the start, since
|
||||
the value we're loading is clearly tagged.
|
||||
|
||||
Fixed: chromium:347724915
|
||||
Change-Id: Ia659155fbc602907ab9a50fb992c79df6ccdaa44
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5630530
|
||||
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
|
||||
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#94527}
|
||||
|
||||
diff --git a/src/compiler/turboshaft/machine-lowering-reducer-inl.h b/src/compiler/turboshaft/machine-lowering-reducer-inl.h
|
||||
index 8f37ef00f7edc1395586439fad4c39f426520d87..1f8ecb428f7d53d20369b82d958b2309ab09d2eb 100644
|
||||
--- a/src/compiler/turboshaft/machine-lowering-reducer-inl.h
|
||||
+++ b/src/compiler/turboshaft/machine-lowering-reducer-inl.h
|
||||
@@ -2372,9 +2372,17 @@ class MachineLoweringReducer : public Next {
|
||||
}
|
||||
|
||||
V<Object> REDUCE(LoadStackArgument)(V<WordPtr> base, V<WordPtr> index) {
|
||||
- V<WordPtr> argument = __ template LoadNonArrayBufferElement<WordPtr>(
|
||||
- base, AccessBuilder::ForStackArgument(), index);
|
||||
- return __ BitcastWordPtrToTagged(argument);
|
||||
+ // Note that this is a load of a Tagged value
|
||||
+ // (MemoryRepresentation::TaggedPointer()), but since it's on the stack
|
||||
+ // where stack slots are all kSystemPointerSize, we use kSystemPointerSize
|
||||
+ // for element_size_log2. On 64-bit plateforms with pointer compression,
|
||||
+ // this means that we're kinda loading a 32-bit value from an array of
|
||||
+ // 64-bit values.
|
||||
+ return __ Load(
|
||||
+ base, index, LoadOp::Kind::RawAligned(),
|
||||
+ MemoryRepresentation::TaggedPointer(),
|
||||
+ CommonFrameConstants::kFixedFrameSizeAboveFp - kSystemPointerSize,
|
||||
+ kSystemPointerSizeLog2);
|
||||
}
|
||||
|
||||
OpIndex REDUCE(StoreTypedElement)(OpIndex buffer, V<Object> base,
|
||||
diff --git a/test/mjsunit/compiler/regress-347724915.js b/test/mjsunit/compiler/regress-347724915.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4a5d1a9a2e3dd7674bf0872c94a971b5f28ddf72
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/compiler/regress-347724915.js
|
||||
@@ -0,0 +1,26 @@
|
||||
+// Copyright 2024 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
|
||||
+
|
||||
+function f(...args) {
|
||||
+ let arr1 = [ undefined, undefined, undefined ];
|
||||
+ %SimulateNewspaceFull();
|
||||
+ arr1[0] = args[0];
|
||||
+ // The following allocation will trigger a full GC, which will move the
|
||||
+ // argument passed to the function (because it was a young object).
|
||||
+ let arr2 = [ arr1 ];
|
||||
+ // Here we're accessing `args[0]` again. This might be load-eliminated with
|
||||
+ // the `args[0]` load from a few lines above, which has been moved by the GC
|
||||
+ // since then. This should be fine though, as the loaded value should be
|
||||
+ // marked as Tagged, which means that it shouldn't point to the stale value
|
||||
+ // but instead have been updated during GC.
|
||||
+ arr1[1] = args[0]
|
||||
+ return arr2;
|
||||
+}
|
||||
+
|
||||
+%PrepareFunctionForOptimization(f);
|
||||
+let expected = f({ x : 42 });
|
||||
+%OptimizeFunctionOnNextCall(f);
|
||||
+assertEquals(expected, f({x : 42}));
|
||||
104
patches/v8/spill_all_loop_inputs_before_entering_loop.patch
Normal file
104
patches/v8/spill_all_loop_inputs_before_entering_loop.patch
Normal file
@@ -0,0 +1,104 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Backes <clemensb@chromium.org>
|
||||
Date: Tue, 20 Aug 2024 12:25:40 +0200
|
||||
Subject: Spill all loop inputs before entering loop
|
||||
|
||||
This avoids having to load the value back into a register if it was
|
||||
spilled inside of the loop.
|
||||
|
||||
R=jkummerow@chromium.org
|
||||
|
||||
Fixed: chromium:360700873
|
||||
Change-Id: I24f5deacebc893293e8a3c007e9f070c7fa0ccd2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5797073
|
||||
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Commit-Queue: Clemens Backes <clemensb@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#95711}
|
||||
|
||||
diff --git a/src/wasm/baseline/liftoff-assembler.cc b/src/wasm/baseline/liftoff-assembler.cc
|
||||
index e1ca7bebdc8408e21715dd0fc9861a474b989bcc..adaa8f9586b76bdb6902dce7ecc64b32dc3f5253 100644
|
||||
--- a/src/wasm/baseline/liftoff-assembler.cc
|
||||
+++ b/src/wasm/baseline/liftoff-assembler.cc
|
||||
@@ -441,29 +441,10 @@ void LiftoffAssembler::DropExceptionValueAtOffset(int offset) {
|
||||
cache_state_.stack_state.pop_back();
|
||||
}
|
||||
|
||||
-void LiftoffAssembler::PrepareLoopArgs(int num) {
|
||||
- for (int i = 0; i < num; ++i) {
|
||||
- VarState& slot = cache_state_.stack_state.end()[-1 - i];
|
||||
- if (slot.is_stack()) continue;
|
||||
- RegClass rc = reg_class_for(slot.kind());
|
||||
- if (slot.is_reg()) {
|
||||
- if (cache_state_.get_use_count(slot.reg()) > 1) {
|
||||
- // If the register is used more than once, we cannot use it for the
|
||||
- // merge. Move it to an unused register instead.
|
||||
- LiftoffRegList pinned;
|
||||
- pinned.set(slot.reg());
|
||||
- LiftoffRegister dst_reg = GetUnusedRegister(rc, pinned);
|
||||
- Move(dst_reg, slot.reg(), slot.kind());
|
||||
- cache_state_.dec_used(slot.reg());
|
||||
- cache_state_.inc_used(dst_reg);
|
||||
- slot.MakeRegister(dst_reg);
|
||||
- }
|
||||
- continue;
|
||||
- }
|
||||
- LiftoffRegister reg = GetUnusedRegister(rc, {});
|
||||
- LoadConstant(reg, slot.constant());
|
||||
- slot.MakeRegister(reg);
|
||||
- cache_state_.inc_used(reg);
|
||||
+void LiftoffAssembler::SpillLoopArgs(int num) {
|
||||
+ for (VarState& slot :
|
||||
+ base::VectorOf(cache_state_.stack_state.end() - num, num)) {
|
||||
+ Spill(&slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,14 +665,14 @@ void LiftoffAssembler::Spill(VarState* slot) {
|
||||
}
|
||||
|
||||
void LiftoffAssembler::SpillLocals() {
|
||||
- for (uint32_t i = 0; i < num_locals_; ++i) {
|
||||
- Spill(&cache_state_.stack_state[i]);
|
||||
+ for (VarState& local_slot :
|
||||
+ base::VectorOf(cache_state_.stack_state.data(), num_locals_)) {
|
||||
+ Spill(&local_slot);
|
||||
}
|
||||
}
|
||||
|
||||
void LiftoffAssembler::SpillAllRegisters() {
|
||||
- for (uint32_t i = 0, e = cache_state_.stack_height(); i < e; ++i) {
|
||||
- auto& slot = cache_state_.stack_state[i];
|
||||
+ for (VarState& slot : cache_state_.stack_state) {
|
||||
if (!slot.is_reg()) continue;
|
||||
Spill(slot.offset(), slot.reg(), slot.kind());
|
||||
slot.MakeStack();
|
||||
diff --git a/src/wasm/baseline/liftoff-assembler.h b/src/wasm/baseline/liftoff-assembler.h
|
||||
index 7cb2f5003735ef826559c247938275f996f61439..5d4ebd7fa30898ec857a92a2f31f18e1ea76905c 100644
|
||||
--- a/src/wasm/baseline/liftoff-assembler.h
|
||||
+++ b/src/wasm/baseline/liftoff-assembler.h
|
||||
@@ -542,9 +542,9 @@ class LiftoffAssembler : public MacroAssembler {
|
||||
// the bottom of the stack.
|
||||
void DropExceptionValueAtOffset(int offset);
|
||||
|
||||
- // Ensure that the loop inputs are either in a register or spilled to the
|
||||
- // stack, so that we can merge different values on the back-edge.
|
||||
- void PrepareLoopArgs(int num);
|
||||
+ // Spill all loop inputs to the stack to free registers and to ensure that we
|
||||
+ // can merge different values on the back-edge.
|
||||
+ void SpillLoopArgs(int num);
|
||||
|
||||
V8_INLINE static int NextSpillOffset(ValueKind kind, int top_spill_offset);
|
||||
V8_INLINE int NextSpillOffset(ValueKind kind);
|
||||
diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc
|
||||
index c185d7273629fda3ddf5d756395f2a367cfa5864..c7b9ca92ecd7369ca3a758d1f69a9516063a44aa 100644
|
||||
--- a/src/wasm/baseline/liftoff-compiler.cc
|
||||
+++ b/src/wasm/baseline/liftoff-compiler.cc
|
||||
@@ -1284,7 +1284,7 @@ class LiftoffCompiler {
|
||||
// pre-analysis of the function.
|
||||
__ SpillLocals();
|
||||
|
||||
- __ PrepareLoopArgs(loop->start_merge.arity);
|
||||
+ __ SpillLoopArgs(loop->start_merge.arity);
|
||||
|
||||
// Loop labels bind at the beginning of the block.
|
||||
__ bind(loop->label.get());
|
||||
@@ -35,6 +35,7 @@
|
||||
"parallel/test-module-loading-globalpaths",
|
||||
"parallel/test-openssl-ca-options",
|
||||
"parallel/test-process-versions",
|
||||
"parallel/test-process-get-builtin",
|
||||
"parallel/test-repl",
|
||||
"parallel/test-repl-underscore",
|
||||
"parallel/test-single-executable-blob-config",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "shell/app/command_line_args.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <locale>
|
||||
|
||||
#include "sandbox/policy/switches.h"
|
||||
@@ -11,46 +12,44 @@
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsUrlArg(const base::CommandLine::CharType* arg) {
|
||||
// the first character must be a letter for this to be a URL
|
||||
auto c = *arg;
|
||||
if (std::isalpha(c, std::locale::classic())) {
|
||||
for (auto* p = arg + 1; *p; ++p) {
|
||||
c = *p;
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
constexpr auto DashDash = base::CommandLine::StringPieceType{L"--"};
|
||||
#else
|
||||
constexpr auto DashDash = base::CommandLine::StringPieceType{"--"};
|
||||
#endif
|
||||
|
||||
// colon indicates that the argument starts with a URI scheme
|
||||
if (c == ':') {
|
||||
// it could also be a Windows filesystem path
|
||||
if (p == arg + 1)
|
||||
break;
|
||||
// we say it's a URL arg if it starts with a URI scheme that:
|
||||
// 1. starts with an alpha, and
|
||||
// 2. contains no spaces, and
|
||||
// 3. is longer than one char (to ensure it's not a Windows drive path)
|
||||
bool IsUrlArg(const base::CommandLine::StringPieceType arg) {
|
||||
const auto scheme_end = arg.find(':');
|
||||
if (scheme_end == base::CommandLine::StringPieceType::npos)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// white-space before a colon means it's not a URL
|
||||
if (std::isspace(c, std::locale::classic()))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
const auto& c_locale = std::locale::classic();
|
||||
const auto isspace = [&](auto ch) { return std::isspace(ch, c_locale); };
|
||||
const auto scheme = arg.substr(0U, scheme_end);
|
||||
return std::size(scheme) > 1U && std::isalpha(scheme.front(), c_locale) &&
|
||||
std::ranges::none_of(scheme, isspace);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
|
||||
const base::CommandLine::StringType dashdash(2, '-');
|
||||
// Check for CVE-2018-1000006 issues. Return true iff argv looks safe.
|
||||
// Sample exploit: 'exodus://aaaaaaaaa" --gpu-launcher="cmd" --aaaaa='
|
||||
// Prevent it by returning false if any arg except '--' follows a URL arg.
|
||||
// More info at https://www.electronjs.org/blog/protocol-handler-fix
|
||||
bool CheckCommandLineArguments(const base::CommandLine::StringVector& argv) {
|
||||
bool block_args = false;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (argv[i] == dashdash)
|
||||
for (const auto& arg : argv) {
|
||||
if (arg == DashDash)
|
||||
break;
|
||||
if (block_args) {
|
||||
if (block_args)
|
||||
return false;
|
||||
} else if (IsUrlArg(argv[i])) {
|
||||
if (IsUrlArg(arg))
|
||||
block_args = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace electron {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
|
||||
bool CheckCommandLineArguments(const base::CommandLine::StringVector& argv);
|
||||
bool IsSandboxEnabled(base::CommandLine* command_line);
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -225,7 +225,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
CHECK_EQ(fiber_status, FiberStatus::kSuccess);
|
||||
#endif // defined(ARCH_CPU_32_BITS)
|
||||
|
||||
if (!electron::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
if (!electron::CheckCommandLineArguments(command_line->argv()))
|
||||
return -1;
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
|
||||
|
||||
@@ -104,10 +104,6 @@ void SetCrashKeyStub(const std::string& key, const std::string& value) {}
|
||||
void ClearCrashKeyStub(const std::string& key) {}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
|
||||
v8::Local<v8::Value> GetParameters(v8::Isolate* isolate) {
|
||||
std::map<std::string, std::string> keys;
|
||||
#if !IS_MAS_BUILD()
|
||||
@@ -116,6 +112,10 @@ v8::Local<v8::Value> GetParameters(v8::Isolate* isolate) {
|
||||
return gin::ConvertToV8(isolate, keys);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
|
||||
int NodeMain(int argc, char* argv[]) {
|
||||
bool initialized = base::CommandLine::Init(argc, argv);
|
||||
if (!initialized) {
|
||||
|
||||
@@ -46,9 +46,9 @@ void AutoUpdater::OnError(const std::string& message) {
|
||||
gin::StringToV8(isolate, message),
|
||||
};
|
||||
|
||||
gin_helper::MicrotasksScope microtasks_scope(
|
||||
gin_helper::MicrotasksScope microtasks_scope{
|
||||
isolate, wrapper->GetCreationContextChecked()->GetMicrotaskQueue(),
|
||||
true);
|
||||
true, v8::MicrotasksScope::kRunMicrotasks};
|
||||
|
||||
node::MakeCallback(isolate, wrapper, "emit", args.size(), args.data(),
|
||||
{0, 0});
|
||||
|
||||
@@ -1249,7 +1249,6 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setHiddenInMissionControl",
|
||||
&BaseWindow::SetHiddenInMissionControl)
|
||||
#endif
|
||||
|
||||
.SetMethod("_setTouchBarItems", &BaseWindow::SetTouchBar)
|
||||
.SetMethod("_refreshTouchBarItem", &BaseWindow::RefreshTouchBarItem)
|
||||
.SetMethod("_setEscapeTouchBarItem", &BaseWindow::SetEscapeTouchBarItem)
|
||||
|
||||
@@ -83,6 +83,8 @@ const std::map<std::string, std::string>& GetGlobalCrashKeys() {
|
||||
return GetGlobalCrashKeysMutable();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool GetClientIdPath(base::FilePath* path) {
|
||||
if (base::PathService::Get(electron::DIR_CRASH_DUMPS, path)) {
|
||||
*path = path->Append("client_id");
|
||||
@@ -111,6 +113,8 @@ void WriteClientId(const std::string& client_id) {
|
||||
base::WriteFile(client_id_path, client_id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string GetClientId() {
|
||||
static base::NoDestructor<std::string> client_id;
|
||||
if (!client_id->empty())
|
||||
|
||||
@@ -41,6 +41,11 @@
|
||||
#include "ui/gfx/x/randr.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "ui/base/cocoa/permissions_utils.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
// Private function in ui/base/x/x11_display_util.cc
|
||||
base::flat_map<x11::RandR::Output, int> GetMonitors(
|
||||
@@ -137,8 +142,6 @@ base::flat_map<int32_t, uint32_t> MonitorAtomIdToDisplayId() {
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<ThumbnailCapturer> MakeWindowCapturer() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (ShouldUseThumbnailCapturerMac(DesktopMediaList::Type::kWindow)) {
|
||||
@@ -294,6 +297,13 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
capture_window_ = capture_window;
|
||||
capture_screen_ = capture_screen;
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (!ui::TryPromptUserForScreenCapture()) {
|
||||
HandleFailure();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// Initialize the source list.
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
@@ -430,21 +440,25 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::back_inserter(captured_sources_));
|
||||
}
|
||||
|
||||
if (!capture_window_ && !capture_screen_) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
gin_helper::CallMethod(this, "_onfinished", captured_sources_);
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
HandleSuccess();
|
||||
}
|
||||
|
||||
screen_capturer_.reset();
|
||||
window_capturer_.reset();
|
||||
void DesktopCapturer::HandleSuccess() {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
gin_helper::CallMethod(this, "_onfinished", captured_sources_);
|
||||
|
||||
Unpin();
|
||||
}
|
||||
screen_capturer_.reset();
|
||||
window_capturer_.reset();
|
||||
|
||||
Unpin();
|
||||
}
|
||||
|
||||
void DesktopCapturer::HandleFailure() {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
|
||||
|
||||
screen_capturer_.reset();
|
||||
|
||||
@@ -90,6 +90,7 @@ class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
|
||||
|
||||
void UpdateSourcesList(DesktopMediaList* list);
|
||||
void HandleFailure();
|
||||
void HandleSuccess();
|
||||
|
||||
std::unique_ptr<DesktopListListener> window_listener_;
|
||||
std::unique_ptr<DesktopListListener> screen_listener_;
|
||||
|
||||
@@ -68,6 +68,10 @@ bool NativeTheme::InForcedColorsMode() {
|
||||
return ui_theme_->InForcedColorsMode();
|
||||
}
|
||||
|
||||
bool NativeTheme::GetPrefersReducedTransparency() {
|
||||
return ui_theme_->GetPrefersReducedTransparency();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
const CFStringRef WhiteOnBlack = CFSTR("whiteOnBlack");
|
||||
const CFStringRef UniversalAccessDomain = CFSTR("com.apple.universalaccess");
|
||||
@@ -108,7 +112,9 @@ gin::ObjectTemplateBuilder NativeTheme::GetObjectTemplateBuilder(
|
||||
&NativeTheme::ShouldUseHighContrastColors)
|
||||
.SetProperty("shouldUseInvertedColorScheme",
|
||||
&NativeTheme::ShouldUseInvertedColorScheme)
|
||||
.SetProperty("inForcedColorsMode", &NativeTheme::InForcedColorsMode);
|
||||
.SetProperty("inForcedColorsMode", &NativeTheme::InForcedColorsMode)
|
||||
.SetProperty("prefersReducedTransparency",
|
||||
&NativeTheme::GetPrefersReducedTransparency);
|
||||
}
|
||||
|
||||
const char* NativeTheme::GetTypeName() {
|
||||
|
||||
@@ -46,6 +46,7 @@ class NativeTheme : public gin::Wrappable<NativeTheme>,
|
||||
bool ShouldUseHighContrastColors();
|
||||
bool ShouldUseInvertedColorScheme();
|
||||
bool InForcedColorsMode();
|
||||
bool GetPrefersReducedTransparency();
|
||||
|
||||
// ui::NativeThemeObserver:
|
||||
void OnNativeThemeUpdated(ui::NativeTheme* theme) override;
|
||||
|
||||
@@ -58,10 +58,7 @@ Notification::Notification(gin::Arguments* args) {
|
||||
opts.Get("title", &title_);
|
||||
opts.Get("subtitle", &subtitle_);
|
||||
opts.Get("body", &body_);
|
||||
has_icon_ = opts.Get("icon", &icon_);
|
||||
if (has_icon_) {
|
||||
opts.Get("icon", &icon_path_);
|
||||
}
|
||||
opts.Get("icon", &icon_);
|
||||
opts.Get("silent", &silent_);
|
||||
opts.Get("replyPlaceholder", &reply_placeholder_);
|
||||
opts.Get("urgency", &urgency_);
|
||||
|
||||
@@ -101,8 +101,6 @@ class Notification : public gin::Wrappable<Notification>,
|
||||
std::u16string subtitle_;
|
||||
std::u16string body_;
|
||||
gfx::Image icon_;
|
||||
std::u16string icon_path_;
|
||||
bool has_icon_ = false;
|
||||
bool silent_ = false;
|
||||
bool has_reply_ = false;
|
||||
std::u16string timeout_type_;
|
||||
|
||||
@@ -37,13 +37,14 @@ void FrameSubscriber::AttachToHost(content::RenderWidgetHost* host) {
|
||||
|
||||
// The view can be null if the renderer process has crashed.
|
||||
// (https://crbug.com/847363)
|
||||
if (!host_->GetView())
|
||||
auto* rwhv = host_->GetView();
|
||||
if (!rwhv)
|
||||
return;
|
||||
|
||||
// Create and configure the video capturer.
|
||||
gfx::Size size = GetRenderViewSize();
|
||||
DCHECK(!size.IsEmpty());
|
||||
video_capturer_ = host_->GetView()->CreateVideoCapturer();
|
||||
video_capturer_ = rwhv->CreateVideoCapturer();
|
||||
video_capturer_->SetResolutionConstraints(size, size, true);
|
||||
video_capturer_->SetAutoThrottlingEnabled(false);
|
||||
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/containers/to_vector.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "gin/arguments.h"
|
||||
@@ -242,11 +243,7 @@ std::vector<blink::MessagePortChannel> MessagePort::DisentanglePorts(
|
||||
}
|
||||
|
||||
// Passed-in ports passed validity checks, so we can disentangle them.
|
||||
std::vector<blink::MessagePortChannel> channels;
|
||||
channels.reserve(ports.size());
|
||||
for (auto port : ports)
|
||||
channels.push_back(port->Disentangle());
|
||||
return channels;
|
||||
return base::ToVector(ports, [](auto& port) { return port->Disentangle(); });
|
||||
}
|
||||
|
||||
void MessagePort::Pin() {
|
||||
|
||||
@@ -885,6 +885,8 @@ void ElectronBrowserClient::RenderProcessExited(
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void OnOpenExternal(const GURL& escaped_url, bool allowed) {
|
||||
if (allowed) {
|
||||
platform_util::OpenExternal(
|
||||
@@ -921,6 +923,8 @@ void HandleExternalProtocolInUI(
|
||||
has_user_gesture, url);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ElectronBrowserClient::HandleExternalProtocol(
|
||||
const GURL& url,
|
||||
content::WebContents::Getter web_contents_getter,
|
||||
@@ -1538,6 +1542,7 @@ void ElectronBrowserClient::BindHostReceiverForRenderer(
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
namespace {
|
||||
void BindMimeHandlerService(
|
||||
content::RenderFrameHost* frame_host,
|
||||
mojo::PendingReceiver<extensions::mime_handler::MimeHandlerService>
|
||||
@@ -1566,6 +1571,7 @@ void BindBeforeUnloadControl(
|
||||
return;
|
||||
guest_view->FuseBeforeUnloadControl(std::move(receiver));
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
void ElectronBrowserClient::ExposeInterfacesToRenderer(
|
||||
@@ -1705,6 +1711,8 @@ content::UsbDelegate* ElectronBrowserClient::GetUsbDelegate() {
|
||||
return usb_delegate_.get();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void BindBadgeServiceForServiceWorker(
|
||||
const content::ServiceWorkerVersionBaseInfo& info,
|
||||
mojo::PendingReceiver<blink::mojom::BadgeService> receiver) {
|
||||
@@ -1719,6 +1727,8 @@ void BindBadgeServiceForServiceWorker(
|
||||
render_process_host, info.scope, std::move(receiver));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ElectronBrowserClient::RegisterBrowserInterfaceBindersForServiceWorker(
|
||||
content::BrowserContext* browser_context,
|
||||
const content::ServiceWorkerVersionBaseInfo& service_worker_version_info,
|
||||
|
||||
@@ -144,11 +144,6 @@ class LinuxUiGetterImpl : public ui::LinuxUiGetter {
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void Erase(T* container, typename T::iterator iter) {
|
||||
container->erase(iter);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
int GetMinimumFontSize() {
|
||||
int min_font_size;
|
||||
|
||||
@@ -466,6 +466,8 @@ ExtensionFunction::ResponseAction TabsSetZoomSettingsFunction::Run() {
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsKillURL(const GURL& url) {
|
||||
#if DCHECK_IS_ON()
|
||||
// Caller should ensure that |url| is already "fixed up" by
|
||||
@@ -585,6 +587,8 @@ base::expected<GURL, std::string> PrepareURLForNavigation(
|
||||
return url;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TabsUpdateFunction::TabsUpdateFunction() : web_contents_(nullptr) {}
|
||||
|
||||
ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/json/values_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/task/bind_post_task.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "base/values.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h" // nogncheck
|
||||
@@ -24,20 +27,72 @@
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "shell/browser/api/electron_api_session.h"
|
||||
#include "shell/browser/electron_permission_manager.h"
|
||||
#include "shell/browser/web_contents_permission_helper.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "third_party/blink/public/mojom/file_system_access/file_system_access_manager.mojom.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<
|
||||
ChromeFileSystemAccessPermissionContext::SensitiveEntryResult> {
|
||||
static bool FromV8(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ChromeFileSystemAccessPermissionContext::SensitiveEntryResult* out) {
|
||||
std::string type;
|
||||
if (!ConvertFromV8(isolate, val, &type))
|
||||
return false;
|
||||
if (type == "allow")
|
||||
*out = ChromeFileSystemAccessPermissionContext::SensitiveEntryResult::
|
||||
kAllowed;
|
||||
else if (type == "tryAgain")
|
||||
*out = ChromeFileSystemAccessPermissionContext::SensitiveEntryResult::
|
||||
kTryAgain;
|
||||
else if (type == "deny")
|
||||
*out =
|
||||
ChromeFileSystemAccessPermissionContext::SensitiveEntryResult::kAbort;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace {
|
||||
|
||||
using BlockType = ChromeFileSystemAccessPermissionContext::BlockType;
|
||||
using HandleType = content::FileSystemAccessPermissionContext::HandleType;
|
||||
using GrantType = electron::FileSystemAccessPermissionContext::GrantType;
|
||||
using SensitiveEntryResult =
|
||||
ChromeFileSystemAccessPermissionContext::SensitiveEntryResult;
|
||||
using blink::mojom::PermissionStatus;
|
||||
|
||||
// Dictionary keys for the FILE_SYSTEM_LAST_PICKED_DIRECTORY website setting.
|
||||
// Schema (per origin):
|
||||
// {
|
||||
// ...
|
||||
// {
|
||||
// "default-id" : { "path" : <path> , "path-type" : <type>}
|
||||
// "custom-id-fruit" : { "path" : <path> , "path-type" : <type> }
|
||||
// "custom-id-flower" : { "path" : <path> , "path-type" : <type> }
|
||||
// ...
|
||||
// }
|
||||
// ...
|
||||
// }
|
||||
const char kDefaultLastPickedDirectoryKey[] = "default-id";
|
||||
const char kCustomLastPickedDirectoryKey[] = "custom-id";
|
||||
const char kPathKey[] = "path";
|
||||
const char kPathTypeKey[] = "path-type";
|
||||
const char kTimestampKey[] = "timestamp";
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
[[nodiscard]] constexpr bool ContainsInvalidDNSCharacter(
|
||||
base::FilePath::StringType hostname) {
|
||||
@@ -79,7 +134,7 @@ bool MaybeIsLocalUNCPath(const base::FilePath& path) {
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
// Describes a rule for blocking a directory, which can be constructed
|
||||
// dynamically (based on state) or statically (from kBlockedPaths).
|
||||
@@ -102,7 +157,7 @@ bool ShouldBlockAccessToPath(const base::FilePath& path,
|
||||
MaybeIsLocalUNCPath(path)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
// Add the hard-coded rules to the dynamic rules.
|
||||
for (auto const& [key, rule_path, type] :
|
||||
@@ -150,6 +205,11 @@ bool ShouldBlockAccessToPath(const base::FilePath& path,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GenerateLastPickedDirectoryKey(const std::string& id) {
|
||||
return id.empty() ? kDefaultLastPickedDirectoryKey
|
||||
: base::StrCat({kCustomLastPickedDirectoryKey, "-", id});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
@@ -367,8 +427,9 @@ struct FileSystemAccessPermissionContext::OriginState {
|
||||
};
|
||||
|
||||
FileSystemAccessPermissionContext::FileSystemAccessPermissionContext(
|
||||
content::BrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
content::BrowserContext* browser_context,
|
||||
const base::Clock* clock)
|
||||
: browser_context_(browser_context), clock_(clock) {
|
||||
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||
}
|
||||
|
||||
@@ -501,11 +562,11 @@ void FileSystemAccessPermissionContext::ConfirmSensitiveEntryAccess(
|
||||
content::GlobalRenderFrameHostId frame_id,
|
||||
base::OnceCallback<void(SensitiveEntryResult)> callback) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
callback_ = std::move(callback);
|
||||
|
||||
auto after_blocklist_check_callback = base::BindOnce(
|
||||
&FileSystemAccessPermissionContext::DidCheckPathAgainstBlocklist,
|
||||
GetWeakPtr(), origin, path, handle_type, user_action, frame_id,
|
||||
std::move(callback));
|
||||
GetWeakPtr(), origin, path, handle_type, user_action, frame_id);
|
||||
CheckPathAgainstBlocklist(path_type, path, handle_type,
|
||||
std::move(after_blocklist_check_callback));
|
||||
}
|
||||
@@ -544,31 +605,87 @@ void FileSystemAccessPermissionContext::PerformAfterWriteChecks(
|
||||
std::move(callback).Run(AfterWriteCheckResult::kAllow);
|
||||
}
|
||||
|
||||
void FileSystemAccessPermissionContext::RunRestrictedPathCallback(
|
||||
SensitiveEntryResult result) {
|
||||
if (callback_)
|
||||
std::move(callback_).Run(result);
|
||||
}
|
||||
|
||||
void FileSystemAccessPermissionContext::OnRestrictedPathResult(
|
||||
gin::Arguments* args) {
|
||||
SensitiveEntryResult result = SensitiveEntryResult::kAbort;
|
||||
args->GetNext(&result);
|
||||
RunRestrictedPathCallback(result);
|
||||
}
|
||||
|
||||
void FileSystemAccessPermissionContext::DidCheckPathAgainstBlocklist(
|
||||
const url::Origin& origin,
|
||||
const base::FilePath& path,
|
||||
HandleType handle_type,
|
||||
UserAction user_action,
|
||||
content::GlobalRenderFrameHostId frame_id,
|
||||
base::OnceCallback<void(SensitiveEntryResult)> callback,
|
||||
bool should_block) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
if (user_action == UserAction::kNone) {
|
||||
std::move(callback).Run(should_block ? SensitiveEntryResult::kAbort
|
||||
: SensitiveEntryResult::kAllowed);
|
||||
RunRestrictedPathCallback(should_block ? SensitiveEntryResult::kAbort
|
||||
: SensitiveEntryResult::kAllowed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Chromium opens a dialog here, but in Electron's case we log and abort.
|
||||
if (should_block) {
|
||||
LOG(INFO) << path.value()
|
||||
<< " is blocked by the blocklis and cannot be accessed";
|
||||
std::move(callback).Run(SensitiveEntryResult::kAbort);
|
||||
auto* session =
|
||||
electron::api::Session::FromBrowserContext(browser_context());
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> details =
|
||||
gin::DataObjectBuilder(isolate)
|
||||
.Set("origin", origin.GetURL().spec())
|
||||
.Set("isDirectory", handle_type == HandleType::kDirectory)
|
||||
.Set("path", path)
|
||||
.Build();
|
||||
session->Emit(
|
||||
"file-system-access-restricted", details,
|
||||
base::BindRepeating(
|
||||
&FileSystemAccessPermissionContext::OnRestrictedPathResult,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
return;
|
||||
}
|
||||
|
||||
std::move(callback).Run(SensitiveEntryResult::kAllowed);
|
||||
RunRestrictedPathCallback(SensitiveEntryResult::kAllowed);
|
||||
}
|
||||
|
||||
void FileSystemAccessPermissionContext::MaybeEvictEntries(
|
||||
base::Value::Dict& dict) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
std::vector<std::pair<base::Time, std::string>> entries;
|
||||
entries.reserve(dict.size());
|
||||
for (auto entry : dict) {
|
||||
// Don't evict the default ID.
|
||||
if (entry.first == kDefaultLastPickedDirectoryKey) {
|
||||
continue;
|
||||
}
|
||||
// If the data is corrupted and `entry.second` is for some reason not a
|
||||
// dict, it should be first in line for eviction.
|
||||
auto timestamp = base::Time::Min();
|
||||
if (entry.second.is_dict()) {
|
||||
timestamp = base::ValueToTime(entry.second.GetDict().Find(kTimestampKey))
|
||||
.value_or(base::Time::Min());
|
||||
}
|
||||
entries.emplace_back(timestamp, entry.first);
|
||||
}
|
||||
|
||||
if (entries.size() <= max_ids_per_origin_) {
|
||||
return;
|
||||
}
|
||||
|
||||
base::ranges::sort(entries);
|
||||
size_t entries_to_remove = entries.size() - max_ids_per_origin_;
|
||||
for (size_t i = 0; i < entries_to_remove; ++i) {
|
||||
bool did_remove_entry = dict.Remove(entries[i].second);
|
||||
DCHECK(did_remove_entry);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSystemAccessPermissionContext::SetLastPickedDirectory(
|
||||
@@ -577,7 +694,24 @@ void FileSystemAccessPermissionContext::SetLastPickedDirectory(
|
||||
const base::FilePath& path,
|
||||
const PathType type) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
LOG(INFO) << "NOTIMPLEMENTED SetLastPickedDirectory: " << path.value();
|
||||
|
||||
// Create an entry into the nested dictionary.
|
||||
base::Value::Dict entry;
|
||||
entry.Set(kPathKey, base::FilePathToValue(path));
|
||||
entry.Set(kPathTypeKey, static_cast<int>(type));
|
||||
entry.Set(kTimestampKey, base::TimeToValue(clock_->Now()));
|
||||
|
||||
auto it = id_pathinfo_map_.find(origin);
|
||||
if (it != id_pathinfo_map_.end()) {
|
||||
base::Value::Dict& dict = it->second;
|
||||
dict.Set(GenerateLastPickedDirectoryKey(id), std::move(entry));
|
||||
MaybeEvictEntries(dict);
|
||||
} else {
|
||||
base::Value::Dict dict;
|
||||
dict.Set(GenerateLastPickedDirectoryKey(id), std::move(entry));
|
||||
MaybeEvictEntries(dict);
|
||||
id_pathinfo_map_.insert(std::make_pair(origin, std::move(dict)));
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemAccessPermissionContext::PathInfo
|
||||
@@ -585,8 +719,27 @@ FileSystemAccessPermissionContext::GetLastPickedDirectory(
|
||||
const url::Origin& origin,
|
||||
const std::string& id) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
LOG(INFO) << "NOTIMPLEMENTED GetLastPickedDirectory";
|
||||
return PathInfo();
|
||||
|
||||
auto it = id_pathinfo_map_.find(origin);
|
||||
|
||||
PathInfo path_info;
|
||||
if (it == id_pathinfo_map_.end()) {
|
||||
return path_info;
|
||||
}
|
||||
|
||||
auto* entry = it->second.FindDict(GenerateLastPickedDirectoryKey(id));
|
||||
if (!entry) {
|
||||
return path_info;
|
||||
}
|
||||
|
||||
auto type_int =
|
||||
entry->FindInt(kPathTypeKey).value_or(static_cast<int>(PathType::kLocal));
|
||||
path_info.type = type_int == static_cast<int>(PathType::kExternal)
|
||||
? PathType::kExternal
|
||||
: PathType::kLocal;
|
||||
path_info.path =
|
||||
base::ValueToFilePath(entry->Find(kPathKey)).value_or(base::FilePath());
|
||||
return path_info;
|
||||
}
|
||||
|
||||
base::FilePath FileSystemAccessPermissionContext::GetWellKnownDirectoryPath(
|
||||
|
||||
@@ -13,11 +13,18 @@
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/time/clock.h"
|
||||
#include "base/time/default_clock.h"
|
||||
#include "base/values.h"
|
||||
#include "components/keyed_service/core/keyed_service.h"
|
||||
#include "content/public/browser/file_system_access_permission_context.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace gin {
|
||||
class Arguments;
|
||||
} // namespace gin
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
} // namespace base
|
||||
@@ -35,7 +42,8 @@ class FileSystemAccessPermissionContext
|
||||
enum class GrantType { kRead, kWrite };
|
||||
|
||||
explicit FileSystemAccessPermissionContext(
|
||||
content::BrowserContext* browser_context);
|
||||
content::BrowserContext* browser_context,
|
||||
const base::Clock* clock = base::DefaultClock::GetInstance());
|
||||
FileSystemAccessPermissionContext(const FileSystemAccessPermissionContext&) =
|
||||
delete;
|
||||
FileSystemAccessPermissionContext& operator=(
|
||||
@@ -124,14 +132,18 @@ class FileSystemAccessPermissionContext
|
||||
const base::FilePath& path,
|
||||
HandleType handle_type,
|
||||
base::OnceCallback<void(bool)> callback);
|
||||
void DidCheckPathAgainstBlocklist(
|
||||
const url::Origin& origin,
|
||||
const base::FilePath& path,
|
||||
HandleType handle_type,
|
||||
UserAction user_action,
|
||||
content::GlobalRenderFrameHostId frame_id,
|
||||
base::OnceCallback<void(SensitiveEntryResult)> callback,
|
||||
bool should_block);
|
||||
void DidCheckPathAgainstBlocklist(const url::Origin& origin,
|
||||
const base::FilePath& path,
|
||||
HandleType handle_type,
|
||||
UserAction user_action,
|
||||
content::GlobalRenderFrameHostId frame_id,
|
||||
bool should_block);
|
||||
|
||||
void RunRestrictedPathCallback(SensitiveEntryResult result);
|
||||
|
||||
void OnRestrictedPathResult(gin::Arguments* args);
|
||||
|
||||
void MaybeEvictEntries(base::Value::Dict& dict);
|
||||
|
||||
void CleanupPermissions(const url::Origin& origin);
|
||||
|
||||
@@ -146,6 +158,15 @@ class FileSystemAccessPermissionContext
|
||||
struct OriginState;
|
||||
std::map<url::Origin, OriginState> active_permissions_map_;
|
||||
|
||||
// Number of custom IDs an origin can specify.
|
||||
size_t max_ids_per_origin_ = 32u;
|
||||
|
||||
const raw_ptr<const base::Clock> clock_;
|
||||
|
||||
std::map<url::Origin, base::Value::Dict> id_pathinfo_map_;
|
||||
|
||||
base::OnceCallback<void(SensitiveEntryResult)> callback_;
|
||||
|
||||
base::WeakPtrFactory<FileSystemAccessPermissionContext> weak_factory_{this};
|
||||
};
|
||||
|
||||
|
||||
@@ -276,13 +276,8 @@ void HidChooserContext::DeviceRemoved(device::mojom::HidDeviceInfoPtr device) {
|
||||
if (CanStorePersistentEntry(*device))
|
||||
return;
|
||||
|
||||
std::vector<url::Origin> revoked_origins;
|
||||
for (auto& map_entry : ephemeral_devices_) {
|
||||
if (map_entry.second.erase(device->guid) > 0)
|
||||
revoked_origins.push_back(map_entry.first);
|
||||
}
|
||||
if (revoked_origins.empty())
|
||||
return;
|
||||
for (auto& [origin, guids] : ephemeral_devices_)
|
||||
guids.erase(device->guid);
|
||||
}
|
||||
|
||||
void HidChooserContext::DeviceChanged(device::mojom::HidDeviceInfoPtr device) {
|
||||
@@ -341,11 +336,6 @@ void HidChooserContext::OnHidManagerConnectionError() {
|
||||
hid_manager_.reset();
|
||||
client_receiver_.reset();
|
||||
devices_.clear();
|
||||
|
||||
std::vector<url::Origin> revoked_origins;
|
||||
revoked_origins.reserve(ephemeral_devices_.size());
|
||||
for (const auto& map_entry : ephemeral_devices_)
|
||||
revoked_origins.push_back(map_entry.first);
|
||||
ephemeral_devices_.clear();
|
||||
|
||||
// Notify all device observers.
|
||||
|
||||
@@ -166,6 +166,7 @@ class NativeWindowMac : public NativeWindow,
|
||||
void DetachChildren() override;
|
||||
|
||||
void NotifyWindowWillEnterFullScreen();
|
||||
void NotifyWindowDidFailToEnterFullScreen();
|
||||
void NotifyWindowWillLeaveFullScreen();
|
||||
|
||||
// Cleanup observers when window is getting closed. Note that the destructor
|
||||
|
||||
@@ -117,50 +117,6 @@ struct Converter<electron::NativeWindowMac::VisualEffectState> {
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
// -[NSWindow orderWindow] does not handle reordering for children
|
||||
// windows. Their order is fixed to the attachment order (the last attached
|
||||
// window is on the top). Therefore, work around it by re-parenting in our
|
||||
// desired order.
|
||||
void ReorderChildWindowAbove(NSWindow* child_window, NSWindow* other_window) {
|
||||
NSWindow* parent = [child_window parentWindow];
|
||||
DCHECK(parent);
|
||||
|
||||
// `ordered_children` sorts children windows back to front.
|
||||
NSArray<NSWindow*>* children = [[child_window parentWindow] childWindows];
|
||||
std::vector<std::pair<NSInteger, NSWindow*>> ordered_children;
|
||||
for (NSWindow* child in children)
|
||||
ordered_children.push_back({[child orderedIndex], child});
|
||||
std::sort(ordered_children.begin(), ordered_children.end(), std::greater<>());
|
||||
|
||||
// If `other_window` is nullptr, place `child_window` in front of
|
||||
// all other children windows.
|
||||
if (other_window == nullptr)
|
||||
other_window = ordered_children.back().second;
|
||||
|
||||
if (child_window == other_window)
|
||||
return;
|
||||
|
||||
for (NSWindow* child in children)
|
||||
[parent removeChildWindow:child];
|
||||
|
||||
const bool relative_to_parent = parent == other_window;
|
||||
if (relative_to_parent)
|
||||
[parent addChildWindow:child_window ordered:NSWindowAbove];
|
||||
|
||||
// Re-parent children windows in the desired order.
|
||||
for (auto [ordered_index, child] : ordered_children) {
|
||||
if (child != child_window && child != other_window) {
|
||||
[parent addChildWindow:child ordered:NSWindowAbove];
|
||||
} else if (child == other_window && !relative_to_parent) {
|
||||
[parent addChildWindow:other_window ordered:NSWindowAbove];
|
||||
[parent addChildWindow:child_window ordered:NSWindowAbove];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||
NativeWindow* parent)
|
||||
: NativeWindow(options, parent), root_view_(new RootViewMac(this)) {
|
||||
@@ -786,22 +742,12 @@ bool NativeWindowMac::MoveAbove(const std::string& sourceId) {
|
||||
if (!webrtc::GetWindowOwnerPid(window_id))
|
||||
return false;
|
||||
|
||||
if (!parent() || is_modal()) {
|
||||
[window_ orderWindow:NSWindowAbove relativeTo:window_id];
|
||||
} else {
|
||||
NSWindow* other_window = [NSApp windowWithWindowNumber:window_id];
|
||||
ReorderChildWindowAbove(window_, other_window);
|
||||
}
|
||||
|
||||
[window_ orderWindowByShuffling:NSWindowAbove relativeTo:window_id];
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeWindowMac::MoveTop() {
|
||||
if (!parent() || is_modal()) {
|
||||
[window_ orderWindow:NSWindowAbove relativeTo:0];
|
||||
} else {
|
||||
ReorderChildWindowAbove(window_, nullptr);
|
||||
}
|
||||
[window_ orderWindowByShuffling:NSWindowAbove relativeTo:0];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetResizable(bool resizable) {
|
||||
@@ -1664,6 +1610,13 @@ void NativeWindowMac::NotifyWindowWillEnterFullScreen() {
|
||||
UpdateVibrancyRadii(true);
|
||||
}
|
||||
|
||||
void NativeWindowMac::NotifyWindowDidFailToEnterFullScreen() {
|
||||
UpdateVibrancyRadii(false);
|
||||
|
||||
if (buttons_proxy_)
|
||||
[buttons_proxy_ redraw];
|
||||
}
|
||||
|
||||
void NativeWindowMac::NotifyWindowWillLeaveFullScreen() {
|
||||
if (buttons_proxy_) {
|
||||
// Hide window title when leaving fullscreen.
|
||||
|
||||
@@ -289,6 +289,15 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
|
||||
|
||||
return false;
|
||||
}
|
||||
case WM_RBUTTONUP: {
|
||||
if (!has_frame()) {
|
||||
bool prevent_default = false;
|
||||
NotifyWindowSystemContextMenu(GET_X_LPARAM(l_param),
|
||||
GET_Y_LPARAM(l_param), &prevent_default);
|
||||
return prevent_default;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case WM_GETMINMAXINFO: {
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
|
||||
@@ -43,7 +43,7 @@ NodeStreamLoader::~NodeStreamLoader() {
|
||||
}
|
||||
|
||||
// Destroy the stream if not already ended
|
||||
if (!ended_) {
|
||||
if (!destroyed_) {
|
||||
node::MakeCallback(isolate_, emitter_.Get(isolate_), "destroy", 0, nullptr,
|
||||
{0, 0});
|
||||
}
|
||||
@@ -63,13 +63,21 @@ void NodeStreamLoader::Start(network::mojom::URLResponseHeadPtr head) {
|
||||
std::nullopt);
|
||||
|
||||
auto weak = weak_factory_.GetWeakPtr();
|
||||
On("end",
|
||||
base::BindRepeating(&NodeStreamLoader::NotifyComplete, weak, net::OK));
|
||||
On("error", base::BindRepeating(&NodeStreamLoader::NotifyComplete, weak,
|
||||
net::ERR_FAILED));
|
||||
On("end", base::BindRepeating(&NodeStreamLoader::NotifyEnd, weak));
|
||||
On("error", base::BindRepeating(&NodeStreamLoader::NotifyError, weak));
|
||||
On("readable", base::BindRepeating(&NodeStreamLoader::NotifyReadable, weak));
|
||||
}
|
||||
|
||||
void NodeStreamLoader::NotifyEnd() {
|
||||
destroyed_ = true;
|
||||
NotifyComplete(net::OK);
|
||||
}
|
||||
|
||||
void NodeStreamLoader::NotifyError() {
|
||||
destroyed_ = true;
|
||||
NotifyComplete(net::ERR_FAILED);
|
||||
}
|
||||
|
||||
void NodeStreamLoader::NotifyReadable() {
|
||||
if (!readable_)
|
||||
ReadMore();
|
||||
@@ -81,7 +89,7 @@ void NodeStreamLoader::NotifyReadable() {
|
||||
void NodeStreamLoader::NotifyComplete(int result) {
|
||||
// Wait until write finishes or fails.
|
||||
if (is_reading_ || is_writing_) {
|
||||
ended_ = true;
|
||||
pending_result_ = true;
|
||||
result_ = result;
|
||||
return;
|
||||
}
|
||||
@@ -121,7 +129,7 @@ void NodeStreamLoader::ReadMore() {
|
||||
}
|
||||
|
||||
readable_ = false;
|
||||
if (ended_) {
|
||||
if (pending_result_) {
|
||||
NotifyComplete(result_);
|
||||
}
|
||||
return;
|
||||
@@ -146,7 +154,7 @@ void NodeStreamLoader::ReadMore() {
|
||||
void NodeStreamLoader::DidWrite(MojoResult result) {
|
||||
is_writing_ = false;
|
||||
// We were told to end streaming.
|
||||
if (ended_) {
|
||||
if (pending_result_) {
|
||||
NotifyComplete(result_);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ class NodeStreamLoader : public network::mojom::URLLoader {
|
||||
using EventCallback = base::RepeatingCallback<void()>;
|
||||
|
||||
void Start(network::mojom::URLResponseHeadPtr head);
|
||||
void NotifyEnd();
|
||||
void NotifyError();
|
||||
void NotifyReadable();
|
||||
void NotifyComplete(int result);
|
||||
void ReadMore();
|
||||
@@ -86,9 +88,13 @@ class NodeStreamLoader : public network::mojom::URLLoader {
|
||||
|
||||
// When NotifyComplete is called while writing, we will save the result and
|
||||
// quit with it after the write is done.
|
||||
bool ended_ = false;
|
||||
bool pending_result_ = false;
|
||||
int result_ = net::OK;
|
||||
|
||||
// Set to `true` when we get either `end` or `error` event on the stream.
|
||||
// If `false` - we call `stream.destroy()` to finalize the stream.
|
||||
bool destroyed_ = false;
|
||||
|
||||
// When the stream emits the readable event, we only want to start reading
|
||||
// data if the stream was not readable before, so we store the state in a
|
||||
// flag.
|
||||
|
||||
@@ -46,7 +46,9 @@ void Notification::NotificationFailed(const std::string& error) {
|
||||
void Notification::Remove() {}
|
||||
|
||||
void Notification::Destroy() {
|
||||
presenter()->RemoveNotification(this);
|
||||
if (presenter()) {
|
||||
presenter()->RemoveNotification(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -27,6 +27,11 @@ base::WeakPtr<Notification> NotificationPresenter::CreateNotification(
|
||||
}
|
||||
|
||||
void NotificationPresenter::RemoveNotification(Notification* notification) {
|
||||
auto it = notifications_.find(notification);
|
||||
if (it == notifications_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifications_.erase(notification);
|
||||
delete notification;
|
||||
}
|
||||
|
||||
@@ -562,10 +562,8 @@ OffScreenRenderWidgetHostView::CreateViewForWidget(
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
content::RenderWidgetHost* embedder_render_widget_host,
|
||||
content::WebContentsView* web_contents_view) {
|
||||
if (render_widget_host->GetView()) {
|
||||
return static_cast<content::RenderWidgetHostViewBase*>(
|
||||
render_widget_host->GetView());
|
||||
}
|
||||
if (auto* rwhv = render_widget_host->GetView())
|
||||
return static_cast<content::RenderWidgetHostViewBase*>(rwhv);
|
||||
|
||||
OffScreenRenderWidgetHostView* embedder_host_view = nullptr;
|
||||
if (embedder_render_widget_host) {
|
||||
|
||||
@@ -33,8 +33,8 @@ void OffScreenWebContentsView::SetWebContents(
|
||||
content::WebContents* web_contents) {
|
||||
web_contents_ = web_contents;
|
||||
|
||||
if (GetView())
|
||||
GetView()->InstallTransparency();
|
||||
if (auto* view = GetView())
|
||||
view->InstallTransparency();
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetNativeWindow(NativeWindow* window) {
|
||||
@@ -51,8 +51,8 @@ void OffScreenWebContentsView::SetNativeWindow(NativeWindow* window) {
|
||||
|
||||
void OffScreenWebContentsView::OnWindowResize() {
|
||||
// In offscreen mode call RenderWidgetHostView's SetSize explicitly
|
||||
if (GetView())
|
||||
GetView()->SetSize(GetSize());
|
||||
if (auto* view = GetView())
|
||||
view->SetSize(GetSize());
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::OnWindowClosed() {
|
||||
@@ -109,7 +109,9 @@ void OffScreenWebContentsView::TransferDragSecurityInfo(WebContentsView* view) {
|
||||
}
|
||||
|
||||
gfx::Rect OffScreenWebContentsView::GetViewBounds() const {
|
||||
return GetView() ? GetView()->GetViewBounds() : gfx::Rect();
|
||||
if (auto* view = GetView())
|
||||
return view->GetViewBounds();
|
||||
return {};
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::CreateView(gfx::NativeView context) {}
|
||||
@@ -117,10 +119,8 @@ void OffScreenWebContentsView::CreateView(gfx::NativeView context) {}
|
||||
content::RenderWidgetHostViewBase*
|
||||
OffScreenWebContentsView::CreateViewForWidget(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
if (render_widget_host->GetView()) {
|
||||
return static_cast<content::RenderWidgetHostViewBase*>(
|
||||
render_widget_host->GetView());
|
||||
}
|
||||
if (auto* rwhv = render_widget_host->GetView())
|
||||
return static_cast<content::RenderWidgetHostViewBase*>(rwhv);
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_, painting_, GetFrameRate(), callback_, render_widget_host,
|
||||
@@ -146,8 +146,8 @@ OffScreenWebContentsView::CreateViewForChildWidget(
|
||||
void OffScreenWebContentsView::SetPageTitle(const std::u16string& title) {}
|
||||
|
||||
void OffScreenWebContentsView::RenderViewReady() {
|
||||
if (GetView())
|
||||
GetView()->InstallTransparency();
|
||||
if (auto* view = GetView())
|
||||
view->InstallTransparency();
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::RenderViewHostChanged(
|
||||
@@ -183,11 +183,9 @@ void OffScreenWebContentsView::UpdateDragOperation(
|
||||
bool document_is_handling_drag) {}
|
||||
|
||||
void OffScreenWebContentsView::SetPainting(bool painting) {
|
||||
auto* view = GetView();
|
||||
painting_ = painting;
|
||||
if (view != nullptr) {
|
||||
if (auto* view = GetView())
|
||||
view->SetPainting(painting);
|
||||
}
|
||||
}
|
||||
|
||||
bool OffScreenWebContentsView::IsPainting() const {
|
||||
@@ -197,11 +195,9 @@ bool OffScreenWebContentsView::IsPainting() const {
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
|
||||
auto* view = GetView();
|
||||
frame_rate_ = frame_rate;
|
||||
if (view != nullptr) {
|
||||
if (auto* view = GetView())
|
||||
view->SetFrameRate(frame_rate);
|
||||
}
|
||||
}
|
||||
|
||||
int OffScreenWebContentsView::GetFrameRate() const {
|
||||
|
||||
@@ -24,17 +24,20 @@ namespace electron {
|
||||
|
||||
constexpr char kPortNameKey[] = "name";
|
||||
constexpr char kTokenKey[] = "token";
|
||||
constexpr char kBluetoothDevicePathKey[] = "bluetooth_device_path";
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const char kDeviceInstanceIdKey[] = "device_instance_id";
|
||||
constexpr char kDeviceInstanceIdKey[] = "device_instance_id";
|
||||
#else
|
||||
const char kVendorIdKey[] = "vendor_id";
|
||||
const char kProductIdKey[] = "product_id";
|
||||
const char kSerialNumberKey[] = "serial_number";
|
||||
constexpr char kVendorIdKey[] = "vendor_id";
|
||||
constexpr char kProductIdKey[] = "product_id";
|
||||
constexpr char kSerialNumberKey[] = "serial_number";
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
const char kUsbDriverKey[] = "usb_driver";
|
||||
constexpr char kUsbDriverKey[] = "usb_driver";
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
namespace {
|
||||
|
||||
std::string EncodeToken(const base::UnguessableToken& token) {
|
||||
const uint64_t data[2] = {token.GetHighForSerialization(),
|
||||
token.GetLowForSerialization()};
|
||||
@@ -44,36 +47,43 @@ std::string EncodeToken(const base::UnguessableToken& token) {
|
||||
|
||||
base::Value PortInfoToValue(const device::mojom::SerialPortInfo& port) {
|
||||
base::Value::Dict value;
|
||||
if (port.display_name && !port.display_name->empty())
|
||||
if (port.display_name && !port.display_name->empty()) {
|
||||
value.Set(kPortNameKey, *port.display_name);
|
||||
else
|
||||
} else {
|
||||
value.Set(kPortNameKey, port.path.LossyDisplayName());
|
||||
}
|
||||
|
||||
if (!SerialChooserContext::CanStorePersistentEntry(port)) {
|
||||
value.Set(kTokenKey, EncodeToken(port.token));
|
||||
return base::Value(std::move(value));
|
||||
}
|
||||
|
||||
if (port.bluetooth_service_class_id &&
|
||||
port.bluetooth_service_class_id->IsValid()) {
|
||||
value.Set(kBluetoothDevicePathKey, port.path.LossyDisplayName());
|
||||
} else {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// Windows provides a handy device identifier which we can rely on to be
|
||||
// sufficiently stable for identifying devices across restarts.
|
||||
value.Set(kDeviceInstanceIdKey, port.device_instance_id);
|
||||
// Windows provides a handy device identifier which we can rely on to be
|
||||
// sufficiently stable for identifying devices across restarts.
|
||||
value.Set(kDeviceInstanceIdKey, port.device_instance_id);
|
||||
#else
|
||||
DCHECK(port.has_vendor_id);
|
||||
value.Set(kVendorIdKey, port.vendor_id);
|
||||
DCHECK(port.has_product_id);
|
||||
value.Set(kProductIdKey, port.product_id);
|
||||
DCHECK(port.serial_number);
|
||||
value.Set(kSerialNumberKey, *port.serial_number);
|
||||
|
||||
CHECK(port.has_vendor_id);
|
||||
value.Set(kVendorIdKey, port.vendor_id);
|
||||
CHECK(port.has_product_id);
|
||||
value.Set(kProductIdKey, port.product_id);
|
||||
CHECK(port.serial_number);
|
||||
value.Set(kSerialNumberKey, *port.serial_number);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
DCHECK(port.usb_driver_name && !port.usb_driver_name->empty());
|
||||
value.Set(kUsbDriverKey, *port.usb_driver_name);
|
||||
CHECK(port.usb_driver_name && !port.usb_driver_name->empty());
|
||||
value.Set(kUsbDriverKey, *port.usb_driver_name);
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
}
|
||||
return base::Value(std::move(value));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SerialChooserContext::SerialChooserContext(ElectronBrowserContext* context)
|
||||
: browser_context_(context) {}
|
||||
|
||||
@@ -173,11 +183,19 @@ bool SerialChooserContext::CanStorePersistentEntry(
|
||||
if (!port.display_name || port.display_name->empty())
|
||||
return false;
|
||||
|
||||
const bool has_bluetooth = port.bluetooth_service_class_id &&
|
||||
port.bluetooth_service_class_id->IsValid() &&
|
||||
!port.path.empty();
|
||||
if (has_bluetooth) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
return !port.device_instance_id.empty();
|
||||
#else
|
||||
if (!port.has_vendor_id || !port.has_product_id || !port.serial_number ||
|
||||
port.serial_number->empty()) {
|
||||
const bool has_usb = port.has_vendor_id && port.has_product_id &&
|
||||
port.serial_number && !port.serial_number->empty();
|
||||
if (!has_usb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,11 +192,8 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
|
||||
view_ = new AutofillPopupView(this, parent->GetWidget());
|
||||
|
||||
if (offscreen) {
|
||||
auto* rwhv = frame_host->GetView();
|
||||
if (embedder_frame_host != nullptr) {
|
||||
rwhv = embedder_frame_host->GetView();
|
||||
}
|
||||
|
||||
auto* rwhv = embedder_frame_host ? embedder_frame_host->GetView()
|
||||
: frame_host->GetView();
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(rwhv);
|
||||
view_->view_proxy_ = std::make_unique<OffscreenViewProxy>(view_);
|
||||
osr_rwhv->AddViewProxy(view_->view_proxy_.get());
|
||||
|
||||
@@ -311,6 +311,18 @@ using FullScreenTransitionState =
|
||||
shell_->HandlePendingFullscreenTransitions();
|
||||
}
|
||||
|
||||
- (void)windowDidFailToEnterFullScreen:(NSWindow*)window {
|
||||
shell_->set_fullscreen_transition_state(FullScreenTransitionState::kNone);
|
||||
|
||||
shell_->SetResizable(is_resizable_);
|
||||
shell_->NotifyWindowDidFailToEnterFullScreen();
|
||||
|
||||
if (shell_->HandleDeferredClose())
|
||||
return;
|
||||
|
||||
shell_->HandlePendingFullscreenTransitions();
|
||||
}
|
||||
|
||||
- (void)windowWillExitFullScreen:(NSNotification*)notification {
|
||||
shell_->set_fullscreen_transition_state(FullScreenTransitionState::kExiting);
|
||||
|
||||
|
||||
@@ -19,13 +19,6 @@
|
||||
|
||||
namespace electron {
|
||||
|
||||
void SetWMSpecState(x11::Window window, bool enabled, x11::Atom state) {
|
||||
ui::SendClientMessage(
|
||||
window, ui::GetX11RootWindow(), x11::GetAtom("_NET_WM_STATE"),
|
||||
{static_cast<uint32_t>(enabled ? 1 : 0), static_cast<uint32_t>(state),
|
||||
static_cast<uint32_t>(x11::Window::None), 1, 0});
|
||||
}
|
||||
|
||||
void SetWindowType(x11::Window window, const std::string& type) {
|
||||
std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
|
||||
std::string window_type_str = type_prefix + base::ToUpperASCII(type);
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
|
||||
namespace electron {
|
||||
|
||||
// Sends a message to the x11 window manager, enabling or disabling the |state|
|
||||
// for _NET_WM_STATE.
|
||||
void SetWMSpecState(x11::Window window, bool enabled, x11::Atom state);
|
||||
|
||||
// Sets the _NET_WM_WINDOW_TYPE of window.
|
||||
void SetWindowType(x11::Window window, const std::string& type);
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@ bool SetVar(const std::string& name, const std::string& value) {
|
||||
return base::Environment::Create()->SetVar(name, value);
|
||||
}
|
||||
|
||||
bool UnSetVar(const std::string& name) {
|
||||
return base::Environment::Create()->UnSetVar(name);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
@@ -37,7 +33,6 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
dict.SetMethod("getVar", &GetVar);
|
||||
dict.SetMethod("hasVar", &HasVar);
|
||||
dict.SetMethod("setVar", &SetVar);
|
||||
dict.SetMethod("unSetVar", &UnSetVar);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_COMMON_API_ELECTRON_API_KEY_WEAK_MAP_H_
|
||||
#define ELECTRON_SHELL_COMMON_API_ELECTRON_API_KEY_WEAK_MAP_H_
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
#include "shell/common/key_weak_map.h"
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
template <typename K>
|
||||
class KeyWeakMap : public gin_helper::Wrappable<KeyWeakMap<K>> {
|
||||
public:
|
||||
static gin::Handle<KeyWeakMap<K>> Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new KeyWeakMap<K>(isolate));
|
||||
}
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "KeyWeakMap"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("set", &KeyWeakMap<K>::Set)
|
||||
.SetMethod("get", &KeyWeakMap<K>::Get)
|
||||
.SetMethod("has", &KeyWeakMap<K>::Has)
|
||||
.SetMethod("remove", &KeyWeakMap<K>::Remove);
|
||||
}
|
||||
|
||||
// disable copy
|
||||
KeyWeakMap(const KeyWeakMap&) = delete;
|
||||
KeyWeakMap& operator=(const KeyWeakMap&) = delete;
|
||||
|
||||
protected:
|
||||
explicit KeyWeakMap(v8::Isolate* isolate) {
|
||||
gin_helper::Wrappable<KeyWeakMap<K>>::Init(isolate);
|
||||
}
|
||||
~KeyWeakMap() override {}
|
||||
|
||||
private:
|
||||
// API for KeyWeakMap.
|
||||
void Set(v8::Isolate* isolate, const K& key, v8::Local<v8::Object> object) {
|
||||
key_weak_map_.Set(isolate, key, object);
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> Get(v8::Isolate* isolate, const K& key) {
|
||||
return key_weak_map_.Get(isolate, key).ToLocalChecked();
|
||||
}
|
||||
|
||||
bool Has(const K& key) { return key_weak_map_.Has(key); }
|
||||
|
||||
void Remove(const K& key) { key_weak_map_.Remove(key); }
|
||||
|
||||
electron::KeyWeakMap<K> key_weak_map_;
|
||||
};
|
||||
|
||||
} // namespace electron::api
|
||||
|
||||
#endif // ELECTRON_SHELL_COMMON_API_ELECTRON_API_KEY_WEAK_MAP_H_
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "base/run_loop.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "shell/common/api/electron_api_key_weak_map.h"
|
||||
#include "shell/common/gin_converters/content_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
@@ -67,17 +66,6 @@ void SetHiddenValue(v8::Isolate* isolate,
|
||||
object->SetPrivate(context, privateKey, value);
|
||||
}
|
||||
|
||||
void DeleteHiddenValue(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
v8::Local<v8::String> key) {
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::Private> privateKey = v8::Private::ForApi(isolate, key);
|
||||
// Actually deleting the value would make force the object into
|
||||
// dictionary mode which is unnecessarily slow. Instead, we replace
|
||||
// the hidden value with "undefined".
|
||||
object->SetPrivate(context, privateKey, v8::Undefined(isolate));
|
||||
}
|
||||
|
||||
int32_t GetObjectHash(v8::Local<v8::Object> object) {
|
||||
return object->GetIdentityHash();
|
||||
}
|
||||
@@ -114,7 +102,6 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("getHiddenValue", &GetHiddenValue);
|
||||
dict.SetMethod("setHiddenValue", &SetHiddenValue);
|
||||
dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue);
|
||||
dict.SetMethod("getObjectHash", &GetObjectHash);
|
||||
dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot);
|
||||
dict.SetMethod("requestGarbageCollectionForTesting",
|
||||
|
||||
@@ -240,8 +240,9 @@ void ElectronBindings::DidReceiveMemoryDump(
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> local_context =
|
||||
v8::Local<v8::Context>::New(isolate, context);
|
||||
gin_helper::MicrotasksScope microtasks_scope(
|
||||
isolate, local_context->GetMicrotaskQueue(), true);
|
||||
gin_helper::MicrotasksScope microtasks_scope{
|
||||
isolate, local_context->GetMicrotaskQueue(), true,
|
||||
v8::MicrotasksScope::kRunMicrotasks};
|
||||
v8::Context::Scope context_scope(local_context);
|
||||
|
||||
if (!success) {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Copyright (c) 2012 Intel Corp. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/common/api/object_life_monitor.h"
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target)
|
||||
: target_(isolate, target) {
|
||||
target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter);
|
||||
}
|
||||
|
||||
ObjectLifeMonitor::~ObjectLifeMonitor() {
|
||||
if (target_.IsEmpty())
|
||||
return;
|
||||
target_.ClearWeak();
|
||||
target_.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
void ObjectLifeMonitor::OnObjectGC(
|
||||
const v8::WeakCallbackInfo<ObjectLifeMonitor>& data) {
|
||||
ObjectLifeMonitor* self = data.GetParameter();
|
||||
self->target_.Reset();
|
||||
self->RunDestructor();
|
||||
data.SetSecondPassCallback(Free);
|
||||
}
|
||||
|
||||
// static
|
||||
void ObjectLifeMonitor::Free(
|
||||
const v8::WeakCallbackInfo<ObjectLifeMonitor>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_COMMON_API_OBJECT_LIFE_MONITOR_H_
|
||||
#define ELECTRON_SHELL_COMMON_API_OBJECT_LIFE_MONITOR_H_
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ObjectLifeMonitor {
|
||||
protected:
|
||||
ObjectLifeMonitor(v8::Isolate* isolate, v8::Local<v8::Object> target);
|
||||
virtual ~ObjectLifeMonitor();
|
||||
|
||||
// disable copy
|
||||
ObjectLifeMonitor(const ObjectLifeMonitor&) = delete;
|
||||
ObjectLifeMonitor& operator=(const ObjectLifeMonitor&) = delete;
|
||||
|
||||
virtual void RunDestructor() = 0;
|
||||
|
||||
private:
|
||||
static void OnObjectGC(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data);
|
||||
static void Free(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data);
|
||||
|
||||
v8::Global<v8::Object> target_;
|
||||
|
||||
base::WeakPtrFactory<ObjectLifeMonitor> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_COMMON_API_OBJECT_LIFE_MONITOR_H_
|
||||
@@ -46,8 +46,6 @@ bool IsDirectoryCached(const base::FilePath& path) {
|
||||
return is_directory_cache[path] = base::DirectoryExists(path);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ArchiveMap& GetArchiveCache() {
|
||||
static base::NoDestructor<ArchiveMap> s_archive_map;
|
||||
return *s_archive_map;
|
||||
@@ -58,6 +56,8 @@ base::Lock& GetArchiveCacheLock() {
|
||||
return *lock;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<Archive> GetOrCreateAsarArchive(const base::FilePath& path) {
|
||||
base::AutoLock auto_lock(GetArchiveCacheLock());
|
||||
ArchiveMap& map = GetArchiveCache();
|
||||
@@ -78,13 +78,6 @@ std::shared_ptr<Archive> GetOrCreateAsarArchive(const base::FilePath& path) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ClearArchives() {
|
||||
base::AutoLock auto_lock(GetArchiveCacheLock());
|
||||
ArchiveMap& map = GetArchiveCache();
|
||||
|
||||
map.clear();
|
||||
}
|
||||
|
||||
bool GetAsarArchivePath(const base::FilePath& full_path,
|
||||
base::FilePath* asar_path,
|
||||
base::FilePath* relative_path,
|
||||
|
||||
@@ -20,9 +20,6 @@ struct IntegrityPayload;
|
||||
// Gets or creates and caches a new Archive from the path.
|
||||
std::shared_ptr<Archive> GetOrCreateAsarArchive(const base::FilePath& path);
|
||||
|
||||
// Destroy cached Archive objects.
|
||||
void ClearArchives();
|
||||
|
||||
// Separates the path to Archive out.
|
||||
bool GetAsarArchivePath(const base::FilePath& full_path,
|
||||
base::FilePath* asar_path,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user