mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50f600b350 | ||
|
|
99b0c77cd7 | ||
|
|
bd191e1862 | ||
|
|
79115938c6 | ||
|
|
03193df4d3 | ||
|
|
80d0d340c7 | ||
|
|
2bf86bcf65 | ||
|
|
2946432147 | ||
|
|
9b552bfe98 | ||
|
|
aa2f4c094f | ||
|
|
f680f21036 | ||
|
|
4717ae4321 | ||
|
|
8c1af31b74 | ||
|
|
4c27ab0a48 | ||
|
|
b645d63b9b | ||
|
|
ebe47b445f | ||
|
|
4e881baaea | ||
|
|
c3d3f9a03b | ||
|
|
85565c0edd | ||
|
|
7644257bcd | ||
|
|
ec951270bd | ||
|
|
48159db088 | ||
|
|
d1475648cb | ||
|
|
1ce4472ae6 | ||
|
|
d323392955 | ||
|
|
5cfaf82036 | ||
|
|
56dedcc291 | ||
|
|
02506a4cb1 | ||
|
|
8cbac3a861 | ||
|
|
9fa958cb5f | ||
|
|
cb26b3689b | ||
|
|
5456137421 | ||
|
|
9945746f1f | ||
|
|
ec6df2b000 | ||
|
|
e35ad40498 | ||
|
|
c281f15bf6 | ||
|
|
e86b4a6f99 | ||
|
|
f62120aa1b | ||
|
|
b0bd900aa3 | ||
|
|
a4f43aaa4d | ||
|
|
63b3434132 | ||
|
|
c881c3f21b | ||
|
|
5014520e2d | ||
|
|
8bde173814 | ||
|
|
7841595cc6 | ||
|
|
870bf8c1f8 | ||
|
|
e8b8ee1454 | ||
|
|
b9d0a5aee3 | ||
|
|
bc3d0bf0c2 | ||
|
|
a0f608b8b6 | ||
|
|
92a338a273 | ||
|
|
f8ab27474f | ||
|
|
d844933377 | ||
|
|
30046ca08d | ||
|
|
98ab127aa1 | ||
|
|
1008774610 | ||
|
|
782e5adc99 | ||
|
|
806d0840ff | ||
|
|
bdf6126133 | ||
|
|
378110b748 | ||
|
|
117b264db5 | ||
|
|
109009f3e7 | ||
|
|
b2ca7f9c05 | ||
|
|
5382df7ea2 | ||
|
|
aedfdadf1b | ||
|
|
7a70765ba1 | ||
|
|
a7ae2511d2 | ||
|
|
cf9f5ca5b8 | ||
|
|
2e85e7fd69 | ||
|
|
3028dcd785 | ||
|
|
d010bcca86 | ||
|
|
1ba8128c8c | ||
|
|
25e504a7ed | ||
|
|
589199f335 | ||
|
|
c0371ab218 | ||
|
|
50f2f10b94 | ||
|
|
2ee36539ba | ||
|
|
0d05ce8d12 | ||
|
|
9e064fec80 | ||
|
|
619a88cf56 | ||
|
|
080bc57145 | ||
|
|
a03ec151e1 | ||
|
|
0858a08097 | ||
|
|
53b6270320 | ||
|
|
4c44e86fd1 | ||
|
|
543a29c926 | ||
|
|
c0c83d2719 | ||
|
|
a7848809fc | ||
|
|
d8ca287700 | ||
|
|
b0c881f608 | ||
|
|
6620ba4e15 | ||
|
|
1babaec6da | ||
|
|
cbe1debbe2 | ||
|
|
3c73ea5259 | ||
|
|
02622b02a6 | ||
|
|
700906c1f1 | ||
|
|
d19a0ac51b | ||
|
|
25521f6286 | ||
|
|
f89b51fe0a | ||
|
|
2a42cd2f65 | ||
|
|
9e419bc4e9 |
@@ -216,6 +216,7 @@ step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
|
||||
rm -rf ~/Library/Application\ Support/electron*
|
||||
security delete-generic-password -l "Chromium Safe Storage" || echo "✓ Keychain does not contain password from tests"
|
||||
security delete-generic-password -l "Electron Test Main Safe Storage" || echo "✓ Keychain does not contain password from tests"
|
||||
security delete-generic-password -a "electron-test-safe-storage" || echo "✓ Keychain does not contain password from tests"
|
||||
elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
XVFB=/usr/bin/Xvfb
|
||||
/sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running"
|
||||
@@ -235,6 +236,11 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
name: Get depot tools
|
||||
command: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
|
||||
git checkout b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
|
||||
touch .disable_auto_update
|
||||
cd ..
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
@@ -454,7 +460,7 @@ step-delete-git-directories: &step-delete-git-directories
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
cd src
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" ) | xargs rm -rf
|
||||
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
|
||||
fi
|
||||
|
||||
# On macOS the yarn install command during gclient sync was run on a linux
|
||||
@@ -812,7 +818,7 @@ step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
ninja -C out/Default electron:licenses
|
||||
ninja -C out/Default electron:electron_version
|
||||
ninja -C out/Default electron:electron_version_file
|
||||
DELETE_DSYMS_AFTER_ZIP=1 electron/script/zip-symbols.py -b $BUILD_PATH
|
||||
|
||||
step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
|
||||
@@ -872,12 +878,12 @@ step-touch-sync-done: &step-touch-sync-done
|
||||
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v14-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
- v16-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache
|
||||
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
|
||||
restore_cache:
|
||||
keys:
|
||||
- v14-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
- v16-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache marker
|
||||
|
||||
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
|
||||
@@ -892,14 +898,6 @@ step-maybe-restore-git-cache: &step-maybe-restore-git-cache
|
||||
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}
|
||||
name: Conditionally restoring git cache
|
||||
|
||||
step-restore-out-cache: &step-restore-out-cache
|
||||
restore_cache:
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
keys:
|
||||
- v10-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Restoring out cache
|
||||
|
||||
step-set-git-cache-path: &step-set-git-cache-path
|
||||
run:
|
||||
name: Set GIT_CACHE_PATH to make gclient to use the cache
|
||||
@@ -917,13 +915,6 @@ step-save-git-cache: &step-save-git-cache
|
||||
key: v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
|
||||
name: Persisting git cache
|
||||
|
||||
step-save-out-cache: &step-save-out-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
key: v10-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Persisting out cache
|
||||
|
||||
step-run-electron-only-hooks: &step-run-electron-only-hooks
|
||||
run:
|
||||
name: Run Electron Only Hooks
|
||||
@@ -953,13 +944,16 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
|
||||
rm -rf third_party/electron_node/deps/openssl
|
||||
rm -rf third_party/electron_node/deps/v8
|
||||
rm -rf chrome/test/data/xr/webvr_info
|
||||
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
|
||||
rm -rf src/third_party/swift-toolchain
|
||||
rm -rf src/third_party/swiftshader/tests/regres/testlists
|
||||
|
||||
# Save the src cache based on the deps hash
|
||||
step-save-src-cache: &step-save-src-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /var/portal
|
||||
key: v14-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v16-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
step-make-src-cache-marker: &step-make-src-cache-marker
|
||||
run:
|
||||
@@ -969,7 +963,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
|
||||
save_cache:
|
||||
paths:
|
||||
- .src-cache-marker
|
||||
key: v14-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v16-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
|
||||
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
|
||||
run:
|
||||
@@ -1293,9 +1287,6 @@ commands:
|
||||
build:
|
||||
type: boolean
|
||||
default: true
|
||||
use-out-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
restore-src-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
@@ -1418,10 +1409,6 @@ commands:
|
||||
- *step-delete-git-directories
|
||||
|
||||
# Electron app
|
||||
- when:
|
||||
condition: << parameters.use-out-cache >>
|
||||
steps:
|
||||
- *step-restore-out-cache
|
||||
- *step-gn-gen-default
|
||||
- *step-electron-build
|
||||
- *step-maybe-electron-dist-strip
|
||||
@@ -1464,22 +1451,6 @@ commands:
|
||||
condition: << parameters.build >>
|
||||
steps:
|
||||
- move_and_store_all_artifacts
|
||||
- run:
|
||||
name: Remove the big things on macOS, this seems to be better on average
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
mkdir -p src/out/Default
|
||||
cd src/out/Default
|
||||
find . -type f -size +50M -delete
|
||||
mkdir -p gen/electron
|
||||
cd gen/electron
|
||||
# These files do not seem to like being in a cache, let us remove them
|
||||
find . -type f -name '*_pkg_info' -delete
|
||||
fi
|
||||
- when:
|
||||
condition: << parameters.use-out-cache >>
|
||||
steps:
|
||||
- *step-save-out-cache
|
||||
|
||||
- *step-maybe-notify-slack-failure
|
||||
|
||||
@@ -1633,7 +1604,6 @@ jobs:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-x64-testing-asan:
|
||||
executor:
|
||||
@@ -1650,7 +1620,6 @@ jobs:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
build-nonproprietary-ffmpeg: false
|
||||
|
||||
linux-x64-testing-no-run-as-node:
|
||||
@@ -1667,7 +1636,6 @@ jobs:
|
||||
- electron-build:
|
||||
persist: false
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-x64-testing-gn-check:
|
||||
executor:
|
||||
@@ -1718,7 +1686,6 @@ jobs:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-arm-publish:
|
||||
executor:
|
||||
@@ -1761,7 +1728,6 @@ jobs:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-arm64-testing-gn-check:
|
||||
executor:
|
||||
|
||||
2
.github/semantic.yml
vendored
2
.github/semantic.yml
vendored
@@ -1,2 +0,0 @@
|
||||
# Always validate the PR title, and ignore the commits
|
||||
titleOnly: true
|
||||
178
.github/workflows/electron_woa_testing.yml
vendored
178
.github/workflows/electron_woa_testing.yml
vendored
@@ -1,178 +0,0 @@
|
||||
name: Electron WOA Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
appveyor_job_id:
|
||||
description: 'Job Id of Appveyor WOA job to test'
|
||||
type: text
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
electron-woa-init:
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'electron/electron' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dummy step for push event
|
||||
run: |
|
||||
echo "This job is a needed initialization step for Electron WOA testing. Another test result will appear once the electron-woa-testing build is done."
|
||||
|
||||
electron-woa-testing:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'electron/electron' }}
|
||||
runs-on: [self-hosted, woa]
|
||||
permissions:
|
||||
checks: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
status: in_progress
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"Test In Progress","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
- name: Clean Workspace
|
||||
run: |
|
||||
Remove-Item * -Recurse -Force
|
||||
shell: powershell
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: src\electron
|
||||
fetch-depth: 0
|
||||
- name: Yarn install
|
||||
run: |
|
||||
cd src\electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
- name: Download and extract dist.zip for test
|
||||
run: |
|
||||
$localArtifactPath = "$pwd\dist.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/dist.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath
|
||||
shell: powershell
|
||||
- name: Download and extract native test executables for test
|
||||
run: |
|
||||
$localArtifactPath = "src\out\Default\shell_browser_ui_unittests.exe"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/shell_browser_ui_unittests.exe"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
shell: powershell
|
||||
- name: Download and extract ffmpeg.zip for test
|
||||
run: |
|
||||
$localArtifactPath = "$pwd\ffmpeg.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/ffmpeg.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath
|
||||
shell: powershell
|
||||
- name: Download node headers for test
|
||||
run: |
|
||||
$localArtifactPath = "src\node_headers.zip"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/node_headers.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
cd src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
|
||||
shell: powershell
|
||||
- name: Download electron.lib for test
|
||||
run: |
|
||||
$localArtifactPath = "src\out\Default\electron.lib"
|
||||
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/electron.lib"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
shell: powershell
|
||||
# Uncomment the following block if pdb files are needed to debug issues
|
||||
# - name: Download pdb files for detailed stacktraces
|
||||
# if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
# run: |
|
||||
# try {
|
||||
# $localArtifactPath = "src\pdb.zip"
|
||||
# $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/pdb.zip"
|
||||
# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
|
||||
# cd src
|
||||
# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
|
||||
# } catch {
|
||||
# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
|
||||
# } finally {
|
||||
# $global:LASTEXITCODE = 0
|
||||
# }
|
||||
# shell: powershell
|
||||
- name: Setup node headers
|
||||
run: |
|
||||
New-Item src\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib
|
||||
shell: powershell
|
||||
- name: Run Electron Main process tests
|
||||
run: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
env:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
- name: Run Electron Remote based tests
|
||||
if: ${{ success() || failure() }}
|
||||
run: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
- name: Verify ffmpeg
|
||||
run: |
|
||||
cd src
|
||||
echo "Verifying non proprietary ffmpeg"
|
||||
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
shell: cmd
|
||||
- name: Kill processes left running from last test run
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
Get-Process | Where Name -Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name -Like "msedge*" | Stop-Process
|
||||
shell: powershell
|
||||
- name: Delete user app data directories
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
shell: powershell
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"${{ job.status }}","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"Job Succeeded","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
- uses: LouisBrunner/checks-action@v1.1.1
|
||||
if: ${{ ! success() }}
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: electron-woa-testing
|
||||
conclusion: "${{ job.status }}"
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
output: |
|
||||
{"summary":"Job Failed","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
|
||||
62
.github/workflows/update_appveyor_image.yml
vendored
Normal file
62
.github/workflows/update_appveyor_image.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Update AppVeyor Image
|
||||
|
||||
# Run chron daily Mon-Fri
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 8 * * 1-5' # runs 8:00 every business day (see https://crontab.guru)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
bake-appveyor-image:
|
||||
name: Bake AppVeyor Image
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write # to create a new PR with updated Appveyor images
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Yarn install
|
||||
run: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
- name: Set Repo for Commit
|
||||
run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
- name: Check AppVeyor Image
|
||||
env:
|
||||
APPVEYOR_TOKEN: ${{ secrets.APPVEYOR_TOKEN }}
|
||||
run: |
|
||||
node ./script/prepare-appveyor
|
||||
if [ -f ./image_version.txt ]; then
|
||||
echo "APPVEYOR_IMAGE_VERSION="$(cat image_version.txt)"" >> $GITHUB_ENV
|
||||
rm image_version.txt
|
||||
fi
|
||||
- name: (Optionally) Update Appveyor Image
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
uses: mikefarah/yq@v4.27.2
|
||||
with:
|
||||
cmd: yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor.yml" > "appveyor2.yml"
|
||||
- name: (Optionally) Generate Commit Diff
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
run: |
|
||||
diff -w -B appveyor.yml appveyor2.yml > appveyor.diff || true
|
||||
patch -f appveyor.yml < appveyor.diff
|
||||
rm appveyor2.yml appveyor.diff
|
||||
- name: (Optionally) Commit and Pull Request
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
|
||||
commit-message: 'build: update appveyor image to latest version'
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
|
||||
signoff: false
|
||||
branch: bump-appveyor-image
|
||||
delete-branch: true
|
||||
title: 'build: update appveyor image to latest version'
|
||||
body: |
|
||||
This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.
|
||||
72
BUILD.gn
72
BUILD.gn
@@ -107,6 +107,14 @@ branding = read_file("shell/app/BRANDING.json", "json")
|
||||
electron_project_name = branding.project_name
|
||||
electron_product_name = branding.product_name
|
||||
electron_mac_bundle_id = branding.mac_bundle_id
|
||||
electron_version = exec_script("script/print-version.py",
|
||||
[],
|
||||
"trim string",
|
||||
[
|
||||
".git/packed-refs",
|
||||
".git/HEAD",
|
||||
"script/lib/get-version.js",
|
||||
])
|
||||
|
||||
if (is_mas_build) {
|
||||
assert(is_mac,
|
||||
@@ -302,12 +310,9 @@ npm_action("electron_version_args") {
|
||||
|
||||
outputs = [ "$target_gen_dir/electron_version.args" ]
|
||||
|
||||
args = rebase_path(outputs)
|
||||
args = rebase_path(outputs) + [ "$electron_version" ]
|
||||
|
||||
inputs = [
|
||||
"ELECTRON_VERSION",
|
||||
"script/generate-version-json.js",
|
||||
]
|
||||
inputs = [ "script/generate-version-json.js" ]
|
||||
}
|
||||
|
||||
templated_file("electron_version_header") {
|
||||
@@ -319,6 +324,39 @@ templated_file("electron_version_header") {
|
||||
args_files = get_target_outputs(":electron_version_args")
|
||||
}
|
||||
|
||||
templated_file("electron_win_rc") {
|
||||
deps = [ ":electron_version_args" ]
|
||||
|
||||
template = "build/templates/electron_rc.tmpl"
|
||||
output = "$target_gen_dir/win-resources/electron.rc"
|
||||
|
||||
args_files = get_target_outputs(":electron_version_args")
|
||||
}
|
||||
|
||||
copy("electron_win_resource_files") {
|
||||
sources = [
|
||||
"shell/browser/resources/win/electron.ico",
|
||||
"shell/browser/resources/win/resource.h",
|
||||
]
|
||||
outputs = [ "$target_gen_dir/win-resources/{{source_file_part}}" ]
|
||||
}
|
||||
|
||||
templated_file("electron_version_file") {
|
||||
deps = [ ":electron_version_args" ]
|
||||
|
||||
template = "build/templates/version_string.tmpl"
|
||||
output = "$root_build_dir/version"
|
||||
|
||||
args_files = get_target_outputs(":electron_version_args")
|
||||
}
|
||||
|
||||
group("electron_win32_resources") {
|
||||
public_deps = [
|
||||
":electron_win_rc",
|
||||
":electron_win_resource_files",
|
||||
]
|
||||
}
|
||||
|
||||
action("electron_fuses") {
|
||||
script = "build/fuses/build.py"
|
||||
|
||||
@@ -403,9 +441,6 @@ source_set("electron_lib") {
|
||||
"//media/mojo/mojom",
|
||||
"//net:extras",
|
||||
"//net:net_resources",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
"//printing/buildflags",
|
||||
"//services/device/public/cpp/geolocation",
|
||||
"//services/device/public/cpp/hid",
|
||||
@@ -616,8 +651,15 @@ source_set("electron_lib") {
|
||||
}
|
||||
|
||||
if (enable_plugins) {
|
||||
deps += [ "chromium_src:plugins" ]
|
||||
deps += [
|
||||
"chromium_src:plugins",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
]
|
||||
sources += [
|
||||
"shell/renderer/electron_renderer_pepper_host_factory.cc",
|
||||
"shell/renderer/electron_renderer_pepper_host_factory.h",
|
||||
"shell/renderer/pepper_helper.cc",
|
||||
"shell/renderer/pepper_helper.h",
|
||||
]
|
||||
@@ -750,7 +792,6 @@ if (is_mac) {
|
||||
electron_helper_name = "$electron_product_name Helper"
|
||||
electron_login_helper_name = "$electron_product_name Login Helper"
|
||||
electron_framework_version = "A"
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
|
||||
mac_xib_bundle_data("electron_xibs") {
|
||||
sources = [ "shell/common/resources/mac/MainMenu.xib" ]
|
||||
@@ -1184,6 +1225,7 @@ if (is_mac) {
|
||||
":default_app_asar",
|
||||
":electron_app_manifest",
|
||||
":electron_lib",
|
||||
":electron_win32_resources",
|
||||
":packed_resources",
|
||||
"//components/crash/core/app",
|
||||
"//content:sandbox_helper_win",
|
||||
@@ -1217,8 +1259,7 @@ if (is_mac) {
|
||||
|
||||
if (is_win) {
|
||||
sources += [
|
||||
# TODO: we should be generating our .rc files more like how chrome does
|
||||
"shell/browser/resources/win/electron.rc",
|
||||
"$target_gen_dir/win-resources/electron.rc",
|
||||
"shell/browser/resources/win/resource.h",
|
||||
]
|
||||
|
||||
@@ -1400,15 +1441,10 @@ group("licenses") {
|
||||
]
|
||||
}
|
||||
|
||||
copy("electron_version") {
|
||||
sources = [ "ELECTRON_VERSION" ]
|
||||
outputs = [ "$root_build_dir/version" ]
|
||||
}
|
||||
|
||||
dist_zip("electron_dist_zip") {
|
||||
data_deps = [
|
||||
":electron_app",
|
||||
":electron_version",
|
||||
":electron_version_file",
|
||||
":licenses",
|
||||
]
|
||||
if (is_linux) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
20.2.0
|
||||
@@ -38,7 +38,7 @@ For more installation options and troubleshooting tips, see
|
||||
|
||||
Each Electron release provides binaries for macOS, Windows, and Linux.
|
||||
|
||||
* macOS (El Capitan and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
|
||||
* macOS (High Sierra and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
|
||||
* Windows (Windows 7 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8.
|
||||
* Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
|
||||
* Ubuntu 14.04 and newer
|
||||
|
||||
52
appveyor-bake.yml
Normal file
52
appveyor-bake.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
# The config is used to bake appveyor images, not for running CI jobs.
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "APPVEYOR_BAKE_IMAGE" e.g. 'electron-99.0.4767.0'. Name of the image to be baked.
|
||||
# Typically named after the Chromium version on which the image is built.
|
||||
# This can be set dynamically in the prepare-appveyor script.
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: Windows_Default_Appveyor
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
PYTHONIOENCODING: UTF-8
|
||||
build_script:
|
||||
- ps: Resize-Partition -DriveLetter C -Size (256GB) # ensure initial partition size
|
||||
- ps: Get-Partition -DriveLetter C
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- mkdir src
|
||||
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- update_depot_tools.bat
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- src\electron\script\setup-win-for-dev.bat
|
||||
- >-
|
||||
gclient config
|
||||
--name "src\electron"
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- ps: cd src\electron
|
||||
- ps: node script\generate-deps-hash.js
|
||||
- ps: $depshash = Get-Content .\.depshash -Raw
|
||||
- ps: Copy-Item -path .\.depshash -destination ..\.depshash
|
||||
- ps: cd ..\..
|
||||
- gclient sync --with_branch_heads --with_tags --nohooks
|
||||
- ps: regsvr32 /s "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\DIA SDK\bin\amd64\msdia140.dll"
|
||||
on_image_bake:
|
||||
- ps: >-
|
||||
echo "Baking image: $env:APPVEYOR_BAKE_IMAGE at dir $PWD"
|
||||
- ps: Remove-Item -Recurse -Force $pwd\depot_tools
|
||||
- ps: Remove-Item -Recurse -Force $pwd\src\electron
|
||||
# Uncomment these lines to enable RDP
|
||||
#on_finish:
|
||||
# - ps: >-
|
||||
# $env:APPVEYOR_RDP_PASSWORD = "electron"
|
||||
# $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
286
appveyor-woa.yml
Normal file
286
appveyor-woa.yml
Normal file
@@ -0,0 +1,286 @@
|
||||
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor.yml
|
||||
# IF APPLICABLE!!!!
|
||||
#
|
||||
#
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
|
||||
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
|
||||
# Otherwise the release will be uploaded to the GitHub Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
# but those are not covered here.
|
||||
#
|
||||
# AppVeyor docs on variables:
|
||||
# https://www.appveyor.com/docs/environment-variables/
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-106.0.5249.199
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
matrix:
|
||||
|
||||
- job_name: Build Arm on X64 Windows
|
||||
- job_name: Test On Windows On Arm Hardware
|
||||
job_depends_on: Build Arm on X64 Windows
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
|
||||
|
||||
clone_folder: C:\projects\src\electron
|
||||
|
||||
skip_branch_with_pr: true
|
||||
|
||||
# the first failed job cancels other jobs and fails entire build
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
for:
|
||||
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Build Arm on X64 Windows
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
$global:LASTEXITCODE = 0
|
||||
- cd ..
|
||||
- ps: Write-Host "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\depot_tools") {
|
||||
Remove-Item -Recurse -Force $pwd\depot_tools
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\build-tools") {
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- ps: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
|
||||
git checkout b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
|
||||
New-Item -Name .disable_auto_update -ItemType File
|
||||
bootstrap\win_tools.bat
|
||||
cd ..
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
Remove-Item -Recurse -Force $pwd\src\electron
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
- cd ..\..
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
|
||||
$host.SetShouldExit(1)
|
||||
}
|
||||
}
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
|
||||
# Patches are applied in the image bake. Check depshash to see if patches have changed.
|
||||
- ps: $env:RUN_GCLIENT_SYNC="false"
|
||||
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
|
||||
- ps: cd src\electron
|
||||
- ps: node script\generate-deps-hash.js
|
||||
- ps: $depshash = Get-Content .\.depshash -Raw
|
||||
- ps: cd ..\..
|
||||
- ps: >-
|
||||
if ($depshash_baked -ne $depshash) {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
|
||||
- cd src
|
||||
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
- ps: >-
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- ps: >-
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python3 electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
|
||||
Write-Output "Uploading Electron release distribution to azure"
|
||||
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python3 script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
}
|
||||
on_finish:
|
||||
# Uncomment this lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- cd C:\projects\src
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test On Windows On Arm Hardware
|
||||
|
||||
environment:
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
$global:LASTEXITCODE = 0
|
||||
- cd ..
|
||||
- mkdir out\Default
|
||||
- cd ..
|
||||
- ps: |
|
||||
# Download build artifacts
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
|
||||
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','pdb.zip','electron.lib')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build Arm on X64 Windows") {
|
||||
$jobId = $job.jobId
|
||||
foreach($artifact_name in $artifacts_to_download) {
|
||||
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
|
||||
$outfile = "src\out\Default\$artifact_name"
|
||||
} else {
|
||||
$outfile = $artifact_name
|
||||
}
|
||||
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
|
||||
}
|
||||
}
|
||||
}
|
||||
- ps: |
|
||||
$out_default_zips = @('dist.zip','pdb.zip')
|
||||
foreach($zip_name in $out_default_zips) {
|
||||
7z x -y -osrc\out\Default $zip_name
|
||||
}
|
||||
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
|
||||
- ps: 7z x -y -osrc node_headers.zip
|
||||
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: |
|
||||
cd src
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
|
||||
- set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
- set npm_config_arch=arm64
|
||||
- cd electron
|
||||
# Explicitly set npm_config_arch because the .env doesn't persist
|
||||
- ps: >-
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- echo Running main test suite & node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
|
||||
on_finish:
|
||||
# Uncomment these lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
|
||||
460
appveyor.yml
460
appveyor.yml
@@ -1,9 +1,13 @@
|
||||
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor-woa.yml
|
||||
# IF APPLICABLE!!!!
|
||||
#
|
||||
#
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
@@ -12,7 +16,7 @@
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
|
||||
# Otherwise the release will be uploaded to the Github Releases.
|
||||
# Otherwise the release will be uploaded to the GitHub Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
@@ -24,224 +28,258 @@
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electron-16-core
|
||||
image: vs2019bt-16.16.11
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-104.0.5112.124-fix
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
Write-Output $result
|
||||
if ($result.ExitCode -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- mkdir src
|
||||
- update_depot_tools.bat
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
- cd ..
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
|
||||
$host.SetShouldExit(1)
|
||||
}
|
||||
}
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- >-
|
||||
gclient config
|
||||
--name "src\electron"
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
} else {
|
||||
cd src\electron
|
||||
node script\generate-deps-hash.js
|
||||
$depshash = Get-Content .\.depshash -Raw
|
||||
$zipfile = "Z:\$depshash.7z"
|
||||
cd ..\..
|
||||
if (Test-Path -Path $zipfile) {
|
||||
# file exists, unzip and then gclient sync
|
||||
7z x -y $zipfile -mmt=30 -aoa
|
||||
if (-not (Test-Path -Path "src\buildtools")) {
|
||||
# the zip file must be corrupt - resync
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# only save on x64/woa to avoid contention saving
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
matrix:
|
||||
|
||||
- job_name: Build
|
||||
- job_name: Test
|
||||
job_depends_on: Build
|
||||
|
||||
clone_folder: C:\projects\src\electron
|
||||
|
||||
skip_branch_with_pr: true
|
||||
|
||||
# the first failed job cancels other jobs and fails entire build
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
for:
|
||||
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Build
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
$global:LASTEXITCODE = 0
|
||||
- cd ..
|
||||
- ps: Write-Host "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\depot_tools") {
|
||||
Remove-Item -Recurse -Force $pwd\depot_tools
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\build-tools") {
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- ps: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
|
||||
git checkout b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
|
||||
New-Item -Name .disable_auto_update -ItemType File
|
||||
bootstrap\win_tools.bat
|
||||
cd ..
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
Remove-Item -Recurse -Force $pwd\src\electron
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
- cd ..\..
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
|
||||
$host.SetShouldExit(1)
|
||||
}
|
||||
}
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
|
||||
# Patches are applied in the image bake. Check depshash to see if patches have changed.
|
||||
- ps: $env:RUN_GCLIENT_SYNC="false"
|
||||
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
|
||||
- ps: cd src\electron
|
||||
- ps: node script\generate-deps-hash.js
|
||||
- ps: $depshash = Get-Content .\.depshash -Raw
|
||||
- ps: cd ..\..
|
||||
- ps: >-
|
||||
if ($depshash_baked -ne $depshash) {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
- ps: >-
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- ps: >-
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python3 electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# update angle
|
||||
cd src\third_party\angle
|
||||
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
|
||||
git fetch
|
||||
cd ..\..\..
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
} else {
|
||||
# file does not exist, gclient sync, then zip
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# only save on x64/woa to avoid contention saving
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
}
|
||||
}
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync )
|
||||
- ps: >-
|
||||
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
|
||||
# archive current source for future use
|
||||
# only run on x64/woa to avoid contention saving
|
||||
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Could not save source to shared drive; continuing anyway"
|
||||
}
|
||||
# build time generation of file gen/angle/angle_commit.h depends on
|
||||
# third_party/angle/.git
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
$(7z a $zipfile src\third_party\angle\.git)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
|
||||
}
|
||||
# build time generation of file dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
|
||||
# https://dawn-review.googlesource.com/c/dawn/+/83901
|
||||
$(7z a $zipfile src\third_party\dawn\.git)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Failed to add third_party\dawn\.git; continuing anyway"
|
||||
}
|
||||
}
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
$env:RUN_TESTS="true"
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:RUN_TESTS -eq 'true') {
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
|
||||
} else {
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeperately --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying chromedriver"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
|
||||
Write-Output "Uploading Electron release distribution to azure"
|
||||
& python script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
}
|
||||
on_finish:
|
||||
# Uncomment this lines to enable RDP
|
||||
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- cd ..
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
|
||||
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
|
||||
Write-Output "Uploading Electron release distribution to azure"
|
||||
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python3 script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
}
|
||||
on_finish:
|
||||
# Uncomment this lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- cd C:\projects\src
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
if ($env:RUN_TESTS -ne 'true') {
|
||||
Write-warning "Skipping tests for $env:APPVEYOR_PROJECT_NAME"; Exit-AppveyorBuild
|
||||
}
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
$global:LASTEXITCODE = 0
|
||||
- cd ..
|
||||
- mkdir out\Default
|
||||
- cd ..
|
||||
- ps: |
|
||||
# Download build artifacts
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
|
||||
$artifacts_to_download = @('dist.zip','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build") {
|
||||
$jobId = $job.jobId
|
||||
foreach($artifact_name in $artifacts_to_download) {
|
||||
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
|
||||
$outfile = "src\out\Default\$artifact_name"
|
||||
} else {
|
||||
$outfile = $artifact_name
|
||||
}
|
||||
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
|
||||
}
|
||||
}
|
||||
}
|
||||
- ps: |
|
||||
$out_default_zips = @('dist.zip','chromedriver.zip','mksnapshot.zip')
|
||||
foreach($zip_name in $out_default_zips) {
|
||||
7z x -y -osrc\out\Default $zip_name
|
||||
}
|
||||
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
|
||||
- ps: 7z x -y -osrc node_headers.zip
|
||||
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: |
|
||||
cd src
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
|
||||
- cd electron
|
||||
# Explicitly set npm_config_arch because the .env doesn't persist
|
||||
- ps: >-
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log
|
||||
- echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
- echo "About to verify mksnapshot"
|
||||
- echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
|
||||
- echo "Done verifying mksnapshot"
|
||||
- echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd%
|
||||
- echo "Done verifying chromedriver"
|
||||
|
||||
on_finish:
|
||||
# Uncomment these lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
|
||||
@@ -7,5 +7,6 @@
|
||||
"node_options": "1",
|
||||
"node_cli_inspect": "1",
|
||||
"embedded_asar_integrity_validation": "0",
|
||||
"only_load_app_from_asar": "0"
|
||||
"only_load_app_from_asar": "0",
|
||||
"load_browser_process_specific_v8_snapshot": "0"
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import sys
|
||||
import os
|
||||
import optparse
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
sys.path.append("%s/../../build" % os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
@@ -36,56 +34,10 @@ def calculate_hash(root):
|
||||
return CalculateHash('.', None)
|
||||
|
||||
def windows_installed_software():
|
||||
powershell_command = [
|
||||
"Get-CimInstance",
|
||||
"-Namespace",
|
||||
"root\cimv2",
|
||||
"-Class",
|
||||
"Win32_product",
|
||||
"|",
|
||||
"Select",
|
||||
"vendor,",
|
||||
"description,",
|
||||
"@{l='install_location';e='InstallLocation'},",
|
||||
"@{l='install_date';e='InstallDate'},",
|
||||
"@{l='install_date_2';e='InstallDate2'},",
|
||||
"caption,",
|
||||
"version,",
|
||||
"name,",
|
||||
"@{l='sku_number';e='SKUNumber'}",
|
||||
"|",
|
||||
"ConvertTo-Json",
|
||||
]
|
||||
|
||||
proc = subprocess.Popen(
|
||||
["powershell.exe", "-Command", "-"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
stdout, _ = proc.communicate(" ".join(powershell_command).encode("utf-8"))
|
||||
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError("Failed to get list of installed software")
|
||||
|
||||
# On AppVeyor there's other output related to PSReadline,
|
||||
# so grab only the JSON output and ignore everything else
|
||||
json_match = re.match(
|
||||
r".*(\[.*{.*}.*\]).*", stdout.decode("utf-8"), re.DOTALL
|
||||
)
|
||||
|
||||
if not json_match:
|
||||
raise RuntimeError(
|
||||
"Couldn't find JSON output for list of installed software"
|
||||
)
|
||||
|
||||
# Filter out missing keys
|
||||
return list(
|
||||
map(
|
||||
lambda info: {k: info[k] for k in info if info[k]},
|
||||
json.loads(json_match.group(1)),
|
||||
)
|
||||
)
|
||||
# file_path = os.path.join(os.getcwd(), 'installed_software.json')
|
||||
# return json.loads(open('installed_software.json').read().decode('utf-8'))
|
||||
f = open('installed_software.json', encoding='utf-8-sig')
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def windows_profile():
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 20,2,0,0
|
||||
PRODUCTVERSION 20,2,0,0
|
||||
FILEVERSION $major,$minor,$patch,$prerelease_number
|
||||
PRODUCTVERSION $major,$minor,$patch,$prerelease_number
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "20.2.0"
|
||||
VALUE "FileVersion", "$major.$minor.$patch"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "20.2.0"
|
||||
VALUE "ProductVersion", "$major.$minor.$patch"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
1
build/templates/version_string.tmpl
Normal file
1
build/templates/version_string.tmpl
Normal file
@@ -0,0 +1 @@
|
||||
$full_version
|
||||
@@ -6,6 +6,7 @@ import("//build/config/ozone.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//electron/buildflags/buildflags.gni")
|
||||
import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
|
||||
@@ -370,15 +371,20 @@ source_set("plugins") {
|
||||
deps += [
|
||||
"//components/strings",
|
||||
"//media:media_buildflags",
|
||||
"//ppapi/buildflags",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//ppapi/shared_impl",
|
||||
"//services/device/public/mojom",
|
||||
"//skia",
|
||||
"//storage/browser",
|
||||
]
|
||||
|
||||
if (enable_plugins) {
|
||||
deps += [
|
||||
"//ppapi/buildflags",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//ppapi/shared_impl",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This source set is just so we don't have to depend on all of //chrome/browser
|
||||
|
||||
@@ -83,7 +83,7 @@ function loadApplicationPackage (packagePath: string) {
|
||||
});
|
||||
|
||||
try {
|
||||
// Override app name and version.
|
||||
// Override app's package.json data.
|
||||
packagePath = path.resolve(packagePath);
|
||||
const packageJsonPath = path.join(packagePath, 'package.json');
|
||||
let appPath;
|
||||
@@ -104,6 +104,16 @@ function loadApplicationPackage (packagePath: string) {
|
||||
} else if (packageJson.name) {
|
||||
app.name = packageJson.name;
|
||||
}
|
||||
if (packageJson.desktopName) {
|
||||
app.setDesktopName(packageJson.desktopName);
|
||||
} else {
|
||||
app.setDesktopName(`${app.name}.desktop`);
|
||||
}
|
||||
// Set v8 flags, deliberately lazy load so that apps that do not use this
|
||||
// feature do not pay the price
|
||||
if (packageJson.v8Flags) {
|
||||
require('v8').setFlagsFromString(packageJson.v8Flags);
|
||||
}
|
||||
appPath = packagePath;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
* Electron Releases & Developer Feedback
|
||||
* [Versioning Policy](tutorial/electron-versioning.md)
|
||||
* [Release Timelines](tutorial/electron-timelines.md)
|
||||
* [Testing Widevine CDM](tutorial/testing-widevine-cdm.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -96,14 +96,6 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process should listen for `channel` with
|
||||
[`ipcMain.handle()`](./ipc-main.md#ipcmainhandlechannel-listener).
|
||||
|
||||
@@ -126,6 +118,21 @@ If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRender
|
||||
|
||||
If you do not need a response to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
|
||||
|
||||
> **Note**
|
||||
> Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
> **Note**
|
||||
> If the handler in the main process throws an error,
|
||||
> the promise returned by `invoke` will reject.
|
||||
> However, the `Error` object in the renderer process
|
||||
> will not be the same as the one thrown in the main process.
|
||||
|
||||
### `ipcRenderer.sendSync(channel, ...args)`
|
||||
|
||||
* `channel` string
|
||||
|
||||
@@ -635,9 +635,10 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
|
||||
* `midi` - Request MIDI access in the `webmidi` API.
|
||||
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more.
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more. These requests always appear to originate from the main frame.
|
||||
* `fullscreen` - Request for the app to enter fullscreen mode.
|
||||
* `openExternal` - Request to open links in external applications.
|
||||
* `window-placement` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
|
||||
* `unknown` - An unrecognized permission request
|
||||
* `callback` Function
|
||||
* `permissionGranted` boolean - Allow or deny the permission.
|
||||
|
||||
@@ -11,8 +11,8 @@ can either use specialized tooling or manual approaches.
|
||||
## With tooling
|
||||
|
||||
There are a couple tools out there that exist to package and distribute your Electron app.
|
||||
We recommend using [Electron Forge](https://www.electronforge.io). You can check out
|
||||
its documentation directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
|
||||
We recommend using [Electron Forge](./forge-overview.md). You can check out
|
||||
its [documentation](https://www.electronforge.io) directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
|
||||
part of the Electron tutorial.
|
||||
|
||||
## Manual packaging
|
||||
|
||||
@@ -26,10 +26,8 @@ beginners, using a command line tool is likely to be helpful*.
|
||||
|
||||
## electron-forge
|
||||
|
||||
A "complete tool for building modern Electron applications". Electron Forge
|
||||
unifies the existing (and well maintained) build tools for Electron development
|
||||
into a cohesive package so that anyone can jump right in to Electron
|
||||
development.
|
||||
Electron Forge is a tool for packaging and publishing Electron applications. It unifies Electron's tooling ecosystem
|
||||
into a single extensible interface so that anyone can jump right into making Electron apps.
|
||||
|
||||
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
|
||||
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager)) –
|
||||
|
||||
@@ -54,85 +54,11 @@ and notarized requires a few additions to your configuration. [Forge](https://el
|
||||
collection of the official Electron tools, using [`electron-packager`],
|
||||
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
|
||||
|
||||
Let's take a look at an example `package.json` configuration with all required fields. Not all of them are
|
||||
required: the tools will be clever enough to automatically find a suitable `identity`, for instance,
|
||||
but we recommend that you are explicit.
|
||||
|
||||
```json title="package.json" {7}
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.0.1",
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {
|
||||
"osxSign": {
|
||||
"identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)",
|
||||
"hardened-runtime": true,
|
||||
"entitlements": "entitlements.plist",
|
||||
"entitlements-inherit": "entitlements.plist",
|
||||
"signature-flags": "library"
|
||||
},
|
||||
"osxNotarize": {
|
||||
"appleId": "felix@felix.fun",
|
||||
"appleIdPassword": "my-apple-id-password"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `entitlements.plist` file referenced here needs the following macOS-specific entitlements
|
||||
to assure the Apple security mechanisms that your app is doing these things
|
||||
without meaning any harm:
|
||||
|
||||
```xml title="entitlements.plist"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.debugger</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
Note that up until Electron 12, the `com.apple.security.cs.allow-unsigned-executable-memory` entitlement was required
|
||||
as well. However, it should not be used anymore if it can be avoided.
|
||||
|
||||
To see all of this in action, check out Electron Fiddle's source code,
|
||||
[especially its `electron-forge` configuration
|
||||
file](https://github.com/electron/fiddle/blob/master/forge.config.js).
|
||||
|
||||
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also
|
||||
need to add the following entitlements:
|
||||
|
||||
```xml title="entitlements.plist"
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
If these are not present in your app's entitlements when you invoke, for example:
|
||||
|
||||
```js title="main.js"
|
||||
const { systemPreferences } = require('electron')
|
||||
const microphone = systemPreferences.askForMediaAccess('microphone')
|
||||
```
|
||||
|
||||
Your app may crash. See the Resource Access section in [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) for more information and entitlements you may need.
|
||||
|
||||
### Using Electron Builder
|
||||
|
||||
Electron Builder comes with a custom solution for signing your application. You
|
||||
can find [its documentation here](https://www.electron.build/code-signing).
|
||||
Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
|
||||
|
||||
### Using Electron Packager
|
||||
|
||||
If you're not using an integrated build pipeline like Forge or Builder, you
|
||||
If you're not using an integrated build pipeline like Forge, you
|
||||
are likely using [`electron-packager`], which includes [`electron-osx-sign`] and
|
||||
[`electron-notarize`].
|
||||
|
||||
@@ -204,36 +130,7 @@ commit it to your source code.
|
||||
|
||||
### Using Electron Forge
|
||||
|
||||
Once you have a code signing certificate file (`.pfx`), you can sign
|
||||
[Squirrel.Windows][maker-squirrel] and [MSI][maker-msi] installers in Electron Forge
|
||||
with the `certificateFile` and `certificatePassword` fields in their respective
|
||||
configuration objects.
|
||||
|
||||
For example, if you keep your Forge config in your `package.json` file and are
|
||||
creating a Squirrel.Windows installer:
|
||||
|
||||
```json {9-15} title='package.json'
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.0.1",
|
||||
//...
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"certificateFile": "./cert.pfx",
|
||||
"certificatePassword": "this-is-a-secret"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
//...
|
||||
}
|
||||
```
|
||||
Electron Forge is the recommended way to sign your `Squirrel.Windows` and `WiX MSI` installers. Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
|
||||
|
||||
### Using electron-winstaller (Squirrel.Windows)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ you can deliver it to your users.
|
||||
## Packaging
|
||||
|
||||
To distribute your app with Electron, you need to package all your resources and assets
|
||||
into an executable and rebrand it. To do this, you can either use specialized tooling
|
||||
into an executable and rebrand it. To do this, you can either use specialized tooling like Electron Forge
|
||||
or do it manually. See the [Application Packaging][application-packaging] tutorial
|
||||
for more information.
|
||||
|
||||
|
||||
36
docs/tutorial/forge-overview.md
Normal file
36
docs/tutorial/forge-overview.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Distributing Apps With Electron Forge
|
||||
|
||||
Electron Forge is a tool for packaging and publishing Electron applications.
|
||||
It unifies Electron's build tooling ecosystem into
|
||||
a single extensible interface so that anyone can jump right into making Electron apps.
|
||||
|
||||
## Getting started
|
||||
|
||||
The [Electron Forge docs] contain detailed information on taking your application
|
||||
from source code to your end users' machines.
|
||||
This includes:
|
||||
|
||||
* Packaging your application [(package)]
|
||||
* Generating executables and installers for each OS [(make)], and,
|
||||
* Publishing these files to online platforms to download [(publish)].
|
||||
|
||||
For beginners, we recommend following through Electron's [tutorial] to develop, build,
|
||||
package and publish your first Electron app. If you have already developed an app on your machine
|
||||
and want to start on packaging and distribution, start from [step 5] of the tutorial.
|
||||
|
||||
## Getting help
|
||||
|
||||
* If you need help with developing your app, our [community Discord server][discord] is a great place
|
||||
to get advice from other Electron app developers.
|
||||
* If you suspect you're running into a bug with Forge, please check the [GitHub issue tracker]
|
||||
to see if any existing issues match your problem. If not, feel free to fill out our bug report
|
||||
template and submit a new issue.
|
||||
|
||||
[Electron Forge Docs]: https://www.electronforge.io/
|
||||
[step 5]: ./tutorial-5-packaging.md
|
||||
[(package)]: https://www.electronforge.io/cli#package
|
||||
[(make)]: https://www.electronforge.io/cli#make
|
||||
[(publish)]: https://www.electronforge.io/cli#publish
|
||||
[GitHub issue tracker]: https://github.com/electron-userland/electron-forge/issues
|
||||
[discord]: https://discord.gg/APGC3k5yaH
|
||||
[tutorial]: https://www.electronjs.org/docs/latest/tutorial/tutorial-prerequisites
|
||||
@@ -54,6 +54,13 @@ For more information on how to use asar integrity validation please read the [As
|
||||
|
||||
The onlyLoadAppFromAsar fuse changes the search system that Electron uses to locate your app code. By default Electron will search in the following order `app.asar` -> `app` -> `default_app.asar`. When this fuse is enabled the search order becomes a single entry `app.asar` thus ensuring that when combined with the `embeddedAsarIntegrityValidation` fuse it is impossible to load non-validated code.
|
||||
|
||||
### `loadBrowserProcessSpecificV8Snapshot`
|
||||
|
||||
**Default:** Disabled
|
||||
**@electron/fuses:** `FuseV1Options.LoadBrowserProcessSpecificV8Snapshot`
|
||||
|
||||
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
|
||||
|
||||
## How do I flip the fuses?
|
||||
|
||||
### The easy way
|
||||
|
||||
@@ -232,7 +232,7 @@ how to meet the Mac App Store requirements.
|
||||
|
||||
### Upload
|
||||
|
||||
The Application Loader should be used to upload the signed app to iTunes
|
||||
[Apple Transporter][apple-transporter] should be used to upload the signed app to App Store
|
||||
Connect for processing, making sure you have [created a record][create-record]
|
||||
before uploading.
|
||||
|
||||
@@ -345,7 +345,8 @@ Electron uses following cryptographic algorithms:
|
||||
[app-sandboxing]: https://developer.apple.com/app-sandboxing/
|
||||
[app-notarization]: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution
|
||||
[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html
|
||||
[create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html
|
||||
[create-record]: https://help.apple.com/app-store-connect/#/dev2cd126805
|
||||
[apple-transporter]: https://help.apple.com/itc/transporteruserguide/en.lproj/static.html
|
||||
[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html
|
||||
[export-compliance]: https://help.apple.com/app-store-connect/#/devc3f64248f
|
||||
[user-selected]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW6
|
||||
|
||||
@@ -101,7 +101,7 @@ app.whenReady().then(async () => {
|
||||
}
|
||||
})
|
||||
|
||||
const secondaryWindow = BrowserWindow({
|
||||
const secondaryWindow = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
@@ -144,7 +144,7 @@ to use `contextIsolation` and set up specific contextBridge calls for each of yo
|
||||
expected messages, but for the simplicity of this example we don't. You can find an
|
||||
example of context isolation further down this page at [Communicating directly between the main process and the main world of a context-isolated page](#communicating-directly-between-the-main-process-and-the-main-world-of-a-context-isolated-page)
|
||||
|
||||
That means window.messagePort is globally available and you can call
|
||||
That means window.electronMessagePort is globally available and you can call
|
||||
`postMessage` on it from anywhere in your app to send a message to the other
|
||||
renderer.
|
||||
|
||||
@@ -272,7 +272,7 @@ const makeStreamingRequest = (element, callback) => {
|
||||
}
|
||||
|
||||
makeStreamingRequest(42, (data) => {
|
||||
console.log('got response data:', event.data)
|
||||
console.log('got response data:', data)
|
||||
})
|
||||
// We will see "got response data: 42" 10 times.
|
||||
```
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
# Testing Widevine CDM
|
||||
|
||||
In Electron you can use the Widevine CDM library shipped with Chrome browser.
|
||||
|
||||
Widevine Content Decryption Modules (CDMs) are how streaming services protect
|
||||
content using HTML5 video to web browsers without relying on an NPAPI plugin
|
||||
like Flash or Silverlight. Widevine support is an alternative solution for
|
||||
streaming services that currently rely on Silverlight for playback of
|
||||
DRM-protected video content. It will allow websites to show DRM-protected video
|
||||
content in Firefox without the use of NPAPI plugins. The Widevine CDM runs in an
|
||||
open-source CDM sandbox providing better user security than NPAPI plugins.
|
||||
|
||||
#### Note on VMP
|
||||
|
||||
As of [`Electron v1.8.0 (Chrome v59)`](https://electronjs.org/releases#1.8.1),
|
||||
the below steps are may only be some of the necessary steps to enable Widevine;
|
||||
any app on or after that version intending to use the Widevine CDM may need to
|
||||
be signed using a license obtained from [Widevine](https://www.widevine.com/)
|
||||
itself.
|
||||
|
||||
Per [Widevine](https://www.widevine.com/):
|
||||
|
||||
> Chrome 59 (and later) includes support for Verified Media Path (VMP). VMP
|
||||
> provides a method to verify the authenticity of a device platform. For browser
|
||||
> deployments, this will provide an additional signal to determine if a
|
||||
> browser-based implementation is reliable and secure.
|
||||
>
|
||||
> The proxy integration guide has been updated with information about VMP and
|
||||
> how to issue licenses.
|
||||
>
|
||||
> Widevine recommends our browser-based integrations (vendors and browser-based
|
||||
> applications) add support for VMP.
|
||||
|
||||
To enable video playback with this new restriction,
|
||||
[castLabs](https://castlabs.com/open-source/downstream/) has created a
|
||||
[fork](https://github.com/castlabs/electron-releases) that has implemented the
|
||||
necessary changes to enable Widevine to be played in an Electron application if
|
||||
one has obtained the necessary licenses from widevine.
|
||||
|
||||
## Getting the library
|
||||
|
||||
Open `chrome://components/` in Chrome browser, find `Widevine Content Decryption Module`
|
||||
and make sure it is up to date, then you can find the library files from the
|
||||
application directory.
|
||||
|
||||
### On Windows
|
||||
|
||||
The library file `widevinecdm.dll` will be under
|
||||
`Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/`
|
||||
directory.
|
||||
|
||||
### On macOS
|
||||
|
||||
The library file `libwidevinecdm.dylib` will be under
|
||||
`/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/`
|
||||
directory.
|
||||
|
||||
**Note:** Make sure that chrome version used by Electron is greater than or
|
||||
equal to the `min_chrome_version` value of Chrome's widevine cdm component.
|
||||
The value can be found in `manifest.json` under `WidevineCdm` directory.
|
||||
|
||||
## Using the library
|
||||
|
||||
After getting the library files, you should pass the path to the file
|
||||
with `--widevine-cdm-path` command line switch, and the library's version
|
||||
with `--widevine-cdm-version` switch. The command line switches have to be
|
||||
passed before the `ready` event of `app` module gets emitted.
|
||||
|
||||
Example code:
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// You have to pass the directory that contains widevine library here, it is
|
||||
// * `libwidevinecdm.dylib` on macOS,
|
||||
// * `widevinecdm.dll` on Windows.
|
||||
app.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevine_library')
|
||||
// The version of plugin can be got from `chrome://components` page in Chrome.
|
||||
app.commandLine.appendSwitch('widevine-cdm-version', '1.4.8.866')
|
||||
|
||||
let win = null
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow()
|
||||
win.show()
|
||||
})
|
||||
```
|
||||
|
||||
## Verifying Widevine CDM support
|
||||
|
||||
To verify whether widevine works, you can use following ways:
|
||||
|
||||
* Open https://shaka-player-demo.appspot.com/ and load a manifest that uses
|
||||
`Widevine`.
|
||||
* Open http://www.dash-player.com/demo/drm-test-area/, check whether the page
|
||||
says `bitdash uses Widevine in your browser`, then play the video.
|
||||
@@ -123,7 +123,7 @@ the list of versions in the [electron/releases] repository.
|
||||
[homebrew]: https://brew.sh/
|
||||
[mdn-guide]: https://developer.mozilla.org/en-US/docs/Learn/
|
||||
[node]: https://nodejs.org/
|
||||
[node-guide]: https://nodejs.dev/learn
|
||||
[node-guide]: https://nodejs.dev/en/learn/
|
||||
[node-download]: https://nodejs.org/en/download/
|
||||
[nvm]: https://github.com/nvm-sh/nvm
|
||||
[process-model]: ./process-model.md
|
||||
|
||||
@@ -369,12 +369,12 @@ run. Create a launch.json configuration in a new `.vscode` folder in your projec
|
||||
"name": "Renderer",
|
||||
"port": 9222,
|
||||
"request": "attach",
|
||||
"type": "pwa-chrome",
|
||||
"type": "chrome",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "Main",
|
||||
"type": "pwa-node",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
|
||||
@@ -398,11 +398,11 @@ What we have done in the `launch.json` file is to create 3 configurations:
|
||||
- `Main` is used to start the main process and also expose port 9222 for remote debugging
|
||||
(`--remote-debugging-port=9222`). This is the port that we will use to attach the debugger
|
||||
for the `Renderer`. Because the main process is a Node.js process, the type is set to
|
||||
`pwa-node` (`pwa-` is the prefix that tells VS Code to use the latest JavaScript debugger).
|
||||
`node`.
|
||||
- `Renderer` is used to debug the renderer process. Because the main process is the one
|
||||
that creates the process, we have to "attach" to it (`"request": "attach"`) instead of
|
||||
creating a new one.
|
||||
The renderer process is a web one, so the debugger we have to use is `pwa-chrome`.
|
||||
The renderer process is a web one, so the debugger we have to use is `chrome`.
|
||||
- `Main + renderer` is a [compound task] that executes the previous ones simultaneously.
|
||||
|
||||
:::caution
|
||||
|
||||
@@ -111,6 +111,12 @@ Electron Forge can be configured to create distributables in different OS-specif
|
||||
|
||||
:::
|
||||
|
||||
:::tip Creating and Adding Application Icons
|
||||
|
||||
Setting custom application icons requires a few additions to your config. Check out [Forge's icon tutorial] for more information.
|
||||
|
||||
:::
|
||||
|
||||
:::note Packaging without Electron Forge
|
||||
|
||||
If you want to manually package your code, or if you're just interested understanding the
|
||||
@@ -214,6 +220,7 @@ information.
|
||||
[electron forge]: https://www.electronforge.io
|
||||
[electron forge cli documentation]: https://www.electronforge.io/cli#commands
|
||||
[makers]: https://www.electronforge.io/config/makers
|
||||
[Forge's icon tutorial]: https://www.electronforge.io/guides/create-and-add-icons
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
|
||||
@@ -672,8 +672,6 @@ filenames = {
|
||||
"shell/renderer/electron_render_frame_observer.h",
|
||||
"shell/renderer/electron_renderer_client.cc",
|
||||
"shell/renderer/electron_renderer_client.h",
|
||||
"shell/renderer/electron_renderer_pepper_host_factory.cc",
|
||||
"shell/renderer/electron_renderer_pepper_host_factory.h",
|
||||
"shell/renderer/electron_sandboxed_renderer_client.cc",
|
||||
"shell/renderer/electron_sandboxed_renderer_client.h",
|
||||
"shell/renderer/guest_view_container.cc",
|
||||
|
||||
@@ -475,12 +475,14 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
const removeListeners = () => {
|
||||
this.removeListener('did-finish-load', finishListener);
|
||||
this.removeListener('did-fail-load', failListener);
|
||||
this.removeListener('did-navigate-in-page', finishListener);
|
||||
this.removeListener('did-start-navigation', navigationListener);
|
||||
this.removeListener('did-stop-loading', stopLoadingListener);
|
||||
this.removeListener('destroyed', stopLoadingListener);
|
||||
};
|
||||
this.on('did-finish-load', finishListener);
|
||||
this.on('did-fail-load', failListener);
|
||||
this.on('did-navigate-in-page', finishListener);
|
||||
this.on('did-start-navigation', navigationListener);
|
||||
this.on('did-stop-loading', stopLoadingListener);
|
||||
this.on('destroyed', stopLoadingListener);
|
||||
|
||||
@@ -186,7 +186,10 @@ export class SrcAttribute extends WebViewAttribute {
|
||||
opts.userAgent = useragent;
|
||||
}
|
||||
|
||||
(this.webViewImpl.webviewNode as Electron.WebviewTag).loadURL(this.getValue(), opts);
|
||||
(this.webViewImpl.webviewNode as Electron.WebviewTag).loadURL(this.getValue(), opts)
|
||||
.catch(err => {
|
||||
console.error('Unexpected error while loading URL', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,22 @@ function isInstalled () {
|
||||
|
||||
// unzips and makes path.txt point at the correct executable
|
||||
function extractFile (zipPath) {
|
||||
return extract(zipPath, { dir: path.join(__dirname, 'dist') })
|
||||
.then(() => fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath));
|
||||
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
|
||||
|
||||
return extract(zipPath, { dir: path.join(__dirname, 'dist') }).then(() => {
|
||||
// If the zip contains an "electron.d.ts" file,
|
||||
// move that up
|
||||
const srcTypeDefPath = path.join(distPath, 'electron.d.ts');
|
||||
const targetTypeDefPath = path.join(__dirname, 'electron.d.ts');
|
||||
const hasTypeDefinitions = fs.existsSync(srcTypeDefPath);
|
||||
|
||||
if (hasTypeDefinitions) {
|
||||
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
|
||||
}
|
||||
|
||||
// Write a "path.txt" file.
|
||||
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
|
||||
});
|
||||
}
|
||||
|
||||
function getPlatformPath () {
|
||||
|
||||
12
package.json
12
package.json
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "20.2.0",
|
||||
"version": "0.0.0-development",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/docs-parser": "^0.12.4",
|
||||
"@electron/typescript-definitions": "^8.9.5",
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/docs-parser": "^1.0.0",
|
||||
"@electron/typescript-definitions": "^8.10.0",
|
||||
"@octokit/auth-app": "^2.10.0",
|
||||
"@octokit/rest": "^18.0.3",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
@@ -31,7 +32,6 @@
|
||||
"@types/webpack-env": "^1.16.3",
|
||||
"@typescript-eslint/eslint-plugin": "^4.4.1",
|
||||
"@typescript-eslint/parser": "^4.4.1",
|
||||
"asar": "^3.1.0",
|
||||
"aws-sdk": "^2.814.0",
|
||||
"check-for-leaks": "^1.2.1",
|
||||
"colors": "1.4.0",
|
||||
@@ -89,7 +89,7 @@
|
||||
"lint:docs-relative-links": "python3 ./script/check-relative-doc-links.py",
|
||||
"lint:markdownlint": "markdownlint \"*.md\" \"docs/**/*.md\"",
|
||||
"lint:js-in-markdown": "standard-markdown docs",
|
||||
"create-api-json": "electron-docs-parser --dir=./",
|
||||
"create-api-json": "node script/create-api-json.js",
|
||||
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --api=electron-api.json && node spec/ts-smoke/runner.js",
|
||||
"gn-typescript-definitions": "npm run create-typescript-definitions && shx cp electron.d.ts",
|
||||
"pre-flight": "pre-flight",
|
||||
@@ -146,4 +146,4 @@
|
||||
"resolutions": {
|
||||
"nan": "nodejs/nan#16fa32231e2ccd89d2804b3f765319128b20c4ac"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
patches/angle/.patches
Normal file
1
patches/angle/.patches
Normal file
@@ -0,0 +1 @@
|
||||
cherry-pick-b8636b57b8f2.patch
|
||||
46
patches/angle/cherry-pick-b8636b57b8f2.patch
Normal file
46
patches/angle/cherry-pick-b8636b57b8f2.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
From b8636b57b8f231994ecb3fb14f181c593c83a3fb Mon Sep 17 00:00:00 2001
|
||||
From: Jamie Madill <jmadill@chromium.org>
|
||||
Date: Mon, 29 Aug 2022 16:25:46 -0400
|
||||
Subject: [PATCH] [M106] Vulkan: Ensure we sync the draw FB before beingQuery.
|
||||
|
||||
Bug: chromium:1354271
|
||||
(cherry picked from commit 4ebdac790c76b65abf5703bcef9482c638076195)
|
||||
Change-Id: I7b715a9c28badfe58a0ae1a478d2b4e8bbd23c47
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3956939
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
---
|
||||
|
||||
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
|
||||
index 168104e..2f498d3 100644
|
||||
--- a/src/libANGLE/State.h
|
||||
+++ b/src/libANGLE/State.h
|
||||
@@ -603,6 +603,11 @@
|
||||
|
||||
bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
|
||||
|
||||
+ bool isDrawFramebufferBindingDirty() const
|
||||
+ {
|
||||
+ return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
|
||||
+ }
|
||||
+
|
||||
// Sets the dirty bit for the program executable.
|
||||
angle::Result onProgramExecutableChange(const Context *context, Program *program);
|
||||
// Sets the dirty bit for the program pipeline executable.
|
||||
diff --git a/src/libANGLE/renderer/vulkan/QueryVk.cpp b/src/libANGLE/renderer/vulkan/QueryVk.cpp
|
||||
index 9f475e6..6ef5f72 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/QueryVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp
|
||||
@@ -303,6 +303,13 @@
|
||||
{
|
||||
ContextVk *contextVk = vk::GetImpl(context);
|
||||
|
||||
+ // Ensure that we start with the right RenderPass when we begin a new query.
|
||||
+ if (contextVk->getState().isDrawFramebufferBindingDirty())
|
||||
+ {
|
||||
+ ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
|
||||
+ RenderPassClosureReason::FramebufferBindingChange));
|
||||
+ }
|
||||
+
|
||||
mCachedResultValid = false;
|
||||
|
||||
// Transform feedback query is handled by a CPU-calculated value when emulated.
|
||||
@@ -124,3 +124,41 @@ feat_add_set_can_resize_mutator.patch
|
||||
cherry-pick-2083e894852c.patch
|
||||
cherry-pick-51daffbf5cd8.patch
|
||||
dpwa_enable_window_controls_overlay_by_default.patch
|
||||
create_browser_v8_snapshot_file_name_fuse.patch
|
||||
cherry-pick-fefd6198da31.patch
|
||||
cherry-pick-1eb1e18ad41d.patch
|
||||
cherry-pick-05a0d99c9715.patch
|
||||
cherry-pick-c83640db21b5.patch
|
||||
fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch
|
||||
cherry-pick-65f0ef609c00.patch
|
||||
cherry-pick-cb9dff93f3d4.patch
|
||||
build_fix_building_with_enable_plugins_false.patch
|
||||
build_allow_electron_to_use_exec_script.patch
|
||||
cherry-pick-d5ffb4dd4112.patch
|
||||
cherry-pick-65d46507a0c9.patch
|
||||
cherry-pick-933cc81c6bad.patch
|
||||
cherry-pick-06c87f9f42ff.patch
|
||||
cherry-pick-67c9cbc784d6.patch
|
||||
cherry-pick-a1cbf05b4163.patch
|
||||
cherry-pick-ac4785387fff.patch
|
||||
cherry-pick-81cb17c24788.patch
|
||||
cherry-pick-9b3d0e2f1aab.patch
|
||||
cherry-pick-1894458e04a2.patch
|
||||
cherry-pick-6b4af5d82083.patch
|
||||
cherry-pick-176c526846cb.patch
|
||||
cherry-pick-65ad70274d4b.patch
|
||||
cherry-pick-f46db6aac3e9.patch
|
||||
cherry-pick-2ef09109c0ec.patch
|
||||
cherry-pick-f98adc846aad.patch
|
||||
cherry-pick-eed5a4de2c40.patch
|
||||
cherry-pick-d1d654d73222.patch
|
||||
cherry-pick-42e15c2055c4.patch
|
||||
cherry-pick-77208afba04d.patch
|
||||
mojo_disable_sync_call_interrupts_in_the_browser.patch
|
||||
mojo_validate_that_a_message_is_allowed_to_use_the_sync_flag.patch
|
||||
cherry-pick-819d876e1bb8.patch
|
||||
cherry-pick-43637378b14e.patch
|
||||
win_fix_touch_mode_detection_dcheck_in_canary.patch
|
||||
cherry-pick-ca2b108a0f1f.patch
|
||||
cherry-pick-d652130c4bc2.patch
|
||||
cherry-pick-e545559df538.patch
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@salesforce.com>
|
||||
Date: Fri, 21 Oct 2022 16:29:06 -0700
|
||||
Subject: build: allow electron to use exec_script
|
||||
|
||||
This is similar to the //build usecase so we're OK adding ourselves here
|
||||
|
||||
diff --git a/.gn b/.gn
|
||||
index 7d538f812d72e0937e7a031e1c53651c352149c5..1cad40a9825f3c6df67dbcc12d2f9650aad809b2 100644
|
||||
--- a/.gn
|
||||
+++ b/.gn
|
||||
@@ -169,4 +169,6 @@ exec_script_whitelist =
|
||||
|
||||
"//tools/grit/grit_rule.gni",
|
||||
"//tools/gritsettings/BUILD.gn",
|
||||
+
|
||||
+ "//electron/BUILD.gn"
|
||||
]
|
||||
@@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Milan Burda <miburda@microsoft.com>
|
||||
Date: Sun, 30 Oct 2022 22:32:39 +0100
|
||||
Subject: build: fix building with enable_plugins = false
|
||||
|
||||
This issue is fixed in latest Chromium
|
||||
|
||||
diff --git a/tools/ipc_fuzzer/message_lib/BUILD.gn b/tools/ipc_fuzzer/message_lib/BUILD.gn
|
||||
index 00618d9f81cabd5084218431658fd91d22fb4208..26be64a51fc5767e0ee97681a0b3f2dfd74159fe 100644
|
||||
--- a/tools/ipc_fuzzer/message_lib/BUILD.gn
|
||||
+++ b/tools/ipc_fuzzer/message_lib/BUILD.gn
|
||||
@@ -3,6 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//components/nacl/features.gni")
|
||||
+import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//remoting/remoting_enable.gni")
|
||||
|
||||
static_library("ipc_message_lib") {
|
||||
@@ -22,7 +23,6 @@ static_library("ipc_message_lib") {
|
||||
"//ipc",
|
||||
"//media/cast:net",
|
||||
"//media/gpu/ipc/common",
|
||||
- "//ppapi/proxy:ipc",
|
||||
"//skia",
|
||||
"//third_party/blink/public:blink",
|
||||
"//third_party/blink/public:blink_headers",
|
||||
@@ -49,4 +49,7 @@ static_library("ipc_message_lib") {
|
||||
if (enable_remoting) {
|
||||
public_deps += [ "//remoting/host" ]
|
||||
}
|
||||
+ if (enable_plugins) {
|
||||
+ public_deps += [ "//ppapi/proxy:ipc" ]
|
||||
+ }
|
||||
}
|
||||
34
patches/chromium/cherry-pick-05a0d99c9715.patch
Normal file
34
patches/chromium/cherry-pick-05a0d99c9715.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Bokan <bokan@chromium.org>
|
||||
Date: Thu, 28 Jul 2022 18:09:13 +0000
|
||||
Subject: Prevent handling input for provisional frames
|
||||
|
||||
Bug: 1347644,1322812
|
||||
Change-Id: Ifd60f6aa593ce23ca6cbb65552fc9fb8f8690035
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3791883
|
||||
Commit-Queue: David Bokan <bokan@chromium.org>
|
||||
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1029361}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
index fe775337fbc22817d7489df143821eea2d9425ec..13a241273090e54fabdba9d82510e36d2386c4a4 100644
|
||||
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
@@ -2460,10 +2460,15 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent(
|
||||
DCHECK(!WebInputEvent::IsTouchEventType(input_event.GetType()));
|
||||
CHECK(LocalRootImpl());
|
||||
|
||||
+ // Clients shouldn't be dispatching events to a provisional frame but this
|
||||
+ // can happen. Ensure that event handling can assume we're in a committed
|
||||
+ // frame.
|
||||
+ if (IsProvisional())
|
||||
+ return WebInputEventResult::kHandledSuppressed;
|
||||
+
|
||||
// Only record metrics for the root frame.
|
||||
- if (ForTopMostMainFrame()) {
|
||||
+ if (ForTopMostMainFrame())
|
||||
GetPage()->GetVisualViewport().StartTrackingPinchStats();
|
||||
- }
|
||||
|
||||
// If a drag-and-drop operation is in progress, ignore input events except
|
||||
// PointerCancel and GestureLongPress.
|
||||
153
patches/chromium/cherry-pick-06c87f9f42ff.patch
Normal file
153
patches/chromium/cherry-pick-06c87f9f42ff.patch
Normal file
@@ -0,0 +1,153 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rune Lillesveen <futhark@chromium.org>
|
||||
Date: Fri, 14 Oct 2022 09:52:34 +0000
|
||||
Subject: Avoid layout roots in subtrees skipped for style recalc
|
||||
|
||||
Layout roots are laid out from inner to outer in LocalFrameView. DOM
|
||||
mutations may have added layout roots inside size container subtrees
|
||||
before style recalc. If we decide to postpone style recalc until layout
|
||||
of the size container, it means we may try to layout a root inside a
|
||||
subtree skipped for style recalc. That causes a DCHECK and possibly
|
||||
other issues.
|
||||
|
||||
This also fixes the use-after-poison issue 1365330.
|
||||
|
||||
(cherry picked from commit 0f0f1e99201fadb3c68518350e1cd6af1b665346)
|
||||
|
||||
Bug: 1371820, 1365330
|
||||
Change-Id: Ia48890c08aacfe7b9a3e660817702abce0570564
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934847
|
||||
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
|
||||
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1055853}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3953455
|
||||
Auto-Submit: Rune Lillesveen <futhark@chromium.org>
|
||||
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#836}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
|
||||
index f51b8878eb0abe23889a07277efeaf7cdf961cc8..ddcef20b47357e58acae08b4183db6187b046f80 100644
|
||||
--- a/third_party/blink/renderer/core/css/style_engine.cc
|
||||
+++ b/third_party/blink/renderer/core/css/style_engine.cc
|
||||
@@ -2808,6 +2808,7 @@ void StyleEngine::RecalcStyle(StyleRecalcChange change,
|
||||
const StyleRecalcContext& style_recalc_context) {
|
||||
DCHECK(GetDocument().documentElement());
|
||||
ScriptForbiddenScope forbid_script;
|
||||
+ SkipStyleRecalcScope skip_scope(*this);
|
||||
CheckPseudoHasCacheScope check_pseudo_has_cache_scope(&GetDocument());
|
||||
Element& root_element = style_recalc_root_.RootElement();
|
||||
Element* parent = FlatTreeTraversal::ParentElement(root_element);
|
||||
@@ -3400,4 +3401,17 @@ void StyleEngine::MarkForLayoutTreeChangesAfterDetach() {
|
||||
parent_for_detached_subtree_ = nullptr;
|
||||
}
|
||||
|
||||
+bool StyleEngine::AllowSkipStyleRecalcForScope() const {
|
||||
+ if (InContainerQueryStyleRecalc())
|
||||
+ return true;
|
||||
+ if (LocalFrameView* view = GetDocument().View()) {
|
||||
+ // Existing layout roots before starting style recalc may end up being
|
||||
+ // inside skipped subtrees if we allowed skipping. If we start out with an
|
||||
+ // empty list, any added ones will be a result of an element style recalc,
|
||||
+ // which means the will not be inside a skipped subtree.
|
||||
+ return !view->IsSubtreeLayout();
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
|
||||
index a6c325b69e5bc43c657519f4c0730f6e2efd4f71..f7ccc6c2b7b306d76bba60cf46da91a5b291c29e 100644
|
||||
--- a/third_party/blink/renderer/core/css/style_engine.h
|
||||
+++ b/third_party/blink/renderer/core/css/style_engine.h
|
||||
@@ -178,6 +178,20 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
base::AutoReset<bool> allow_marking_;
|
||||
};
|
||||
|
||||
+ // Set up the condition for allowing to skip style recalc before starting
|
||||
+ // RecalcStyle().
|
||||
+ class SkipStyleRecalcScope {
|
||||
+ STACK_ALLOCATED();
|
||||
+
|
||||
+ public:
|
||||
+ explicit SkipStyleRecalcScope(StyleEngine& engine)
|
||||
+ : allow_skip_(&engine.allow_skip_style_recalc_,
|
||||
+ engine.AllowSkipStyleRecalcForScope()) {}
|
||||
+
|
||||
+ private:
|
||||
+ base::AutoReset<bool> allow_skip_;
|
||||
+ };
|
||||
+
|
||||
explicit StyleEngine(Document&);
|
||||
~StyleEngine() override;
|
||||
|
||||
@@ -342,6 +356,10 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
|
||||
bool MarkReattachAllowed() const;
|
||||
|
||||
+ // Returns true if we can skip style recalc for a size container subtree and
|
||||
+ // resume it during layout.
|
||||
+ bool SkipStyleRecalcAllowed() const { return allow_skip_style_recalc_; }
|
||||
+
|
||||
CSSFontSelector* GetFontSelector() { return font_selector_; }
|
||||
|
||||
void RemoveFontFaceRules(const HeapVector<Member<const StyleRuleFontFace>>&);
|
||||
@@ -743,6 +761,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
Element& changed_element,
|
||||
bool for_pseudo_change);
|
||||
|
||||
+ // Initialization value for SkipStyleRecalcScope.
|
||||
+ bool AllowSkipStyleRecalcForScope() const;
|
||||
+
|
||||
Member<Document> document_;
|
||||
|
||||
// Tracks the number of currently loading top-level stylesheets. Sheets loaded
|
||||
@@ -812,6 +833,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
|
||||
// AllowMarkStyleDirtyFromRecalcScope.
|
||||
bool allow_mark_for_reattach_from_rebuild_layout_tree_{false};
|
||||
|
||||
+ // Set to true if we are allowed to skip recalc for a size container subtree.
|
||||
+ bool allow_skip_style_recalc_{false};
|
||||
+
|
||||
// See enum ViewportUnitFlag.
|
||||
unsigned viewport_unit_dirty_flags_{0};
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
|
||||
index 8e5c4aab2e37ed0acda0ef56273d007fbaa58780..2df360c33c54e12af341b77771fcda95e562fa92 100644
|
||||
--- a/third_party/blink/renderer/core/dom/element.cc
|
||||
+++ b/third_party/blink/renderer/core/dom/element.cc
|
||||
@@ -3532,6 +3532,10 @@ bool Element::SkipStyleRecalcForContainer(
|
||||
const ComputedStyle& style,
|
||||
const StyleRecalcChange& child_change) {
|
||||
DCHECK(RuntimeEnabledFeatures::CSSContainerSkipStyleRecalcEnabled());
|
||||
+
|
||||
+ if (!GetDocument().GetStyleEngine().SkipStyleRecalcAllowed())
|
||||
+ return false;
|
||||
+
|
||||
if (!child_change.TraversePseudoElements(*this)) {
|
||||
// If none of the children or pseudo elements need to be traversed for style
|
||||
// recalc, there is no point in marking the subtree as skipped.
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e3e709a240bd870250b2747c94fe96880bdf52e3
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html
|
||||
@@ -0,0 +1,17 @@
|
||||
+<!doctype html>
|
||||
+<html class="reftest-wait">
|
||||
+<link rel="help" href="https://crbug.com/1371820">
|
||||
+<style>
|
||||
+ body, div, img { container-type: size; }
|
||||
+</style>
|
||||
+<p>Pass if no crash.</p>
|
||||
+<div id="div"><img id="img" alt="a"></div>
|
||||
+<script>
|
||||
+ requestAnimationFrame(() => requestAnimationFrame(() => {
|
||||
+ // Adds a layout root inside the div size container.
|
||||
+ img.alt = img.src = "b";
|
||||
+ // Marks div size container for layout which skips style recalc for the sub-tree.
|
||||
+ div.style.width = "500px";
|
||||
+ document.documentElement.classList.remove("reftest-wait");
|
||||
+ }));
|
||||
+</script>
|
||||
192
patches/chromium/cherry-pick-176c526846cb.patch
Normal file
192
patches/chromium/cherry-pick-176c526846cb.patch
Normal file
@@ -0,0 +1,192 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Sesek <rsesek@chromium.org>
|
||||
Date: Fri, 18 Nov 2022 19:31:38 +0000
|
||||
Subject: Fix a data race leading to use-after-free in mojo::ChannelMac
|
||||
ShutDown
|
||||
|
||||
(cherry picked from commit bd8a1e43aa93d5bb7674cb5a431e7375f7e2f192)
|
||||
|
||||
Bug: 1378564
|
||||
Change-Id: I67041b1e2ef08dd0ee1ccbf6d534249c539b74db
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4027242
|
||||
Commit-Queue: Robert Sesek <rsesek@chromium.org>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1071700}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4035114
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Robert Sesek <rsesek@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#881}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/mojo/core/channel_mac.cc b/mojo/core/channel_mac.cc
|
||||
index 686dea5c783af06e41c290b03db251ca584d9a72..a24d5ab4ea9ae63f652acc2f903e577d45b1f0ee 100644
|
||||
--- a/mojo/core/channel_mac.cc
|
||||
+++ b/mojo/core/channel_mac.cc
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "base/mac/scoped_mach_vm.h"
|
||||
#include "base/message_loop/message_pump_for_io.h"
|
||||
#include "base/task/current_thread.h"
|
||||
+#include "base/thread_annotations.h"
|
||||
#include "base/trace_event/typed_macros.h"
|
||||
|
||||
extern "C" {
|
||||
@@ -167,7 +168,10 @@ class ChannelMac : public Channel,
|
||||
vm_allocate(mach_task_self(), &address, size,
|
||||
VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | VM_FLAGS_ANYWHERE);
|
||||
MACH_CHECK(kr == KERN_SUCCESS, kr) << "vm_allocate";
|
||||
- send_buffer_.reset(address, size);
|
||||
+ {
|
||||
+ base::AutoLock lock(write_lock_);
|
||||
+ send_buffer_.reset(address, size);
|
||||
+ }
|
||||
|
||||
kr = vm_allocate(mach_task_self(), &address, size,
|
||||
VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | VM_FLAGS_ANYWHERE);
|
||||
@@ -207,7 +211,11 @@ class ChannelMac : public Channel,
|
||||
|
||||
watch_controller_.StopWatchingMachPort();
|
||||
|
||||
- send_buffer_.reset();
|
||||
+ {
|
||||
+ base::AutoLock lock(write_lock_);
|
||||
+ send_buffer_.reset();
|
||||
+ reject_writes_ = true;
|
||||
+ }
|
||||
receive_buffer_.reset();
|
||||
incoming_handles_.clear();
|
||||
|
||||
@@ -315,7 +323,7 @@ class ChannelMac : public Channel,
|
||||
SendPendingMessagesLocked();
|
||||
}
|
||||
|
||||
- void SendPendingMessagesLocked() {
|
||||
+ void SendPendingMessagesLocked() EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
|
||||
// If a previous send failed due to the receiver's kernel message queue
|
||||
// being full, attempt to send that failed message first.
|
||||
if (send_buffer_contains_message_ && !reject_writes_) {
|
||||
@@ -342,7 +350,8 @@ class ChannelMac : public Channel,
|
||||
}
|
||||
}
|
||||
|
||||
- bool SendMessageLocked(MessagePtr message) {
|
||||
+ bool SendMessageLocked(MessagePtr message)
|
||||
+ EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
|
||||
DCHECK(!send_buffer_contains_message_);
|
||||
base::BufferIterator<char> buffer(
|
||||
reinterpret_cast<char*>(send_buffer_.address()), send_buffer_.size());
|
||||
@@ -437,7 +446,8 @@ class ChannelMac : public Channel,
|
||||
return MachMessageSendLocked(header);
|
||||
}
|
||||
|
||||
- bool MachMessageSendLocked(mach_msg_header_t* header) {
|
||||
+ bool MachMessageSendLocked(mach_msg_header_t* header)
|
||||
+ EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
|
||||
kern_return_t kr = mach_msg(header, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
|
||||
header->msgh_size, 0, MACH_PORT_NULL,
|
||||
/*timeout=*/0, MACH_PORT_NULL);
|
||||
@@ -659,7 +669,7 @@ class ChannelMac : public Channel,
|
||||
}
|
||||
|
||||
// Marks the channel as unaccepting of new messages and shuts it down.
|
||||
- void OnWriteErrorLocked(Error error) {
|
||||
+ void OnWriteErrorLocked(Error error) EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
|
||||
reject_writes_ = true;
|
||||
io_task_runner_->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ChannelMac::OnError, this, error));
|
||||
@@ -701,17 +711,17 @@ class ChannelMac : public Channel,
|
||||
// Lock that protects the following members.
|
||||
base::Lock write_lock_;
|
||||
// Whether writes should be rejected due to an internal error.
|
||||
- bool reject_writes_ = false;
|
||||
+ bool reject_writes_ GUARDED_BY(write_lock_) = false;
|
||||
// IO buffer for sending Mach messages.
|
||||
- base::mac::ScopedMachVM send_buffer_;
|
||||
+ base::mac::ScopedMachVM send_buffer_ GUARDED_BY(write_lock_);
|
||||
// If a message timed out during send in MachMessageSendLocked(), this will
|
||||
// be true to indicate that |send_buffer_| contains a message that must
|
||||
// be sent. If this is true, then other calls to Write() queue messages onto
|
||||
// |pending_messages_|.
|
||||
- bool send_buffer_contains_message_ = false;
|
||||
+ bool send_buffer_contains_message_ GUARDED_BY(write_lock_) = false;
|
||||
// When |handshake_done_| is false or |send_buffer_contains_message_| is true,
|
||||
// calls to Write() will enqueue messages here.
|
||||
- base::circular_deque<MessagePtr> pending_messages_;
|
||||
+ base::circular_deque<MessagePtr> pending_messages_ GUARDED_BY(write_lock_);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
diff --git a/mojo/core/channel_unittest.cc b/mojo/core/channel_unittest.cc
|
||||
index e9dee384440ee5a0500e86c522eef19c12bd8045..47422267cbaa0d3f90be6adc851a0651c1b74133 100644
|
||||
--- a/mojo/core/channel_unittest.cc
|
||||
+++ b/mojo/core/channel_unittest.cc
|
||||
@@ -712,6 +712,69 @@ TEST(ChannelTest, SendToDeadMachPortName) {
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
+TEST(ChannelTest, ShutDownStress) {
|
||||
+ base::test::SingleThreadTaskEnvironment task_environment(
|
||||
+ base::test::TaskEnvironment::MainThreadType::IO);
|
||||
+
|
||||
+ // Create a second IO thread for Channel B.
|
||||
+ base::Thread peer_thread("channel_b_io");
|
||||
+ peer_thread.StartWithOptions(
|
||||
+ base::Thread::Options(base::MessagePumpType::IO, 0));
|
||||
+
|
||||
+ // Create two channels, A and B, which run on different threads.
|
||||
+ PlatformChannel platform_channel;
|
||||
+
|
||||
+ CallbackChannelDelegate delegate_a;
|
||||
+ scoped_refptr<Channel> channel_a = Channel::Create(
|
||||
+ &delegate_a, ConnectionParams(platform_channel.TakeLocalEndpoint()),
|
||||
+ Channel::HandlePolicy::kRejectHandles,
|
||||
+ task_environment.GetMainThreadTaskRunner());
|
||||
+ channel_a->Start();
|
||||
+
|
||||
+ scoped_refptr<Channel> channel_b = Channel::Create(
|
||||
+ nullptr, ConnectionParams(platform_channel.TakeRemoteEndpoint()),
|
||||
+ Channel::HandlePolicy::kRejectHandles, peer_thread.task_runner());
|
||||
+ channel_b->Start();
|
||||
+
|
||||
+ base::WaitableEvent go_event;
|
||||
+
|
||||
+ // Warm up the channel to ensure that A and B are connected, then quit.
|
||||
+ channel_b->Write(Channel::Message::CreateMessage(0, 0));
|
||||
+ {
|
||||
+ base::RunLoop run_loop;
|
||||
+ delegate_a.set_on_message(run_loop.QuitClosure());
|
||||
+ run_loop.Run();
|
||||
+ }
|
||||
+
|
||||
+ // Block the peer thread while some tasks are queued up from the test main
|
||||
+ // thread.
|
||||
+ peer_thread.task_runner()->PostTask(
|
||||
+ FROM_HERE,
|
||||
+ base::BindOnce(&base::WaitableEvent::Wait, base::Unretained(&go_event)));
|
||||
+
|
||||
+ // First, write some messages for Channel B.
|
||||
+ for (int i = 0; i < 500; ++i) {
|
||||
+ channel_b->Write(Channel::Message::CreateMessage(0, 0));
|
||||
+ }
|
||||
+
|
||||
+ // Then shut down channel B.
|
||||
+ channel_b->ShutDown();
|
||||
+
|
||||
+ // Un-block the peer thread.
|
||||
+ go_event.Signal();
|
||||
+
|
||||
+ // And then flood the channel with messages. This will suss out data races
|
||||
+ // during Channel B's shutdown, since Writes can happen across threads
|
||||
+ // without a PostTask.
|
||||
+ for (int i = 0; i < 1000; ++i) {
|
||||
+ channel_b->Write(Channel::Message::CreateMessage(0, 0));
|
||||
+ }
|
||||
+
|
||||
+ // Explicitly join the thread to wait for pending tasks, which may reference
|
||||
+ // stack variables, to complete.
|
||||
+ peer_thread.Stop();
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
} // namespace core
|
||||
} // namespace mojo
|
||||
37
patches/chromium/cherry-pick-1894458e04a2.patch
Normal file
37
patches/chromium/cherry-pick-1894458e04a2.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Peraza <jperaza@chromium.org>
|
||||
Date: Thu, 3 Nov 2022 21:18:35 +0000
|
||||
Subject: Validate number of bytes read
|
||||
|
||||
Original commit:
|
||||
https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3994208
|
||||
|
||||
(cherry picked from commit 7585111a6c1dfa502f3ca1e3d27aed066e479fd9)
|
||||
|
||||
Bug: chromium:1380083
|
||||
Change-Id: If9708ccdbf6957ef169b35f8f89e2b0744d066d7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4000305
|
||||
Reviewed-by: Mark Mentovai <mark@chromium.org>
|
||||
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/5359@{#529}
|
||||
Cr-Original-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4004067
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#905}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/crashpad/crashpad/util/linux/ptrace_client.cc b/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
|
||||
index 1863841f73f64d89391646f5c3e5fc2e2766a6cc..32cc35d9567117fe0eb6f1ec4736ac4a15ddfd83 100644
|
||||
--- a/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
|
||||
+++ b/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
|
||||
@@ -331,6 +331,11 @@ ssize_t PtraceClient::ReadUpTo(VMAddress address, size_t size, void* buffer) {
|
||||
return total_read;
|
||||
}
|
||||
|
||||
+ if (static_cast<size_t>(bytes_read) > size) {
|
||||
+ LOG(ERROR) << "invalid size " << bytes_read;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (!LoggingReadFileExactly(sock_, buffer_c, bytes_read)) {
|
||||
return -1;
|
||||
}
|
||||
184
patches/chromium/cherry-pick-1eb1e18ad41d.patch
Normal file
184
patches/chromium/cherry-pick-1eb1e18ad41d.patch
Normal file
@@ -0,0 +1,184 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Date: Tue, 20 Sep 2022 17:43:47 +0000
|
||||
Subject: Add CSSTokenizer-created strings to CSSVariableData's backing strings
|
||||
|
||||
When computing the value of a registered custom property, we create
|
||||
a CSSVariableData object equivalent to the computed CSSValue by
|
||||
serializing that CSSValue to a String, then tokenizing that value.
|
||||
|
||||
The problem is that CSSTokenizer can create *new* string objects
|
||||
during the tokenization process (see calls to CSSTokenizer::
|
||||
RegisterString), without communicating that fact to the call-site.
|
||||
|
||||
Therefore, this CL adds a way to access those strings so they can
|
||||
be added to the backing strings of the CSSVariableData.
|
||||
|
||||
Also added a DCHECK to verify that we don't have any tokens with
|
||||
non-backed string pointers.
|
||||
|
||||
Fixed: 1358907
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3892782
|
||||
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
|
||||
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1046868}
|
||||
Change-Id: Ifb6d194508e99030a5a3ed5fbad5496b7263bdc1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3905727
|
||||
Auto-Submit: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#518}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/css_variable_data.cc b/third_party/blink/renderer/core/css/css_variable_data.cc
|
||||
index a2294cc70c59ac0357dddf0f7719cc3c09d23554..b3a61b312eb5f0360e8aa4cb706c60f0085fead9 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_variable_data.cc
|
||||
+++ b/third_party/blink/renderer/core/css/css_variable_data.cc
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "third_party/blink/renderer/core/css/css_variable_data.h"
|
||||
|
||||
+#include "base/containers/span.h"
|
||||
#include "third_party/blink/renderer/core/css/css_syntax_definition.h"
|
||||
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
|
||||
@@ -109,6 +110,51 @@ void CSSVariableData::ConsumeAndUpdateTokens(const CSSParserTokenRange& range) {
|
||||
UpdateTokens<UChar>(range, backing_string, tokens_);
|
||||
}
|
||||
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+template <typename CharacterType>
|
||||
+bool IsSubspan(base::span<const CharacterType> inner,
|
||||
+ base::span<const CharacterType> outer) {
|
||||
+ // Note that base::span uses CheckedContiguousIterator, which restricts
|
||||
+ // which comparisons are allowed. Therefore we must avoid begin()/end() here.
|
||||
+ return inner.data() >= outer.data() &&
|
||||
+ (inner.data() + inner.size()) <= (outer.data() + outer.size());
|
||||
+}
|
||||
+
|
||||
+bool TokenValueIsBacked(const CSSParserToken& token,
|
||||
+ const String& backing_string) {
|
||||
+ StringView value = token.Value();
|
||||
+ if (value.Is8Bit() != backing_string.Is8Bit())
|
||||
+ return false;
|
||||
+ return value.Is8Bit() ? IsSubspan(value.Span8(), backing_string.Span8())
|
||||
+ : IsSubspan(value.Span16(), backing_string.Span16());
|
||||
+}
|
||||
+
|
||||
+bool TokenValueIsBacked(const CSSParserToken& token,
|
||||
+ const Vector<String>& backing_strings) {
|
||||
+ DCHECK(token.HasStringBacking());
|
||||
+ for (const String& backing_string : backing_strings) {
|
||||
+ if (TokenValueIsBacked(token, backing_string)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+void CSSVariableData::VerifyStringBacking() const {
|
||||
+ for (const CSSParserToken& token : tokens_) {
|
||||
+ DCHECK(!token.HasStringBacking() ||
|
||||
+ TokenValueIsBacked(token, backing_strings_))
|
||||
+ << "Token value is not backed: " << token.Value().ToString();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+
|
||||
CSSVariableData::CSSVariableData(const CSSTokenizedValue& tokenized_value,
|
||||
bool is_animation_tainted,
|
||||
bool needs_variable_resolution,
|
||||
@@ -120,6 +166,9 @@ CSSVariableData::CSSVariableData(const CSSTokenizedValue& tokenized_value,
|
||||
base_url_(base_url.IsValid() ? base_url.GetString() : String()),
|
||||
charset_(charset) {
|
||||
ConsumeAndUpdateTokens(tokenized_value.range);
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ VerifyStringBacking();
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
}
|
||||
|
||||
const CSSValue* CSSVariableData::ParseForSyntax(
|
||||
diff --git a/third_party/blink/renderer/core/css/css_variable_data.h b/third_party/blink/renderer/core/css/css_variable_data.h
|
||||
index f042f85736c2c49f8337c29cb742976c5e97a14b..7be7d201313ec3e591e2c45c9fd5bda327856645 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_variable_data.h
|
||||
+++ b/third_party/blink/renderer/core/css/css_variable_data.h
|
||||
@@ -100,11 +100,18 @@ class CORE_EXPORT CSSVariableData : public RefCounted<CSSVariableData> {
|
||||
has_font_units_(has_font_units),
|
||||
has_root_font_units_(has_root_font_units),
|
||||
base_url_(base_url),
|
||||
- charset_(charset) {}
|
||||
+ charset_(charset) {
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ VerifyStringBacking();
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ }
|
||||
CSSVariableData(const CSSVariableData&) = delete;
|
||||
CSSVariableData& operator=(const CSSVariableData&) = delete;
|
||||
|
||||
void ConsumeAndUpdateTokens(const CSSParserTokenRange&);
|
||||
+#if EXPENSIVE_DCHECKS_ARE_ON()
|
||||
+ void VerifyStringBacking() const;
|
||||
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
|
||||
|
||||
// tokens_ may have raw pointers to string data, we store the String objects
|
||||
// owning that data in backing_strings_ to keep it alive alongside the
|
||||
diff --git a/third_party/blink/renderer/core/css/parser/css_tokenizer.h b/third_party/blink/renderer/core/css/parser/css_tokenizer.h
|
||||
index 817bcbd4b6b9a9a5519bb92d6870c5b16a19278f..682a44a478bcd0ee3aa1638601650fd420033625 100644
|
||||
--- a/third_party/blink/renderer/core/css/parser/css_tokenizer.h
|
||||
+++ b/third_party/blink/renderer/core/css/parser/css_tokenizer.h
|
||||
@@ -33,6 +33,7 @@ class CORE_EXPORT CSSTokenizer {
|
||||
wtf_size_t Offset() const { return input_.Offset(); }
|
||||
wtf_size_t PreviousOffset() const { return prev_offset_; }
|
||||
StringView StringRangeAt(wtf_size_t start, wtf_size_t length) const;
|
||||
+ const Vector<String>& StringPool() const { return string_pool_; }
|
||||
|
||||
private:
|
||||
CSSParserToken TokenizeSingle();
|
||||
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
index 6739b9de4b500d6173c04966905e26f856594502..f0082d88d70d4ea76604cfac77c09727de134f2a 100644
|
||||
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
|
||||
@@ -2176,6 +2176,10 @@ StyleBuilderConverter::ConvertRegisteredPropertyVariableData(
|
||||
|
||||
Vector<String> backing_strings;
|
||||
backing_strings.push_back(text);
|
||||
+ // CSSTokenizer may allocate new strings for some tokens (e.g. for escapes)
|
||||
+ // and produce tokens that point to those strings. We need to retain those
|
||||
+ // strings (if any) as well.
|
||||
+ backing_strings.AppendVector(tokenizer.StringPool());
|
||||
|
||||
const bool has_font_units = false;
|
||||
const bool has_root_font_units = false;
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
|
||||
index f03b257246e520bd93055203a5cb27188babc8ca..168495247a3b16a2203fb361f662b6db83044d09 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
|
||||
@@ -167,4 +167,6 @@ test_computed_value('<resolution>', '1dppx', '1dppx');
|
||||
test_computed_value('<resolution>', '96dpi', '1dppx');
|
||||
test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx');
|
||||
|
||||
+test_computed_value('*', 'url(why)', 'url(why)');
|
||||
+
|
||||
</script>
|
||||
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
|
||||
index 3823a752b99f506d11c50aee36474c6c51c849cd..eeed0dfc0def17b1ba636f7f6a076caf770e1327 100644
|
||||
--- a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
|
||||
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
|
||||
@@ -1,5 +1,5 @@
|
||||
This is a testharness.js-based test.
|
||||
-Found 60 tests; 59 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
|
||||
+Found 61 tests; 60 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
|
||||
PASS <length> values computed are correctly via var()-reference
|
||||
PASS <length> values computed are correctly via var()-reference when font-size is inherited
|
||||
PASS <length> values are computed correctly when font-size is inherited [14em]
|
||||
@@ -60,5 +60,6 @@ PASS * values are computed correctly [50dpi]
|
||||
PASS <resolution> values are computed correctly [1dppx]
|
||||
PASS <resolution> values are computed correctly [96dpi]
|
||||
FAIL <resolution> values are computed correctly [calc(1dppx + 96dpi)] assert_equals: expected "2dppx" but got "0dppx"
|
||||
+PASS * values are computed correctly [url(why)]
|
||||
Harness: the test ran to completion.
|
||||
|
||||
364
patches/chromium/cherry-pick-2ef09109c0ec.patch
Normal file
364
patches/chromium/cherry-pick-2ef09109c0ec.patch
Normal file
@@ -0,0 +1,364 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jun Kokatsu <jkokatsu@google.com>
|
||||
Date: Thu, 22 Sep 2022 22:16:55 +0000
|
||||
Subject: Unify security check for Javascript URL navigation
|
||||
|
||||
This change unifies CSP and Trusted Types check for Javascript URL
|
||||
navigations.
|
||||
|
||||
Bug: 1365082
|
||||
Change-Id: I46aea31a918c6397ea71fd5ab345bc9dc19d91c2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3905476
|
||||
Auto-Submit: Jun Kokatsu <jkokatsu@google.com>
|
||||
Commit-Queue: Jun Kokatsu <jkokatsu@google.com>
|
||||
Reviewed-by: Nate Chapin <japhet@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1050416}
|
||||
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
index 5ad3d687829db7ed64424b0f593e3aab7951e37e..da289bc7ffc4416ad817b0f344bc24cc0f084582 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
@@ -164,34 +164,9 @@ void ScriptController::ExecuteJavaScriptURL(
|
||||
const DOMWrapperWorld* world_for_csp) {
|
||||
DCHECK(url.ProtocolIsJavaScript());
|
||||
|
||||
- const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
|
||||
- String script_source = DecodeURLEscapeSequences(
|
||||
- url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
|
||||
-
|
||||
if (!window_->GetFrame())
|
||||
return;
|
||||
|
||||
- auto* policy = window_->GetContentSecurityPolicyForWorld(world_for_csp);
|
||||
- if (csp_disposition == network::mojom::CSPDisposition::CHECK &&
|
||||
- !policy->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
|
||||
- nullptr, script_source, String() /* nonce */,
|
||||
- window_->Url(), EventHandlerPosition().line_)) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- // TODO(crbug.com/896041): Investigate how trusted type checks can be
|
||||
- // implemented for isolated worlds.
|
||||
- const bool should_bypass_trusted_type_check =
|
||||
- csp_disposition == network::mojom::CSPDisposition::DO_NOT_CHECK ||
|
||||
- ContentSecurityPolicy::ShouldBypassMainWorldDeprecated(world_for_csp);
|
||||
- script_source = script_source.Substring(kJavascriptSchemeLength);
|
||||
- if (!should_bypass_trusted_type_check) {
|
||||
- script_source = TrustedTypesCheckForJavascriptURLinNavigation(
|
||||
- script_source, window_.Get());
|
||||
- if (script_source.IsEmpty())
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
bool had_navigation_before =
|
||||
window_->GetFrame()->Loader().HasProvisionalNavigation();
|
||||
|
||||
@@ -199,6 +174,9 @@ void ScriptController::ExecuteJavaScriptURL(
|
||||
// Step 6. "Let baseURL be settings's API base URL." [spec text]
|
||||
const KURL base_url = window_->BaseURL();
|
||||
|
||||
+ String script_source = window_->CheckAndGetJavascriptUrl(
|
||||
+ world_for_csp, url, nullptr /* element */, csp_disposition);
|
||||
+
|
||||
// Step 7. "Let script be the result of creating a classic script given
|
||||
// scriptSource, settings, baseURL, and the default classic script fetch
|
||||
// options." [spec text]
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
index 2f0615ee1454946d6f46f6626ce9b860a0e04fee..3eab00e4410e749aecdf600097cb68df22dcf072 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
@@ -415,6 +415,39 @@ bool LocalDOMWindow::CanExecuteScripts(
|
||||
return script_enabled;
|
||||
}
|
||||
|
||||
+String LocalDOMWindow::CheckAndGetJavascriptUrl(
|
||||
+ const DOMWrapperWorld* world,
|
||||
+ const KURL& url,
|
||||
+ Element* element,
|
||||
+ network::mojom::CSPDisposition csp_disposition) {
|
||||
+ const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
|
||||
+ String decoded_url = DecodeURLEscapeSequences(
|
||||
+ url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
|
||||
+ String script_source = decoded_url.Substring(kJavascriptSchemeLength);
|
||||
+
|
||||
+ if (csp_disposition == network::mojom::CSPDisposition::DO_NOT_CHECK)
|
||||
+ return script_source;
|
||||
+
|
||||
+ // Check the CSP of the caller (the "source browsing context") if required,
|
||||
+ // as per https://html.spec.whatwg.org/C/#javascript-protocol.
|
||||
+ if (!GetContentSecurityPolicyForWorld(world)->AllowInline(
|
||||
+ ContentSecurityPolicy::InlineType::kNavigation, element, decoded_url,
|
||||
+ String() /* nonce */, Url(), OrdinalNumber::First()))
|
||||
+ return String();
|
||||
+
|
||||
+ // TODO(crbug.com/896041): Investigate how trusted type checks can be
|
||||
+ // implemented for isolated worlds.
|
||||
+ if (ContentSecurityPolicy::ShouldBypassMainWorldDeprecated(world))
|
||||
+ return script_source;
|
||||
+
|
||||
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#require-trusted-types-for-pre-navigation-check
|
||||
+ // 4.9.1.1. require-trusted-types-for Pre-Navigation check
|
||||
+ script_source =
|
||||
+ TrustedTypesCheckForJavascriptURLinNavigation(script_source, this);
|
||||
+
|
||||
+ return script_source;
|
||||
+}
|
||||
+
|
||||
void LocalDOMWindow::ExceptionThrown(ErrorEvent* event) {
|
||||
MainThreadDebugger::Instance()->ExceptionThrown(this, event);
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
|
||||
index dcc065abe83948ca3d906f676365226dd82c732d..da06213cfbe2bd156509cd1ff67d600d528c34b0 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "services/metrics/public/cpp/ukm_recorder.h"
|
||||
#include "services/metrics/public/cpp/ukm_source_id.h"
|
||||
+#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
|
||||
#include "third_party/blink/public/common/frame/fullscreen_request_token.h"
|
||||
#include "third_party/blink/public/common/frame/payment_request_token.h"
|
||||
#include "third_party/blink/public/common/metrics/post_message_counter.h"
|
||||
@@ -211,6 +212,16 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
|
||||
mojom::blink::PermissionsPolicyFeature feature,
|
||||
UseCounterImpl::PermissionsPolicyUsageType type);
|
||||
|
||||
+ // Checks if navigation to Javascript URL is allowed. This check should run
|
||||
+ // before any action is taken (e.g. creating new window) for all
|
||||
+ // same-origin navigations.
|
||||
+ String CheckAndGetJavascriptUrl(
|
||||
+ const DOMWrapperWorld* world,
|
||||
+ const KURL& url,
|
||||
+ Element* element,
|
||||
+ network::mojom::CSPDisposition csp_disposition =
|
||||
+ network::mojom::CSPDisposition::CHECK);
|
||||
+
|
||||
Document* InstallNewDocument(const DocumentInit&);
|
||||
|
||||
// EventTarget overrides:
|
||||
diff --git a/third_party/blink/renderer/core/frame/location.cc b/third_party/blink/renderer/core/frame/location.cc
|
||||
index a1aeede568cfe33267d87fa68f096d20a83d50f9..92740842827d470d63da34dd90bdb937321c1a83 100644
|
||||
--- a/third_party/blink/renderer/core/frame/location.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/location.cc
|
||||
@@ -270,23 +270,6 @@ void Location::SetLocation(const String& url,
|
||||
return;
|
||||
}
|
||||
|
||||
- // Check the source browsing context's CSP to fulfill the CSP check
|
||||
- // requirement of https://html.spec.whatwg.org/C/#navigate for javascript
|
||||
- // URLs. Although the spec states we should perform this check on task
|
||||
- // execution, there are concerns about the correctness of that statement,
|
||||
- // see http://github.com/whatwg/html/issues/2591.
|
||||
- if (completed_url.ProtocolIsJavaScript()) {
|
||||
- String script_source = DecodeURLEscapeSequences(
|
||||
- completed_url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
|
||||
- if (!incumbent_window->GetContentSecurityPolicyForCurrentWorld()
|
||||
- ->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
|
||||
- nullptr /* element */, script_source,
|
||||
- String() /* nonce */, incumbent_window->Url(),
|
||||
- OrdinalNumber::First())) {
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
V8DOMActivityLogger* activity_logger =
|
||||
V8DOMActivityLogger::CurrentActivityLoggerIfIsolatedWorld();
|
||||
if (activity_logger) {
|
||||
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
|
||||
index e2398389b2064f0d804977ea9f5233cf34da5dae..49601b48571fbaebda29b6c2848a65275e4fd861 100644
|
||||
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
|
||||
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
|
||||
@@ -547,19 +547,12 @@ bool FrameLoader::AllowRequestForThisFrame(const FrameLoadRequest& request) {
|
||||
|
||||
const KURL& url = request.GetResourceRequest().Url();
|
||||
if (url.ProtocolIsJavaScript()) {
|
||||
- // Check the CSP of the caller (the "source browsing context") if required,
|
||||
- // as per https://html.spec.whatwg.org/C/#javascript-protocol.
|
||||
- bool javascript_url_is_allowed =
|
||||
- request.GetOriginWindow()
|
||||
- ->GetContentSecurityPolicyForWorld(request.JavascriptWorld().get())
|
||||
- ->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
|
||||
- frame_->DeprecatedLocalOwner(), url.GetString(),
|
||||
- String() /* nonce */,
|
||||
- request.GetOriginWindow()->Url(),
|
||||
- OrdinalNumber::First());
|
||||
-
|
||||
- if (!javascript_url_is_allowed)
|
||||
+ if (request.GetOriginWindow()
|
||||
+ ->CheckAndGetJavascriptUrl(request.JavascriptWorld().get(), url,
|
||||
+ frame_->DeprecatedLocalOwner())
|
||||
+ .IsEmpty()) {
|
||||
return false;
|
||||
+ }
|
||||
|
||||
if (frame_->Owner() && ((frame_->Owner()->GetFramePolicy().sandbox_flags &
|
||||
network::mojom::blink::WebSandboxFlags::kOrigin) !=
|
||||
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc
|
||||
index c526aab02f300a32404253537df6ff6c506664f8..36796587c96a51bc90f460def64358ec9788c72e 100644
|
||||
--- a/third_party/blink/renderer/core/page/create_window.cc
|
||||
+++ b/third_party/blink/renderer/core/page/create_window.cc
|
||||
@@ -294,15 +294,11 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
|
||||
request.SetFrameType(mojom::RequestContextFrameType::kAuxiliary);
|
||||
|
||||
const KURL& url = request.GetResourceRequest().Url();
|
||||
- auto* csp_for_world = opener_window.GetContentSecurityPolicyForCurrentWorld();
|
||||
- if (url.ProtocolIsJavaScript() && csp_for_world) {
|
||||
- String script_source = DecodeURLEscapeSequences(
|
||||
- url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
|
||||
-
|
||||
- if (!csp_for_world->AllowInline(
|
||||
- ContentSecurityPolicy::InlineType::kNavigation,
|
||||
- nullptr /* element */, script_source, String() /* nonce */,
|
||||
- opener_window.Url(), OrdinalNumber::First())) {
|
||||
+ if (url.ProtocolIsJavaScript()) {
|
||||
+ if (opener_window
|
||||
+ .CheckAndGetJavascriptUrl(request.JavascriptWorld().get(), url,
|
||||
+ nullptr /* element */)
|
||||
+ .IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/frame-without-trusted-types.html b/third_party/blink/web_tests/external/wpt/trusted-types/support/frame-without-trusted-types.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..25cf073e79fa48f4311c3729f0b39d9be2a64e7c
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/frame-without-trusted-types.html
|
||||
@@ -0,0 +1,6 @@
|
||||
+<!DOCTYPE html>
|
||||
+<head>
|
||||
+</head>
|
||||
+<body>
|
||||
+</body>
|
||||
+</html>
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html
|
||||
index d00d0538753a74411feeec42d5682082031c09d4..5f7856fabb7bb16085ffaffffbf6d7553179e8f3 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html
|
||||
@@ -5,7 +5,8 @@
|
||||
<p>Support page for trusted-types-navigation-report-only.*.html tests.</p>
|
||||
<a id="anchor" href="#">link</a>
|
||||
<script>
|
||||
- if (location.search == "?defaultpolicy") {
|
||||
+ const params = new URLSearchParams(location.search);
|
||||
+ if (!!params.get("defaultpolicy")) {
|
||||
trustedTypes.createPolicy("default", {
|
||||
createScript: s => s.replace("continue", "defaultpolicywashere"),
|
||||
});
|
||||
@@ -36,9 +37,17 @@
|
||||
// won't disturb delivery of that event to the opener.
|
||||
const anchor = document.getElementById("anchor");
|
||||
anchor.href = target;
|
||||
+
|
||||
+ if (!!params.get("frame")) {
|
||||
+ const frame = document.createElement("iframe");
|
||||
+ frame.src = "frame-without-trusted-types.html";
|
||||
+ frames.name = "frame";
|
||||
+ document.body.appendChild(frame);
|
||||
+ anchor.target = "frame";
|
||||
+ }
|
||||
+
|
||||
if (!location.hash) {
|
||||
document.addEventListener("DOMContentLoaded", _ => anchor.click());
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
-
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html
|
||||
index cd41f3968e7c74f84a7541506053808073ce541d..5e02e6d4bf5aff9fa4f0b4b897a35726ed24168b 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html
|
||||
@@ -5,7 +5,8 @@
|
||||
<p>Support page for trusted-types-navigation.*.html tests.</p>
|
||||
<a id="anchor" href="#">link</a>
|
||||
<script>
|
||||
- if (location.search == "?defaultpolicy") {
|
||||
+ const params = new URLSearchParams(location.search);
|
||||
+ if (!!params.get("defaultpolicy")) {
|
||||
trustedTypes.createPolicy("default", {
|
||||
createScript: s => s.replace("continue", "defaultpolicywashere"),
|
||||
});
|
||||
@@ -35,8 +36,16 @@
|
||||
|
||||
const anchor = document.getElementById("anchor");
|
||||
anchor.href = target;
|
||||
+
|
||||
+ if (!!params.get("frame")) {
|
||||
+ const frame = document.createElement("iframe");
|
||||
+ frame.src = "frame-without-trusted-types.html";
|
||||
+ frames.name = "frame";
|
||||
+ document.body.appendChild(frame);
|
||||
+ anchor.target = "frame";
|
||||
+ }
|
||||
+
|
||||
if (!location.hash)
|
||||
document.addEventListener("DOMContentLoaded", _ => anchor.click());
|
||||
</script>
|
||||
</body>
|
||||
-
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html
|
||||
index 4e784611dd64ecf2f9995403b1d4e5a19f8b4548..2113711902ae787cb3ad5d0e44eaed0fc2e99b87 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html
|
||||
@@ -38,10 +38,10 @@
|
||||
}, "Navigate a window with javascript:-urls in enforcing mode.");
|
||||
|
||||
promise_test(t => {
|
||||
- openWindow(t, "support/navigation-support.html?defaultpolicy");
|
||||
+ openWindow(t, "support/navigation-support.html?defaultpolicy=1");
|
||||
return Promise.all([
|
||||
- expectLoadedAsMessage("navigation-support.html?defaultpolicy"),
|
||||
- expectLoadedAsMessage("navigation-support.html?defaultpolicy&defaultpolicywashere"),
|
||||
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1"),
|
||||
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&defaultpolicywashere"),
|
||||
]);
|
||||
}, "Navigate a window with javascript:-urls w/ default policy in enforcing mode.");
|
||||
|
||||
@@ -55,12 +55,46 @@
|
||||
}, "Navigate a window with javascript:-urls in report-only mode.");
|
||||
|
||||
promise_test(t => {
|
||||
- const page = "navigation-report-only-support.html?defaultpolicy";
|
||||
+ const page = "navigation-report-only-support.html?defaultpolicy=1";
|
||||
openWindow(t, `support/${page}`);
|
||||
return Promise.all([
|
||||
expectLoadedAsMessage(page),
|
||||
- expectLoadedAsMessage("navigation-support.html?defaultpolicy#defaultpolicywashere"),
|
||||
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1#defaultpolicywashere"),
|
||||
]);
|
||||
}, "Navigate a window with javascript:-urls w/ default policy in report-only mode.");
|
||||
+
|
||||
+ promise_test(t => {
|
||||
+ openWindow(t, "support/navigation-support.html?frame=1");
|
||||
+ return Promise.all([
|
||||
+ expectLoadedAsMessage("navigation-support.html?frame=1"),
|
||||
+ expectViolationAsMessage("Location href"),
|
||||
+ ]);
|
||||
+ }, "Navigate a frame with javascript:-urls in enforcing mode.");
|
||||
+
|
||||
+ promise_test(t => {
|
||||
+ openWindow(t, "support/navigation-support.html?defaultpolicy=1&frame=1");
|
||||
+ return Promise.all([
|
||||
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1"),
|
||||
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1&defaultpolicywashere"),
|
||||
+ ]);
|
||||
+ }, "Navigate a frame with javascript:-urls w/ default policy in enforcing mode.");
|
||||
+
|
||||
+ promise_test(t => {
|
||||
+ const page = "navigation-report-only-support.html?frame=1"
|
||||
+ openWindow(t, `support/${page}`);
|
||||
+ return Promise.all([
|
||||
+ expectLoadedAsMessage(page),
|
||||
+ expectLoadedAsMessage("navigation-support.html?frame=1#continue"),
|
||||
+ ]);
|
||||
+ }, "Navigate a frame with javascript:-urls in report-only mode.");
|
||||
+
|
||||
+ promise_test(t => {
|
||||
+ const page = "navigation-report-only-support.html?defaultpolicy=1&frame=1";
|
||||
+ openWindow(t, `support/${page}`);
|
||||
+ return Promise.all([
|
||||
+ expectLoadedAsMessage(page),
|
||||
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1#defaultpolicywashere"),
|
||||
+ ]);
|
||||
+ }, "Navigate a frame with javascript:-urls w/ default policy in report-only mode.");
|
||||
</script>
|
||||
</body>
|
||||
115
patches/chromium/cherry-pick-42e15c2055c4.patch
Normal file
115
patches/chromium/cherry-pick-42e15c2055c4.patch
Normal file
@@ -0,0 +1,115 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joey Arhar <jarhar@chromium.org>
|
||||
Date: Tue, 22 Nov 2022 00:12:31 +0000
|
||||
Subject: Avoid use-after-free in ValidationMessageOverlayDelegate
|
||||
|
||||
When ValidationMessageOverlayDelegate calls
|
||||
ForceSynchronousDocumentInstall, it can somehow cause another validation
|
||||
overlay to be created and delete the ValidationMessageOverlayDelegate.
|
||||
This patch avoids additional code from being run inside the deleted
|
||||
ValidationMessageOverlayDelegate.
|
||||
|
||||
(cherry picked from commit a37b66ded21af7ff1442bddd2ec3a0845535b3d6)
|
||||
|
||||
Fixed: 1382581
|
||||
Change-Id: I044f91ecb55c77c4a5c40030b6856fc9a8ac7f6f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4019655
|
||||
Reviewed-by: David Baron <dbaron@chromium.org>
|
||||
Commit-Queue: Joey Arhar <jarhar@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1071652}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4043489
|
||||
Commit-Queue: David Baron <dbaron@chromium.org>
|
||||
Auto-Submit: Joey Arhar <jarhar@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#911}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
|
||||
index 33575769b1fa9361c91d27815832f467f7a7f19c..a8a1df886fd8accfdf9fcf9d06ba24e11f16293a 100644
|
||||
--- a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
|
||||
+++ b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
|
||||
@@ -85,6 +85,8 @@ ValidationMessageOverlayDelegate::~ValidationMessageOverlayDelegate() {
|
||||
EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
|
||||
page_->WillBeDestroyed();
|
||||
}
|
||||
+ if (destroyed_ptr_)
|
||||
+ *destroyed_ptr_ = true;
|
||||
}
|
||||
|
||||
LocalFrameView& ValidationMessageOverlayDelegate::FrameView() const {
|
||||
@@ -175,7 +177,18 @@ void ValidationMessageOverlayDelegate::CreatePage(const FrameOverlay& overlay) {
|
||||
WriteDocument(data.get());
|
||||
float zoom_factor = anchor_->GetDocument().GetFrame()->PageZoomFactor();
|
||||
frame->SetPageZoomFactor(zoom_factor);
|
||||
+
|
||||
+ // ForceSynchronousDocumentInstall can cause another call to
|
||||
+ // ValidationMessageClientImpl::ShowValidationMessage, which will hide this
|
||||
+ // validation message and may even delete this. In order to avoid continuing
|
||||
+ // when this is destroyed, |destroyed| will be set to true in the destructor.
|
||||
+ bool destroyed = false;
|
||||
+ DCHECK(!destroyed_ptr_);
|
||||
+ destroyed_ptr_ = &destroyed;
|
||||
frame->ForceSynchronousDocumentInstall("text/html", data);
|
||||
+ if (destroyed)
|
||||
+ return;
|
||||
+ destroyed_ptr_ = nullptr;
|
||||
|
||||
Element& main_message = GetElementById("main-message");
|
||||
main_message.setTextContent(message_);
|
||||
diff --git a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h
|
||||
index 9db786a4fbd12bc6aeefc520143f872965ad7df8..26e96d8ffad11938dcc3dc5b059f2c7ebf077b94 100644
|
||||
--- a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h
|
||||
+++ b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h
|
||||
@@ -72,6 +72,10 @@ class CORE_EXPORT ValidationMessageOverlayDelegate
|
||||
String sub_message_;
|
||||
TextDirection message_dir_;
|
||||
TextDirection sub_message_dir_;
|
||||
+
|
||||
+ // Used by CreatePage() to determine if this has been deleted in the middle of
|
||||
+ // the function.
|
||||
+ bool* destroyed_ptr_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/reportValidity-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/reportValidity-crash.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d6bab924adc9fb481235af10d706cbf4d4ef2df9
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/reportValidity-crash.html
|
||||
@@ -0,0 +1,37 @@
|
||||
+<!DOCTYPE html>
|
||||
+<html>
|
||||
+
|
||||
+<head>
|
||||
+<script>
|
||||
+Object.prototype.__defineGetter__('then', prom);
|
||||
+var prom_count = 0;
|
||||
+function prom() {
|
||||
+prom_count++;
|
||||
+if (prom_count > 2) return;
|
||||
+var v14 = x37.animate({},100);
|
||||
+v14.reverse();
|
||||
+v14.ready;
|
||||
+v14.currentTime = 0;
|
||||
+x57.reportValidity();
|
||||
+}
|
||||
+function f0() {
|
||||
+var v38 = x37.animate({},300);
|
||||
+v38.ready;
|
||||
+x57.prepend(x78);
|
||||
+}
|
||||
+function f1() {
|
||||
+var x57 = document.getElementById("x57");
|
||||
+x57.disabled = false;
|
||||
+}
|
||||
+</script>
|
||||
+</head>
|
||||
+
|
||||
+<body>
|
||||
+<fieldset id="x37">
|
||||
+<canvas onfocusin="f0()" >
|
||||
+<input id="x78" autofocus="" onfocusout="f1()" >
|
||||
+</canvas>
|
||||
+<select id="x57" disabled="" required=""></select>
|
||||
+</body>
|
||||
+
|
||||
+</html>
|
||||
104
patches/chromium/cherry-pick-43637378b14e.patch
Normal file
104
patches/chromium/cherry-pick-43637378b14e.patch
Normal file
@@ -0,0 +1,104 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maks Orlovich <morlovich@chromium.org>
|
||||
Date: Tue, 22 Nov 2022 22:18:55 +0000
|
||||
Subject: Align NetworkContext::SetNetworkConditions better with devtools
|
||||
emulateNetworkConditions
|
||||
|
||||
The former used values of 0 to disable particular throttles, while the
|
||||
later documents -1, and looks to be pretty much a direct client, and the
|
||||
only one. So make NetworkService handle everything <= 0 as a disable,
|
||||
clamping at intake of config.
|
||||
|
||||
Bug: 1382033
|
||||
|
||||
(cherry picked from commit ce463c2c939818a12bbcec5e2c91c35f2a0a1f0e)
|
||||
|
||||
Change-Id: I2fd3f075d5071cb0cf647838782115b5c00405bf
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4035891
|
||||
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
|
||||
Reviewed-by: Eric Orth <ericorth@chromium.org>
|
||||
Commit-Queue: Maks Orlovich <morlovich@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1073566}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4048289
|
||||
Cr-Commit-Position: refs/branch-heads/5414@{#188}
|
||||
Cr-Branched-From: 4417ee59d7bf6df7a9c9ea28f7722d2ee6203413-refs/heads/main@{#1070088}
|
||||
|
||||
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
|
||||
index b6a2ed2857ee9cb838542d76a5c3031a28483a8b..7f41b5a1cf98576bce93b14196cf7dfabf7aaa93 100644
|
||||
--- a/services/network/public/mojom/network_context.mojom
|
||||
+++ b/services/network/public/mojom/network_context.mojom
|
||||
@@ -554,11 +554,11 @@ struct NetworkConditions {
|
||||
// response received.
|
||||
mojo_base.mojom.TimeDelta latency;
|
||||
|
||||
- // Maximal aggregated download throughput (bytes/sec). 0 disables download
|
||||
+ // Maximal aggregated download throughput (bytes/sec). <=0 disables download
|
||||
// throttling.
|
||||
double download_throughput;
|
||||
|
||||
- // Maximal aggregated upload throughput (bytes/sec). 0 disables upload
|
||||
+ // Maximal aggregated upload throughput (bytes/sec). <=0 disables upload
|
||||
// throttling.
|
||||
double upload_throughput;
|
||||
};
|
||||
diff --git a/services/network/throttling/network_conditions.cc b/services/network/throttling/network_conditions.cc
|
||||
index 71cd4ac0e52cc1f262c5b58caf20448b57b6b64f..18b2b6e0efdc2e17dbbbfaa411b4ab49ec787bc4 100644
|
||||
--- a/services/network/throttling/network_conditions.cc
|
||||
+++ b/services/network/throttling/network_conditions.cc
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "services/network/throttling/network_conditions.h"
|
||||
|
||||
+#include <algorithm>
|
||||
+
|
||||
namespace network {
|
||||
|
||||
NetworkConditions::NetworkConditions() : NetworkConditions(false) {}
|
||||
@@ -16,9 +18,9 @@ NetworkConditions::NetworkConditions(bool offline,
|
||||
double download_throughput,
|
||||
double upload_throughput)
|
||||
: offline_(offline),
|
||||
- latency_(latency),
|
||||
- download_throughput_(download_throughput),
|
||||
- upload_throughput_(upload_throughput) {}
|
||||
+ latency_(std::max(latency, 0.0)),
|
||||
+ download_throughput_(std::max(download_throughput, 0.0)),
|
||||
+ upload_throughput_(std::max(upload_throughput, 0.0)) {}
|
||||
|
||||
NetworkConditions::~NetworkConditions() {}
|
||||
|
||||
diff --git a/services/network/throttling/network_conditions.h b/services/network/throttling/network_conditions.h
|
||||
index f8c8214b34bafcb1f656dd3a39a0cf17fea821ea..c5232231d308b09105234101f4bc575491505372 100644
|
||||
--- a/services/network/throttling/network_conditions.h
|
||||
+++ b/services/network/throttling/network_conditions.h
|
||||
@@ -28,6 +28,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkConditions {
|
||||
bool IsThrottling() const;
|
||||
|
||||
bool offline() const { return offline_; }
|
||||
+
|
||||
+ // These are 0 if the corresponding throttle is disabled, >0 otherwise.
|
||||
double latency() const { return latency_; }
|
||||
double download_throughput() const { return download_throughput_; }
|
||||
double upload_throughput() const { return upload_throughput_; }
|
||||
diff --git a/services/network/throttling/throttling_controller_unittest.cc b/services/network/throttling/throttling_controller_unittest.cc
|
||||
index fbe2c6d20d1d5362a77bd951e87b3fe41be13098..e834f8bdc13b5691b1e458dcafead482a0537e14 100644
|
||||
--- a/services/network/throttling/throttling_controller_unittest.cc
|
||||
+++ b/services/network/throttling/throttling_controller_unittest.cc
|
||||
@@ -297,7 +297,7 @@ TEST(ThrottlingControllerTest, DownloadOnly) {
|
||||
ThrottlingControllerTestHelper helper;
|
||||
TestCallback* callback = helper.callback();
|
||||
|
||||
- helper.SetNetworkState(false, 10000000, 0);
|
||||
+ helper.SetNetworkState(false, 10000000, -1);
|
||||
int rv = helper.Start(false);
|
||||
EXPECT_EQ(rv, net::ERR_IO_PENDING);
|
||||
helper.FastForwardUntilNoTasksRemain();
|
||||
@@ -316,7 +316,7 @@ TEST(ThrottlingControllerTest, UploadOnly) {
|
||||
ThrottlingControllerTestHelper helper;
|
||||
TestCallback* callback = helper.callback();
|
||||
|
||||
- helper.SetNetworkState(false, 0, 1000000);
|
||||
+ helper.SetNetworkState(false, -2, 1000000);
|
||||
int rv = helper.Start(true);
|
||||
EXPECT_EQ(rv, net::OK);
|
||||
helper.FastForwardUntilNoTasksRemain();
|
||||
78
patches/chromium/cherry-pick-65ad70274d4b.patch
Normal file
78
patches/chromium/cherry-pick-65ad70274d4b.patch
Normal file
@@ -0,0 +1,78 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Nikolaevskiy <ilnik@chromium.org>
|
||||
Date: Mon, 14 Nov 2022 12:33:49 +0000
|
||||
Subject: Fix UAF in VideoCaptureDeviceWin::FrameReceived
|
||||
|
||||
(cherry picked from commit d08a3822658cb4ca4261659f1487069a14b51bd9)
|
||||
|
||||
Bug: 1381401
|
||||
Change-Id: Ib742ec7b86d3c419f37f12694bf9cd5f3f03305c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4013158
|
||||
Reviewed-by: Markus Handell <handellm@google.com>
|
||||
Commit-Queue: Ilya Nikolaevskiy <ilnik@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1069054}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4023295
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#809}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/media/capture/video/win/video_capture_device_win.cc b/media/capture/video/win/video_capture_device_win.cc
|
||||
index df0aef940a007a594c328f10a2ea26e1d381505f..b220ded61ed5c501426ccc5c128dd4494c448b2f 100644
|
||||
--- a/media/capture/video/win/video_capture_device_win.cc
|
||||
+++ b/media/capture/video/win/video_capture_device_win.cc
|
||||
@@ -866,34 +866,35 @@ void VideoCaptureDeviceWin::FrameReceived(const uint8_t* buffer,
|
||||
const VideoCaptureFormat& format,
|
||||
base::TimeDelta timestamp,
|
||||
bool flip_y) {
|
||||
+ // We always calculate camera rotation for the first frame. We also cache
|
||||
+ // the latest value to use when AutoRotation is turned off.
|
||||
+ // To avoid potential deadlock, do this without holding a lock.
|
||||
+ if (!camera_rotation_.has_value() || IsAutoRotationEnabled())
|
||||
+ camera_rotation_ = GetCameraRotation(device_descriptor_.facing);
|
||||
+
|
||||
{
|
||||
base::AutoLock lock(lock_);
|
||||
if (state_ != kCapturing)
|
||||
return;
|
||||
- }
|
||||
|
||||
- if (first_ref_time_.is_null())
|
||||
- first_ref_time_ = base::TimeTicks::Now();
|
||||
+ if (first_ref_time_.is_null())
|
||||
+ first_ref_time_ = base::TimeTicks::Now();
|
||||
|
||||
- // There is a chance that the platform does not provide us with the timestamp,
|
||||
- // in which case, we use reference time to calculate a timestamp.
|
||||
- if (timestamp == kNoTimestamp)
|
||||
- timestamp = base::TimeTicks::Now() - first_ref_time_;
|
||||
+ // There is a chance that the platform does not provide us with the
|
||||
+ // timestamp, in which case, we use reference time to calculate a timestamp.
|
||||
+ if (timestamp == kNoTimestamp)
|
||||
+ timestamp = base::TimeTicks::Now() - first_ref_time_;
|
||||
|
||||
- // We always calculate camera rotation for the first frame. We also cache the
|
||||
- // latest value to use when AutoRotation is turned off.
|
||||
- if (!camera_rotation_.has_value() || IsAutoRotationEnabled())
|
||||
- camera_rotation_ = GetCameraRotation(device_descriptor_.facing);
|
||||
-
|
||||
- // TODO(julien.isorce): retrieve the color space information using the
|
||||
- // DirectShow api, AM_MEDIA_TYPE::VIDEOINFOHEADER2::dwControlFlags. If
|
||||
- // AMCONTROL_COLORINFO_PRESENT, then reinterpret dwControlFlags as a
|
||||
- // DXVA_ExtendedFormat. Then use its fields DXVA_VideoPrimaries,
|
||||
- // DXVA_VideoTransferMatrix, DXVA_VideoTransferFunction and
|
||||
- // DXVA_NominalRangeto build a gfx::ColorSpace. See http://crbug.com/959992.
|
||||
- client_->OnIncomingCapturedData(buffer, length, format, gfx::ColorSpace(),
|
||||
- camera_rotation_.value(), flip_y,
|
||||
- base::TimeTicks::Now(), timestamp);
|
||||
+ // TODO(julien.isorce): retrieve the color space information using the
|
||||
+ // DirectShow api, AM_MEDIA_TYPE::VIDEOINFOHEADER2::dwControlFlags. If
|
||||
+ // AMCONTROL_COLORINFO_PRESENT, then reinterpret dwControlFlags as a
|
||||
+ // DXVA_ExtendedFormat. Then use its fields DXVA_VideoPrimaries,
|
||||
+ // DXVA_VideoTransferMatrix, DXVA_VideoTransferFunction and
|
||||
+ // DXVA_NominalRangeto build a gfx::ColorSpace. See http://crbug.com/959992.
|
||||
+ client_->OnIncomingCapturedData(buffer, length, format, gfx::ColorSpace(),
|
||||
+ camera_rotation_.value(), flip_y,
|
||||
+ base::TimeTicks::Now(), timestamp);
|
||||
+ }
|
||||
|
||||
while (!take_photo_callbacks_.empty()) {
|
||||
TakePhotoCallback cb = std::move(take_photo_callbacks_.front());
|
||||
115
patches/chromium/cherry-pick-65d46507a0c9.patch
Normal file
115
patches/chromium/cherry-pick-65d46507a0c9.patch
Normal file
@@ -0,0 +1,115 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: evliu <evliu@google.com>
|
||||
Date: Mon, 14 Nov 2022 20:05:12 +0000
|
||||
Subject: Replace raw pointer to LocalMuter with weak ptr
|
||||
|
||||
This CL replaces a raw pointer to LocalMuter with a weak ptr. Additional
|
||||
info about this bug here: http://crbug/1377783
|
||||
|
||||
(cherry picked from commit 9989b93eb12c93b9351d5bf2872c1069ef5f7d01)
|
||||
|
||||
Bug: 1377783
|
||||
Change-Id: Id821ea800ba12f1cfae4677fc591c12dec112852
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3997421
|
||||
Reviewed-by: Paul Semel <paulsemel@chromium.org>
|
||||
Reviewed-by: Olga Sharonova <olka@chromium.org>
|
||||
Commit-Queue: Evan Liu <evliu@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1068776}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4024547
|
||||
Auto-Submit: Evan Liu <evliu@google.com>
|
||||
Owners-Override: Srinivas Sista <srinivassista@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Reviewed-by: Evan Liu <evliu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#824}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/services/audio/local_muter.h b/services/audio/local_muter.h
|
||||
index a484c7dfd60883b07c8fc61da768edf508ac53af..b108e32306a264be4d51027c4419efc70a5dbe0c 100644
|
||||
--- a/services/audio/local_muter.h
|
||||
+++ b/services/audio/local_muter.h
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
+#include "base/memory/weak_ptr.h"
|
||||
#include "base/sequence_checker.h"
|
||||
#include "base/unguessable_token.h"
|
||||
#include "media/mojo/mojom/audio_stream_factory.mojom.h"
|
||||
@@ -46,6 +47,8 @@ class LocalMuter final : public media::mojom::LocalMuter,
|
||||
|
||||
bool HasReceivers() { return !receivers_.empty(); }
|
||||
|
||||
+ base::WeakPtr<LocalMuter> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
+
|
||||
private:
|
||||
// Runs the |all_bindings_lost_callback_| when |bindings_| becomes empty.
|
||||
void OnBindingLost();
|
||||
@@ -57,6 +60,8 @@ class LocalMuter final : public media::mojom::LocalMuter,
|
||||
base::RepeatingClosure all_bindings_lost_callback_;
|
||||
|
||||
SEQUENCE_CHECKER(sequence_checker_);
|
||||
+
|
||||
+ base::WeakPtrFactory<LocalMuter> weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace audio
|
||||
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc
|
||||
index 48152cb64769ab1a76920d2581f373b57fef85c9..60ff2766809d4c43c021e47cfa5087b9dbe089b8 100644
|
||||
--- a/services/audio/stream_factory.cc
|
||||
+++ b/services/audio/stream_factory.cc
|
||||
@@ -181,8 +181,9 @@ void StreamFactory::BindMuter(
|
||||
if (it == muters_.end()) {
|
||||
auto muter_ptr = std::make_unique<LocalMuter>(&coordinator_, group_id);
|
||||
muter = muter_ptr.get();
|
||||
- muter->SetAllBindingsLostCallback(base::BindRepeating(
|
||||
- &StreamFactory::DestroyMuter, base::Unretained(this), muter));
|
||||
+ muter->SetAllBindingsLostCallback(
|
||||
+ base::BindRepeating(&StreamFactory::DestroyMuter,
|
||||
+ base::Unretained(this), muter_ptr->GetWeakPtr()));
|
||||
muters_.emplace_back(std::move(muter_ptr));
|
||||
} else {
|
||||
muter = it->get();
|
||||
@@ -254,9 +255,10 @@ void StreamFactory::DestroyOutputStream(OutputStream* stream) {
|
||||
DCHECK_EQ(1u, erased);
|
||||
}
|
||||
|
||||
-void StreamFactory::DestroyMuter(LocalMuter* muter) {
|
||||
+void StreamFactory::DestroyMuter(base::WeakPtr<LocalMuter> muter) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
|
||||
- DCHECK(muter);
|
||||
+ if (!muter)
|
||||
+ return;
|
||||
|
||||
// Output streams have a task posting before destruction (see the OnError
|
||||
// function in output_stream.cc). To ensure that stream destruction and
|
||||
@@ -265,13 +267,11 @@ void StreamFactory::DestroyMuter(LocalMuter* muter) {
|
||||
// Otherwise, a "destroy all streams, then destroy the muter" sequence may
|
||||
// result in a brief blip of audio.
|
||||
auto do_destroy = [](base::WeakPtr<StreamFactory> weak_this,
|
||||
- LocalMuter* muter) {
|
||||
- if (weak_this) {
|
||||
-
|
||||
+ base::WeakPtr<LocalMuter> muter) {
|
||||
+ if (weak_this && muter) {
|
||||
const auto it =
|
||||
std::find_if(weak_this->muters_.begin(), weak_this->muters_.end(),
|
||||
- base::MatchesUniquePtr(muter));
|
||||
- DCHECK(it != weak_this->muters_.end());
|
||||
+ base::MatchesUniquePtr(muter.get()));
|
||||
|
||||
// The LocalMuter can still have receivers if a receiver was bound after
|
||||
// DestroyMuter is called but before the do_destroy task is run.
|
||||
diff --git a/services/audio/stream_factory.h b/services/audio/stream_factory.h
|
||||
index 2207c72cb39e666e5c207016035a9d295d708aa0..b6119025f043e433455b35ee71e2b130299d1d21 100644
|
||||
--- a/services/audio/stream_factory.h
|
||||
+++ b/services/audio/stream_factory.h
|
||||
@@ -110,7 +110,7 @@ class StreamFactory final : public media::mojom::AudioStreamFactory {
|
||||
|
||||
void DestroyInputStream(InputStream* stream);
|
||||
void DestroyOutputStream(OutputStream* stream);
|
||||
- void DestroyMuter(LocalMuter* muter);
|
||||
+ void DestroyMuter(base::WeakPtr<LocalMuter> muter);
|
||||
void DestroyLoopbackStream(LoopbackStream* stream);
|
||||
|
||||
SEQUENCE_CHECKER(owning_sequence_);
|
||||
46
patches/chromium/cherry-pick-65f0ef609c00.patch
Normal file
46
patches/chromium/cherry-pick-65f0ef609c00.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Paicu <andypaicu@chromium.org>
|
||||
Date: Thu, 6 Oct 2022 21:04:23 +0000
|
||||
Subject: Fix UAF issue around permission status observer list
|
||||
|
||||
(cherry picked from commit 4df595127d95d4b0bf115be1ab4604d95b75273c)
|
||||
|
||||
(cherry picked from commit 1dc5dda6112bdd811c923520cc728a474583409e)
|
||||
|
||||
Bug: 1363040
|
||||
Change-Id: I1f64a901b83aa834ae652c8041456e9b7d253c1f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3907744
|
||||
Reviewed-by: Kamila Hasanbega <hkamila@chromium.org>
|
||||
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/main@{#1049058}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3929034
|
||||
Reviewed-by: Illia Klimov <elklm@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/5304@{#483}
|
||||
Cr-Original-Branched-From: 5d7b1fc9cb7103d9c82eed647cf4be38cf09738b-refs/heads/main@{#1047731}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3936291
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#764}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/permissions/permission_status_listener.cc b/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
|
||||
index 424314c1dd49bd693643e41adb537f7a9d01e5d2..946e28ac3139a1927ac36281f04cec9f5faf76d2 100644
|
||||
--- a/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
|
||||
+++ b/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
|
||||
@@ -62,7 +62,17 @@ void PermissionStatusListener::OnPermissionStatusChange(
|
||||
|
||||
status_ = status;
|
||||
|
||||
+ // The `observers_` list can change in response to permission status change
|
||||
+ // events as the observers map to PermissionStatus JS objects which can be
|
||||
+ // created and destroyed in the JS event handler function. To avoid UAF and
|
||||
+ // list modification issues, a temporary snapshot of the observers is made and
|
||||
+ // used instead.
|
||||
+ HeapHashSet<WeakMember<Observer>> observers;
|
||||
for (const auto& observer : observers_) {
|
||||
+ observers.insert(observer);
|
||||
+ }
|
||||
+
|
||||
+ for (const auto& observer : observers) {
|
||||
if (observer)
|
||||
observer->OnPermissionStatusChange(status);
|
||||
else
|
||||
622
patches/chromium/cherry-pick-67c9cbc784d6.patch
Normal file
622
patches/chromium/cherry-pick-67c9cbc784d6.patch
Normal file
@@ -0,0 +1,622 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Anforowicz <lukasza@chromium.org>
|
||||
Date: Tue, 30 Aug 2022 19:18:15 +0000
|
||||
Subject: Validate `source_context` in ExtensionHostMsg_OpenChannelToNativeApp.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
After this CL, the Browser process will verify `source_context` in the
|
||||
IPC payload of the ExtensionHostMsg_OpenChannelToNativeApp message and
|
||||
avoid processing malformed or spoofed IPCs.
|
||||
|
||||
Change-Id: I9466dc076c4d07dbb4bec38973000dc0418565f6
|
||||
Bug: 1356234
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3854987
|
||||
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1041118}
|
||||
|
||||
diff --git a/chrome/browser/extensions/extension_security_exploit_browsertest.cc b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
|
||||
index 19c9c52fa5a796c93e80f77029727d64acfdfa07..4e5215739f8533d25831f3302515861df179525f 100644
|
||||
--- a/chrome/browser/extensions/extension_security_exploit_browsertest.cc
|
||||
+++ b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/test/bind.h"
|
||||
+#include "build/build_config.h"
|
||||
#include "chrome/browser/chrome_content_browser_client.h"
|
||||
#include "chrome/browser/extensions/extension_browsertest.h"
|
||||
#include "chrome/browser/extensions/extension_tab_util.h"
|
||||
@@ -40,6 +41,10 @@
|
||||
#include "third_party/blink/public/mojom/service_worker/service_worker_database.mojom-forward.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+#include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h"
|
||||
+#endif
|
||||
+
|
||||
namespace extensions {
|
||||
|
||||
// Waits for a kill of the given RenderProcessHost and returns the
|
||||
@@ -233,6 +238,10 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
|
||||
return ipc_message_waiter_->WaitForMessage();
|
||||
}
|
||||
|
||||
+ content::WebContents* active_web_contents() {
|
||||
+ return browser()->tab_strip_model()->GetActiveWebContents();
|
||||
+ }
|
||||
+
|
||||
// Asks the `extension_id` to inject `content_script` into `web_contents`.
|
||||
// Returns true if the content script execution started successfully.
|
||||
bool ExecuteProgrammaticContentScript(content::WebContents* web_contents,
|
||||
@@ -246,63 +255,86 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
|
||||
browser()->profile(), extension_id, background_script);
|
||||
}
|
||||
|
||||
+ const Extension& active_extension() { return *active_extension_; }
|
||||
const ExtensionId& active_extension_id() { return active_extension_->id(); }
|
||||
|
||||
const ExtensionId& spoofed_extension_id() { return spoofed_extension_->id(); }
|
||||
|
||||
private:
|
||||
+ // Installs an `active_extension` and a separate, but otherwise identical
|
||||
+ // `spoofed_extension` (the only difference will be the extension id).
|
||||
void InstallTestExtensions() {
|
||||
- // Install an `active_extension` and a separate, but otherwise identical
|
||||
- // `spoofed_extension` (the only difference will be the extension id).
|
||||
- auto install_extension = [this](TestExtensionDir& dir) -> const Extension* {
|
||||
+ auto install_extension =
|
||||
+ [this](TestExtensionDir& dir,
|
||||
+ const char* extra_manifest_bits) -> const Extension* {
|
||||
const char kManifestTemplate[] = R"(
|
||||
{
|
||||
+ %s
|
||||
"name": "ContentScriptTrackerBrowserTest - Programmatic",
|
||||
"version": "1.0",
|
||||
"manifest_version": 2,
|
||||
- "permissions": [ "tabs", "<all_urls>" ],
|
||||
+ "permissions": [
|
||||
+ "tabs",
|
||||
+ "<all_urls>",
|
||||
+ "nativeMessaging"
|
||||
+ ],
|
||||
"background": {"scripts": ["background_script.js"]}
|
||||
} )";
|
||||
- dir.WriteManifest(kManifestTemplate);
|
||||
+ dir.WriteManifest(
|
||||
+ base::StringPrintf(kManifestTemplate, extra_manifest_bits));
|
||||
dir.WriteFile(FILE_PATH_LITERAL("background_script.js"), "");
|
||||
+ dir.WriteFile(FILE_PATH_LITERAL("page.html"), "<p>page</p>");
|
||||
return LoadExtension(dir.UnpackedPath());
|
||||
};
|
||||
- TestExtensionDir active_dir;
|
||||
- TestExtensionDir spoofed_dir;
|
||||
- active_extension_ = install_extension(active_dir);
|
||||
- spoofed_extension_ = install_extension(spoofed_dir);
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+ // The key below corresponds to the extension ID used by
|
||||
+ // ScopedTestNativeMessagingHost::kExtensionId.
|
||||
+ const char kActiveExtensionKey[] = R"(
|
||||
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
|
||||
+ )";
|
||||
+#else
|
||||
+ // Native messaging is not available on Fuchsia (i.e.
|
||||
+ // //chrome/browser/extensions/BUILD.gn excludes
|
||||
+ // api/messaging/native_messaging_test_util.h on Fuchsia).
|
||||
+ const char kActiveExtensionKey[] = "";
|
||||
+#endif
|
||||
+ active_extension_ = install_extension(active_dir_, kActiveExtensionKey);
|
||||
+ spoofed_extension_ = install_extension(spoofed_dir_, "");
|
||||
ASSERT_TRUE(active_extension_);
|
||||
ASSERT_TRUE(spoofed_extension_);
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+ ASSERT_EQ(active_extension_id(),
|
||||
+ ScopedTestNativeMessagingHost::kExtensionId);
|
||||
+#endif
|
||||
ASSERT_NE(active_extension_id(), spoofed_extension_id());
|
||||
}
|
||||
|
||||
using OpenChannelMessageWaiter =
|
||||
ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToExtension>;
|
||||
- std::unique_ptr<OpenChannelMessageWaiter> StartInterceptingIpcs(
|
||||
- const GURL& test_page_url) {
|
||||
// Start capturing IPC messages in all future/new RenderProcessHosts.
|
||||
- auto ipc_message_waiter = std::make_unique<OpenChannelMessageWaiter>();
|
||||
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
|
||||
|
||||
// Navigate to an arbitrary, mostly empty test page. Make sure that a new
|
||||
// RenderProcessHost is created to make sure it is covered by the
|
||||
- // `ipc_message_waiter`. (A WebUI -> http navigation should swap the
|
||||
+ // `ipc_message_waiter_`. (A WebUI -> http navigation should swap the
|
||||
// RenderProcessHost on all platforms.)
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
+ GURL test_page_url =
|
||||
+ embedded_test_server()->GetURL("foo.com", "/title1.html");
|
||||
int old_process_id =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
EXPECT_TRUE(
|
||||
ui_test_utils::NavigateToURL(browser(), GURL("chrome://version")));
|
||||
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
|
||||
int new_process_id =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
EXPECT_NE(old_process_id, new_process_id);
|
||||
|
||||
// Only intercept messages from `active_extension`'s content script running
|
||||
// in the main frame's process.
|
||||
std::string matching_extension_id = active_extension_id();
|
||||
- int matching_process_id = new_process_id;
|
||||
- ipc_message_waiter->SetIpcMatcher(base::BindLambdaForTesting(
|
||||
+ int matching_process_id =
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
|
||||
[matching_extension_id, matching_process_id](
|
||||
int captured_render_process_id,
|
||||
const ExtensionHostMsg_OpenChannelToExtension::Param& param) {
|
||||
@@ -319,12 +351,19 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
|
||||
|
||||
return true;
|
||||
}));
|
||||
+ }
|
||||
|
||||
- return ipc_message_waiter;
|
||||
+ // Waits for ExtensionHostMsg_OpenChannelToExtension IPC and returns its
|
||||
+ // payload.
|
||||
+ ExtensionHostMsg_OpenChannelToExtension::Param WaitForMessage() {
|
||||
+ return ipc_message_waiter_->WaitForMessage();
|
||||
}
|
||||
|
||||
+ private:
|
||||
std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
|
||||
|
||||
+ TestExtensionDir active_dir_;
|
||||
+ TestExtensionDir spoofed_dir_;
|
||||
raw_ptr<const Extension> active_extension_ = nullptr;
|
||||
raw_ptr<const Extension> spoofed_extension_ = nullptr;
|
||||
};
|
||||
@@ -340,24 +379,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.extension_id = spoofed_extension_id();
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -371,24 +408,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_UnexpectedNativeAppType) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.type = MessagingEndpoint::Type::kNativeApp;
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -401,24 +436,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_UnexpectedExtensionType) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.type = MessagingEndpoint::Type::kExtension;
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -432,25 +465,23 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_NoExtensionIdForExtensionType) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
|
||||
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
info.source_endpoint.type = MessagingEndpoint::Type::kExtension;
|
||||
info.source_endpoint.extension_id = absl::nullopt;
|
||||
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -464,18 +495,16 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
FromContentScript_UnexpectedWorkerContext) {
|
||||
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
|
||||
// from a content script of an `active_extension_id`.
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
ASSERT_TRUE(ExecuteProgrammaticContentScript(
|
||||
- web_contents, active_extension_id(),
|
||||
+ active_web_contents(), active_extension_id(),
|
||||
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
|
||||
|
||||
// Capture the IPC.
|
||||
auto [source_context, info, channel_name, port_id] = WaitForMessage();
|
||||
-
|
||||
- // Mutate the IPC payload.
|
||||
EXPECT_TRUE(source_context.is_for_render_frame());
|
||||
EXPECT_FALSE(source_context.is_for_service_worker());
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
source_context.frame = absl::nullopt;
|
||||
source_context.worker = PortContext::WorkerContext(
|
||||
/* thread_id = */ 123, /* version_id = */ 456,
|
||||
@@ -484,7 +513,7 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
// Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
// as expected.
|
||||
content::RenderProcessHost* main_frame_process =
|
||||
- web_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
main_frame_process->GetChannel(),
|
||||
@@ -494,4 +523,98 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
kill_waiter.Wait());
|
||||
}
|
||||
|
||||
+// Native messaging is not available on Fuchsia (i.e.
|
||||
+// //chrome/browser/extensions/BUILD.gn excludes
|
||||
+// api/messaging/native_messaging_test_util.h on Fuchsia).
|
||||
+#if !(BUILDFLAG(IS_FUCHSIA))
|
||||
+
|
||||
+// Test suite for covering ExtensionHostMsg_OpenChannelToNativeApp IPC.
|
||||
+class OpenChannelToNativeAppExploitTest
|
||||
+ : public ExtensionSecurityExploitBrowserTest {
|
||||
+ public:
|
||||
+ OpenChannelToNativeAppExploitTest() = default;
|
||||
+
|
||||
+ using OpenChannelMessageWaiter =
|
||||
+ ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToNativeApp>;
|
||||
+ void SetUpOnMainThread() override {
|
||||
+ // Set up ExtensionMessageWaiter *before* installing the extensions (i.e.
|
||||
+ // *before* the corresponding RenderProcessHost objects are created).
|
||||
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
|
||||
+
|
||||
+ // SetUpOnMainThread in the base class will install the test extensions.
|
||||
+ ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
|
||||
+
|
||||
+ // Register a (fake, test-only) native messaging host.
|
||||
+ test_native_messaging_host_.RegisterTestHost(/* user_level= */ false);
|
||||
+
|
||||
+ // Navigate the test tab to an extension page.
|
||||
+ GURL test_page_url = active_extension().GetResourceURL("page.html");
|
||||
+ EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
|
||||
+
|
||||
+ // Only intercept messages from the test process.
|
||||
+ int matching_process_id =
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
|
||||
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
|
||||
+ [matching_process_id](
|
||||
+ int captured_render_process_id,
|
||||
+ const ExtensionHostMsg_OpenChannelToNativeApp::Param& param) {
|
||||
+ if (captured_render_process_id != matching_process_id)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+ }));
|
||||
+ }
|
||||
+
|
||||
+ // Waits for ExtensionHostMsg_OpenChannelToNativeApp IPC and returns its
|
||||
+ // payload.
|
||||
+ ExtensionHostMsg_OpenChannelToNativeApp::Param WaitForMessage() {
|
||||
+ return ipc_message_waiter_->WaitForMessage();
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ ScopedTestNativeMessagingHost test_native_messaging_host_;
|
||||
+ std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
|
||||
+};
|
||||
+
|
||||
+IN_PROC_BROWSER_TEST_F(OpenChannelToNativeAppExploitTest,
|
||||
+ SourceContextWithSpoofedExtensionId) {
|
||||
+ // Trigger sending of a valid ExtensionHostMsg_OpenChannelToNativeApp IPC
|
||||
+ // from a frame of an `active_extension`.
|
||||
+ const char kScript[] = R"(
|
||||
+ var message = {text: 'Hello!'};
|
||||
+ var host = $1;
|
||||
+ chrome.runtime.sendNativeMessage(host, message);
|
||||
+ )";
|
||||
+ ASSERT_EQ(
|
||||
+ active_extension().origin(),
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
|
||||
+ ASSERT_TRUE(content::ExecuteScript(
|
||||
+ active_web_contents(),
|
||||
+ content::JsReplace(kScript, ScopedTestNativeMessagingHost::kHostName)));
|
||||
+
|
||||
+ // Capture the IPC.
|
||||
+ auto [source_context, native_app_name, port_id] = WaitForMessage();
|
||||
+ EXPECT_EQ(native_app_name, ScopedTestNativeMessagingHost::kHostName);
|
||||
+ EXPECT_TRUE(source_context.is_for_render_frame());
|
||||
+
|
||||
+ // Mutate the IPC payload.
|
||||
+ source_context = PortContext::ForWorker(123, // thread_id
|
||||
+ 456, // version_id
|
||||
+ spoofed_extension_id());
|
||||
+
|
||||
+ // Inject the malformed/mutated IPC and verify that the renderer is terminated
|
||||
+ // as expected.
|
||||
+ content::RenderProcessHost* main_frame_process =
|
||||
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
|
||||
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
|
||||
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
|
||||
+ main_frame_process->GetChannel(),
|
||||
+ ExtensionHostMsg_OpenChannelToNativeApp(source_context, native_app_name,
|
||||
+ port_id));
|
||||
+ EXPECT_EQ(bad_message::EMF_INVALID_EXTENSION_ID_FOR_WORKER_CONTEXT,
|
||||
+ kill_waiter.Wait());
|
||||
+}
|
||||
+
|
||||
+#endif // !(BUILDFLAG(IS_FUCHSIA)) - native messaging is available
|
||||
+
|
||||
} // namespace extensions
|
||||
diff --git a/docs/security/compromised-renderers.md b/docs/security/compromised-renderers.md
|
||||
index b7e56be454f2d42dc4ae4ac875586a01f2354d9a..2155a399e0e432fedc2792b6893440efd7fca572 100644
|
||||
--- a/docs/security/compromised-renderers.md
|
||||
+++ b/docs/security/compromised-renderers.md
|
||||
@@ -213,14 +213,21 @@ Compromised renderers shouldn’t be able to:
|
||||
- Spoof the `MessageEvent.origin` seen by a recipient of a `postMessage`.
|
||||
- Bypass enforcement of the `targetOrigin` argument of `postMessage`.
|
||||
- Send or receive `BroadcastChannel` messages for another origin.
|
||||
-- Spoof the `MessageSender.origin` seen by a recipient of a
|
||||
- `chrome.runtime.sendMessage`
|
||||
- (see also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34)).
|
||||
+- Spoof the `MessageSender.origin`, nor `MessageSender.id` (i.e. an
|
||||
+ extension id which can differ from the origin when the message is sent
|
||||
+ from a content script), as seen by a recipient of a
|
||||
+ `chrome.runtime.sendMessage`.
|
||||
+ See also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34).
|
||||
+- Spoof the id of a Chrome extension initiating
|
||||
+ [native messaging](https://developer.chrome.com/docs/apps/nativeMessaging/)
|
||||
+ communication.
|
||||
|
||||
Protection techniques:
|
||||
- Using `CanAccessDataForOrigin` to verify IPCs sent by a renderer process
|
||||
(e.g. in `RenderFrameProxyHost::OnRouteMessageEvent` or
|
||||
`BroadcastChannelProvider::ConnectToChannel`).
|
||||
+- Using `ContentScriptTracker` to check if IPCs from a given renderer process
|
||||
+ can legitimately claim to act on behalf content scripts of a given extension.
|
||||
|
||||
**Known gaps in protection**:
|
||||
- Spoofing of `MessageSender.id` object
|
||||
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.cc b/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
index 5469f5e91bfbb98aece208e9fffa8139dc9dacdf..e57cffb46d74229fff2534f7bb9f9fa3ddbc3d26 100644
|
||||
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
@@ -156,6 +156,16 @@ bool IsValidSourceContext(RenderProcessHost& process,
|
||||
}
|
||||
}
|
||||
|
||||
+ // This function doesn't validate frame-flavoured `source_context`s, because
|
||||
+ // PortContext::FrameContext only contains frame's `routing_id` and therefore
|
||||
+ // inherently cannot spoof frames in another process (a frame is identified
|
||||
+ // by its `routing_id` *and* the `process_id` of the Renderer process hosting
|
||||
+ // the frame; the latter is trustworthy / doesn't come from an IPC payload).
|
||||
+
|
||||
+ // This function doesn't validate native app `source_context`s, because
|
||||
+ // `PortContext::ForNativeHost()` is called with trustoworthy inputs (e.g. it
|
||||
+ // doesn't take input from IPCs sent by a Renderer process).
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -227,6 +237,18 @@ void MessagingAPIMessageFilter::Shutdown() {
|
||||
shutdown_notifier_subscription_ = {};
|
||||
}
|
||||
|
||||
+content::RenderProcessHost* MessagingAPIMessageFilter::GetRenderProcessHost() {
|
||||
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
+ if (!browser_context_)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ // The IPC might race with RenderProcessHost destruction. This may only
|
||||
+ // happen in scenarios that are already inherently racey, so returning nullptr
|
||||
+ // (and dropping the IPC) is okay and won't lead to any additional risk of
|
||||
+ // data loss.
|
||||
+ return content::RenderProcessHost::FromID(render_process_id_);
|
||||
+}
|
||||
+
|
||||
void MessagingAPIMessageFilter::OverrideThreadForMessage(
|
||||
const IPC::Message& message,
|
||||
BrowserThread::ID* thread) {
|
||||
@@ -272,19 +294,14 @@ void MessagingAPIMessageFilter::OnOpenChannelToExtension(
|
||||
const std::string& channel_name,
|
||||
const PortId& port_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
- if (!browser_context_)
|
||||
- return;
|
||||
-
|
||||
- // The IPC might race with RenderProcessHost destruction. This may only
|
||||
- // happen in scenarios that are already inherently racey, so dropping the IPC
|
||||
- // is okay and won't lead to any additional risk of data loss.
|
||||
- auto* process = content::RenderProcessHost::FromID(render_process_id_);
|
||||
+ auto* process = GetRenderProcessHost();
|
||||
if (!process)
|
||||
return;
|
||||
TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToExtension",
|
||||
ChromeTrackEvent::kRenderProcessHost, *process);
|
||||
|
||||
ScopedExternalConnectionInfoCrashKeys info_crash_keys(info);
|
||||
+ debug::ScopedPortContextCrashKeys port_context_crash_keys(source_context);
|
||||
if (!IsValidMessagingSource(*process, info.source_endpoint) ||
|
||||
!IsValidSourceContext(*process, source_context)) {
|
||||
return;
|
||||
@@ -303,7 +320,14 @@ void MessagingAPIMessageFilter::OnOpenChannelToNativeApp(
|
||||
const std::string& native_app_name,
|
||||
const PortId& port_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
- if (!browser_context_)
|
||||
+ auto* process = GetRenderProcessHost();
|
||||
+ if (!process)
|
||||
+ return;
|
||||
+ TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToNativeApp",
|
||||
+ ChromeTrackEvent::kRenderProcessHost, *process);
|
||||
+
|
||||
+ debug::ScopedPortContextCrashKeys port_context_crash_keys(source_context);
|
||||
+ if (!IsValidSourceContext(*process, source_context))
|
||||
return;
|
||||
|
||||
ChannelEndpoint source_endpoint(browser_context_, render_process_id_,
|
||||
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.h b/extensions/browser/api/messaging/messaging_api_message_filter.h
|
||||
index 6a0ccd698629f650d68f2b4ee168aa2b3b3a116c..3358187387cd9a5765a7bd4e522aeecfd787e06b 100644
|
||||
--- a/extensions/browser/api/messaging/messaging_api_message_filter.h
|
||||
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.h
|
||||
@@ -14,6 +14,7 @@ struct ExtensionMsg_TabTargetConnectionInfo;
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
+class RenderProcessHost;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
@@ -40,6 +41,11 @@ class MessagingAPIMessageFilter : public content::BrowserMessageFilter {
|
||||
|
||||
void Shutdown();
|
||||
|
||||
+ // Returns the process that the IPC came from, or `nullptr` if the IPC should
|
||||
+ // be dropped (in case the IPC arrived racily after the process or its
|
||||
+ // BrowserContext already got destructed).
|
||||
+ content::RenderProcessHost* GetRenderProcessHost();
|
||||
+
|
||||
// content::BrowserMessageFilter implementation:
|
||||
void OverrideThreadForMessage(const IPC::Message& message,
|
||||
content::BrowserThread::ID* thread) override;
|
||||
diff --git a/extensions/common/api/messaging/port_context.cc b/extensions/common/api/messaging/port_context.cc
|
||||
index 6872179450d8295de7f15dc1437e9d6edefe4fde..319e2f34eca730c5eb7cf94ef8cdede0ddc3f8e1 100644
|
||||
--- a/extensions/common/api/messaging/port_context.cc
|
||||
+++ b/extensions/common/api/messaging/port_context.cc
|
||||
@@ -40,4 +40,27 @@ PortContext PortContext::ForNativeHost() {
|
||||
return PortContext();
|
||||
}
|
||||
|
||||
+namespace debug {
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+base::debug::CrashKeyString* GetServiceWorkerExtensionIdCrashKey() {
|
||||
+ static auto* crash_key = base::debug::AllocateCrashKeyString(
|
||||
+ "PortContext-worker-extension_id", base::debug::CrashKeySize::Size64);
|
||||
+ return crash_key;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+ScopedPortContextCrashKeys::ScopedPortContextCrashKeys(
|
||||
+ const PortContext& port_context) {
|
||||
+ if (port_context.is_for_service_worker()) {
|
||||
+ extension_id_.emplace(GetServiceWorkerExtensionIdCrashKey(),
|
||||
+ port_context.worker->extension_id);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+ScopedPortContextCrashKeys::~ScopedPortContextCrashKeys() = default;
|
||||
+
|
||||
+} // namespace debug
|
||||
} // namespace extensions
|
||||
diff --git a/extensions/common/api/messaging/port_context.h b/extensions/common/api/messaging/port_context.h
|
||||
index b2e9f057b531d90dc256773959cd586953e4915c..53d94c2ad73c58d45b186a32989e2f4864e67d79 100644
|
||||
--- a/extensions/common/api/messaging/port_context.h
|
||||
+++ b/extensions/common/api/messaging/port_context.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
+#include "base/debug/crash_logging.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
|
||||
namespace extensions {
|
||||
@@ -59,6 +60,19 @@ struct PortContext {
|
||||
absl::optional<WorkerContext> worker;
|
||||
};
|
||||
|
||||
+namespace debug {
|
||||
+
|
||||
+class ScopedPortContextCrashKeys {
|
||||
+ public:
|
||||
+ explicit ScopedPortContextCrashKeys(const PortContext& port_context);
|
||||
+ ~ScopedPortContextCrashKeys();
|
||||
+
|
||||
+ private:
|
||||
+ absl::optional<base::debug::ScopedCrashKeyString> extension_id_;
|
||||
+};
|
||||
+
|
||||
+} // namespace debug
|
||||
+
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_COMMON_API_MESSAGING_PORT_CONTEXT_H_
|
||||
292
patches/chromium/cherry-pick-6b4af5d82083.patch
Normal file
292
patches/chromium/cherry-pick-6b4af5d82083.patch
Normal file
@@ -0,0 +1,292 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Huang <penghuang@chromium.org>
|
||||
Date: Wed, 23 Nov 2022 00:16:49 +0000
|
||||
Subject: Fix potential OOB problem with validating command decoder
|
||||
|
||||
Bug: 1392715
|
||||
Change-Id: If51b10cc08e5b3ca4b6012b97261347a5e4c134e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4048203
|
||||
Auto-Submit: Peng Huang <penghuang@chromium.org>
|
||||
Commit-Queue: Peng Huang <penghuang@chromium.org>
|
||||
Reviewed-by: Geoff Lang <geofflang@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1074966}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||
index a36b9901b50cd99ac641d70d2f316362006e45e7..73148877e2b8b28374ffd32aa10361d21e4911e4 100644
|
||||
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||
@@ -8595,10 +8595,18 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
|
||||
service_id = texture_ref->service_id();
|
||||
}
|
||||
|
||||
+ bool valid_target = false;
|
||||
+ if (texture_ref) {
|
||||
+ valid_target = texture_manager()->ValidForTextureTarget(
|
||||
+ texture_ref->texture(), level, 0, 0, 1);
|
||||
+ } else {
|
||||
+ valid_target = texture_manager()->ValidForTarget(textarget, level, 0, 0, 1);
|
||||
+ }
|
||||
+
|
||||
if ((level > 0 && !feature_info_->IsWebGL2OrES3Context() &&
|
||||
!(fbo_render_mipmap_explicitly_enabled_ &&
|
||||
feature_info_->feature_flags().oes_fbo_render_mipmap)) ||
|
||||
- !texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
|
||||
+ !valid_target) {
|
||||
LOCAL_SET_GL_ERROR(
|
||||
GL_INVALID_VALUE,
|
||||
name, "level out of range");
|
||||
@@ -8670,8 +8678,8 @@ void GLES2DecoderImpl::DoFramebufferTextureLayer(
|
||||
"texture is neither TEXTURE_3D nor TEXTURE_2D_ARRAY");
|
||||
return;
|
||||
}
|
||||
- if (!texture_manager()->ValidForTarget(texture_target, level,
|
||||
- 0, 0, layer)) {
|
||||
+ if (!texture_manager()->ValidForTextureTarget(texture_ref->texture(), level,
|
||||
+ 0, 0, layer)) {
|
||||
LOCAL_SET_GL_ERROR(
|
||||
GL_INVALID_VALUE, function_name, "invalid level or layer");
|
||||
return;
|
||||
@@ -14757,11 +14765,6 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage(
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
|
||||
return error::kNoError;
|
||||
}
|
||||
- if (!texture_manager()->ValidForTarget(target, level, width, height, depth) ||
|
||||
- border != 0) {
|
||||
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
|
||||
- return error::kNoError;
|
||||
- }
|
||||
TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
|
||||
&state_, target);
|
||||
if (!texture_ref) {
|
||||
@@ -14770,6 +14773,12 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage(
|
||||
return error::kNoError;
|
||||
}
|
||||
Texture* texture = texture_ref->texture();
|
||||
+ if (!texture_manager()->ValidForTextureTarget(texture, level, width, height,
|
||||
+ depth) ||
|
||||
+ border != 0) {
|
||||
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
|
||||
+ return error::kNoError;
|
||||
+ }
|
||||
if (texture->IsImmutable()) {
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable");
|
||||
return error::kNoError;
|
||||
@@ -15139,10 +15148,6 @@ error::Error GLES2DecoderImpl::DoCompressedTexSubImage(
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
|
||||
return error::kNoError;
|
||||
}
|
||||
- if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) {
|
||||
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
|
||||
- return error::kNoError;
|
||||
- }
|
||||
TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
|
||||
&state_, target);
|
||||
if (!texture_ref) {
|
||||
@@ -15150,7 +15155,14 @@ error::Error GLES2DecoderImpl::DoCompressedTexSubImage(
|
||||
GL_INVALID_OPERATION, func_name, "no texture bound at target");
|
||||
return error::kNoError;
|
||||
}
|
||||
+
|
||||
Texture* texture = texture_ref->texture();
|
||||
+ if (!texture_manager()->ValidForTextureTarget(texture, level, width, height,
|
||||
+ depth)) {
|
||||
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
|
||||
+ return error::kNoError;
|
||||
+ }
|
||||
+
|
||||
GLenum type = 0;
|
||||
GLenum internal_format = 0;
|
||||
if (!texture->GetLevelType(target, level, &type, &internal_format)) {
|
||||
@@ -15275,7 +15287,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
|
||||
GL_INVALID_OPERATION, func_name, "texture is immutable");
|
||||
return;
|
||||
}
|
||||
- if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
|
||||
+ if (!texture_manager()->ValidForTextureTarget(texture, level, width, height,
|
||||
+ 1) ||
|
||||
border != 0) {
|
||||
LOCAL_SET_GL_ERROR(
|
||||
GL_INVALID_VALUE, func_name, "dimensions out of range");
|
||||
@@ -17848,8 +17861,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
|
||||
}
|
||||
|
||||
// Check that this type of texture is allowed.
|
||||
- if (!texture_manager()->ValidForTarget(source_target, source_level,
|
||||
- source_width, source_height, 1)) {
|
||||
+ if (!texture_manager()->ValidForTextureTarget(
|
||||
+ source_texture, source_level, source_width, source_height, 1)) {
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions");
|
||||
return;
|
||||
}
|
||||
@@ -18016,8 +18029,8 @@ void GLES2DecoderImpl::CopySubTextureHelper(const char* function_name,
|
||||
}
|
||||
|
||||
// Check that this type of texture is allowed.
|
||||
- if (!texture_manager()->ValidForTarget(source_target, source_level,
|
||||
- source_width, source_height, 1)) {
|
||||
+ if (!texture_manager()->ValidForTextureTarget(
|
||||
+ source_texture, source_level, source_width, source_height, 1)) {
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
|
||||
"source texture bad dimensions");
|
||||
return;
|
||||
@@ -18257,11 +18270,20 @@ void GLES2DecoderImpl::TexStorageImpl(GLenum target,
|
||||
return;
|
||||
}
|
||||
}
|
||||
+ TextureRef* texture_ref =
|
||||
+ texture_manager()->GetTextureInfoForTarget(&state_, target);
|
||||
+ if (!texture_ref) {
|
||||
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
||||
+ "unknown texture for target");
|
||||
+ return;
|
||||
+ }
|
||||
+ Texture* texture = texture_ref->texture();
|
||||
// The glTexStorage entry points require width, height, and depth to be
|
||||
// at least 1, but the other texture entry points (those which use
|
||||
- // ValidForTarget) do not. So we have to add an extra check here.
|
||||
+ // ValidForTextureTarget) do not. So we have to add an extra check here.
|
||||
bool is_invalid_texstorage_size = width < 1 || height < 1 || depth < 1;
|
||||
- if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) ||
|
||||
+ if (!texture_manager()->ValidForTextureTarget(texture, 0, width, height,
|
||||
+ depth) ||
|
||||
is_invalid_texstorage_size) {
|
||||
LOCAL_SET_GL_ERROR(
|
||||
GL_INVALID_VALUE, function_name, "dimensions out of range");
|
||||
@@ -18274,14 +18296,6 @@ void GLES2DecoderImpl::TexStorageImpl(GLenum target,
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "too many levels");
|
||||
return;
|
||||
}
|
||||
- TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
|
||||
- &state_, target);
|
||||
- if (!texture_ref) {
|
||||
- LOCAL_SET_GL_ERROR(
|
||||
- GL_INVALID_OPERATION, function_name, "unknown texture for target");
|
||||
- return;
|
||||
- }
|
||||
- Texture* texture = texture_ref->texture();
|
||||
if (texture->IsAttachedToFramebuffer()) {
|
||||
framebuffer_state_.clear_state_dirty = true;
|
||||
}
|
||||
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
|
||||
index b20b875b6b37c36623b41e648e393ded96bae93b..f5df8270a8192d36b95e619248c128167455ef46 100644
|
||||
--- a/gpu/command_buffer/service/texture_manager.cc
|
||||
+++ b/gpu/command_buffer/service/texture_manager.cc
|
||||
@@ -1641,7 +1641,7 @@ void Texture::Update() {
|
||||
return;
|
||||
|
||||
if (face_infos_.empty() ||
|
||||
- static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
|
||||
+ static_cast<size_t>(base_level_) >= MaxValidMipLevel()) {
|
||||
texture_complete_ = false;
|
||||
cube_complete_ = false;
|
||||
return;
|
||||
@@ -2028,8 +2028,7 @@ bool Texture::CanRenderTo(const FeatureInfo* feature_info, GLint level) const {
|
||||
// the time.
|
||||
if (face_infos_.size() == 6 && !cube_complete())
|
||||
return false;
|
||||
- DCHECK(level >= 0 &&
|
||||
- level < static_cast<GLint>(face_infos_[0].level_infos.size()));
|
||||
+ DCHECK(level >= 0 && level < static_cast<GLint>(MaxValidMipLevel()));
|
||||
if (level > base_level_ && !texture_complete()) {
|
||||
return false;
|
||||
}
|
||||
@@ -2064,7 +2063,7 @@ void Texture::SetCompatibilitySwizzle(const CompatibilitySwizzle* swizzle) {
|
||||
|
||||
void Texture::ApplyFormatWorkarounds(const FeatureInfo* feature_info) {
|
||||
if (feature_info->gl_version_info().NeedsLuminanceAlphaEmulation()) {
|
||||
- if (static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size())
|
||||
+ if (static_cast<size_t>(base_level_) >= MaxValidMipLevel())
|
||||
return;
|
||||
const Texture::LevelInfo& info = face_infos_[0].level_infos[base_level_];
|
||||
SetCompatibilitySwizzle(GetCompatibilitySwizzleInternal(info.format));
|
||||
@@ -2298,8 +2297,11 @@ scoped_refptr<TextureRef>
|
||||
return default_texture;
|
||||
}
|
||||
|
||||
-bool TextureManager::ValidForTarget(
|
||||
- GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth) {
|
||||
+bool TextureManager::ValidForTarget(GLenum target,
|
||||
+ GLint level,
|
||||
+ GLsizei width,
|
||||
+ GLsizei height,
|
||||
+ GLsizei depth) {
|
||||
if (level < 0 || level >= MaxLevelsForTarget(target))
|
||||
return false;
|
||||
GLsizei max_size = MaxSizeForTarget(target) >> level;
|
||||
@@ -2319,6 +2321,18 @@ bool TextureManager::ValidForTarget(
|
||||
(target != GL_TEXTURE_2D || (depth == 1));
|
||||
}
|
||||
|
||||
+bool TextureManager::ValidForTextureTarget(const Texture* texture,
|
||||
+ GLint level,
|
||||
+ GLsizei width,
|
||||
+ GLsizei height,
|
||||
+ GLsizei depth) {
|
||||
+ if (texture->target() == 0)
|
||||
+ return false;
|
||||
+ if (level < 0 || static_cast<size_t>(level) >= texture->MaxValidMipLevel())
|
||||
+ return false;
|
||||
+ return ValidForTarget(texture->target(), level, width, height, depth);
|
||||
+}
|
||||
+
|
||||
void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
|
||||
DCHECK(ref);
|
||||
ref->texture()->SetTarget(target, MaxLevelsForTarget(target));
|
||||
@@ -2802,14 +2816,6 @@ bool TextureManager::ValidateTexImage(ContextState* state,
|
||||
args.internal_format, args.level)) {
|
||||
return false;
|
||||
}
|
||||
- if (!ValidForTarget(args.target, args.level,
|
||||
- args.width, args.height, args.depth) ||
|
||||
- args.border != 0) {
|
||||
- ERRORSTATE_SET_GL_ERROR(
|
||||
- error_state, GL_INVALID_VALUE, function_name,
|
||||
- "dimensions out of range");
|
||||
- return false;
|
||||
- }
|
||||
if ((GLES2Util::GetChannelsForFormat(args.format) &
|
||||
(GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && args.pixels
|
||||
&& !feature_info_->IsWebGL2OrES3Context()) {
|
||||
@@ -2832,7 +2838,13 @@ bool TextureManager::ValidateTexImage(ContextState* state,
|
||||
"texture is immutable");
|
||||
return false;
|
||||
}
|
||||
-
|
||||
+ if (!ValidForTextureTarget(local_texture_ref->texture(), args.level,
|
||||
+ args.width, args.height, args.depth) ||
|
||||
+ args.border != 0) {
|
||||
+ ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
|
||||
+ "dimensions out of range");
|
||||
+ return false;
|
||||
+ }
|
||||
Buffer* buffer = state->bound_pixel_unpack_buffer.get();
|
||||
if (buffer) {
|
||||
if (buffer->GetMappedRange()) {
|
||||
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
|
||||
index c78c914cbad58abb17439354eeb9f77a9891f21d..8f68e70e6d1c9a4b75f6bec0df7179320bc167c0 100644
|
||||
--- a/gpu/command_buffer/service/texture_manager.h
|
||||
+++ b/gpu/command_buffer/service/texture_manager.h
|
||||
@@ -470,6 +470,11 @@ class GPU_GLES2_EXPORT Texture final : public TextureBase {
|
||||
sampler_state_.min_filter != GL_LINEAR;
|
||||
}
|
||||
|
||||
+ size_t MaxValidMipLevel() const {
|
||||
+ DCHECK(!face_infos_.empty());
|
||||
+ return face_infos_[0].level_infos.size();
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
friend class MailboxManagerTest;
|
||||
friend class TextureManager;
|
||||
@@ -932,6 +937,11 @@ class GPU_GLES2_EXPORT TextureManager
|
||||
bool ValidForTarget(
|
||||
GLenum target, GLint level,
|
||||
GLsizei width, GLsizei height, GLsizei depth);
|
||||
+ bool ValidForTextureTarget(const Texture* texture,
|
||||
+ GLint level,
|
||||
+ GLsizei width,
|
||||
+ GLsizei height,
|
||||
+ GLsizei depth);
|
||||
|
||||
// True if this texture meets all the GLES2 criteria for rendering.
|
||||
// See section 3.8.2 of the GLES2 spec.
|
||||
42
patches/chromium/cherry-pick-77208afba04d.patch
Normal file
42
patches/chromium/cherry-pick-77208afba04d.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Sevcik <jarin@chromium.org>
|
||||
Date: Thu, 1 Dec 2022 14:15:52 +0000
|
||||
Subject: Make WidgetBase::BeginMainFrame resilient to disposed 'this'
|
||||
|
||||
This patch makes sure that WidgetBase::BeginMainFrame can finish
|
||||
execution even if processing the RAF-throttled handlers
|
||||
(DispatchRafAlignedInput) destroys 'this' instance.
|
||||
|
||||
(cherry picked from commit af6e22c14bec7ad64115b24ece6d423f144214ca)
|
||||
|
||||
Bug: chromium:1381871
|
||||
Change-Id: I81aa4ba697f80f8666bb2a3b5542cac210b1efa9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4030809
|
||||
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
|
||||
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1072864}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4068023
|
||||
Auto-Submit: Jaroslav Sevcik <jarin@chromium.org>
|
||||
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1053}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc
|
||||
index e32cbe6473e1e51f4c523b68263cffd1bfb5527c..be585e22e071b078a62552b9fc3e72d1dd8eb036 100644
|
||||
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
|
||||
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
|
||||
@@ -861,8 +861,14 @@ void WidgetBase::BeginMainFrame(base::TimeTicks frame_time) {
|
||||
if (ShouldRecordBeginMainFrameMetrics()) {
|
||||
raf_aligned_input_start_time = base::TimeTicks::Now();
|
||||
}
|
||||
+
|
||||
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
widget_input_handler_manager_->input_event_queue()->DispatchRafAlignedInput(
|
||||
frame_time);
|
||||
+ // DispatchRafAlignedInput could have detached the frame.
|
||||
+ if (!weak_this)
|
||||
+ return;
|
||||
+
|
||||
if (ShouldRecordBeginMainFrameMetrics()) {
|
||||
client_->RecordDispatchRafAlignedInputTime(raf_aligned_input_start_time);
|
||||
}
|
||||
43
patches/chromium/cherry-pick-819d876e1bb8.patch
Normal file
43
patches/chromium/cherry-pick-819d876e1bb8.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ted Meyer <tmathmeyer@chromium.org>
|
||||
Date: Sat, 3 Dec 2022 00:09:22 +0000
|
||||
Subject: Fix UAF caused by vector operations during iteration
|
||||
|
||||
MediaInspectorContextImpl::CullPlayers iterates through dead_players_
|
||||
to remove their events, but this can cause a GC event which can
|
||||
end up adding more players to the |dead_players_| vector, causing
|
||||
it to get re-allocated and it's iterators invalidated.
|
||||
|
||||
We can fix this simply by not using an iterator, and removing elements
|
||||
from the vector before we trigger any GC operations that might cause
|
||||
other changes to the vector.
|
||||
|
||||
Bug: 1383991
|
||||
|
||||
Change-Id: I59f5824c156ff58cf6b55ac9b942c8efdb1ed65a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4064295
|
||||
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
|
||||
Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
|
||||
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1078842}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
|
||||
index c0965693783d5cc0eade67fc78f026cec2942792..6e89262ca229b89407c3f6fff2ab5bf74be460e0 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
|
||||
@@ -109,9 +109,13 @@ void MediaInspectorContextImpl::TrimPlayer(const WebString& playerId) {
|
||||
|
||||
void MediaInspectorContextImpl::CullPlayers(const WebString& prefer_keep) {
|
||||
// Erase all the dead players, but only erase the required number of others.
|
||||
- for (const auto& playerId : dead_players_)
|
||||
+ while (!dead_players_.IsEmpty()) {
|
||||
+ auto playerId = dead_players_.back();
|
||||
+ // remove it first, since |RemovePlayer| can cause a GC event which can
|
||||
+ // potentially caues more players to get added to |dead_players_|.
|
||||
+ dead_players_.pop_back();
|
||||
RemovePlayer(playerId);
|
||||
- dead_players_.clear();
|
||||
+ }
|
||||
|
||||
while (!expendable_players_.IsEmpty()) {
|
||||
if (total_event_count_ <= kMaxCachedPlayerEvents)
|
||||
115
patches/chromium/cherry-pick-81cb17c24788.patch
Normal file
115
patches/chromium/cherry-pick-81cb17c24788.patch
Normal file
@@ -0,0 +1,115 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christoph Schwering <schwering@google.com>
|
||||
Date: Fri, 4 Nov 2022 00:56:32 +0000
|
||||
Subject: Handle misaligned FormData, FormStructure.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This CL handles the case where the fields of the cached FormStructure
|
||||
and the FormData are misaligned in
|
||||
BrowserAutofillManager::WillFillCreditCardNumber.
|
||||
|
||||
(cherry picked from commit 1ad751f7dfa30a12a85824c291394b73c5c47eff)
|
||||
|
||||
Bug: 1376637, 1376639
|
||||
Change-Id: Id7c3357a274b4d6624009ecf52b95a24cf3bfa1d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3965141
|
||||
Commit-Queue: Christoph Schwering <schwering@google.com>
|
||||
Quick-Run: Christoph Schwering <schwering@google.com>
|
||||
Reviewed-by: Dominic Battré <battre@chromium.org>
|
||||
Auto-Submit: Christoph Schwering <schwering@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1061790}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4003032
|
||||
Commit-Queue: Dominic Battré <battre@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#907}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/chrome/test/data/autofill/captured_sites/testcases.json b/chrome/test/data/autofill/captured_sites/testcases.json
|
||||
index bb7ac2a638a410b3e83b9871314eae27aa8ef229..2e69d8f8532760103b9cccd5efc4ca7a4ad016a1 100644
|
||||
--- a/chrome/test/data/autofill/captured_sites/testcases.json
|
||||
+++ b/chrome/test/data/autofill/captured_sites/testcases.json
|
||||
@@ -17,7 +17,7 @@
|
||||
{ "site_name": "bath_and_body_works" },
|
||||
{ "site_name": "beachbody" },
|
||||
{ "site_name": "bed_bath_beyond" },
|
||||
- { "site_name": "belk" },
|
||||
+ { "site_name": "belk", "bug_number": 1376637 },
|
||||
{ "site_name": "bestbuy" },
|
||||
{ "site_name": "bhphotovideo", "bug_number":1173033 },
|
||||
{ "site_name": "bloomingdales" },
|
||||
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
|
||||
index 2dad433c7deb91a2d06f7a10077c9197bd2eba98..0a6e94a1f5327600c1c13cd6fd7586c7ca09037e 100644
|
||||
--- a/components/autofill/core/browser/browser_autofill_manager.cc
|
||||
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
|
||||
@@ -1069,26 +1069,36 @@ void BrowserAutofillManager::OnAskForValuesToFillImpl(
|
||||
|
||||
bool BrowserAutofillManager::WillFillCreditCardNumber(
|
||||
const FormData& form,
|
||||
- const FormFieldData& field) {
|
||||
+ const FormFieldData& triggered_field_data) {
|
||||
FormStructure* form_structure = nullptr;
|
||||
- AutofillField* autofill_field = nullptr;
|
||||
- if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field))
|
||||
+ AutofillField* triggered_field = nullptr;
|
||||
+ if (!GetCachedFormAndField(form, triggered_field_data, &form_structure,
|
||||
+ &triggered_field)) {
|
||||
return false;
|
||||
+ }
|
||||
|
||||
- if (autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER)
|
||||
+ if (triggered_field->Type().GetStorableType() == CREDIT_CARD_NUMBER)
|
||||
return true;
|
||||
|
||||
- DCHECK_EQ(form_structure->field_count(), form.fields.size());
|
||||
- for (size_t i = 0; i < form_structure->field_count(); ++i) {
|
||||
- if (form_structure->field(i)->section == autofill_field->section &&
|
||||
- form_structure->field(i)->Type().GetStorableType() ==
|
||||
- CREDIT_CARD_NUMBER &&
|
||||
- form.fields[i].value.empty() && !form.fields[i].is_autofilled) {
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
+ // `form` is the latest version of the form received from the renderer and may
|
||||
+ // be more up to date than the `form_structure` in the cache. Therefore, we
|
||||
+ // need to validate for each `field` in the cache we try to fill whether
|
||||
+ // it still exists in the renderer and whether it is fillable.
|
||||
+ auto IsFillableField = [&form](FieldGlobalId id) {
|
||||
+ auto it = base::ranges::find(form.fields, id, &FormFieldData::global_id);
|
||||
+ return it != form.fields.end() && it->value.empty() && !it->is_autofilled;
|
||||
+ };
|
||||
|
||||
- return false;
|
||||
+ auto IsFillableCreditCardNumberField = [&triggered_field,
|
||||
+ &IsFillableField](const auto& field) {
|
||||
+ return field->Type().GetStorableType() == CREDIT_CARD_NUMBER &&
|
||||
+ field->section == triggered_field->section &&
|
||||
+ IsFillableField(field->global_id());
|
||||
+ };
|
||||
+
|
||||
+ // This runs O(N^2) in the worst case, but usually there aren't too many
|
||||
+ // credit card number fields in a form.
|
||||
+ return base::ranges::any_of(*form_structure, IsFillableCreditCardNumberField);
|
||||
}
|
||||
|
||||
void BrowserAutofillManager::FillOrPreviewCreditCardForm(
|
||||
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
|
||||
index d6d33df90907dd1521108cfbae1ecbd430bb4e8e..03f92c993a05122b0df1e3b6afdad50edd9e1b41 100644
|
||||
--- a/components/autofill/core/browser/browser_autofill_manager.h
|
||||
+++ b/components/autofill/core/browser/browser_autofill_manager.h
|
||||
@@ -475,11 +475,11 @@ class BrowserAutofillManager : public AutofillManager,
|
||||
// profile does not exist.
|
||||
AutofillProfile* GetProfile(int unique_id);
|
||||
|
||||
- // Determines whether a fill on |form| initiated from |field| will wind up
|
||||
- // filling a credit card number. This is useful to determine if we will need
|
||||
- // to unmask a card.
|
||||
+ // Determines whether a fill on |form| initiated from |triggered_field| will
|
||||
+ // wind up filling a credit card number. This is useful to determine if we
|
||||
+ // will need to unmask a card.
|
||||
bool WillFillCreditCardNumber(const FormData& form,
|
||||
- const FormFieldData& field);
|
||||
+ const FormFieldData& triggered_field);
|
||||
|
||||
// Fills or previews the credit card form.
|
||||
// Assumes the form and field are valid.
|
||||
323
patches/chromium/cherry-pick-933cc81c6bad.patch
Normal file
323
patches/chromium/cherry-pick-933cc81c6bad.patch
Normal file
@@ -0,0 +1,323 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Date: Sat, 10 Sep 2022 05:53:49 +0000
|
||||
Subject: Remove symlinks from FileChooserImpl folder upload result
|
||||
|
||||
FileChooserImpl is the browser-side implementation of
|
||||
<input type=file>. When uploading a whole folder, it
|
||||
currently uses DirectoryLister to list all the files in a
|
||||
directory. The result also includes resolved symbolic links
|
||||
(which may even hide deep in some subfolder), which is not a
|
||||
desired behavior.
|
||||
|
||||
Therefore, this patch removes all symbolic links from the
|
||||
result by checking each file against `base::IsLink()`. Since
|
||||
the function needs blocking calls to access file data, the
|
||||
job is sent to a worker pool thread.
|
||||
|
||||
Fixed: 1345275
|
||||
Change-Id: I8ab58214c87944408c64b177e915247a7485925b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3866767
|
||||
Reviewed-by: Austin Sullivan <asully@chromium.org>
|
||||
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Reviewed-by: Mason Freed <masonf@chromium.org>
|
||||
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1045491}
|
||||
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl.cc b/content/browser/web_contents/file_chooser_impl.cc
|
||||
index 7a3ea45d32c97980c141662f6a071cc517a15ad8..1aa19f7a735b444f2c33d5084edcdd14e3c2f5c5 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl.cc
|
||||
+++ b/content/browser/web_contents/file_chooser_impl.cc
|
||||
@@ -4,8 +4,11 @@
|
||||
|
||||
#include "content/browser/web_contents/file_chooser_impl.h"
|
||||
|
||||
+#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
+#include "base/ranges/algorithm.h"
|
||||
+#include "base/task/thread_pool.h"
|
||||
#include "content/browser/child_process_security_policy_impl.h"
|
||||
#include "content/browser/renderer_host/back_forward_cache_disable.h"
|
||||
#include "content/browser/renderer_host/render_frame_host_delegate.h"
|
||||
@@ -18,6 +21,19 @@
|
||||
|
||||
namespace content {
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+std::vector<blink::mojom::FileChooserFileInfoPtr> RemoveSymlinks(
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
|
||||
+ auto new_end = base::ranges::remove_if(
|
||||
+ files, &base::IsLink,
|
||||
+ [](const auto& file) { return file->get_native_file()->file_path; });
|
||||
+ files.erase(new_end, files.end());
|
||||
+ return files;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
FileChooserImpl::FileSelectListenerImpl::~FileSelectListenerImpl() {
|
||||
#if DCHECK_IS_ON()
|
||||
if (!was_file_select_listener_function_called_) {
|
||||
@@ -51,8 +67,20 @@ void FileChooserImpl::FileSelectListenerImpl::FileSelected(
|
||||
"FileSelectListener::FileSelectionCanceled()";
|
||||
was_file_select_listener_function_called_ = true;
|
||||
#endif
|
||||
- if (owner_)
|
||||
- owner_->FileSelected(std::move(files), base_dir, mode);
|
||||
+ if (!owner_)
|
||||
+ return;
|
||||
+
|
||||
+ if (mode != blink::mojom::FileChooserParams::Mode::kUploadFolder) {
|
||||
+ owner_->FileSelected(base_dir, mode, std::move(files));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ base::ThreadPool::PostTaskAndReplyWithResult(
|
||||
+ FROM_HERE,
|
||||
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
|
||||
+ base::BindOnce(&RemoveSymlinks, std::move(files)),
|
||||
+ base::BindOnce(&FileChooserImpl::FileSelected, owner_->GetWeakPtr(),
|
||||
+ base_dir, mode));
|
||||
}
|
||||
|
||||
void FileChooserImpl::FileSelectListenerImpl::FileSelectionCanceled() {
|
||||
@@ -162,9 +190,9 @@ void FileChooserImpl::EnumerateChosenDirectory(
|
||||
}
|
||||
|
||||
void FileChooserImpl::FileSelected(
|
||||
- std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
const base::FilePath& base_dir,
|
||||
- blink::mojom::FileChooserParams::Mode mode) {
|
||||
+ blink::mojom::FileChooserParams::Mode mode,
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
|
||||
listener_impl_ = nullptr;
|
||||
if (!render_frame_host_) {
|
||||
std::move(callback_).Run(nullptr);
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl.h b/content/browser/web_contents/file_chooser_impl.h
|
||||
index b9f11f9e6a0b548cb5ab8ca721ae823e079ce6fa..b628b29a5f84264e62bb3fa9e92550787b8342de 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl.h
|
||||
+++ b/content/browser/web_contents/file_chooser_impl.h
|
||||
@@ -37,6 +37,8 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
|
||||
// FileSelectListener overrides:
|
||||
|
||||
+ // TODO(xiaochengh): Move |file| to the end of the argument list to match
|
||||
+ // the argument ordering of FileChooserImpl::FileSelected().
|
||||
void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
const base::FilePath& base_dir,
|
||||
blink::mojom::FileChooserParams::Mode mode) override;
|
||||
@@ -68,9 +70,9 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
|
||||
~FileChooserImpl() override;
|
||||
|
||||
- void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
- const base::FilePath& base_dir,
|
||||
- blink::mojom::FileChooserParams::Mode mode);
|
||||
+ void FileSelected(const base::FilePath& base_dir,
|
||||
+ blink::mojom::FileChooserParams::Mode mode,
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files);
|
||||
|
||||
void FileSelectionCanceled();
|
||||
|
||||
@@ -82,6 +84,10 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
const base::FilePath& directory_path,
|
||||
EnumerateChosenDirectoryCallback callback) override;
|
||||
|
||||
+ base::WeakPtr<FileChooserImpl> GetWeakPtr() {
|
||||
+ return weak_factory_.GetWeakPtr();
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
explicit FileChooserImpl(RenderFrameHostImpl* render_frame_host);
|
||||
|
||||
@@ -95,6 +101,8 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
|
||||
raw_ptr<RenderFrameHostImpl> render_frame_host_;
|
||||
scoped_refptr<FileSelectListenerImpl> listener_impl_;
|
||||
base::OnceCallback<void(blink::mojom::FileChooserResultPtr)> callback_;
|
||||
+
|
||||
+ base::WeakPtrFactory<FileChooserImpl> weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace content
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl_browsertest.cc b/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
index ced9bfd8fe905acbb6ab5c3e52a9882fc23a7303..f7519189638ece437c4285ddd490be3ea59e638d 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
+++ b/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
@@ -5,14 +5,18 @@
|
||||
#include "content/browser/web_contents/file_chooser_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
+#include "base/files/file_util.h"
|
||||
+#include "base/path_service.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "content/browser/renderer_host/render_frame_host_impl.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
+#include "content/public/common/content_paths.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/browser_test_utils.h"
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/public/test/content_browser_test_utils.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
+#include "content/test/content_browser_test_utils_internal.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
@@ -143,11 +147,52 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest,
|
||||
->SetListenerFunctionCalledTrueForTesting();
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
|
||||
files.emplace_back(blink::mojom::FileChooserFileInfoPtr(nullptr));
|
||||
- chooser->FileSelected(std::move(files), base::FilePath(),
|
||||
- blink::mojom::FileChooserParams::Mode::kOpen);
|
||||
+ chooser->FileSelected(base::FilePath(),
|
||||
+ blink::mojom::FileChooserParams::Mode::kOpen,
|
||||
+ std::move(files));
|
||||
|
||||
// Test passes if this run_loop.Run() returns instead of timing out.
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
+// https://crbug.com/1345275
|
||||
+IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
|
||||
+ EXPECT_TRUE(NavigateToURL(
|
||||
+ shell(), GetTestUrl(".", "file_input_webkitdirectory.html")));
|
||||
+
|
||||
+ // The folder contains a regular file and a symbolic link.
|
||||
+ // When uploading the folder, the symbolic link should be excluded.
|
||||
+ base::FilePath dir_test_data;
|
||||
+ ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &dir_test_data));
|
||||
+ base::FilePath folder_to_upload =
|
||||
+ dir_test_data.AppendASCII("file_chooser").AppendASCII("dir_with_symlink");
|
||||
+
|
||||
+ base::FilePath text_file = folder_to_upload.AppendASCII("text_file.txt");
|
||||
+ base::FilePath symlink_file = folder_to_upload.AppendASCII("symlink");
|
||||
+
|
||||
+ // Skip the test if symbolic links are not supported.
|
||||
+ {
|
||||
+ base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
+ if (!base::IsLink(symlink_file))
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ std::unique_ptr<FileChooserDelegate> delegate(
|
||||
+ new FileChooserDelegate({text_file, symlink_file}, base::OnceClosure()));
|
||||
+ shell()->web_contents()->SetDelegate(delegate.get());
|
||||
+ EXPECT_TRUE(ExecJs(shell(),
|
||||
+ "(async () => {"
|
||||
+ " let listener = new Promise("
|
||||
+ " resolve => fileinput.onchange = resolve);"
|
||||
+ " fileinput.click();"
|
||||
+ " await listener;"
|
||||
+ "})()"));
|
||||
+
|
||||
+ EXPECT_EQ(
|
||||
+ 1, EvalJs(shell(), "document.getElementById('fileinput').files.length;"));
|
||||
+ EXPECT_EQ(
|
||||
+ "text_file.txt",
|
||||
+ EvalJs(shell(), "document.getElementById('fileinput').files[0].name;"));
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc
|
||||
index d8e63b56c8ac89a08cd7c40cabb156eb4d1923aa..c70d088bfd007e9a6cd9cfcb6f92b07b99653048 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.cc
|
||||
+++ b/content/test/content_browser_test_utils_internal.cc
|
||||
@@ -446,9 +446,14 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
|
||||
return new_shell_observer.GetShell();
|
||||
}
|
||||
|
||||
+FileChooserDelegate::FileChooserDelegate(std::vector<base::FilePath> files,
|
||||
+ base::OnceClosure callback)
|
||||
+ : files_(std::move(files)), callback_(std::move(callback)) {}
|
||||
+
|
||||
FileChooserDelegate::FileChooserDelegate(const base::FilePath& file,
|
||||
base::OnceClosure callback)
|
||||
- : file_(file), callback_(std::move(callback)) {}
|
||||
+ : FileChooserDelegate(std::vector<base::FilePath>(1, file),
|
||||
+ std::move(callback)) {}
|
||||
|
||||
FileChooserDelegate::~FileChooserDelegate() = default;
|
||||
|
||||
@@ -456,16 +461,18 @@ void FileChooserDelegate::RunFileChooser(
|
||||
RenderFrameHost* render_frame_host,
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
const blink::mojom::FileChooserParams& params) {
|
||||
- // Send the selected file to the renderer process.
|
||||
- auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
|
||||
- blink::mojom::NativeFileInfo::New(file_, std::u16string()));
|
||||
+ // Send the selected files to the renderer process.
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
|
||||
- files.push_back(std::move(file_info));
|
||||
- listener->FileSelected(std::move(files), base::FilePath(),
|
||||
- blink::mojom::FileChooserParams::Mode::kOpen);
|
||||
+ for (const auto& file : files_) {
|
||||
+ auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
|
||||
+ blink::mojom::NativeFileInfo::New(file, std::u16string()));
|
||||
+ files.push_back(std::move(file_info));
|
||||
+ }
|
||||
+ listener->FileSelected(std::move(files), base::FilePath(), params.mode);
|
||||
|
||||
params_ = params.Clone();
|
||||
- std::move(callback_).Run();
|
||||
+ if (callback_)
|
||||
+ std::move(callback_).Run();
|
||||
}
|
||||
|
||||
FrameTestNavigationManager::FrameTestNavigationManager(
|
||||
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h
|
||||
index 73be6e8a2f458128b08aae34d951c7a80139997d..43c6aabc5414d0cc12fb5a03142e8b20e2a7fab3 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.h
|
||||
+++ b/content/test/content_browser_test_utils_internal.h
|
||||
@@ -176,9 +176,11 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
|
||||
class FileChooserDelegate : public WebContentsDelegate {
|
||||
public:
|
||||
// Constructs a WebContentsDelegate that mocks a file dialog.
|
||||
- // The mocked file dialog will always reply that the user selected |file|.
|
||||
- // |callback| is invoked when RunFileChooser() is called.
|
||||
+ // The mocked file dialog will always reply that the user selected |file| or
|
||||
+ // |files|. |callback| is invoked when RunFileChooser() is called.
|
||||
FileChooserDelegate(const base::FilePath& file, base::OnceClosure callback);
|
||||
+ FileChooserDelegate(std::vector<base::FilePath> files,
|
||||
+ base::OnceClosure callback);
|
||||
~FileChooserDelegate() override;
|
||||
|
||||
// Implementation of WebContentsDelegate::RunFileChooser.
|
||||
@@ -190,7 +192,7 @@ class FileChooserDelegate : public WebContentsDelegate {
|
||||
const blink::mojom::FileChooserParams& params() const { return *params_; }
|
||||
|
||||
private:
|
||||
- base::FilePath file_;
|
||||
+ std::vector<base::FilePath> files_;
|
||||
base::OnceClosure callback_;
|
||||
blink::mojom::FileChooserParamsPtr params_;
|
||||
};
|
||||
diff --git a/content/test/data/file_chooser/dir_with_symlink/symlink b/content/test/data/file_chooser/dir_with_symlink/symlink
|
||||
new file mode 120000
|
||||
index 0000000000000000000000000000000000000000..7857c689f7043265b4e6d4dcdf6d40d0be2d3d60
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/dir_with_symlink/symlink
|
||||
@@ -0,0 +1 @@
|
||||
+../linked_text_file.txt
|
||||
\ No newline at end of file
|
||||
diff --git a/content/test/data/file_chooser/dir_with_symlink/text_file.txt b/content/test/data/file_chooser/dir_with_symlink/text_file.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8e27be7d6154a1f68ea9160ef0e18691d20560dc
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/dir_with_symlink/text_file.txt
|
||||
@@ -0,0 +1 @@
|
||||
+text
|
||||
diff --git a/content/test/data/file_chooser/linked_text_file.txt b/content/test/data/file_chooser/linked_text_file.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9a1f4bc60917c014eac1464ad664a0271c288b84
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/linked_text_file.txt
|
||||
@@ -0,0 +1 @@
|
||||
+linked text file
|
||||
diff --git a/content/test/data/file_input_webkitdirectory.html b/content/test/data/file_input_webkitdirectory.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5b7bb501f7eb5d9f28751f36380e4ad01d2da0c7
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_input_webkitdirectory.html
|
||||
@@ -0,0 +1 @@
|
||||
+<input type="file" id="fileinput" webkitdirectory />
|
||||
119
patches/chromium/cherry-pick-9b3d0e2f1aab.patch
Normal file
119
patches/chromium/cherry-pick-9b3d0e2f1aab.patch
Normal file
@@ -0,0 +1,119 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Corentin Wallez <cwallez@chromium.org>
|
||||
Date: Tue, 29 Nov 2022 14:07:46 +0000
|
||||
Subject: Keep a reference to the transfer buffer in Dawn read/write handles.
|
||||
|
||||
Previously the Dawn read/write handles in the GPU process only contained
|
||||
a pointer to the inside of a shmem region owned by a gpu::Buffer that
|
||||
had a different lifetime. This could allow a renderer process to
|
||||
deallocate the memory from underneath the handle which is bad.
|
||||
|
||||
Fix this by keepind a scoped_refptr to the gpu::Buffer inside the
|
||||
read/write handles to extend the lifetime of the shmem to be at least as
|
||||
big as the handle's.
|
||||
|
||||
Fixed: chromium:1393177
|
||||
Change-Id: I9d9c18d5155a46e0e3a01d385d221a6370bd2bea
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4056276
|
||||
Reviewed-by: Austin Eng <enga@chromium.org>
|
||||
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1076828}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
index a15b6f9b3b345079d8cf8251ca5f77b6e7ef647a..10941d9f65c66e50303cf7293180c29fced8ffe2 100644
|
||||
--- a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
+++ b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "gpu/command_buffer/common/dawn_memory_transfer_handle.h"
|
||||
+#include "gpu/command_buffer/service/command_buffer_service.h"
|
||||
#include "gpu/command_buffer/service/common_decoder.h"
|
||||
|
||||
namespace gpu {
|
||||
@@ -16,8 +17,8 @@ namespace {
|
||||
class ReadHandleImpl
|
||||
: public dawn::wire::server::MemoryTransferService::ReadHandle {
|
||||
public:
|
||||
- ReadHandleImpl(void* ptr, uint32_t size)
|
||||
- : ReadHandle(), ptr_(ptr), size_(size) {}
|
||||
+ ReadHandleImpl(scoped_refptr<Buffer> buffer, void* ptr, uint32_t size)
|
||||
+ : buffer_(std::move(buffer)), ptr_(ptr), size_(size) {}
|
||||
|
||||
~ReadHandleImpl() override = default;
|
||||
|
||||
@@ -44,6 +45,8 @@ class ReadHandleImpl
|
||||
}
|
||||
|
||||
private:
|
||||
+ scoped_refptr<gpu::Buffer> buffer_;
|
||||
+ // Pointer to client-visible shared memory owned by buffer_.
|
||||
raw_ptr<void> ptr_;
|
||||
uint32_t size_;
|
||||
};
|
||||
@@ -51,8 +54,8 @@ class ReadHandleImpl
|
||||
class WriteHandleImpl
|
||||
: public dawn::wire::server::MemoryTransferService::WriteHandle {
|
||||
public:
|
||||
- WriteHandleImpl(const void* ptr, uint32_t size)
|
||||
- : WriteHandle(), ptr_(ptr), size_(size) {}
|
||||
+ WriteHandleImpl(scoped_refptr<Buffer> buffer, const void* ptr, uint32_t size)
|
||||
+ : buffer_(std::move(buffer)), ptr_(ptr), size_(size) {}
|
||||
|
||||
~WriteHandleImpl() override = default;
|
||||
|
||||
@@ -82,7 +85,9 @@ class WriteHandleImpl
|
||||
}
|
||||
|
||||
private:
|
||||
- raw_ptr<const void> ptr_; // Pointer to client-visible shared memory.
|
||||
+ scoped_refptr<gpu::Buffer> buffer_;
|
||||
+ // Pointer to client-visible shared memory owned by buffer_.
|
||||
+ raw_ptr<const void> ptr_;
|
||||
uint32_t size_;
|
||||
};
|
||||
|
||||
@@ -111,13 +116,19 @@ bool DawnServiceMemoryTransferService::DeserializeReadHandle(
|
||||
int32_t shm_id = handle->shm_id;
|
||||
uint32_t shm_offset = handle->shm_offset;
|
||||
|
||||
- void* ptr = decoder_->GetAddressAndCheckSize(shm_id, shm_offset, size);
|
||||
+ scoped_refptr<gpu::Buffer> buffer =
|
||||
+ decoder_->command_buffer_service()->GetTransferBuffer(shm_id);
|
||||
+ if (buffer == nullptr) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ void* ptr = buffer->GetDataAddress(shm_offset, size);
|
||||
if (ptr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DCHECK(read_handle);
|
||||
- *read_handle = new ReadHandleImpl(ptr, size);
|
||||
+ *read_handle = new ReadHandleImpl(std::move(buffer), ptr, size);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -139,13 +150,19 @@ bool DawnServiceMemoryTransferService::DeserializeWriteHandle(
|
||||
int32_t shm_id = handle->shm_id;
|
||||
uint32_t shm_offset = handle->shm_offset;
|
||||
|
||||
- void* ptr = decoder_->GetAddressAndCheckSize(shm_id, shm_offset, size);
|
||||
+ scoped_refptr<gpu::Buffer> buffer =
|
||||
+ decoder_->command_buffer_service()->GetTransferBuffer(shm_id);
|
||||
+ if (buffer == nullptr) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ const void* ptr = buffer->GetDataAddress(shm_offset, size);
|
||||
if (ptr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DCHECK(write_handle);
|
||||
- *write_handle = new WriteHandleImpl(ptr, size);
|
||||
+ *write_handle = new WriteHandleImpl(std::move(buffer), ptr, size);
|
||||
|
||||
return true;
|
||||
}
|
||||
102
patches/chromium/cherry-pick-a1cbf05b4163.patch
Normal file
102
patches/chromium/cherry-pick-a1cbf05b4163.patch
Normal file
@@ -0,0 +1,102 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Wolenetz <wolenetz@chromium.org>
|
||||
Date: Fri, 4 Nov 2022 22:06:47 +0000
|
||||
Subject: webcodecs: Fix race in VE.isConfigSupported() promise resolution
|
||||
|
||||
If the context is destroyed before VideoEncoder calls `done_callback`, bad
|
||||
things can happen. That's why we extract a callback runner before doing
|
||||
anything asynchronous. Since we hold a ref-counted pointer to the
|
||||
runner it should be safe now.
|
||||
|
||||
(cherry picked from commit 2acf28478008315f302fd52b571623e784be707b)
|
||||
|
||||
Bug: 1375059
|
||||
Change-Id: I984ab27e03e50bd5ae4bf0eb13431834b14f89b7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3965544
|
||||
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
|
||||
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1061737}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4005574
|
||||
Reviewed-by: Matthew Wolenetz <wolenetz@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#911}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
|
||||
index 5332ae4094c5a8062cb1b8c830869095b964eabc..8f2be276b702bf5a3071b1bf44a9a5419880acf1 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
|
||||
@@ -68,6 +68,7 @@
|
||||
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
|
||||
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
|
||||
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
|
||||
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
|
||||
|
||||
@@ -100,16 +101,6 @@ namespace {
|
||||
constexpr const char kCategory[] = "media";
|
||||
constexpr int kMaxActiveEncodes = 5;
|
||||
|
||||
-// Use this function in cases when we can't immediately delete |ptr| because
|
||||
-// there might be its methods on the call stack.
|
||||
-template <typename T>
|
||||
-void DeleteLater(ScriptState* state, std::unique_ptr<T> ptr) {
|
||||
- DCHECK(state->ContextIsValid());
|
||||
- auto* context = ExecutionContext::From(state);
|
||||
- auto runner = context->GetTaskRunner(TaskType::kInternalDefault);
|
||||
- runner->DeleteSoon(FROM_HERE, std::move(ptr));
|
||||
-}
|
||||
-
|
||||
bool IsAcceleratedConfigurationSupported(
|
||||
media::VideoCodecProfile profile,
|
||||
const media::VideoEncoder::Options& options,
|
||||
@@ -979,6 +970,7 @@ void VideoEncoder::ResetInternal() {
|
||||
}
|
||||
|
||||
static void isConfigSupportedWithSoftwareOnly(
|
||||
+ ScriptState* script_state,
|
||||
ScriptPromiseResolver* resolver,
|
||||
VideoEncoderSupport* support,
|
||||
VideoEncoderTraits::ParsedConfig* config) {
|
||||
@@ -1003,22 +995,25 @@ static void isConfigSupportedWithSoftwareOnly(
|
||||
return;
|
||||
}
|
||||
|
||||
- auto done_callback = [](std::unique_ptr<media::VideoEncoder> sw_encoder,
|
||||
+ auto done_callback = [](std::unique_ptr<media::VideoEncoder> encoder,
|
||||
ScriptPromiseResolver* resolver,
|
||||
+ scoped_refptr<base::SingleThreadTaskRunner> runner,
|
||||
VideoEncoderSupport* support,
|
||||
media::EncoderStatus status) {
|
||||
support->setSupported(status.is_ok());
|
||||
resolver->Resolve(support);
|
||||
- DeleteLater(resolver->GetScriptState(), std::move(sw_encoder));
|
||||
+ runner->DeleteSoon(FROM_HERE, std::move(encoder));
|
||||
};
|
||||
|
||||
+ auto* context = ExecutionContext::From(script_state);
|
||||
+ auto runner = context->GetTaskRunner(TaskType::kInternalDefault);
|
||||
auto* software_encoder_raw = software_encoder.get();
|
||||
software_encoder_raw->Initialize(
|
||||
config->profile, config->options, base::DoNothing(),
|
||||
- ConvertToBaseOnceCallback(
|
||||
- CrossThreadBindOnce(done_callback, std::move(software_encoder),
|
||||
- WrapCrossThreadPersistent(resolver),
|
||||
- WrapCrossThreadPersistent(support))));
|
||||
+ ConvertToBaseOnceCallback(CrossThreadBindOnce(
|
||||
+ done_callback, std::move(software_encoder),
|
||||
+ WrapCrossThreadPersistent(resolver), std::move(runner),
|
||||
+ WrapCrossThreadPersistent(support))));
|
||||
}
|
||||
|
||||
static void isConfigSupportedWithHardwareOnly(
|
||||
@@ -1105,7 +1100,8 @@ ScriptPromise VideoEncoder::isConfigSupported(ScriptState* script_state,
|
||||
promises.push_back(resolver->Promise());
|
||||
auto* support = VideoEncoderSupport::Create();
|
||||
support->setConfig(config_copy);
|
||||
- isConfigSupportedWithSoftwareOnly(resolver, support, parsed_config);
|
||||
+ isConfigSupportedWithSoftwareOnly(script_state, resolver, support,
|
||||
+ parsed_config);
|
||||
}
|
||||
|
||||
// Wait for all |promises| to resolve and check if any of them have
|
||||
285
patches/chromium/cherry-pick-ac4785387fff.patch
Normal file
285
patches/chromium/cherry-pick-ac4785387fff.patch
Normal file
@@ -0,0 +1,285 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Tapuska <dtapuska@chromium.org>
|
||||
Date: Thu, 3 Nov 2022 23:16:16 +0000
|
||||
Subject: Fix PauseOrFreezeOnWorkerThread with nested Worklets.
|
||||
|
||||
Worklets can use the same backing thread which means we can have
|
||||
nested WorkerThreads paused. If a parent WorkerThread gets deallocated
|
||||
make sure we don't access anything after it is deallocated once the
|
||||
nested event queue is released.
|
||||
|
||||
BUG=1372695
|
||||
|
||||
(cherry picked from commit ff5696ba4bc0f8782e3de40e04685507d9f17fd2)
|
||||
|
||||
Change-Id: I176b8f750da5a41d19d1b3a623944d9a2ed4a441
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3953152
|
||||
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1059485}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4004562
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#906}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
|
||||
index c54d0a91447717f014f44d36e004d9092e98f8bb..dbe40e69a276983bc2df5dcddd7b9b483d2534b1 100644
|
||||
--- a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
|
||||
+++ b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
|
||||
@@ -234,6 +234,7 @@ class ThreadedWorkletMessagingProxyForTest
|
||||
|
||||
private:
|
||||
friend class ThreadedWorkletTest;
|
||||
+ FRIEND_TEST_ALL_PREFIXES(ThreadedWorkletTest, NestedRunLoopTermination);
|
||||
|
||||
std::unique_ptr<WorkerThread> CreateWorkerThread() final {
|
||||
return std::make_unique<ThreadedWorkletThreadForTest>(WorkletObjectProxy());
|
||||
@@ -280,6 +281,16 @@ class ThreadedWorkletTest : public testing::Test {
|
||||
}
|
||||
Document& GetDocument() { return page_->GetDocument(); }
|
||||
|
||||
+ void WaitForReady(WorkerThread* worker_thread) {
|
||||
+ base::WaitableEvent child_waitable;
|
||||
+ PostCrossThreadTask(
|
||||
+ *worker_thread->GetTaskRunner(TaskType::kInternalTest), FROM_HERE,
|
||||
+ CrossThreadBindOnce(&base::WaitableEvent::Signal,
|
||||
+ CrossThreadUnretained(&child_waitable)));
|
||||
+
|
||||
+ child_waitable.Wait();
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
std::unique_ptr<DummyPageHolder> page_;
|
||||
Persistent<ThreadedWorkletMessagingProxyForTest> messaging_proxy_;
|
||||
@@ -403,4 +414,40 @@ TEST_F(ThreadedWorkletTest, TaskRunner) {
|
||||
test::EnterRunLoop();
|
||||
}
|
||||
|
||||
+TEST_F(ThreadedWorkletTest, NestedRunLoopTermination) {
|
||||
+ MessagingProxy()->Start();
|
||||
+
|
||||
+ ThreadedWorkletMessagingProxyForTest* second_messaging_proxy =
|
||||
+ MakeGarbageCollected<ThreadedWorkletMessagingProxyForTest>(
|
||||
+ GetExecutionContext());
|
||||
+
|
||||
+ // Get a nested event loop where the first one is on the stack
|
||||
+ // and the second is still alive.
|
||||
+ second_messaging_proxy->Start();
|
||||
+
|
||||
+ // Wait until the workers are setup and ready to accept work before we
|
||||
+ // pause them.
|
||||
+ WaitForReady(GetWorkerThread());
|
||||
+ WaitForReady(second_messaging_proxy->GetWorkerThread());
|
||||
+
|
||||
+ // Pause the second worker, then the first.
|
||||
+ second_messaging_proxy->GetWorkerThread()->Pause();
|
||||
+ GetWorkerThread()->Pause();
|
||||
+
|
||||
+ // Resume then terminate the second worker.
|
||||
+ second_messaging_proxy->GetWorkerThread()->Resume();
|
||||
+ second_messaging_proxy->GetWorkerThread()->Terminate();
|
||||
+ second_messaging_proxy = nullptr;
|
||||
+
|
||||
+ // Now resume the first worker.
|
||||
+ GetWorkerThread()->Resume();
|
||||
+
|
||||
+ // Make sure execution still works without crashing.
|
||||
+ PostCrossThreadTask(
|
||||
+ *GetWorkerThread()->GetTaskRunner(TaskType::kInternalTest), FROM_HERE,
|
||||
+ CrossThreadBindOnce(&ThreadedWorkletThreadForTest::TestTaskRunner,
|
||||
+ CrossThreadUnretained(GetWorkerThread())));
|
||||
+ test::EnterRunLoop();
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
|
||||
index 892b3e58443f1a82a6a41c6d52df7d2d701b377d..3a98c2d192e1e47d1586d1dab1fc9e9dc9daf83b 100644
|
||||
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
|
||||
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
-#include "base/auto_reset.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
@@ -593,6 +592,7 @@ void WorkerThread::InitializeOnWorkerThread(
|
||||
const absl::optional<WorkerBackingThreadStartupData>& thread_startup_data,
|
||||
std::unique_ptr<WorkerDevToolsParams> devtools_params) {
|
||||
DCHECK(IsCurrentThread());
|
||||
+ backing_thread_weak_factory_.emplace(this);
|
||||
worker_reporting_proxy_.WillInitializeWorkerContext();
|
||||
{
|
||||
TRACE_EVENT0("blink.worker", "WorkerThread::InitializeWorkerContext");
|
||||
@@ -728,11 +728,13 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
|
||||
SetThreadState(ThreadState::kReadyToShutdown);
|
||||
}
|
||||
|
||||
+ backing_thread_weak_factory_ = absl::nullopt;
|
||||
if (pause_or_freeze_count_ > 0) {
|
||||
DCHECK(nested_runner_);
|
||||
pause_or_freeze_count_ = 0;
|
||||
nested_runner_->QuitNow();
|
||||
}
|
||||
+ pause_handle_.reset();
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(GetIsolate());
|
||||
@@ -883,8 +885,7 @@ void WorkerThread::PauseOrFreezeOnWorkerThread(
|
||||
if (pause_or_freeze_count_ > 1)
|
||||
return;
|
||||
|
||||
- std::unique_ptr<scheduler::WorkerScheduler::PauseHandle> pause_handle =
|
||||
- GetScheduler()->Pause();
|
||||
+ pause_handle_ = GetScheduler()->Pause();
|
||||
{
|
||||
// Since the nested message loop runner needs to be created and destroyed on
|
||||
// the same thread we allocate and destroy a new message loop runner each
|
||||
@@ -892,13 +893,20 @@ void WorkerThread::PauseOrFreezeOnWorkerThread(
|
||||
// the worker thread such that the resume/terminate can quit this runner.
|
||||
std::unique_ptr<Platform::NestedMessageLoopRunner> nested_runner =
|
||||
Platform::Current()->CreateNestedMessageLoopRunner();
|
||||
- base::AutoReset<Platform::NestedMessageLoopRunner*> nested_runner_autoreset(
|
||||
- &nested_runner_, nested_runner.get());
|
||||
+ auto weak_this = backing_thread_weak_factory_->GetWeakPtr();
|
||||
+ nested_runner_ = nested_runner.get();
|
||||
nested_runner->Run();
|
||||
+
|
||||
+ // Careful `this` may be destroyed.
|
||||
+ if (!weak_this) {
|
||||
+ return;
|
||||
+ }
|
||||
+ nested_runner_ = nullptr;
|
||||
}
|
||||
GlobalScope()->SetDefersLoadingForResourceFetchers(LoaderFreezeMode::kNone);
|
||||
GlobalScope()->SetIsInBackForwardCache(false);
|
||||
GlobalScope()->SetLifecycleState(mojom::blink::FrameLifecycleState::kRunning);
|
||||
+ pause_handle_.reset();
|
||||
}
|
||||
|
||||
void WorkerThread::ResumeOnWorkerThread() {
|
||||
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h
|
||||
index 834aabc12fe0c43f69bb3a5fa669571c84847c6d..2431c406268a3631df157a24c3fd7accf184cccc 100644
|
||||
--- a/third_party/blink/renderer/core/workers/worker_thread.h
|
||||
+++ b/third_party/blink/renderer/core/workers/worker_thread.h
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
+#include "base/memory/weak_ptr.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "base/thread_annotations.h"
|
||||
@@ -80,7 +81,7 @@ struct WorkerMainScriptLoadParameters;
|
||||
// abstract class. Multiple WorkerThreads may share one WorkerBackingThread for
|
||||
// worklets.
|
||||
//
|
||||
-// WorkerThread start and termination must be initiated on the main thread and
|
||||
+// WorkerThread start and termination must be initiated on the parent thread and
|
||||
// an actual task is executed on the worker thread.
|
||||
//
|
||||
// When termination starts, (debugger) tasks on WorkerThread are handled as
|
||||
@@ -103,7 +104,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
~WorkerThread() override;
|
||||
|
||||
// Starts the underlying thread and creates the global scope. Called on the
|
||||
- // main thread.
|
||||
+ // parent thread.
|
||||
// Startup data for WorkerBackingThread is absl::nullopt if |this| doesn't own
|
||||
// the underlying WorkerBackingThread.
|
||||
// TODO(nhiroki): We could separate WorkerBackingThread initialization from
|
||||
@@ -115,14 +116,14 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
std::unique_ptr<WorkerDevToolsParams>);
|
||||
|
||||
// Posts a task to evaluate a top-level classic script on the worker thread.
|
||||
- // Called on the main thread after Start().
|
||||
+ // Called on the parent thread after Start().
|
||||
void EvaluateClassicScript(const KURL& script_url,
|
||||
const String& source_code,
|
||||
std::unique_ptr<Vector<uint8_t>> cached_meta_data,
|
||||
const v8_inspector::V8StackTraceId& stack_id);
|
||||
|
||||
// Posts a task to fetch and run a top-level classic script on the worker
|
||||
- // thread. Called on the main thread after Start().
|
||||
+ // thread. Called on the parent thread after Start().
|
||||
void FetchAndRunClassicScript(
|
||||
const KURL& script_url,
|
||||
std::unique_ptr<WorkerMainScriptLoadParameters>
|
||||
@@ -133,7 +134,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
const v8_inspector::V8StackTraceId& stack_id);
|
||||
|
||||
// Posts a task to fetch and run a top-level module script on the worker
|
||||
- // thread. Called on the main thread after Start().
|
||||
+ // thread. Called on the parent thread after Start().
|
||||
void FetchAndRunModuleScript(
|
||||
const KURL& script_url,
|
||||
std::unique_ptr<WorkerMainScriptLoadParameters>
|
||||
@@ -154,7 +155,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
// Terminates the worker thread. Subclasses of WorkerThread can override this
|
||||
// to do cleanup. The default behavior is to call Terminate() and
|
||||
// synchronously call EnsureScriptExecutionTerminates() to ensure the thread
|
||||
- // is quickly terminated. Called on the main thread.
|
||||
+ // is quickly terminated. Called on the parent thread.
|
||||
virtual void TerminateForTesting();
|
||||
|
||||
// Thread::TaskObserver.
|
||||
@@ -181,7 +182,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
void DebuggerTaskStarted();
|
||||
void DebuggerTaskFinished();
|
||||
|
||||
- // Callable on both the main thread and the worker thread.
|
||||
+ // Callable on both the parent thread and the worker thread.
|
||||
const base::UnguessableToken& GetDevToolsWorkerToken() const {
|
||||
return devtools_worker_token_;
|
||||
}
|
||||
@@ -325,7 +326,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
// already shutting down. Does not terminate if a debugger task is running,
|
||||
// because the debugger task is guaranteed to finish and it heavily uses V8
|
||||
// API calls which would crash after forcible script termination. Called on
|
||||
- // the main thread.
|
||||
+ // the parent thread.
|
||||
void EnsureScriptExecutionTerminates(ExitCode) LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// These are called in this order during worker thread startup.
|
||||
@@ -410,7 +411,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
// A unique identifier among all WorkerThreads.
|
||||
const int worker_thread_id_;
|
||||
|
||||
- // Set on the main thread.
|
||||
+ // Set on the parent thread.
|
||||
bool requested_to_terminate_ GUARDED_BY(mutex_) = false;
|
||||
|
||||
ThreadState thread_state_ GUARDED_BY(mutex_) = ThreadState::kNotStarted;
|
||||
@@ -444,7 +445,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
TaskTypeTraits>;
|
||||
TaskRunnerHashMap worker_task_runners_;
|
||||
|
||||
- // This lock protects shared states between the main thread and the worker
|
||||
+ // This lock protects shared states between the parent thread and the worker
|
||||
// thread. See thread-safety annotations (e.g., GUARDED_BY) in this header
|
||||
// file.
|
||||
Mutex mutex_;
|
||||
@@ -453,6 +454,10 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
// only on the worker thread.
|
||||
int pause_or_freeze_count_ = 0;
|
||||
|
||||
+ // The `PauseHandle` needs to be destroyed before the scheduler is destroyed
|
||||
+ // otherwise we will hit a DCHECK.
|
||||
+ std::unique_ptr<scheduler::WorkerScheduler::PauseHandle> pause_handle_;
|
||||
+
|
||||
// A nested message loop for handling pausing. Pointer is not owned. Used only
|
||||
// on the worker thread.
|
||||
Platform::NestedMessageLoopRunner* nested_runner_ = nullptr;
|
||||
@@ -479,6 +484,12 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
|
||||
HashSet<std::unique_ptr<InterruptData>> pending_interrupts_
|
||||
GUARDED_BY(mutex_);
|
||||
|
||||
+ // Since the WorkerThread is allocated and deallocated on the parent thread,
|
||||
+ // we need a WeakPtrFactory that is allocated and cleared on the backing
|
||||
+ // thread.
|
||||
+ absl::optional<base::WeakPtrFactory<WorkerThread>>
|
||||
+ backing_thread_weak_factory_;
|
||||
+
|
||||
THREAD_CHECKER(parent_thread_checker_);
|
||||
};
|
||||
|
||||
122
patches/chromium/cherry-pick-c83640db21b5.patch
Normal file
122
patches/chromium/cherry-pick-c83640db21b5.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Wed, 5 Oct 2022 06:03:23 +0000
|
||||
Subject: build: set DTSDKBuild correctly when generating plist files
|
||||
|
||||
Currently we set DTSDKBuild to the version of the SDK used to build
|
||||
Chromium. This value is supposed to be the build version (this is
|
||||
what xcode sets it to for instance). We read this value out of the
|
||||
SDK directly and use it instead.
|
||||
|
||||
Change-Id: Ieb7990f13095683ad8c026f027b2605ae39523a4
|
||||
|
||||
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
|
||||
index 7b1761607c853ae79619d6b872167a00a39f8236..c8e07ad62519236ead55c9b7ce1b1a4c3d5491af 100644
|
||||
--- a/build/config/mac/mac_sdk.gni
|
||||
+++ b/build/config/mac/mac_sdk.gni
|
||||
@@ -40,6 +40,11 @@ declare_args() {
|
||||
# will fail.
|
||||
mac_sdk_official_version = "12.3"
|
||||
|
||||
+ # The SDK build version used when making official builds. This is a single
|
||||
+ # exact version found at "System/Library/CoreServices/SystemVersion.plist"
|
||||
+ # inside the SDK.
|
||||
+ mac_sdk_official_build_version = "21E226"
|
||||
+
|
||||
# Production builds should use hermetic Xcode. If you want to do production
|
||||
# builds with system Xcode to test new SDKs, set this.
|
||||
# Don't set this on any bots.
|
||||
@@ -101,11 +106,13 @@ if (use_system_xcode) {
|
||||
find_sdk_args = [
|
||||
"--print_sdk_path",
|
||||
"--print_bin_path",
|
||||
+ "--print_sdk_build",
|
||||
mac_sdk_min,
|
||||
]
|
||||
find_sdk_lines =
|
||||
exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
|
||||
- mac_sdk_version = find_sdk_lines[2]
|
||||
+ mac_sdk_version = find_sdk_lines[3]
|
||||
+ mac_sdk_build_version = find_sdk_lines[2]
|
||||
if (mac_sdk_path == "") {
|
||||
mac_sdk_path = find_sdk_lines[0]
|
||||
mac_bin_path = find_sdk_lines[1]
|
||||
@@ -114,6 +121,7 @@ if (use_system_xcode) {
|
||||
}
|
||||
} else {
|
||||
mac_sdk_version = mac_sdk_official_version
|
||||
+ mac_sdk_build_version = mac_sdk_official_build_version
|
||||
_dev = _hermetic_xcode_path + "/Contents/Developer"
|
||||
_sdk = "MacOSX${mac_sdk_version}.sdk"
|
||||
mac_sdk_path = _dev + "/Platforms/MacOSX.platform/Developer/SDKs/$_sdk"
|
||||
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni
|
||||
index 03073f830401c4891376a3b59e2e7a870e3d34b7..04d403054c1a83fcbbc70be7cfd239ecbec315d3 100644
|
||||
--- a/build/config/mac/rules.gni
|
||||
+++ b/build/config/mac/rules.gni
|
||||
@@ -41,7 +41,7 @@ template("mac_info_plist") {
|
||||
apple_info_plist(target_name) {
|
||||
format = "xml1"
|
||||
extra_substitutions = [
|
||||
- "MAC_SDK_BUILD=$mac_sdk_version",
|
||||
+ "MAC_SDK_BUILD=$mac_sdk_build_version",
|
||||
"MAC_SDK_NAME=$mac_sdk_name$mac_sdk_version",
|
||||
"MACOSX_DEPLOYMENT_TARGET=$mac_deployment_target",
|
||||
"CHROMIUM_MIN_SYSTEM_VERSION=$mac_min_system_version",
|
||||
diff --git a/build/mac/find_sdk.py b/build/mac/find_sdk.py
|
||||
index d86f3109357a9246d570cb02992dc82552ba7c20..b2400c7e8c70957e364444f509880900ce3b641f 100755
|
||||
--- a/build/mac/find_sdk.py
|
||||
+++ b/build/mac/find_sdk.py
|
||||
@@ -24,6 +24,7 @@ Sample Output:
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
+import plistlib
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -51,6 +52,9 @@ def main():
|
||||
parser.add_option("--print_bin_path",
|
||||
action="store_true", dest="print_bin_path", default=False,
|
||||
help="Additionally print the path the toolchain bin dir.")
|
||||
+ parser.add_option("--print_sdk_build",
|
||||
+ action="store_true", dest="print_sdk_build", default=False,
|
||||
+ help="Additionally print the build version of the SDK.")
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.error('Please specify a minimum SDK version')
|
||||
@@ -80,20 +84,30 @@ def main():
|
||||
if not sdks:
|
||||
raise Exception('No %s+ SDK found' % min_sdk_version)
|
||||
best_sdk = sorted(sdks, key=parse_version)[0]
|
||||
+ sdk_name = 'MacOSX' + best_sdk + '.sdk'
|
||||
+ sdk_path = os.path.join(sdk_dir, sdk_name)
|
||||
|
||||
if options.print_sdk_path:
|
||||
- sdk_name = 'MacOSX' + best_sdk + '.sdk'
|
||||
- print(os.path.join(sdk_dir, sdk_name))
|
||||
+ print(sdk_path)
|
||||
|
||||
if options.print_bin_path:
|
||||
bin_path = 'Toolchains/XcodeDefault.xctoolchain/usr/bin/'
|
||||
print(os.path.join(dev_dir, bin_path))
|
||||
|
||||
- return best_sdk
|
||||
+ if options.print_sdk_build:
|
||||
+ system_version_plist = os.path.join(sdk_path,
|
||||
+ 'System/Library/CoreServices/SystemVersion.plist')
|
||||
+ with open(system_version_plist, 'rb') as f:
|
||||
+ system_version_info = plistlib.load(f)
|
||||
+ if 'ProductBuildVersion' not in system_version_info:
|
||||
+ raise Exception('Failed to determine ProductBuildVersion' +
|
||||
+ 'for SDK at path %s' % system_version_plist)
|
||||
+ print(system_version_info['ProductBuildVersion'])
|
||||
+
|
||||
+ print(best_sdk)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.platform != 'darwin':
|
||||
raise Exception("This script only runs on Mac")
|
||||
- print(main())
|
||||
- sys.exit(0)
|
||||
+ sys.exit(main())
|
||||
116
patches/chromium/cherry-pick-ca2b108a0f1f.patch
Normal file
116
patches/chromium/cherry-pick-ca2b108a0f1f.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Alvestrand <hta@chromium.org>
|
||||
Date: Wed, 18 Jan 2023 08:02:48 +0000
|
||||
Subject: Delete PeerConnectionHandler in PeerConnection finalizer
|
||||
|
||||
Also guard against removal of PC during PeerConnectionHandler
|
||||
call that may cause garbage collection.
|
||||
|
||||
(cherry picked from commit 5066dd66309d884762e5fb9be04b59582893d09a)
|
||||
|
||||
Bug: chromium:1405256
|
||||
Change-Id: I9adf7b219e2026e07ccc0868c1a85f3b35cd9d26
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4154578
|
||||
Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
||||
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1091801}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4176372
|
||||
Auto-Submit: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#418}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
index bcb9e9f13cfa525499023e369cefe0ed23f47abc..cf01e7144fc2901c88f320ea7b1c093dfb6ab8b1 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
@@ -819,10 +819,11 @@ RTCPeerConnection::~RTCPeerConnection() {
|
||||
}
|
||||
|
||||
void RTCPeerConnection::Dispose() {
|
||||
- // Promptly clears the handler's pointer to |this|
|
||||
+ // Promptly clears the handler
|
||||
// so that content/ doesn't access it in a lazy sweeping phase.
|
||||
+ // Other references to the handler use a weak pointer, preventing access.
|
||||
if (peer_handler_) {
|
||||
- peer_handler_->CloseAndUnregister();
|
||||
+ peer_handler_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
index 7662f2cda29b6265705a4f83dbf76ccaf50ab576..48bd8a4eee90b07a38c7f09f260da30c9e7e34bc 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
@@ -771,6 +771,8 @@ class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl
|
||||
if (handler_) {
|
||||
handler_->OnModifySctpTransport(std::move(states.sctp_transport_state));
|
||||
}
|
||||
+ // Since OnSessionDescriptionsUpdated can fire events, it may cause
|
||||
+ // garbage collection. Ensure that handler_ is still valid.
|
||||
if (handler_) {
|
||||
handler_->OnModifyTransceivers(
|
||||
states.signaling_state, std::move(states.transceiver_states),
|
||||
@@ -1128,6 +1130,8 @@ bool RTCPeerConnectionHandler::Initialize(
|
||||
CHECK(!initialize_called_);
|
||||
initialize_called_ = true;
|
||||
|
||||
+ // Prevent garbage collection of client_ during processing.
|
||||
+ auto* client_on_stack = client_;
|
||||
peer_connection_tracker_ = PeerConnectionTracker::From(*frame);
|
||||
|
||||
configuration_ = server_configuration;
|
||||
@@ -1165,8 +1169,8 @@ bool RTCPeerConnectionHandler::Initialize(
|
||||
peer_connection_tracker_->RegisterPeerConnection(this, configuration_,
|
||||
options, frame_);
|
||||
}
|
||||
-
|
||||
- return true;
|
||||
+ // Gratuitous usage of client_on_stack to prevent compiler errors.
|
||||
+ return !!client_on_stack;
|
||||
}
|
||||
|
||||
bool RTCPeerConnectionHandler::InitializeForTest(
|
||||
@@ -2229,9 +2233,11 @@ void RTCPeerConnectionHandler::OnSessionDescriptionsUpdated(
|
||||
pending_remote_description,
|
||||
std::unique_ptr<webrtc::SessionDescriptionInterface>
|
||||
current_remote_description) {
|
||||
+ // Prevent garbage collection of client_ during processing.
|
||||
+ auto* client_on_stack = client_;
|
||||
if (!client_ || is_closed_)
|
||||
return;
|
||||
- client_->DidChangeSessionDescriptions(
|
||||
+ client_on_stack->DidChangeSessionDescriptions(
|
||||
pending_local_description
|
||||
? CreateWebKitSessionDescription(pending_local_description.get())
|
||||
: nullptr,
|
||||
@@ -2552,8 +2558,12 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
|
||||
int sdp_mline_index,
|
||||
int component,
|
||||
int address_family) {
|
||||
+ // In order to ensure that the RTCPeerConnection is not garbage collected
|
||||
+ // from under the function, we keep a pointer to it on the stack.
|
||||
+ auto* client_on_stack = client_;
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
|
||||
+ // This line can cause garbage collection.
|
||||
auto* platform_candidate = MakeGarbageCollected<RTCIceCandidatePlatform>(
|
||||
sdp, sdp_mid, sdp_mline_index);
|
||||
if (peer_connection_tracker_) {
|
||||
@@ -2573,7 +2583,7 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
|
||||
}
|
||||
}
|
||||
if (!is_closed_)
|
||||
- client_->DidGenerateICECandidate(platform_candidate);
|
||||
+ client_on_stack->DidGenerateICECandidate(platform_candidate);
|
||||
}
|
||||
|
||||
void RTCPeerConnectionHandler::OnIceCandidateError(
|
||||
@@ -2585,7 +2595,6 @@ void RTCPeerConnectionHandler::OnIceCandidateError(
|
||||
const String& error_text) {
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateError");
|
||||
-
|
||||
if (peer_connection_tracker_) {
|
||||
peer_connection_tracker_->TrackIceCandidateError(
|
||||
this, address, port, host_candidate, url, error_code, error_text);
|
||||
86
patches/chromium/cherry-pick-cb9dff93f3d4.patch
Normal file
86
patches/chromium/cherry-pick-cb9dff93f3d4.patch
Normal file
@@ -0,0 +1,86 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Alvestrand <hta@chromium.org>
|
||||
Date: Mon, 10 Oct 2022 08:37:15 +0000
|
||||
Subject: Use HeapMojoReceiver rather than mojo::Receiver for
|
||||
PeerConnectionTracker
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
HeapMojoReceiver is recommended for garbage collected objects, avoiding
|
||||
problems with conflicting lifetimes.
|
||||
|
||||
(cherry picked from commit e3437317c4cd8401f0f0d599b61751bbe0e1ec70)
|
||||
|
||||
Bug: chromium:1369882
|
||||
Change-Id: Ic38e761cf4275e6d7b30a6d7e2daa5d1596e67a4
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3936144
|
||||
Reviewed-by: Henrik Boström <hbos@chromium.org>
|
||||
Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1055630}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934344
|
||||
Commit-Queue: Henrik Boström <hbos@chromium.org>
|
||||
Auto-Submit: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#790}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
|
||||
index 30e5b6bfb365a738d72fdab31fee0d657cbc26c7..e77370db8ae1115a9e99e658364b14efe8d27cd3 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
|
||||
@@ -644,16 +644,20 @@ PeerConnectionTracker::PeerConnectionTracker(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
|
||||
base::PassKey<PeerConnectionTracker>)
|
||||
: Supplement<LocalDOMWindow>(window),
|
||||
+ receiver_(this, &window),
|
||||
main_thread_task_runner_(std::move(main_thread_task_runner)) {
|
||||
window.GetBrowserInterfaceBroker().GetInterface(
|
||||
peer_connection_tracker_host_.BindNewPipeAndPassReceiver());
|
||||
}
|
||||
|
||||
+// Constructor used for testing. Note that receiver_ doesn't have a context
|
||||
+// notifier in this case.
|
||||
PeerConnectionTracker::PeerConnectionTracker(
|
||||
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost> host,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
|
||||
: Supplement(nullptr),
|
||||
peer_connection_tracker_host_(std::move(host)),
|
||||
+ receiver_(this, nullptr),
|
||||
main_thread_task_runner_(std::move(main_thread_task_runner)) {}
|
||||
|
||||
PeerConnectionTracker::~PeerConnectionTracker() {}
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
|
||||
index 477dfc3a5384643f46804966888afa549769d39d..6a31cf39f3d1a03981ff438c9c1463f168f53423 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||||
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
|
||||
#include "third_party/blink/renderer/modules/modules_export.h"
|
||||
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
|
||||
#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
|
||||
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
|
||||
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
|
||||
@@ -252,6 +253,11 @@ class MODULES_EXPORT PeerConnectionTracker
|
||||
virtual void TrackRtcEventLogWrite(RTCPeerConnectionHandler* pc_handler,
|
||||
const WTF::Vector<uint8_t>& output);
|
||||
|
||||
+ void Trace(Visitor* visitor) const override {
|
||||
+ visitor->Trace(receiver_);
|
||||
+ Supplement<LocalDOMWindow>::Trace(visitor);
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
|
||||
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnThermalStateChange);
|
||||
@@ -320,7 +326,9 @@ class MODULES_EXPORT PeerConnectionTracker
|
||||
THREAD_CHECKER(main_thread_);
|
||||
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost>
|
||||
peer_connection_tracker_host_;
|
||||
- mojo::Receiver<blink::mojom::blink::PeerConnectionManager> receiver_{this};
|
||||
+ HeapMojoReceiver<blink::mojom::blink::PeerConnectionManager,
|
||||
+ PeerConnectionTracker>
|
||||
+ receiver_;
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
|
||||
};
|
||||
38
patches/chromium/cherry-pick-d1d654d73222.patch
Normal file
38
patches/chromium/cherry-pick-d1d654d73222.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Wed, 7 Dec 2022 20:35:15 +0000
|
||||
Subject: Mojo: Fix potential UAF in IPC Channel
|
||||
|
||||
(cherry picked from commit 120b4b05ac7eaa9024f677394aa663c2702174ce)
|
||||
|
||||
Fixed: 1394692
|
||||
Change-Id: I1753b79eb6e9230ebb663eca47295d81dd859068
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4066994
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1077742}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4085806
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Ken Rockot <rockot@google.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1115}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
|
||||
index a0bd86951a20cf2d60c7805a3a7fa687d66ca329..eb8fa358b0a72eea2e294c531549da5fc81f394c 100644
|
||||
--- a/ipc/ipc_mojo_bootstrap.cc
|
||||
+++ b/ipc/ipc_mojo_bootstrap.cc
|
||||
@@ -629,9 +629,12 @@ class ChannelAssociatedGroupController
|
||||
void OnSyncMessageEventReady() {
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
|
||||
- scoped_refptr<Endpoint> keepalive(this);
|
||||
+ // SUBTLE: The order of these scoped_refptrs matters.
|
||||
+ // `controller_keepalive` MUST outlive `keepalive` because the Endpoint
|
||||
+ // holds raw pointer to the AssociatedGroupController.
|
||||
scoped_refptr<AssociatedGroupController> controller_keepalive(
|
||||
controller_.get());
|
||||
+ scoped_refptr<Endpoint> keepalive(this);
|
||||
base::AutoLock locker(controller_->lock_);
|
||||
bool more_to_process = false;
|
||||
if (!sync_messages_.empty()) {
|
||||
70
patches/chromium/cherry-pick-d5ffb4dd4112.patch
Normal file
70
patches/chromium/cherry-pick-d5ffb4dd4112.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shrek Shao <shrekshao@google.com>
|
||||
Date: Tue, 18 Oct 2022 01:30:12 +0000
|
||||
Subject: WebGPU: use CHECK instead of DCHECK to crash out of bounds write in
|
||||
SerializeDataUpdate
|
||||
|
||||
A comprised renderer could have a shared memory size not large enough
|
||||
to fit the GPU buffer contents. Instead of DCHECK, do a CHECK here to
|
||||
crash the release build. The crash is fine since it is not reachable
|
||||
from normal behavior. WebGPU post-V1 will have a refactored API.
|
||||
|
||||
(cherry picked from commit 9bcbce75d5feaa1ba48a5d0d8036b5c77500bb67)
|
||||
|
||||
Fixed: 1373314
|
||||
Change-Id: I8d8e1a469c2b10ff16e7363f9b6f7b63587cb007
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3946246
|
||||
Reviewed-by: Austin Eng <enga@chromium.org>
|
||||
Commit-Queue: Shrek Shao <shrekshao@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1058233}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3956286
|
||||
Owners-Override: Prudhvikumar Bommana <pbommana@google.com>
|
||||
Reviewed-by: Prudhvikumar Bommana <pbommana@google.com>
|
||||
Commit-Queue: Prudhvikumar Bommana <pbommana@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#850}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
index 579cd3cbdfcd5990db02960413bcac86e41c69b2..a15b6f9b3b345079d8cf8251ca5f77b6e7ef647a 100644
|
||||
--- a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
+++ b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
|
||||
@@ -30,8 +30,13 @@ class ReadHandleImpl
|
||||
size_t offset,
|
||||
size_t size,
|
||||
void* serializePointer) override {
|
||||
- DCHECK_LE(offset, size_);
|
||||
- DCHECK_LE(size, size_ - offset);
|
||||
+ // TODO(crbug.com/1373314): A compromised renderer could have a shared
|
||||
+ // memory size not large enough to fit the GPU buffer contents. Instead of
|
||||
+ // DCHECK, do a CHECK here to crash the release build. The crash is fine
|
||||
+ // since it is not reachable from normal behavior. WebGPU post-V1 will have
|
||||
+ // a refactored API.
|
||||
+ CHECK_LE(offset, size_);
|
||||
+ CHECK_LE(size, size_ - offset);
|
||||
// Copy the data into the shared memory allocation.
|
||||
// In the case of buffer mapping, this is the mapped GPU memory which we
|
||||
// copy into client-visible shared memory.
|
||||
@@ -94,7 +99,10 @@ bool DawnServiceMemoryTransferService::DeserializeReadHandle(
|
||||
size_t deserialize_size,
|
||||
ReadHandle** read_handle) {
|
||||
DCHECK(deserialize_pointer);
|
||||
- DCHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
+ // Use CHECK instead of DCHECK because the cast of the memory to
|
||||
+ // MemoryTransferHandle and subsequent reads won't be safe if deserialize_size
|
||||
+ // is too small.
|
||||
+ CHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
const volatile MemoryTransferHandle* handle =
|
||||
reinterpret_cast<const volatile MemoryTransferHandle*>(
|
||||
deserialize_pointer);
|
||||
@@ -119,7 +127,10 @@ bool DawnServiceMemoryTransferService::DeserializeWriteHandle(
|
||||
size_t deserialize_size,
|
||||
WriteHandle** write_handle) {
|
||||
DCHECK(deserialize_pointer);
|
||||
- DCHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
+ // Use CHECK instead of DCHECK because the cast of the memory to
|
||||
+ // MemoryTransferHandle and subsequent reads won't be safe if deserialize_size
|
||||
+ // is too small.
|
||||
+ CHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
|
||||
const volatile MemoryTransferHandle* handle =
|
||||
reinterpret_cast<const volatile MemoryTransferHandle*>(
|
||||
deserialize_pointer);
|
||||
31
patches/chromium/cherry-pick-d652130c4bc2.patch
Normal file
31
patches/chromium/cherry-pick-d652130c4bc2.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Date: Mon, 16 Jan 2023 17:43:34 +0000
|
||||
Subject: Remove NUM_COMMAND_BUFFER_NAMESPACES from SyncToken.mojom
|
||||
|
||||
Mojo validates input for allowed values, NUM_COMMAND_BUFFER_NAMESPACES
|
||||
is not valid value to send over ipc and is used only to know maximum
|
||||
value in code.
|
||||
|
||||
Bug: 1406115
|
||||
Change-Id: I8e5c3b6b2a9a9206fbeb377b27ceb1242a4f54e2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4167409
|
||||
Reviewed-by: danakj <danakj@chromium.org>
|
||||
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1093100}
|
||||
|
||||
diff --git a/gpu/ipc/common/sync_token.mojom b/gpu/ipc/common/sync_token.mojom
|
||||
index 7c957007e3a377bd1e9969f14d9edc80c7d76645..b24017647aa6a11080580dd48e4c3d1cd79d1cf3 100644
|
||||
--- a/gpu/ipc/common/sync_token.mojom
|
||||
+++ b/gpu/ipc/common/sync_token.mojom
|
||||
@@ -11,9 +11,7 @@ enum CommandBufferNamespace {
|
||||
GPU_IO,
|
||||
IN_PROCESS,
|
||||
MOJO,
|
||||
- MOJO_LOCAL,
|
||||
-
|
||||
- NUM_COMMAND_BUFFER_NAMESPACES
|
||||
+ MOJO_LOCAL
|
||||
};
|
||||
|
||||
// See gpu/command_buffer/common/sync_token.h
|
||||
103
patches/chromium/cherry-pick-e545559df538.patch
Normal file
103
patches/chromium/cherry-pick-e545559df538.patch
Normal file
@@ -0,0 +1,103 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Vasiliev <vasilvv@chromium.org>
|
||||
Date: Thu, 12 Jan 2023 22:03:48 +0000
|
||||
Subject: Ensure clean destruction of network::WebTransport
|
||||
|
||||
Once the destruction of the object begins, we should not process any
|
||||
callbacks, nor should we attempt to reset the streams on a connection
|
||||
that is already being closed.
|
||||
|
||||
(cherry picked from commit 57c54ae221d60e9f9394d7ee69634d66c9cd26f3)
|
||||
|
||||
Bug: 1376354
|
||||
Change-Id: Ib49e0ce0b177062cccd0e52368782e291cf8166c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4117501
|
||||
Reviewed-by: Eric Orth <ericorth@chromium.org>
|
||||
Commit-Queue: Victor Vasiliev <vasilvv@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1085965}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4139783
|
||||
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1326}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/services/network/web_transport.cc b/services/network/web_transport.cc
|
||||
index fd62b83d43052d9d588a211b59e46a6c25ffeb76..534954181abcd7c4cf11eade64a2aa97c62785cc 100644
|
||||
--- a/services/network/web_transport.cc
|
||||
+++ b/services/network/web_transport.cc
|
||||
@@ -177,7 +177,7 @@ class WebTransport::Stream final {
|
||||
|
||||
~Stream() {
|
||||
auto* stream = incoming_ ? incoming_.get() : outgoing_.get();
|
||||
- if (!stream) {
|
||||
+ if (!stream || transport_->closing_ || transport_->torn_down_) {
|
||||
return;
|
||||
}
|
||||
stream->MaybeResetDueToStreamObjectGone();
|
||||
@@ -399,7 +399,10 @@ WebTransport::WebTransport(
|
||||
transport_->Connect();
|
||||
}
|
||||
|
||||
-WebTransport::~WebTransport() = default;
|
||||
+WebTransport::~WebTransport() {
|
||||
+ // Ensure that we ignore all callbacks while mid-destruction.
|
||||
+ torn_down_ = true;
|
||||
+}
|
||||
|
||||
void WebTransport::SendDatagram(base::span<const uint8_t> data,
|
||||
base::OnceCallback<void(bool)> callback) {
|
||||
diff --git a/services/network/web_transport_unittest.cc b/services/network/web_transport_unittest.cc
|
||||
index ffac5c19f9d154b91eb6aeac1e19a62277e4e7e8..46deb561091232fe64950be01e9157c8d891f111 100644
|
||||
--- a/services/network/web_transport_unittest.cc
|
||||
+++ b/services/network/web_transport_unittest.cc
|
||||
@@ -611,6 +611,51 @@ TEST_F(WebTransportTest, EchoOnUnidirectionalStreams) {
|
||||
EXPECT_EQ(0u, resets_sent.size());
|
||||
}
|
||||
|
||||
+TEST_F(WebTransportTest, DeleteClientWithStreamsOpen) {
|
||||
+ base::RunLoop run_loop_for_handshake;
|
||||
+ mojo::PendingRemote<mojom::WebTransportHandshakeClient> handshake_client;
|
||||
+ TestHandshakeClient test_handshake_client(
|
||||
+ handshake_client.InitWithNewPipeAndPassReceiver(),
|
||||
+ run_loop_for_handshake.QuitClosure());
|
||||
+
|
||||
+ CreateWebTransport(GetURL("/echo"),
|
||||
+ url::Origin::Create(GURL("https://example.org/")),
|
||||
+ std::move(handshake_client));
|
||||
+
|
||||
+ run_loop_for_handshake.Run();
|
||||
+
|
||||
+ ASSERT_TRUE(test_handshake_client.has_seen_connection_establishment());
|
||||
+
|
||||
+ TestClient client(test_handshake_client.PassClientReceiver());
|
||||
+ mojo::Remote<mojom::WebTransport> transport_remote(
|
||||
+ test_handshake_client.PassTransport());
|
||||
+
|
||||
+ constexpr int kNumStreams = 10;
|
||||
+ auto writable_for_outgoing =
|
||||
+ std::make_unique<mojo::ScopedDataPipeProducerHandle[]>(kNumStreams);
|
||||
+ for (int i = 0; i < kNumStreams; i++) {
|
||||
+ const MojoCreateDataPipeOptions options = {
|
||||
+ sizeof(options), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 4 * 1024};
|
||||
+ mojo::ScopedDataPipeConsumerHandle readable_for_outgoing;
|
||||
+ ASSERT_EQ(MOJO_RESULT_OK,
|
||||
+ mojo::CreateDataPipe(&options, writable_for_outgoing[i],
|
||||
+ readable_for_outgoing));
|
||||
+ base::RunLoop run_loop_for_stream_creation;
|
||||
+ bool stream_created;
|
||||
+ transport_remote->CreateStream(
|
||||
+ std::move(readable_for_outgoing),
|
||||
+ /*writable=*/{},
|
||||
+ base::BindLambdaForTesting([&](bool b, uint32_t /*id*/) {
|
||||
+ stream_created = b;
|
||||
+ run_loop_for_stream_creation.Quit();
|
||||
+ }));
|
||||
+ run_loop_for_stream_creation.Run();
|
||||
+ ASSERT_TRUE(stream_created);
|
||||
+ }
|
||||
+
|
||||
+ // Keep the streams open so that they are closed via destructor.
|
||||
+}
|
||||
+
|
||||
// crbug.com/1129847: disabled because it is flaky.
|
||||
TEST_F(WebTransportTest, DISABLED_EchoOnBidirectionalStream) {
|
||||
base::RunLoop run_loop_for_handshake;
|
||||
132
patches/chromium/cherry-pick-eed5a4de2c40.patch
Normal file
132
patches/chromium/cherry-pick-eed5a4de2c40.patch
Normal file
@@ -0,0 +1,132 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Yeung <dayeung@chromium.org>
|
||||
Date: Thu, 8 Dec 2022 17:56:44 +0000
|
||||
Subject: Fix UaF in ui::DropTargetEvent::DropTargetEvent.
|
||||
|
||||
There is an async operation in WebContentsViewAura that uses a ui::DropTargetEvent. DropTargetEvent has a pointer to OSExchangeData which gets destroyed before the async operation is called. This triggers the UaF because the operation attempts to reference a freed object (OSExchangeData).
|
||||
|
||||
Fix is for WebContentsViewAura::DragUpdatedCallback to use a DropMetadata struct instead of a ui::DropTargetEvent. This is the same pattern used by other callbacks in WebContentsViewAura.
|
||||
|
||||
(cherry picked from commit 9f4b5761c546a118b7187c0c7ddcb9ee5756f32c)
|
||||
|
||||
Bug: 1392661
|
||||
Change-Id: I3c62a7473ef9b6cdd223f75fbda50671f539f9eb
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4070787
|
||||
Reviewed-by: Avi Drissman <avi@chromium.org>
|
||||
Commit-Queue: David Yeung <dayeung@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1078218}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4085256
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1125}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
|
||||
index 6792e64b2f0f4a5080beb57804f861d8297524d2..aae78786a7fd9290fb1e79e3417f29662d58ed0d 100644
|
||||
--- a/content/browser/web_contents/web_contents_view_aura.cc
|
||||
+++ b/content/browser/web_contents/web_contents_view_aura.cc
|
||||
@@ -348,6 +348,7 @@ aura::Window* GetHostWindow(aura::Window* window) {
|
||||
WebContentsViewAura::DropMetadata::DropMetadata(
|
||||
const ui::DropTargetEvent& event) {
|
||||
localized_location = event.location_f();
|
||||
+ root_location = event.root_location_f();
|
||||
source_operations = event.source_operations();
|
||||
flags = event.flags();
|
||||
}
|
||||
@@ -1444,7 +1445,7 @@ void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
|
||||
}
|
||||
|
||||
void WebContentsViewAura::DragUpdatedCallback(
|
||||
- ui::DropTargetEvent event,
|
||||
+ DropMetadata drop_metadata,
|
||||
std::unique_ptr<DropData> drop_data,
|
||||
base::WeakPtr<RenderWidgetHostViewBase> target,
|
||||
absl::optional<gfx::PointF> transformed_pt) {
|
||||
@@ -1465,24 +1466,23 @@ void WebContentsViewAura::DragUpdatedCallback(
|
||||
aura::Window* root_window = GetNativeView()->GetRootWindow();
|
||||
aura::client::ScreenPositionClient* screen_position_client =
|
||||
aura::client::GetScreenPositionClient(root_window);
|
||||
- gfx::PointF screen_pt = event.root_location_f();
|
||||
+ gfx::PointF screen_pt = drop_metadata.root_location;
|
||||
if (screen_position_client)
|
||||
screen_position_client->ConvertPointToScreen(root_window, &screen_pt);
|
||||
|
||||
if (target_rwh != current_rwh_for_drag_.get()) {
|
||||
if (current_rwh_for_drag_) {
|
||||
- gfx::PointF transformed_leave_point = event.location_f();
|
||||
+ gfx::PointF transformed_leave_point = drop_metadata.localized_location;
|
||||
static_cast<RenderWidgetHostViewBase*>(
|
||||
web_contents_->GetRenderWidgetHostView())
|
||||
->TransformPointToCoordSpaceForView(
|
||||
- event.location_f(),
|
||||
+ drop_metadata.localized_location,
|
||||
static_cast<RenderWidgetHostViewBase*>(
|
||||
current_rwh_for_drag_->GetView()),
|
||||
&transformed_leave_point);
|
||||
current_rwh_for_drag_->DragTargetDragLeave(transformed_leave_point,
|
||||
screen_pt);
|
||||
}
|
||||
- DropMetadata drop_metadata(event);
|
||||
DragEnteredCallback(drop_metadata, std::move(drop_data), target,
|
||||
transformed_pt);
|
||||
}
|
||||
@@ -1493,10 +1493,11 @@ void WebContentsViewAura::DragUpdatedCallback(
|
||||
|
||||
DCHECK(transformed_pt.has_value());
|
||||
blink::DragOperationsMask op_mask =
|
||||
- ConvertToDragOperationsMask(event.source_operations());
|
||||
+ ConvertToDragOperationsMask(drop_metadata.source_operations);
|
||||
target_rwh->DragTargetDragOver(
|
||||
transformed_pt.value(), screen_pt, op_mask,
|
||||
- ui::EventFlagsToWebEventModifiers(event.flags()), base::DoNothing());
|
||||
+ ui::EventFlagsToWebEventModifiers(drop_metadata.flags),
|
||||
+ base::DoNothing());
|
||||
|
||||
if (drag_dest_delegate_)
|
||||
drag_dest_delegate_->OnDragOver();
|
||||
@@ -1506,7 +1507,6 @@ aura::client::DragUpdateInfo WebContentsViewAura::OnDragUpdated(
|
||||
const ui::DropTargetEvent& event) {
|
||||
if (web_contents_->ShouldIgnoreInputEvents())
|
||||
return aura::client::DragUpdateInfo();
|
||||
-
|
||||
aura::client::DragUpdateInfo drag_info;
|
||||
auto* focused_frame = web_contents_->GetFocusedFrame();
|
||||
if (focused_frame && !web_contents_->GetBrowserContext()->IsOffTheRecord()) {
|
||||
@@ -1517,13 +1517,13 @@ aura::client::DragUpdateInfo WebContentsViewAura::OnDragUpdated(
|
||||
std::unique_ptr<DropData> drop_data = std::make_unique<DropData>();
|
||||
// Calling this here as event.data might become invalid inside the callback.
|
||||
PrepareDropData(drop_data.get(), event.data());
|
||||
-
|
||||
+ DropMetadata drop_metadata(event);
|
||||
web_contents_->GetInputEventRouter()
|
||||
->GetRenderWidgetHostAtPointAsynchronously(
|
||||
web_contents_->GetRenderViewHost()->GetWidget()->GetView(),
|
||||
event.location_f(),
|
||||
base::BindOnce(&WebContentsViewAura::DragUpdatedCallback,
|
||||
- weak_ptr_factory_.GetWeakPtr(), event,
|
||||
+ weak_ptr_factory_.GetWeakPtr(), drop_metadata,
|
||||
std::move(drop_data)));
|
||||
|
||||
drag_info.drag_operation = static_cast<int>(current_drag_op_);
|
||||
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h
|
||||
index 17745664eda9832da61ec0150fe5085776c9c7bc..aaa42c930ef04d8f0d20d65fbb22d5fd06ba2d48 100644
|
||||
--- a/content/browser/web_contents/web_contents_view_aura.h
|
||||
+++ b/content/browser/web_contents/web_contents_view_aura.h
|
||||
@@ -84,6 +84,10 @@ class CONTENT_EXPORT WebContentsViewAura
|
||||
|
||||
// Location local to WebContentsViewAura.
|
||||
gfx::PointF localized_location;
|
||||
+
|
||||
+ // Root location of the drop target event.
|
||||
+ gfx::PointF root_location;
|
||||
+
|
||||
// The supported DnD operation of the source. A bitmask of
|
||||
// ui::mojom::DragOperations.
|
||||
int source_operations;
|
||||
@@ -263,7 +267,7 @@ class CONTENT_EXPORT WebContentsViewAura
|
||||
std::unique_ptr<DropData> drop_data,
|
||||
base::WeakPtr<RenderWidgetHostViewBase> target,
|
||||
absl::optional<gfx::PointF> transformed_pt);
|
||||
- void DragUpdatedCallback(ui::DropTargetEvent event,
|
||||
+ void DragUpdatedCallback(DropMetadata drop_metadata,
|
||||
std::unique_ptr<DropData> drop_data,
|
||||
base::WeakPtr<RenderWidgetHostViewBase> target,
|
||||
absl::optional<gfx::PointF> transformed_pt);
|
||||
218
patches/chromium/cherry-pick-f46db6aac3e9.patch
Normal file
218
patches/chromium/cherry-pick-f46db6aac3e9.patch
Normal file
@@ -0,0 +1,218 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Date: Mon, 14 Nov 2022 20:01:38 +0000
|
||||
Subject: Do not traverse directory symlinks when uploading folder
|
||||
|
||||
Previous patch crrev.com/c/3866767 removed symlink files when uploading
|
||||
a folder. However, while the remaining files are themselves not
|
||||
symlinks, they may be included as the result of traversing directory
|
||||
symlink.
|
||||
|
||||
This patch further excludes such files by checking if any parent
|
||||
directory is a symlink, all the way until the base directory (which is
|
||||
the directory chosen for upload).
|
||||
|
||||
(cherry picked from commit 4fa830d8af6b2fb293219edeb39eebccfd322305)
|
||||
|
||||
Fixed: 1378997
|
||||
Change-Id: I75a92df4cd50f9aba7824955a3de792583bc6154
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3997720
|
||||
Reviewed-by: Austin Sullivan <asully@chromium.org>
|
||||
Reviewed-by: Mason Freed <masonf@chromium.org>
|
||||
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
|
||||
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1067310}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4025427
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
|
||||
Owners-Override: Srinivas Sista <srinivassista@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#823}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl.cc b/content/browser/web_contents/file_chooser_impl.cc
|
||||
index 1aa19f7a735b444f2c33d5084edcdd14e3c2f5c5..f4fa1afda64bf0606d28d4accaec56e2624133db 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl.cc
|
||||
+++ b/content/browser/web_contents/file_chooser_impl.cc
|
||||
@@ -23,10 +23,24 @@ namespace content {
|
||||
|
||||
namespace {
|
||||
|
||||
+// Removes any file that is a symlink or is inside a directory symlink.
|
||||
+// For |kUploadFolder| mode only. |base_dir| is the folder being uploaded.
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> RemoveSymlinks(
|
||||
- std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
|
||||
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files,
|
||||
+ base::FilePath base_dir) {
|
||||
+ DCHECK(!base_dir.empty());
|
||||
auto new_end = base::ranges::remove_if(
|
||||
- files, &base::IsLink,
|
||||
+ files,
|
||||
+ [&base_dir](const base::FilePath& file_path) {
|
||||
+ if (base::IsLink(file_path))
|
||||
+ return true;
|
||||
+ for (base::FilePath path = file_path.DirName(); base_dir.IsParent(path);
|
||||
+ path = path.DirName()) {
|
||||
+ if (base::IsLink(path))
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ },
|
||||
[](const auto& file) { return file->get_native_file()->file_path; });
|
||||
files.erase(new_end, files.end());
|
||||
return files;
|
||||
@@ -78,7 +92,7 @@ void FileChooserImpl::FileSelectListenerImpl::FileSelected(
|
||||
base::ThreadPool::PostTaskAndReplyWithResult(
|
||||
FROM_HERE,
|
||||
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
|
||||
- base::BindOnce(&RemoveSymlinks, std::move(files)),
|
||||
+ base::BindOnce(&RemoveSymlinks, std::move(files), base_dir),
|
||||
base::BindOnce(&FileChooserImpl::FileSelected, owner_->GetWeakPtr(),
|
||||
base_dir, mode));
|
||||
}
|
||||
diff --git a/content/browser/web_contents/file_chooser_impl_browsertest.cc b/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
index f7519189638ece437c4285ddd490be3ea59e638d..7753f01681c21dc7afcb9ab124d301407874b76b 100644
|
||||
--- a/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
+++ b/content/browser/web_contents/file_chooser_impl_browsertest.cc
|
||||
@@ -177,8 +177,8 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
|
||||
return;
|
||||
}
|
||||
|
||||
- std::unique_ptr<FileChooserDelegate> delegate(
|
||||
- new FileChooserDelegate({text_file, symlink_file}, base::OnceClosure()));
|
||||
+ std::unique_ptr<FileChooserDelegate> delegate(new FileChooserDelegate(
|
||||
+ {text_file, symlink_file}, folder_to_upload, base::OnceClosure()));
|
||||
shell()->web_contents()->SetDelegate(delegate.get());
|
||||
EXPECT_TRUE(ExecJs(shell(),
|
||||
"(async () => {"
|
||||
@@ -195,4 +195,45 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
|
||||
EvalJs(shell(), "document.getElementById('fileinput').files[0].name;"));
|
||||
}
|
||||
|
||||
+// https://crbug.com/1378997
|
||||
+IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithDirSymlink) {
|
||||
+ EXPECT_TRUE(NavigateToURL(
|
||||
+ shell(), GetTestUrl(".", "file_input_webkitdirectory.html")));
|
||||
+
|
||||
+ // The folder contains a regular file and a directory symbolic link.
|
||||
+ // When uploading the folder, the symbolic link should not be followed.
|
||||
+ base::FilePath dir_test_data;
|
||||
+ ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &dir_test_data));
|
||||
+ base::FilePath folder_to_upload = dir_test_data.AppendASCII("file_chooser")
|
||||
+ .AppendASCII("dir_with_dir_symlink");
|
||||
+
|
||||
+ base::FilePath foo_file = folder_to_upload.AppendASCII("foo.txt");
|
||||
+ base::FilePath dir_symlink = folder_to_upload.AppendASCII("symlink");
|
||||
+ base::FilePath bar_file = dir_symlink.AppendASCII("bar.txt");
|
||||
+
|
||||
+ // Skip the test if symbolic links are not supported.
|
||||
+ {
|
||||
+ base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
+ if (!base::IsLink(dir_symlink))
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ std::unique_ptr<FileChooserDelegate> delegate(new FileChooserDelegate(
|
||||
+ {foo_file, bar_file}, folder_to_upload, base::OnceClosure()));
|
||||
+ shell()->web_contents()->SetDelegate(delegate.get());
|
||||
+ EXPECT_TRUE(ExecJs(shell(),
|
||||
+ "(async () => {"
|
||||
+ " let listener = new Promise("
|
||||
+ " resolve => fileinput.onchange = resolve);"
|
||||
+ " fileinput.click();"
|
||||
+ " await listener;"
|
||||
+ "})()"));
|
||||
+
|
||||
+ EXPECT_EQ(
|
||||
+ 1, EvalJs(shell(), "document.getElementById('fileinput').files.length;"));
|
||||
+ EXPECT_EQ(
|
||||
+ "foo.txt",
|
||||
+ EvalJs(shell(), "document.getElementById('fileinput').files[0].name;"));
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc
|
||||
index c70d088bfd007e9a6cd9cfcb6f92b07b99653048..3e68311abfefc1e93ccc5c05de14137d8db0dc60 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.cc
|
||||
+++ b/content/test/content_browser_test_utils_internal.cc
|
||||
@@ -447,12 +447,16 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
|
||||
}
|
||||
|
||||
FileChooserDelegate::FileChooserDelegate(std::vector<base::FilePath> files,
|
||||
+ const base::FilePath& base_dir,
|
||||
base::OnceClosure callback)
|
||||
- : files_(std::move(files)), callback_(std::move(callback)) {}
|
||||
+ : files_(std::move(files)),
|
||||
+ base_dir_(base_dir),
|
||||
+ callback_(std::move(callback)) {}
|
||||
|
||||
FileChooserDelegate::FileChooserDelegate(const base::FilePath& file,
|
||||
base::OnceClosure callback)
|
||||
: FileChooserDelegate(std::vector<base::FilePath>(1, file),
|
||||
+ base::FilePath(),
|
||||
std::move(callback)) {}
|
||||
|
||||
FileChooserDelegate::~FileChooserDelegate() = default;
|
||||
@@ -461,6 +465,9 @@ void FileChooserDelegate::RunFileChooser(
|
||||
RenderFrameHost* render_frame_host,
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
const blink::mojom::FileChooserParams& params) {
|
||||
+ // |base_dir_| should be set for and only for |kUploadFolder| mode.
|
||||
+ DCHECK(base_dir_.empty() ==
|
||||
+ (params.mode != blink::mojom::FileChooserParams::Mode::kUploadFolder));
|
||||
// Send the selected files to the renderer process.
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
|
||||
for (const auto& file : files_) {
|
||||
@@ -468,7 +475,7 @@ void FileChooserDelegate::RunFileChooser(
|
||||
blink::mojom::NativeFileInfo::New(file, std::u16string()));
|
||||
files.push_back(std::move(file_info));
|
||||
}
|
||||
- listener->FileSelected(std::move(files), base::FilePath(), params.mode);
|
||||
+ listener->FileSelected(std::move(files), base_dir_, params.mode);
|
||||
|
||||
params_ = params.Clone();
|
||||
if (callback_)
|
||||
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h
|
||||
index 43c6aabc5414d0cc12fb5a03142e8b20e2a7fab3..bff69b028af40726107928868748ad0f19dc4459 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.h
|
||||
+++ b/content/test/content_browser_test_utils_internal.h
|
||||
@@ -179,7 +179,10 @@ class FileChooserDelegate : public WebContentsDelegate {
|
||||
// The mocked file dialog will always reply that the user selected |file| or
|
||||
// |files|. |callback| is invoked when RunFileChooser() is called.
|
||||
FileChooserDelegate(const base::FilePath& file, base::OnceClosure callback);
|
||||
+ // |base_dir| must be set to the folder being uploaded in |kUploadFolder|
|
||||
+ // mode, and must be empty in all other modes.
|
||||
FileChooserDelegate(std::vector<base::FilePath> files,
|
||||
+ const base::FilePath& base_dir,
|
||||
base::OnceClosure callback);
|
||||
~FileChooserDelegate() override;
|
||||
|
||||
@@ -193,6 +196,7 @@ class FileChooserDelegate : public WebContentsDelegate {
|
||||
|
||||
private:
|
||||
std::vector<base::FilePath> files_;
|
||||
+ const base::FilePath base_dir_;
|
||||
base::OnceClosure callback_;
|
||||
blink::mojom::FileChooserParamsPtr params_;
|
||||
};
|
||||
diff --git a/content/test/data/file_chooser/dir_with_dir_symlink/foo.txt b/content/test/data/file_chooser/dir_with_dir_symlink/foo.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..257cc5642cb1a054f08cc83f2d943e56fd3ebe99
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/dir_with_dir_symlink/foo.txt
|
||||
@@ -0,0 +1 @@
|
||||
+foo
|
||||
diff --git a/content/test/data/file_chooser/dir_with_dir_symlink/symlink b/content/test/data/file_chooser/dir_with_dir_symlink/symlink
|
||||
new file mode 120000
|
||||
index 0000000000000000000000000000000000000000..10f6d1ab9ba9ede59b719d4ba1581588e172abb6
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/dir_with_dir_symlink/symlink
|
||||
@@ -0,0 +1 @@
|
||||
+../linked_dir/
|
||||
\ No newline at end of file
|
||||
diff --git a/content/test/data/file_chooser/linked_dir/bar.txt b/content/test/data/file_chooser/linked_dir/bar.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5716ca5987cbf97d6bb54920bea6adde242d87e6
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/file_chooser/linked_dir/bar.txt
|
||||
@@ -0,0 +1 @@
|
||||
+bar
|
||||
55
patches/chromium/cherry-pick-f98adc846aad.patch
Normal file
55
patches/chromium/cherry-pick-f98adc846aad.patch
Normal file
@@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Austin Sullivan <asully@chromium.org>
|
||||
Date: Tue, 11 Oct 2022 20:53:22 +0000
|
||||
Subject: FSA: Block .url files in getFileHandle and getEntries
|
||||
|
||||
Fixed: 1354518
|
||||
Change-Id: I663d4481ccc2047c49d7466bbfe9751e8c140edf
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3945587
|
||||
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Auto-Submit: Austin Sullivan <asully@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1057675}
|
||||
|
||||
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
|
||||
index 7e673f903a71a309e8d92b966330875ef2772f84..13ce0b974268215f0e92ccedd2f56643c8a36679 100644
|
||||
--- a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
|
||||
+++ b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
|
||||
@@ -444,9 +444,12 @@ bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
|
||||
|
||||
// .lnk and .scf files may be used to execute arbitrary code (see
|
||||
// https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
|
||||
- // https://crbug.com/1227995, respectively).
|
||||
+ // https://crbug.com/1227995, respectively). '.url' files can be used to read
|
||||
+ // arbitrary files (see https://crbug.com/1307930 and
|
||||
+ // https://crbug.com/1354518).
|
||||
if (extension_lower == FILE_PATH_LITERAL("lnk") ||
|
||||
- extension_lower == FILE_PATH_LITERAL("scf")) {
|
||||
+ extension_lower == FILE_PATH_LITERAL("scf") ||
|
||||
+ extension_lower == FILE_PATH_LITERAL("url")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
|
||||
index 606e34473296199317747fa949158f402b163ec0..9dd03ca412fdc69d7e6bb18b08a157ac9b69bf13 100644
|
||||
--- a/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
|
||||
+++ b/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
|
||||
@@ -150,6 +150,7 @@ TEST_F(FileSystemAccessDirectoryHandleImplTest, IsSafePathComponent) {
|
||||
"My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
|
||||
"a\\a",
|
||||
"a.lnk",
|
||||
+ "a.url",
|
||||
"a/a",
|
||||
"C:\\",
|
||||
"C:/",
|
||||
@@ -205,8 +206,8 @@ TEST_F(FileSystemAccessDirectoryHandleImplTest, GetEntries) {
|
||||
constexpr const char* kSafeNames[] = {"a", "a.txt", "My Computer", "lnk.txt",
|
||||
"a.local"};
|
||||
constexpr const char* kUnsafeNames[] = {
|
||||
- "con", "con.zip", "NUL", "a.",
|
||||
- "a\"a", "a . .", "a.lnk", "My Computer.{a}",
|
||||
+ "con", "con.zip", "NUL", "a.", "a\"a", "a . .",
|
||||
+ "a.lnk", "My Computer.{a}", "a.url",
|
||||
};
|
||||
for (const char* name : kSafeNames) {
|
||||
ASSERT_TRUE(base::WriteFile(dir_.GetPath().AppendASCII(name), "data"))
|
||||
305
patches/chromium/cherry-pick-fefd6198da31.patch
Normal file
305
patches/chromium/cherry-pick-fefd6198da31.patch
Normal file
@@ -0,0 +1,305 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Wagner <benjaminwagner@google.com>
|
||||
Date: Tue, 20 Sep 2022 18:38:53 +0000
|
||||
Subject: Fix races in FrameQueueUnderlyingSource related to
|
||||
CrossThreadPersistent
|
||||
|
||||
The repro in bug 1323488 unfortunately does not reliably reproduce
|
||||
the races when run as a web test. I was also not able to repro the
|
||||
races in a unit test.
|
||||
|
||||
There are actually three fixes in this CL; it was easiest to fix them
|
||||
all together so that I can run the repro locally for an extended period
|
||||
without it being stopped by a crash.
|
||||
|
||||
The underlying cause for all three races is that CrossThreadPersistent
|
||||
can refer to an object whose heap has already been destroyed. When
|
||||
accessed on the thread corresponding to that heap, there is no race,
|
||||
but when accessed from a different thread, there is a period of time
|
||||
after the heap is destroyed before the CrossThreadPersistent is
|
||||
cleared.
|
||||
|
||||
1. The FrameQueueUnderlyingSource::transferred_source_ member's pointer
|
||||
is accessed in FrameQueueUnderlyingSource::Close. This CL adds a
|
||||
callback to clear the pointer in
|
||||
TransferredFrameQueueUnderlyingSource::ContextDestroyed.
|
||||
|
||||
2. The TransferredFrameQueueUnderlyingSource constructor takes a raw
|
||||
pointer to the original FrameQueueUnderlyingSource, which is
|
||||
associated with a different thread. GC won't be able to update this
|
||||
raw pointer since it's on the wrong stack. This CL changes the raw
|
||||
pointer to a CrossThreadPersistent which is visible to GC.
|
||||
|
||||
3. Same as 2, but for the callstack ConnectHostCallback,
|
||||
MediaStream(Audio|Video)TrackUnderlyingSource::OnSourceTransferStarted
|
||||
and FrameQueueUnderlyingSource::TransferSource.
|
||||
|
||||
(cherry picked from commit 63ce9c40e1a67395278dfc70ecfb545a818747bb)
|
||||
|
||||
Bug: 1323488
|
||||
Change-Id: Id63484eebefd2e003959b25bd752ac8263caab4f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3865452
|
||||
Commit-Queue: Ben Wagner <benjaminwagner@google.com>
|
||||
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
|
||||
Auto-Submit: Ben Wagner <benjaminwagner@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1041434}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3908010
|
||||
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
|
||||
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5249@{#521}
|
||||
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
|
||||
index 2cc89e8cd32421bf80b262bac2e4a7cb685db62f..ab41fa086ad9eb8c1cd66db74ea1f05a66ac56a4 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
|
||||
@@ -19,10 +19,13 @@ FrameQueueTransferringOptimizer<NativeFrameType>::
|
||||
FrameQueueHost* host,
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
wtf_size_t max_queue_size,
|
||||
- ConnectHostCallback connect_host_callback)
|
||||
+ ConnectHostCallback connect_host_callback,
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback)
|
||||
: host_(host),
|
||||
host_runner_(std::move(host_runner)),
|
||||
connect_host_callback_(std::move(connect_host_callback)),
|
||||
+ transferred_source_destroyed_callback_(
|
||||
+ std::move(transferred_source_destroyed_callback)),
|
||||
max_queue_size_(max_queue_size) {}
|
||||
|
||||
template <typename NativeFrameType>
|
||||
@@ -40,7 +43,8 @@ FrameQueueTransferringOptimizer<NativeFrameType>::PerformInProcessOptimization(
|
||||
|
||||
auto* source = MakeGarbageCollected<
|
||||
TransferredFrameQueueUnderlyingSource<NativeFrameType>>(
|
||||
- script_state, host, host_runner_);
|
||||
+ script_state, host, host_runner_,
|
||||
+ std::move(transferred_source_destroyed_callback_));
|
||||
|
||||
PostCrossThreadTask(
|
||||
*host_runner_, FROM_HERE,
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
|
||||
index 6d33945b7c840e55ae73a1efd1f1cf33ccfaaa71..336073235ba7f6c05cf2cf19fccbfac0be9597c9 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
|
||||
@@ -25,13 +25,15 @@ class FrameQueueTransferringOptimizer final
|
||||
|
||||
using ConnectHostCallback = CrossThreadOnceFunction<void(
|
||||
scoped_refptr<base::SequencedTaskRunner>,
|
||||
- TransferredFrameQueueUnderlyingSource<NativeFrameType>*)>;
|
||||
+ CrossThreadPersistent<
|
||||
+ TransferredFrameQueueUnderlyingSource<NativeFrameType>>)>;
|
||||
|
||||
FrameQueueTransferringOptimizer(
|
||||
FrameQueueHost*,
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
wtf_size_t max_queue_size,
|
||||
- ConnectHostCallback callback);
|
||||
+ ConnectHostCallback connect_host_callback,
|
||||
+ CrossThreadOnceFunction<void()> transferred_source_destroyed_callback);
|
||||
~FrameQueueTransferringOptimizer() override = default;
|
||||
|
||||
UnderlyingSourceBase* PerformInProcessOptimization(
|
||||
@@ -41,6 +43,7 @@ class FrameQueueTransferringOptimizer final
|
||||
CrossThreadWeakPersistent<FrameQueueHost> host_;
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner_;
|
||||
ConnectHostCallback connect_host_callback_;
|
||||
+ CrossThreadOnceFunction<void()> transferred_source_destroyed_callback_;
|
||||
wtf_size_t max_queue_size_;
|
||||
};
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
|
||||
index b93b67f131e1e58118e32d2c9b29e472a28d4664..fcd676b3035e19c6e0b28ee1c44109c6737a1c35 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
|
||||
@@ -266,15 +266,22 @@ double FrameQueueUnderlyingSource<NativeFrameType>::DesiredSizeForTesting()
|
||||
|
||||
template <typename NativeFrameType>
|
||||
void FrameQueueUnderlyingSource<NativeFrameType>::TransferSource(
|
||||
- FrameQueueUnderlyingSource<NativeFrameType>* transferred_source) {
|
||||
+ CrossThreadPersistent<FrameQueueUnderlyingSource<NativeFrameType>>
|
||||
+ transferred_source) {
|
||||
DCHECK(realm_task_runner_->RunsTasksInCurrentSequence());
|
||||
MutexLocker locker(mutex_);
|
||||
DCHECK(!transferred_source_);
|
||||
- transferred_source_ = transferred_source;
|
||||
+ transferred_source_ = std::move(transferred_source);
|
||||
CloseController();
|
||||
frame_queue_handle_.Invalidate();
|
||||
}
|
||||
|
||||
+template <typename NativeFrameType>
|
||||
+void FrameQueueUnderlyingSource<NativeFrameType>::ClearTransferredSource() {
|
||||
+ MutexLocker locker(mutex_);
|
||||
+ transferred_source_.Clear();
|
||||
+}
|
||||
+
|
||||
template <typename NativeFrameType>
|
||||
void FrameQueueUnderlyingSource<NativeFrameType>::CloseController() {
|
||||
DCHECK(realm_task_runner_->RunsTasksInCurrentSequence());
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
|
||||
index 7e097b4eb6e9085be73ceb7fd84a4588baf64471..3908909d04f5b6cf4a9be4a3a3e004c3775a3d42 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
|
||||
@@ -85,7 +85,13 @@ class FrameQueueUnderlyingSource
|
||||
// QueueFrame(). |transferred_source| will pull frames from the same circular
|
||||
// queue. Must be called on |realm_task_runner_|.
|
||||
void TransferSource(
|
||||
- FrameQueueUnderlyingSource<NativeFrameType>* transferred_source);
|
||||
+ CrossThreadPersistent<FrameQueueUnderlyingSource<NativeFrameType>>
|
||||
+ transferred_source);
|
||||
+
|
||||
+ // Due to a potential race condition between |transferred_source_|'s heap
|
||||
+ // being destroyed and the Close() method being called, we need to explicitly
|
||||
+ // clear |transferred_source_| when its context is being destroyed.
|
||||
+ void ClearTransferredSource();
|
||||
|
||||
protected:
|
||||
bool MustUseMonitor() const;
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
index bfc966452e4134e5133d559698497ce82f89aad4..da9a4bffc3a8c9ec5a1595a7cd78110bfadbfb5e 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
@@ -93,14 +93,17 @@ MediaStreamAudioTrackUnderlyingSource::GetTransferringOptimizer() {
|
||||
this, GetRealmRunner(), MaxQueueSize(),
|
||||
CrossThreadBindOnce(
|
||||
&MediaStreamAudioTrackUnderlyingSource::OnSourceTransferStarted,
|
||||
+ WrapCrossThreadWeakPersistent(this)),
|
||||
+ CrossThreadBindOnce(
|
||||
+ &MediaStreamAudioTrackUnderlyingSource::ClearTransferredSource,
|
||||
WrapCrossThreadWeakPersistent(this)));
|
||||
}
|
||||
|
||||
void MediaStreamAudioTrackUnderlyingSource::OnSourceTransferStarted(
|
||||
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
|
||||
- TransferredAudioDataQueueUnderlyingSource* source) {
|
||||
+ CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
- TransferSource(source);
|
||||
+ TransferSource(std::move(source));
|
||||
RecordBreakoutBoxUsage(BreakoutBoxUsage::kReadableAudioWorker);
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
index 19a290ea6b83e4b56b8d96cb7632fca55bd65fd0..73c16dc5ff3855e258e1e70397def478485f1481 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
@@ -56,7 +56,7 @@ class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource
|
||||
void DisconnectFromTrack();
|
||||
void OnSourceTransferStarted(
|
||||
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
|
||||
- TransferredAudioDataQueueUnderlyingSource* source);
|
||||
+ CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source);
|
||||
|
||||
// Only used to prevent the gargabe collector from reclaiming the media
|
||||
// stream track processor that created |this|.
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
|
||||
index bcb941aca4e4d0729dc1253e01ef477fdaae1877..e748bf6eaf8f9d1acf8519c38a5a8cb53b031d0e 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
|
||||
@@ -66,6 +66,9 @@ MediaStreamVideoTrackUnderlyingSource::GetStreamTransferOptimizer() {
|
||||
this, GetRealmRunner(), MaxQueueSize(),
|
||||
CrossThreadBindOnce(
|
||||
&MediaStreamVideoTrackUnderlyingSource::OnSourceTransferStarted,
|
||||
+ WrapCrossThreadWeakPersistent(this)),
|
||||
+ CrossThreadBindOnce(
|
||||
+ &MediaStreamVideoTrackUnderlyingSource::ClearTransferredSource,
|
||||
WrapCrossThreadWeakPersistent(this)));
|
||||
}
|
||||
|
||||
@@ -76,9 +79,9 @@ MediaStreamVideoTrackUnderlyingSource::GetIOTaskRunner() {
|
||||
|
||||
void MediaStreamVideoTrackUnderlyingSource::OnSourceTransferStarted(
|
||||
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
|
||||
- TransferredVideoFrameQueueUnderlyingSource* source) {
|
||||
+ CrossThreadPersistent<TransferredVideoFrameQueueUnderlyingSource> source) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
- TransferSource(source);
|
||||
+ TransferSource(std::move(source));
|
||||
RecordBreakoutBoxUsage(BreakoutBoxUsage::kReadableVideoWorker);
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
|
||||
index 1bbd4f6bbf20eaf168bf1319f1b35819dabe3cce..8964eb5eb83964c4bb2633092a12cb144da4e9b0 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
|
||||
@@ -59,8 +59,9 @@ class MODULES_EXPORT MediaStreamVideoTrackUnderlyingSource
|
||||
bool StartFrameDelivery() override;
|
||||
void StopFrameDelivery() override;
|
||||
|
||||
- void OnSourceTransferStarted(scoped_refptr<base::SequencedTaskRunner>,
|
||||
- TransferredVideoFrameQueueUnderlyingSource*);
|
||||
+ void OnSourceTransferStarted(
|
||||
+ scoped_refptr<base::SequencedTaskRunner>,
|
||||
+ CrossThreadPersistent<TransferredVideoFrameQueueUnderlyingSource>);
|
||||
|
||||
void OnFrameFromTrack(
|
||||
scoped_refptr<media::VideoFrame> media_frame,
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
|
||||
index 5c62b8f1b752c24f8b8d0048d646ea64dba0e49c..e38173482d455788861a1d831dd3422119d4d4d6 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
|
||||
@@ -15,11 +15,14 @@ template <typename NativeFrameType>
|
||||
TransferredFrameQueueUnderlyingSource<NativeFrameType>::
|
||||
TransferredFrameQueueUnderlyingSource(
|
||||
ScriptState* script_state,
|
||||
- FrameQueueHost* host,
|
||||
- scoped_refptr<base::SequencedTaskRunner> host_runner)
|
||||
+ CrossThreadPersistent<FrameQueueHost> host,
|
||||
+ scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback)
|
||||
: FrameQueueUnderlyingSource<NativeFrameType>(script_state, host),
|
||||
host_runner_(host_runner),
|
||||
- host_(host) {}
|
||||
+ host_(std::move(host)),
|
||||
+ transferred_source_destroyed_callback_(
|
||||
+ std::move(transferred_source_destroyed_callback)) {}
|
||||
|
||||
template <typename NativeFrameType>
|
||||
bool TransferredFrameQueueUnderlyingSource<
|
||||
@@ -44,6 +47,13 @@ void TransferredFrameQueueUnderlyingSource<
|
||||
CrossThreadBindOnce(&FrameQueueHost::Close, host_));
|
||||
}
|
||||
|
||||
+template <typename NativeFrameType>
|
||||
+void TransferredFrameQueueUnderlyingSource<
|
||||
+ NativeFrameType>::ContextDestroyed() {
|
||||
+ std::move(transferred_source_destroyed_callback_).Run();
|
||||
+ FrameQueueUnderlyingSource<NativeFrameType>::ContextDestroyed();
|
||||
+}
|
||||
+
|
||||
template <typename NativeFrameType>
|
||||
void TransferredFrameQueueUnderlyingSource<NativeFrameType>::Trace(
|
||||
Visitor* visitor) const {
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
|
||||
index 5f8a36719407a404756d672530c0b9fcff9d6924..7cd3270fbb3cf5b0e2c09b16000ea5c0e4247866 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
|
||||
@@ -19,8 +19,9 @@ class TransferredFrameQueueUnderlyingSource
|
||||
|
||||
TransferredFrameQueueUnderlyingSource(
|
||||
ScriptState*,
|
||||
- FrameQueueHost*,
|
||||
- scoped_refptr<base::SequencedTaskRunner> host_runner);
|
||||
+ CrossThreadPersistent<FrameQueueHost>,
|
||||
+ scoped_refptr<base::SequencedTaskRunner> host_runner,
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback);
|
||||
~TransferredFrameQueueUnderlyingSource() override = default;
|
||||
|
||||
TransferredFrameQueueUnderlyingSource(
|
||||
@@ -32,11 +33,15 @@ class TransferredFrameQueueUnderlyingSource
|
||||
bool StartFrameDelivery() override;
|
||||
void StopFrameDelivery() override;
|
||||
|
||||
+ // ExecutionLifecycleObserver
|
||||
+ void ContextDestroyed() override;
|
||||
+
|
||||
void Trace(Visitor*) const override;
|
||||
|
||||
private:
|
||||
scoped_refptr<base::SequencedTaskRunner> host_runner_;
|
||||
CrossThreadPersistent<FrameQueueHost> host_;
|
||||
+ CrossThreadOnceClosure transferred_source_destroyed_callback_;
|
||||
};
|
||||
|
||||
extern template class MODULES_EXTERN_TEMPLATE_EXPORT
|
||||
156
patches/chromium/create_browser_v8_snapshot_file_name_fuse.patch
Normal file
156
patches/chromium/create_browser_v8_snapshot_file_name_fuse.patch
Normal file
@@ -0,0 +1,156 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Manuel <ryanm@cypress.io>
|
||||
Date: Thu, 4 Aug 2022 22:37:01 -0500
|
||||
Subject: Create browser v8 snapshot file name fuse
|
||||
|
||||
By default, chromium sets up one v8 snapshot to be used in all v8 contexts. This patch allows consumers
|
||||
to have a dedicated browser process v8 snapshot defined by the file `browser_v8_context_snapshot.bin`.
|
||||
|
||||
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
|
||||
index 328f8b800c36544f7906536416ac61dc87cc45d3..2f973efcf3e38edcc74060929339fc21bdf0aa3b 100644
|
||||
--- a/content/app/content_main_runner_impl.cc
|
||||
+++ b/content/app/content_main_runner_impl.cc
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "base/process/memory.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/process/process_handle.h"
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||
@@ -232,8 +233,13 @@ std::string GetSnapshotDataDescriptor(const base::CommandLine& command_line) {
|
||||
|
||||
#endif
|
||||
|
||||
-void LoadV8SnapshotFile(const base::CommandLine& command_line) {
|
||||
+void LoadV8SnapshotFile(const raw_ptr<ContentMainDelegate> delegate, const base::CommandLine& command_line) {
|
||||
const gin::V8SnapshotFileType snapshot_type = GetSnapshotType(command_line);
|
||||
+ base::StringPiece browser_v8_snapshot_file_name = delegate->GetBrowserV8SnapshotFilename();
|
||||
+ if (!browser_v8_snapshot_file_name.empty()) {
|
||||
+ gin::V8Initializer::LoadV8SnapshotFromFileName(browser_v8_snapshot_file_name, snapshot_type);
|
||||
+ return;
|
||||
+ }
|
||||
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
|
||||
base::FileDescriptorStore& file_descriptor_store =
|
||||
base::FileDescriptorStore::GetInstance();
|
||||
@@ -262,11 +268,12 @@ bool ShouldLoadV8Snapshot(const base::CommandLine& command_line,
|
||||
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
|
||||
-void LoadV8SnapshotIfNeeded(const base::CommandLine& command_line,
|
||||
+void LoadV8SnapshotIfNeeded(const raw_ptr<ContentMainDelegate> delegate,
|
||||
+ const base::CommandLine& command_line,
|
||||
const std::string& process_type) {
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
if (ShouldLoadV8Snapshot(command_line, process_type))
|
||||
- LoadV8SnapshotFile(command_line);
|
||||
+ LoadV8SnapshotFile(delegate, command_line);
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
}
|
||||
|
||||
@@ -917,7 +924,7 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
|
||||
return TerminateForFatalInitializationError();
|
||||
#endif // BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
|
||||
|
||||
- LoadV8SnapshotIfNeeded(command_line, process_type);
|
||||
+ LoadV8SnapshotIfNeeded(delegate_, command_line, process_type);
|
||||
|
||||
blink::TrialTokenValidator::SetOriginTrialPolicyGetter(
|
||||
base::BindRepeating([]() -> blink::OriginTrialPolicy* {
|
||||
diff --git a/content/public/app/content_main_delegate.cc b/content/public/app/content_main_delegate.cc
|
||||
index ce6b8b454d0cc57ec4de81c7a19b5e0f0087a162..c421d3b5bc02b702e89c714d3d521207cbca156b 100644
|
||||
--- a/content/public/app/content_main_delegate.cc
|
||||
+++ b/content/public/app/content_main_delegate.cc
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
|
||||
#include "base/check.h"
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
@@ -55,6 +56,10 @@ ContentMainDelegate::CreateVariationsIdsProvider() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+base::StringPiece ContentMainDelegate::GetBrowserV8SnapshotFilename() {
|
||||
+ return base::StringPiece();
|
||||
+}
|
||||
+
|
||||
ContentClient* ContentMainDelegate::CreateContentClient() {
|
||||
return new ContentClient();
|
||||
}
|
||||
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h
|
||||
index f81430b564a3cf44c2168e18c4c53c6629353d75..34a5531cd33b439114a796adc71af7251b6b1f81 100644
|
||||
--- a/content/public/app/content_main_delegate.h
|
||||
+++ b/content/public/app/content_main_delegate.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
@@ -149,6 +150,8 @@ class CONTENT_EXPORT ContentMainDelegate {
|
||||
virtual bool ShouldHandleConsoleControlEvents();
|
||||
#endif
|
||||
|
||||
+ virtual base::StringPiece GetBrowserV8SnapshotFilename();
|
||||
+
|
||||
protected:
|
||||
friend class ContentClientCreator;
|
||||
friend class ContentClientInitializer;
|
||||
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
|
||||
index 34a65998cbaa22241fd7c6cc60d8ab01982ca3ce..68c12e9bb1f334d6fec050018da8bc0a6db4a850 100644
|
||||
--- a/gin/v8_initializer.cc
|
||||
+++ b/gin/v8_initializer.cc
|
||||
@@ -512,8 +512,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
|
||||
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
|
||||
-// static
|
||||
-void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
|
||||
+void V8Initializer::LoadV8SnapshotFromFileName(base::StringPiece file_name, V8SnapshotFileType snapshot_file_type) {
|
||||
if (g_mapped_snapshot) {
|
||||
// TODO(crbug.com/802962): Confirm not loading different type of snapshot
|
||||
// files in a process.
|
||||
@@ -522,10 +521,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
|
||||
|
||||
base::MemoryMappedFile::Region file_region;
|
||||
base::File file =
|
||||
- OpenV8File(GetSnapshotFileName(snapshot_file_type), &file_region);
|
||||
+ OpenV8File(file_name.data(), &file_region);
|
||||
LoadV8SnapshotFromFile(std::move(file), &file_region, snapshot_file_type);
|
||||
}
|
||||
|
||||
+// static
|
||||
+void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
|
||||
+ const char* file_name = GetSnapshotFileName(snapshot_file_type);
|
||||
+
|
||||
+ LoadV8SnapshotFromFileName(file_name, snapshot_file_type);
|
||||
+}
|
||||
+
|
||||
// static
|
||||
void V8Initializer::LoadV8SnapshotFromFile(
|
||||
base::File snapshot_file,
|
||||
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
|
||||
index 13a120c7fe8e69a44793473f3124c33d572a07a3..acb294780873c1d84546eb2b9acc00f86838361d 100644
|
||||
--- a/gin/v8_initializer.h
|
||||
+++ b/gin/v8_initializer.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "base/files/file.h"
|
||||
#include "base/files/memory_mapped_file.h"
|
||||
+#include "base/strings/string_piece.h"
|
||||
#include "build/build_config.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/gin_export.h"
|
||||
@@ -42,6 +43,7 @@ class GIN_EXPORT V8Initializer {
|
||||
int* snapshot_size_out);
|
||||
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
+ static void LoadV8SnapshotFromFileName(base::StringPiece file_name, V8SnapshotFileType snapshot_file_type);
|
||||
// Load V8 snapshot from default resources, if they are available.
|
||||
static void LoadV8Snapshot(
|
||||
V8SnapshotFileType snapshot_file_type = V8SnapshotFileType::kDefault);
|
||||
@@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
|
||||
Date: Thu, 6 Oct 2022 18:30:53 +0200
|
||||
Subject: fix: on-screen-keyboard hides on input blur in webview
|
||||
|
||||
Changes introduced by this patch fix issue where OSK does not hide on
|
||||
input rendered inside webview is blurred. This patch should be removed
|
||||
when proper fix in chromium repo is available.
|
||||
|
||||
Note: the issue still occurs if input rendered in webview blurred due
|
||||
to touch outside of webview. It is caused by webview implementation
|
||||
details. Specificaly due to webview has its own tree nodes and focused
|
||||
node does not change in this case.
|
||||
|
||||
chromium-bug: https://crbug.com/1369605
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
|
||||
index c56d5c06ca3eb5e2c11bd1af00a8667bfa422dc9..bccc940958180481947a5a5ee82562bd99d28b78 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
|
||||
@@ -985,6 +985,12 @@ RenderWidgetHostViewChildFrame::DidUpdateVisualProperties(
|
||||
return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
|
||||
}
|
||||
|
||||
+void RenderWidgetHostViewChildFrame::FocusedNodeChanged(
|
||||
+ bool is_editable_node,
|
||||
+ const gfx::Rect& node_bounds_in_screen) {
|
||||
+ NOTREACHED();
|
||||
+}
|
||||
+
|
||||
ui::TextInputType RenderWidgetHostViewChildFrame::GetTextInputType() const {
|
||||
if (!text_input_manager_)
|
||||
return ui::TEXT_INPUT_TYPE_NONE;
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
|
||||
index 457dabe428e84230b2e831e9281feee06e7c8e76..9436d55b390ac6fa16398efebad0a87beef6e959 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
|
||||
@@ -178,6 +178,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
|
||||
void DisableAutoResize(const gfx::Size& new_size) override;
|
||||
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
|
||||
const cc::RenderFrameMetadata& metadata) override;
|
||||
+ void FocusedNodeChanged(bool is_editable_node,
|
||||
+ const gfx::Rect& node_bounds_in_screen) override;
|
||||
|
||||
// RenderFrameMetadataProvider::Observer implementation.
|
||||
void OnRenderFrameMetadataChangedBeforeActivation(
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 8982a2a4d2be23e56472b17e9d59e289e8255336..92f73106ba8c9559281add6fe7a2f2a613ca3cdc 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -7891,7 +7891,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
"WebContentsImpl::OnFocusedElementChangedInFrame",
|
||||
"render_frame_host", frame);
|
||||
RenderWidgetHostViewBase* root_view =
|
||||
- static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
|
||||
+ static_cast<RenderWidgetHostViewBase*>(GetTopLevelRenderWidgetHostView());
|
||||
if (!root_view || !frame->GetView())
|
||||
return;
|
||||
// Convert to screen coordinates from window coordinates by adding the
|
||||
@@ -0,0 +1,536 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Thu, 10 Nov 2022 03:24:17 +0000
|
||||
Subject: Mojo: Disable sync call interrupts in the browser
|
||||
|
||||
This changes the default Mojo sync call behavior in the browser process
|
||||
to prevent any blocking sync calls from being interrupted by other
|
||||
incoming sync IPC dispatches.
|
||||
|
||||
(cherry picked from commit b6f921260e0e763db7a72de9c7a3f0f78a99f21f)
|
||||
|
||||
Bug: 1376099
|
||||
Change-Id: I53681ef379fdd3c2bfc37d7e16b3de17acad5d20
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3989408
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1065369}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4018257
|
||||
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
|
||||
Auto-Submit: Daniel Cheng <dcheng@chromium.org>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#719}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
|
||||
index 2f973efcf3e38edcc74060929339fc21bdf0aa3b..f8f72678fd8bbcf857bf09176b8b6388d35e3605 100644
|
||||
--- a/content/app/content_main_runner_impl.cc
|
||||
+++ b/content/app/content_main_runner_impl.cc
|
||||
@@ -92,6 +92,7 @@
|
||||
#include "media/media_buildflags.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
+#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/system/dynamic_library_support.h"
|
||||
#include "mojo/public/cpp/system/invitation.h"
|
||||
@@ -1073,6 +1074,11 @@ int ContentMainRunnerImpl::RunBrowser(MainFunctionParams main_params,
|
||||
if (is_browser_main_loop_started_)
|
||||
return -1;
|
||||
|
||||
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
+ switches::kSingleProcess)) {
|
||||
+ mojo::SyncCallRestrictions::DisableSyncCallInterrupts();
|
||||
+ }
|
||||
+
|
||||
if (!mojo_ipc_support_) {
|
||||
const auto invoked_in = main_params.ui_task
|
||||
? InvokedIn::kBrowserProcessUnderTest
|
||||
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
|
||||
index eb8fa358b0a72eea2e294c531549da5fc81f394c..8c13ef236ba6f7cf05584cffba522a3cb54536c9 100644
|
||||
--- a/ipc/ipc_mojo_bootstrap.cc
|
||||
+++ b/ipc/ipc_mojo_bootstrap.cc
|
||||
@@ -16,13 +16,15 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/check_op.h"
|
||||
+#include "base/containers/circular_deque.h"
|
||||
#include "base/containers/contains.h"
|
||||
-#include "base/containers/queue.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/no_destructor.h"
|
||||
+#include "base/ranges/algorithm.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
+#include "base/synchronization/waitable_event.h"
|
||||
#include "base/task/common/task_annotator.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
@@ -48,6 +50,7 @@
|
||||
#include "mojo/public/cpp/bindings/pipe_control_message_proxy.h"
|
||||
#include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h"
|
||||
#include "mojo/public/cpp/bindings/tracing_helpers.h"
|
||||
+#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
@@ -466,6 +469,11 @@ class ChannelAssociatedGroupController
|
||||
return *this;
|
||||
}
|
||||
|
||||
+ bool HasRequestId(uint64_t request_id) {
|
||||
+ return !value_.IsNull() && value_.version() >= 1 &&
|
||||
+ value_.header_v1()->request_id == request_id;
|
||||
+ }
|
||||
+
|
||||
mojo::Message& value() { return value_; }
|
||||
|
||||
private:
|
||||
@@ -557,10 +565,15 @@ class ChannelAssociatedGroupController
|
||||
sync_watcher_.reset();
|
||||
}
|
||||
|
||||
- uint32_t EnqueueSyncMessage(MessageWrapper message) {
|
||||
+ absl::optional<uint32_t> EnqueueSyncMessage(MessageWrapper message) {
|
||||
controller_->lock_.AssertAcquired();
|
||||
+ if (exclusive_wait_ && exclusive_wait_->TryFulfillingWith(message)) {
|
||||
+ exclusive_wait_ = nullptr;
|
||||
+ return absl::nullopt;
|
||||
+ }
|
||||
+
|
||||
uint32_t id = GenerateSyncMessageId();
|
||||
- sync_messages_.emplace(id, std::move(message));
|
||||
+ sync_messages_.emplace_back(id, std::move(message));
|
||||
SignalSyncMessageEvent();
|
||||
return id;
|
||||
}
|
||||
@@ -577,7 +590,7 @@ class ChannelAssociatedGroupController
|
||||
if (sync_messages_.empty() || sync_messages_.front().first != id)
|
||||
return MessageWrapper();
|
||||
MessageWrapper message = std::move(sync_messages_.front().second);
|
||||
- sync_messages_.pop();
|
||||
+ sync_messages_.pop_front();
|
||||
return message;
|
||||
}
|
||||
|
||||
@@ -607,10 +620,38 @@ class ChannelAssociatedGroupController
|
||||
return sync_watcher_->SyncWatch(&should_stop);
|
||||
}
|
||||
|
||||
+ MessageWrapper WaitForIncomingSyncReply(uint64_t request_id) {
|
||||
+ absl::optional<ExclusiveSyncWait> wait;
|
||||
+ {
|
||||
+ base::AutoLock lock(controller_->lock_);
|
||||
+ for (auto& [id, message] : sync_messages_) {
|
||||
+ if (message.HasRequestId(request_id)) {
|
||||
+ return std::move(message);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ DCHECK(!exclusive_wait_);
|
||||
+ wait.emplace(request_id);
|
||||
+ exclusive_wait_ = &wait.value();
|
||||
+ }
|
||||
+
|
||||
+ wait->event.Wait();
|
||||
+ return std::move(wait->message);
|
||||
+ }
|
||||
+
|
||||
bool SyncWatchExclusive(uint64_t request_id) override {
|
||||
- // We don't support exclusive waits on Channel-associated interfaces.
|
||||
- NOTREACHED();
|
||||
- return false;
|
||||
+ MessageWrapper message = WaitForIncomingSyncReply(request_id);
|
||||
+ if (message.value().IsNull() || !client_) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (!client_->HandleIncomingMessage(&message.value())) {
|
||||
+ base::AutoLock locker(controller_->lock_);
|
||||
+ controller_->RaiseError();
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
void RegisterExternalSyncWaiter(uint64_t request_id) override {}
|
||||
@@ -624,6 +665,9 @@ class ChannelAssociatedGroupController
|
||||
DCHECK(closed_);
|
||||
DCHECK(peer_closed_);
|
||||
DCHECK(!sync_watcher_);
|
||||
+ if (exclusive_wait_) {
|
||||
+ exclusive_wait_->event.Signal();
|
||||
+ }
|
||||
}
|
||||
|
||||
void OnSyncMessageEventReady() {
|
||||
@@ -640,7 +684,7 @@ class ChannelAssociatedGroupController
|
||||
if (!sync_messages_.empty()) {
|
||||
MessageWrapper message_wrapper =
|
||||
std::move(sync_messages_.front().second);
|
||||
- sync_messages_.pop();
|
||||
+ sync_messages_.pop_front();
|
||||
|
||||
bool dispatch_succeeded;
|
||||
mojo::InterfaceEndpointClient* client = client_;
|
||||
@@ -688,6 +732,28 @@ class ChannelAssociatedGroupController
|
||||
return id;
|
||||
}
|
||||
|
||||
+ // Tracks the state of a pending sync wait which excludes all other incoming
|
||||
+ // IPC on the waiting thread.
|
||||
+ struct ExclusiveSyncWait {
|
||||
+ explicit ExclusiveSyncWait(uint64_t request_id)
|
||||
+ : request_id(request_id) {}
|
||||
+ ~ExclusiveSyncWait() = default;
|
||||
+
|
||||
+ bool TryFulfillingWith(MessageWrapper& wrapper) {
|
||||
+ if (!wrapper.HasRequestId(request_id)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ message = std::move(wrapper);
|
||||
+ event.Signal();
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ uint64_t request_id;
|
||||
+ base::WaitableEvent event;
|
||||
+ MessageWrapper message;
|
||||
+ };
|
||||
+
|
||||
const raw_ptr<ChannelAssociatedGroupController> controller_;
|
||||
const mojo::InterfaceId id_;
|
||||
|
||||
@@ -699,7 +765,8 @@ class ChannelAssociatedGroupController
|
||||
raw_ptr<mojo::InterfaceEndpointClient> client_ = nullptr;
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||
std::unique_ptr<mojo::SequenceLocalSyncEventWatcher> sync_watcher_;
|
||||
- base::queue<std::pair<uint32_t, MessageWrapper>> sync_messages_;
|
||||
+ base::circular_deque<std::pair<uint32_t, MessageWrapper>> sync_messages_;
|
||||
+ ExclusiveSyncWait* exclusive_wait_ = nullptr;
|
||||
uint32_t next_sync_message_id_ = 0;
|
||||
};
|
||||
|
||||
@@ -932,12 +999,15 @@ class ChannelAssociatedGroupController
|
||||
// sync message queue. If the endpoint was blocking, it will dequeue the
|
||||
// message and dispatch it. Otherwise the posted |AcceptSyncMessage()|
|
||||
// call will dequeue the message and dispatch it.
|
||||
- uint32_t message_id =
|
||||
+ absl::optional<uint32_t> message_id =
|
||||
endpoint->EnqueueSyncMessage(std::move(message_wrapper));
|
||||
- task_runner->PostTask(
|
||||
- FROM_HERE,
|
||||
- base::BindOnce(&ChannelAssociatedGroupController::AcceptSyncMessage,
|
||||
- this, id, message_id));
|
||||
+ if (message_id) {
|
||||
+ task_runner->PostTask(
|
||||
+ FROM_HERE,
|
||||
+ base::BindOnce(
|
||||
+ &ChannelAssociatedGroupController::AcceptSyncMessage, this,
|
||||
+ id, *message_id));
|
||||
+ }
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/interface_endpoint_controller.h b/mojo/public/cpp/bindings/interface_endpoint_controller.h
|
||||
index 89dbe39994620148e0ef33910b7cc7baacd7cc2e..8649abe1ac9c4b964c2bf833b850aa6f898b7103 100644
|
||||
--- a/mojo/public/cpp/bindings/interface_endpoint_controller.h
|
||||
+++ b/mojo/public/cpp/bindings/interface_endpoint_controller.h
|
||||
@@ -36,6 +36,10 @@ class InterfaceEndpointController {
|
||||
// Watches the endpoint for a specific incoming sync reply. This method only
|
||||
// returns true once the reply is received, or false if the endpoint is
|
||||
// detached or destroyed beforehand.
|
||||
+ //
|
||||
+ // Unlike with SyncWatch(), no other IPCs (not even other sync IPCs) can be
|
||||
+ // dispatched to the calling thread while SyncWatchExclusive() is waiting on
|
||||
+ // the reply for `request_id`.
|
||||
virtual bool SyncWatchExclusive(uint64_t request_id) = 0;
|
||||
|
||||
// Notifies the controller that a specific in-flight sync message identified
|
||||
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
|
||||
index 6e87db197c603d8ac44b591f2cd70023217dcbe2..1a786923f6d66c0b8d17765ea7b629add2db104c 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
|
||||
@@ -387,7 +387,9 @@ void ThreadSafeInterfaceEndpointClientProxy::SendMessageWithResponder(
|
||||
}
|
||||
|
||||
// If the Remote is bound on another sequence, post the call.
|
||||
- const bool allow_interrupt = !message.has_flag(Message::kFlagNoInterrupt);
|
||||
+ const bool allow_interrupt =
|
||||
+ SyncCallRestrictions::AreSyncCallInterruptsEnabled() &&
|
||||
+ !message.has_flag(Message::kFlagNoInterrupt);
|
||||
auto response = base::MakeRefCounted<SyncResponseInfo>();
|
||||
auto response_signaler = std::make_unique<SyncResponseSignaler>(response);
|
||||
task_runner_->PostTask(
|
||||
@@ -625,7 +627,9 @@ bool InterfaceEndpointClient::SendMessageWithResponder(
|
||||
|
||||
const uint32_t message_name = message->name();
|
||||
const bool is_sync = message->has_flag(Message::kFlagIsSync);
|
||||
- const bool exclusive_wait = message->has_flag(Message::kFlagNoInterrupt);
|
||||
+ const bool exclusive_wait =
|
||||
+ message->has_flag(Message::kFlagNoInterrupt) ||
|
||||
+ !SyncCallRestrictions::AreSyncCallInterruptsEnabled();
|
||||
if (!controller_->SendMessage(message))
|
||||
return false;
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
|
||||
index 329901dec12572e8d8833eba33ad1cc793919084..6242391074ee6279cfea29cf1e73ac4ef874445a 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
||||
|
||||
-#if ENABLE_SYNC_CALL_RESTRICTIONS
|
||||
-
|
||||
#include "base/check_op.h"
|
||||
#include "base/debug/leak_annotations.h"
|
||||
#include "base/logging.h"
|
||||
@@ -19,6 +17,11 @@ namespace mojo {
|
||||
|
||||
namespace {
|
||||
|
||||
+// Sync call interrupts are enabled by default.
|
||||
+bool g_enable_sync_call_interrupts = true;
|
||||
+
|
||||
+#if ENABLE_SYNC_CALL_RESTRICTIONS
|
||||
+
|
||||
class GlobalSyncCallSettings {
|
||||
public:
|
||||
GlobalSyncCallSettings() = default;
|
||||
@@ -61,8 +64,12 @@ bool SyncCallRestrictionsEnforceable() {
|
||||
return base::internal::SequenceLocalStorageMap::IsSetForCurrentThread();
|
||||
}
|
||||
|
||||
+#endif // ENABLE_SYNC_CALL_RESTRICTIONS
|
||||
+
|
||||
} // namespace
|
||||
|
||||
+#if ENABLE_SYNC_CALL_RESTRICTIONS
|
||||
+
|
||||
// static
|
||||
void SyncCallRestrictions::AssertSyncCallAllowed() {
|
||||
if (GetGlobalSettings().sync_call_allowed_by_default() ||
|
||||
@@ -102,6 +109,21 @@ void SyncCallRestrictions::DecreaseScopedAllowCount() {
|
||||
--GetSequenceLocalScopedAllowCount();
|
||||
}
|
||||
|
||||
-} // namespace mojo
|
||||
-
|
||||
#endif // ENABLE_SYNC_CALL_RESTRICTIONS
|
||||
+
|
||||
+// static
|
||||
+void SyncCallRestrictions::DisableSyncCallInterrupts() {
|
||||
+ g_enable_sync_call_interrupts = false;
|
||||
+}
|
||||
+
|
||||
+// static
|
||||
+void SyncCallRestrictions::EnableSyncCallInterruptsForTesting() {
|
||||
+ g_enable_sync_call_interrupts = true;
|
||||
+}
|
||||
+
|
||||
+// static
|
||||
+bool SyncCallRestrictions::AreSyncCallInterruptsEnabled() {
|
||||
+ return g_enable_sync_call_interrupts;
|
||||
+}
|
||||
+
|
||||
+} // namespace mojo
|
||||
diff --git a/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h
|
||||
index e7e67ee824b2a87eb14b45a3f2d76d471ff864fb..1653fd63033383b40b643c03500b26bdc65a44a6 100644
|
||||
--- a/mojo/public/cpp/bindings/sync_call_restrictions.h
|
||||
+++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
|
||||
@@ -86,6 +86,20 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions {
|
||||
static void DisallowSyncCall() {}
|
||||
#endif
|
||||
|
||||
+ // Globally disables sync call interrupts. This means that all sync calls in
|
||||
+ // the current process will be strictly blocking until a reply is received,
|
||||
+ // and no incoming sync calls can dispatch on the blocking thread in interim.
|
||||
+ static void DisableSyncCallInterrupts();
|
||||
+
|
||||
+ // Used only in tests to re-enable sync call interrupts after disabling them.
|
||||
+ static void EnableSyncCallInterruptsForTesting();
|
||||
+
|
||||
+ // Indicates whether sync call interrupts are enabled in the calling process.
|
||||
+ // They're enabled by default, so any sync message that isn't marked [Sync]
|
||||
+ // may have its blocking call interrupted to dispatch other incoming sync
|
||||
+ // IPCs which target the blocking thread.
|
||||
+ static bool AreSyncCallInterruptsEnabled();
|
||||
+
|
||||
private:
|
||||
// DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to mojo/OWNERS first.
|
||||
// BEGIN ALLOWED USAGE.
|
||||
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
||||
index cfac737af29e653d788eb1ce7669f73ae7b320d4..d794d29df07d289d34b3b1aae9f8574fc914c050 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
||||
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/shared_associated_remote.h"
|
||||
#include "mojo/public/cpp/bindings/shared_remote.h"
|
||||
+#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
||||
#include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
|
||||
#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom.h"
|
||||
#include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h"
|
||||
@@ -1563,7 +1564,144 @@ TEST_P(SyncInterruptTest, SharedAssociatedRemoteNoInterrupt) {
|
||||
EXPECT_EQ(0, same_pipe_ponger().num_sync_pongs());
|
||||
}
|
||||
|
||||
+class SyncService : public mojom::SyncService {
|
||||
+ public:
|
||||
+ explicit SyncService(PendingReceiver<mojom::SyncService> receiver)
|
||||
+ : receiver_(this, std::move(receiver)) {}
|
||||
+
|
||||
+ void SetCallHandler(base::OnceClosure call_handler) {
|
||||
+ call_handler_ = std::move(call_handler);
|
||||
+ }
|
||||
+
|
||||
+ // mojom::SyncService:
|
||||
+ void SyncCall(SyncCallCallback callback) override {
|
||||
+ std::move(callback).Run();
|
||||
+ if (call_handler_) {
|
||||
+ std::move(call_handler_).Run();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ Receiver<mojom::SyncService> receiver_;
|
||||
+ base::OnceClosure call_handler_;
|
||||
+};
|
||||
+
|
||||
+class DisableSyncInterruptTest : public BindingsTestBase {
|
||||
+ public:
|
||||
+ void SetUp() override {
|
||||
+ mojo::SyncCallRestrictions::DisableSyncCallInterrupts();
|
||||
+ }
|
||||
+
|
||||
+ void TearDown() override {
|
||||
+ mojo::SyncCallRestrictions::EnableSyncCallInterruptsForTesting();
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+TEST_P(DisableSyncInterruptTest, NoInterruptWhenDisabled) {
|
||||
+ PendingRemote<mojom::SyncService> interrupter;
|
||||
+ SyncService service(interrupter.InitWithNewPipeAndPassReceiver());
|
||||
+
|
||||
+ base::RunLoop wait_for_main_thread_service_call;
|
||||
+ bool main_thread_service_called = false;
|
||||
+ service.SetCallHandler(base::BindLambdaForTesting([&] {
|
||||
+ main_thread_service_called = true;
|
||||
+ wait_for_main_thread_service_call.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ Remote<mojom::SyncService> caller;
|
||||
+ base::Thread background_service_thread("SyncService");
|
||||
+ background_service_thread.Start();
|
||||
+ base::SequenceBound<SyncService> background_service{
|
||||
+ background_service_thread.task_runner(),
|
||||
+ caller.BindNewPipeAndPassReceiver()};
|
||||
+
|
||||
+ base::Thread interrupter_thread("Interrupter");
|
||||
+ interrupter_thread.Start();
|
||||
+ interrupter_thread.task_runner()->PostTask(
|
||||
+ FROM_HERE, base::BindLambdaForTesting([&interrupter] {
|
||||
+ // Issue a sync call to the SyncService on the main thread. This should
|
||||
+ // never be dispatched until *after* the sync call *from* the main
|
||||
+ // thread completes below.
|
||||
+ Remote<mojom::SyncService>(std::move(interrupter))->SyncCall();
|
||||
+ }));
|
||||
+
|
||||
+ // The key test expectation here is that `main_thread_service_called` cannot
|
||||
+ // be set to true until after SyncCall() returns and we can pump the thread's
|
||||
+ // message loop. If sync interrupts are not properly disabled, this
|
||||
+ // expectation can fail flakily (and often.)
|
||||
+ caller->SyncCall();
|
||||
+ EXPECT_FALSE(main_thread_service_called);
|
||||
+
|
||||
+ // Now the incoming sync call can be dispatched.
|
||||
+ wait_for_main_thread_service_call.Run();
|
||||
+ EXPECT_TRUE(main_thread_service_called);
|
||||
+
|
||||
+ background_service.SynchronouslyResetForTest();
|
||||
+ interrupter_thread.Stop();
|
||||
+ background_service_thread.Stop();
|
||||
+}
|
||||
+
|
||||
+TEST_P(DisableSyncInterruptTest, SharedRemoteNoInterruptWhenDisabled) {
|
||||
+ PendingRemote<mojom::SyncService> interrupter;
|
||||
+ SyncService service(interrupter.InitWithNewPipeAndPassReceiver());
|
||||
+
|
||||
+ base::RunLoop wait_for_main_thread_service_call;
|
||||
+ bool main_thread_service_called = false;
|
||||
+ service.SetCallHandler(base::BindLambdaForTesting([&] {
|
||||
+ main_thread_service_called = true;
|
||||
+ wait_for_main_thread_service_call.Quit();
|
||||
+ }));
|
||||
+
|
||||
+ // Bind a SharedRemote to another background thread so that we exercise
|
||||
+ // SharedRemote's own sync wait codepath when called into from the main
|
||||
+ // thread.
|
||||
+ base::Thread background_client_thread("Client");
|
||||
+ background_client_thread.Start();
|
||||
+
|
||||
+ base::Thread background_service_thread("Service");
|
||||
+ background_service_thread.Start();
|
||||
+
|
||||
+ SharedRemote<mojom::SyncService> caller;
|
||||
+ base::SequenceBound<SyncService> background_service{
|
||||
+ background_service_thread.task_runner(),
|
||||
+ caller.BindNewPipeAndPassReceiver(
|
||||
+ background_client_thread.task_runner())};
|
||||
+
|
||||
+ base::Thread interrupter_thread("Interrupter");
|
||||
+ interrupter_thread.Start();
|
||||
+ interrupter_thread.task_runner()->PostTask(
|
||||
+ FROM_HERE, base::BindLambdaForTesting([&interrupter] {
|
||||
+ // Issue a sync call to the SyncService on the main thread. This should
|
||||
+ // never be dispatched until *after* the sync call *from* the main
|
||||
+ // thread completes below.
|
||||
+ Remote<mojom::SyncService>(std::move(interrupter))->SyncCall();
|
||||
+ }));
|
||||
+
|
||||
+ // The key test expectation here is that `main_thread_service_called` cannot
|
||||
+ // be set to true until after SyncCall() returns and we can pump the thread's
|
||||
+ // message loop. If sync interrupts are not properly disabled, this
|
||||
+ // expectation can fail flakily (and often.)
|
||||
+ caller->SyncCall();
|
||||
+ EXPECT_FALSE(main_thread_service_called);
|
||||
+
|
||||
+ // Now the incoming sync call can be dispatched.
|
||||
+ wait_for_main_thread_service_call.Run();
|
||||
+ EXPECT_TRUE(main_thread_service_called);
|
||||
+
|
||||
+ background_service.SynchronouslyResetForTest();
|
||||
+
|
||||
+ // We need to reset the SharedRemote before the client thread is stopped, to
|
||||
+ // ensure the necessary teardown work is executed on that thread. Otherwise
|
||||
+ // the underlying pipe and related state will leak, and ASan will complain.
|
||||
+ caller.reset();
|
||||
+
|
||||
+ interrupter_thread.Stop();
|
||||
+ background_service_thread.Stop();
|
||||
+ background_client_thread.Stop();
|
||||
+}
|
||||
+
|
||||
INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(SyncInterruptTest);
|
||||
+INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(DisableSyncInterruptTest);
|
||||
|
||||
} // namespace
|
||||
} // namespace sync_method_unittest
|
||||
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
|
||||
index 383b54f3ab654d664192522c061058b29fd0509a..951442b3585ad22f936568e211ad41f8ae358705 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
|
||||
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
|
||||
@@ -45,3 +45,7 @@ interface Ponger {
|
||||
[Sync] Pong() => ();
|
||||
PongAsync();
|
||||
};
|
||||
+
|
||||
+interface SyncService {
|
||||
+ [Sync] SyncCall() => ();
|
||||
+};
|
||||
@@ -0,0 +1,953 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Cheng <dcheng@chromium.org>
|
||||
Date: Sat, 12 Nov 2022 00:27:56 +0000
|
||||
Subject: Validate that a message is allowed to use the sync flag.
|
||||
|
||||
This changes consists of several coordinated changes:
|
||||
- The C++ bindings generator now emits an array of method ordinals that
|
||||
are allowed to use sync calls, but only if any method has a [Sync]
|
||||
annotation. This is intended to minimize the code cost to interfaces
|
||||
that do not have any sync methods (i.e. most of them).
|
||||
- The C++ binding endpoints (mojo::Receiver, et cetera) now plumb the
|
||||
array of sync-allowed ordinals to the InterfaceEndpointClient.
|
||||
- Processing an incoming message checks if the incoming message is
|
||||
allowed to use the sync flag by filtering it against the array of
|
||||
sync-allowed ordinals that was previously passed to the
|
||||
InterfaceEndpointClient.
|
||||
|
||||
This also fixes an incorrect forward declaration of ValidationContext in
|
||||
the generated bindings that discovered in the process of writing the
|
||||
test.
|
||||
|
||||
(cherry picked from commit 4365dddb49847a422bce674383b4aa4f38ff9e89)
|
||||
|
||||
Bug: 1376099
|
||||
Change-Id: Icb5864dcab96ccd18c98b4cc6ade7cdef39e209f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3994146
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1067894}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4018151
|
||||
Auto-Submit: Daniel Cheng <dcheng@chromium.org>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#774}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn
|
||||
index 2c27474d1200f80ff7abc773eaafdc9d30494f58..de587d8759f2e850ef9de355551c4be12f3ca6e7 100644
|
||||
--- a/mojo/public/cpp/bindings/BUILD.gn
|
||||
+++ b/mojo/public/cpp/bindings/BUILD.gn
|
||||
@@ -183,6 +183,7 @@ component("bindings") {
|
||||
"lib/sync_event_watcher.cc",
|
||||
"lib/sync_handle_registry.cc",
|
||||
"lib/sync_handle_watcher.cc",
|
||||
+ "lib/sync_method_traits.h",
|
||||
"lib/task_runner_helper.cc",
|
||||
"lib/task_runner_helper.h",
|
||||
"lib/thread_safe_forwarder_base.cc",
|
||||
diff --git a/mojo/public/cpp/bindings/associated_receiver.h b/mojo/public/cpp/bindings/associated_receiver.h
|
||||
index 78c53543ed01cafe627d0559c31be1d792750685..59b86367122074e8c59fcbd9877bf59d669cc436 100644
|
||||
--- a/mojo/public/cpp/bindings/associated_receiver.h
|
||||
+++ b/mojo/public/cpp/bindings/associated_receiver.h
|
||||
@@ -5,15 +5,19 @@
|
||||
#ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_RECEIVER_H_
|
||||
#define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_RECEIVER_H_
|
||||
|
||||
+#include <stdint.h>
|
||||
+
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check.h"
|
||||
+#include "base/containers/span.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
+#include "mojo/public/cpp/bindings/lib/sync_method_traits.h"
|
||||
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
|
||||
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
|
||||
@@ -60,7 +64,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) AssociatedReceiverBase {
|
||||
void BindImpl(ScopedInterfaceEndpointHandle handle,
|
||||
MessageReceiverWithResponderStatus* receiver,
|
||||
std::unique_ptr<MessageReceiver> payload_validator,
|
||||
- bool expect_sync_requests,
|
||||
+ base::span<const uint32_t> sync_method_ordinals,
|
||||
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||
uint32_t interface_version,
|
||||
const char* interface_name,
|
||||
@@ -201,8 +205,8 @@ class AssociatedReceiver : public internal::AssociatedReceiverBase {
|
||||
if (pending_receiver) {
|
||||
BindImpl(pending_receiver.PassHandle(), &stub_,
|
||||
base::WrapUnique(new typename Interface::RequestValidator_()),
|
||||
- Interface::HasSyncMethods_, std::move(task_runner),
|
||||
- Interface::Version_, Interface::Name_,
|
||||
+ internal::SyncMethodTraits<Interface>::GetOrdinals(),
|
||||
+ std::move(task_runner), Interface::Version_, Interface::Name_,
|
||||
Interface::MessageToStableIPCHash_,
|
||||
Interface::MessageToMethodName_);
|
||||
} else {
|
||||
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
|
||||
index dcc6e2aa8d9e97ff716d6ab1de02a83eba95eec2..93aea2bd29c5171f63401bc5d88fb7d6dc302e71 100644
|
||||
--- a/mojo/public/cpp/bindings/interface_endpoint_client.h
|
||||
+++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/component_export.h"
|
||||
+#include "base/containers/span.h"
|
||||
#include "base/dcheck_is_on.h"
|
||||
#include "base/location.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
@@ -56,7 +57,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
|
||||
InterfaceEndpointClient(ScopedInterfaceEndpointHandle handle,
|
||||
MessageReceiverWithResponderStatus* receiver,
|
||||
std::unique_ptr<MessageReceiver> payload_validator,
|
||||
- bool expect_sync_requests,
|
||||
+ base::span<const uint32_t> sync_method_ordinals,
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
||||
uint32_t interface_version,
|
||||
const char* interface_name,
|
||||
@@ -220,6 +221,10 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
|
||||
// The router lock must be held when calling this.
|
||||
void ForgetAsyncRequest(uint64_t request_id);
|
||||
|
||||
+ base::span<const uint32_t> sync_method_ordinals() const {
|
||||
+ return sync_method_ordinals_;
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
struct PendingAsyncResponse {
|
||||
public:
|
||||
@@ -281,7 +286,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
|
||||
|
||||
bool HandleValidatedMessage(Message* message);
|
||||
|
||||
- const bool expect_sync_requests_ = false;
|
||||
+ const base::span<const uint32_t> sync_method_ordinals_;
|
||||
|
||||
// The callback to invoke when our peer endpoint sends us NotifyIdle and we
|
||||
// have no outstanding unacked messages. If null, no callback has been set and
|
||||
diff --git a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc
|
||||
index 957ce42c4fa8e69ce63ee876653ef8f8a2ae5b28..a8b86f529329c8358172e4d0d6c3fe61fbede31b 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
#include "mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h"
|
||||
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <utility>
|
||||
+
|
||||
+#include "base/containers/span.h"
|
||||
#include "mojo/public/cpp/bindings/lib/task_runner_helper.h"
|
||||
|
||||
namespace mojo {
|
||||
@@ -70,7 +75,8 @@ void AssociatedInterfacePtrStateBase::Bind(
|
||||
// The version is only queried from the client so the value passed here
|
||||
// will not be used.
|
||||
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
|
||||
- std::move(handle), nullptr, std::move(validator), false,
|
||||
+ std::move(handle), nullptr, std::move(validator),
|
||||
+ /*sync_method_ordinals=*/base::span<const uint32_t>(),
|
||||
GetTaskRunnerToUseFromUserProvidedTaskRunner(std::move(runner)), 0u,
|
||||
interface_name, ipc_hash_callback, method_name_callback);
|
||||
}
|
||||
diff --git a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
|
||||
index d9a4ef1fd6c8141a69de15895ae411a77a03462a..81806976b9c5ccc3d001344a55633d447ac2df24 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
|
||||
+++ b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
|
||||
@@ -141,6 +141,10 @@ class AssociatedInterfacePtrState : public AssociatedInterfacePtrStateBase {
|
||||
return info;
|
||||
}
|
||||
|
||||
+ InterfaceEndpointClient* endpoint_client_for_test() {
|
||||
+ return endpoint_client();
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
std::unique_ptr<Proxy> proxy_;
|
||||
};
|
||||
diff --git a/mojo/public/cpp/bindings/lib/associated_receiver.cc b/mojo/public/cpp/bindings/lib/associated_receiver.cc
|
||||
index be3d8689cbdeaaa685f470f39fef3650d19f0aa0..413104e622a879db15ab6d6fa631462104a409e4 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/associated_receiver.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/associated_receiver.cc
|
||||
@@ -64,7 +64,7 @@ void AssociatedReceiverBase::BindImpl(
|
||||
ScopedInterfaceEndpointHandle handle,
|
||||
MessageReceiverWithResponderStatus* receiver,
|
||||
std::unique_ptr<MessageReceiver> payload_validator,
|
||||
- bool expect_sync_requests,
|
||||
+ base::span<const uint32_t> sync_method_ordinals,
|
||||
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||
uint32_t interface_version,
|
||||
const char* interface_name,
|
||||
@@ -74,7 +74,7 @@ void AssociatedReceiverBase::BindImpl(
|
||||
|
||||
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
|
||||
std::move(handle), receiver, std::move(payload_validator),
|
||||
- expect_sync_requests,
|
||||
+ sync_method_ordinals,
|
||||
internal::GetTaskRunnerToUseFromUserProvidedTaskRunner(std::move(runner)),
|
||||
interface_version, interface_name, ipc_hash_callback,
|
||||
method_name_callback);
|
||||
diff --git a/mojo/public/cpp/bindings/lib/binding_state.cc b/mojo/public/cpp/bindings/lib/binding_state.cc
|
||||
index c40b244184601a6fc661a623f6ae45430925b789..a07943d50add0f840752eceb5d7c56f11ce958e6 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/binding_state.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/binding_state.cc
|
||||
@@ -107,7 +107,7 @@ void BindingStateBase::BindInternal(
|
||||
const char* interface_name,
|
||||
std::unique_ptr<MessageReceiver> request_validator,
|
||||
bool passes_associated_kinds,
|
||||
- bool has_sync_methods,
|
||||
+ base::span<const uint32_t> sync_method_ordinals,
|
||||
MessageReceiverWithResponderStatus* stub,
|
||||
uint32_t interface_version,
|
||||
MessageToStableIPCHashCallback ipc_hash_callback,
|
||||
@@ -121,7 +121,7 @@ void BindingStateBase::BindInternal(
|
||||
MultiplexRouter::Config config =
|
||||
passes_associated_kinds
|
||||
? MultiplexRouter::MULTI_INTERFACE
|
||||
- : (has_sync_methods
|
||||
+ : (!sync_method_ordinals.empty()
|
||||
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
|
||||
: MultiplexRouter::SINGLE_INTERFACE);
|
||||
router_ = MultiplexRouter::CreateAndStartReceiving(
|
||||
@@ -131,7 +131,7 @@ void BindingStateBase::BindInternal(
|
||||
|
||||
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
|
||||
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), stub,
|
||||
- std::move(request_validator), has_sync_methods,
|
||||
+ std::move(request_validator), sync_method_ordinals,
|
||||
std::move(sequenced_runner), interface_version, interface_name,
|
||||
ipc_hash_callback, method_name_callback);
|
||||
endpoint_client_->SetIdleTrackingEnabledCallback(
|
||||
diff --git a/mojo/public/cpp/bindings/lib/binding_state.h b/mojo/public/cpp/bindings/lib/binding_state.h
|
||||
index 64e3fb139fcd8afcf66a85f68e5264dbb47ca997..949b6d8a6eb5ae7d19e26e1b0afe63f1640cff76 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/binding_state.h
|
||||
+++ b/mojo/public/cpp/bindings/lib/binding_state.h
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
|
||||
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
|
||||
|
||||
+#include <stdint.h>
|
||||
+
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
@@ -12,6 +14,7 @@
|
||||
#include "base/callback.h"
|
||||
#include "base/check.h"
|
||||
#include "base/component_export.h"
|
||||
+#include "base/containers/span.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
@@ -23,6 +26,7 @@
|
||||
#include "mojo/public/cpp/bindings/interface_id.h"
|
||||
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
|
||||
#include "mojo/public/cpp/bindings/lib/pending_receiver_state.h"
|
||||
+#include "mojo/public/cpp/bindings/lib/sync_method_traits.h"
|
||||
#include "mojo/public/cpp/bindings/message_header_validator.h"
|
||||
#include "mojo/public/cpp/bindings/pending_flush.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
@@ -90,7 +94,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) BindingStateBase {
|
||||
const char* interface_name,
|
||||
std::unique_ptr<MessageReceiver> request_validator,
|
||||
bool passes_associated_kinds,
|
||||
- bool has_sync_methods,
|
||||
+ base::span<const uint32_t> sync_method_ordinals,
|
||||
MessageReceiverWithResponderStatus* stub,
|
||||
uint32_t interface_version,
|
||||
MessageToStableIPCHashCallback ipc_hash_callback,
|
||||
@@ -121,9 +125,9 @@ class BindingState : public BindingStateBase {
|
||||
BindingStateBase::BindInternal(
|
||||
std::move(receiver_state), runner, Interface::Name_,
|
||||
std::make_unique<typename Interface::RequestValidator_>(),
|
||||
- Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_, &stub_,
|
||||
- Interface::Version_, Interface::MessageToStableIPCHash_,
|
||||
- Interface::MessageToMethodName_);
|
||||
+ Interface::PassesAssociatedKinds_,
|
||||
+ SyncMethodTraits<Interface>::GetOrdinals(), &stub_, Interface::Version_,
|
||||
+ Interface::MessageToStableIPCHash_, Interface::MessageToMethodName_);
|
||||
}
|
||||
|
||||
PendingReceiver<Interface> Unbind() {
|
||||
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
|
||||
index 1a786923f6d66c0b8d17765ea7b629add2db104c..c1e7efe6954ae3dc9186d33067bc324b05273e65 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
|
||||
@@ -439,13 +439,13 @@ InterfaceEndpointClient::InterfaceEndpointClient(
|
||||
ScopedInterfaceEndpointHandle handle,
|
||||
MessageReceiverWithResponderStatus* receiver,
|
||||
std::unique_ptr<MessageReceiver> payload_validator,
|
||||
- bool expect_sync_requests,
|
||||
+ base::span<const uint32_t> sync_method_ordinals,
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
||||
uint32_t interface_version,
|
||||
const char* interface_name,
|
||||
MessageToStableIPCHashCallback ipc_hash_callback,
|
||||
MessageToMethodNameCallback method_name_callback)
|
||||
- : expect_sync_requests_(expect_sync_requests),
|
||||
+ : sync_method_ordinals_(sync_method_ordinals),
|
||||
handle_(std::move(handle)),
|
||||
incoming_receiver_(receiver),
|
||||
dispatcher_(&thunk_),
|
||||
@@ -849,7 +849,8 @@ void InterfaceEndpointClient::InitControllerIfNecessary() {
|
||||
|
||||
controller_ = handle_.group_controller()->AttachEndpointClient(handle_, this,
|
||||
task_runner_);
|
||||
- if (expect_sync_requests_ && task_runner_->RunsTasksInCurrentSequence())
|
||||
+ if (!sync_method_ordinals_.empty() &&
|
||||
+ task_runner_->RunsTasksInCurrentSequence())
|
||||
controller_->AllowWokenUpBySyncWatchOnSameThread();
|
||||
}
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/lib/interface_ptr_state.cc b/mojo/public/cpp/bindings/lib/interface_ptr_state.cc
|
||||
index 8607d5fba2fd59f4f0ca154a9085c47a26ff2c21..aa12189148f79a742be39f3cfaeba9cf54c2dc91 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/interface_ptr_state.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/interface_ptr_state.cc
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
|
||||
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <utility>
|
||||
+
|
||||
+#include "base/containers/span.h"
|
||||
#include "mojo/public/cpp/bindings/lib/task_runner_helper.h"
|
||||
|
||||
namespace mojo {
|
||||
@@ -100,7 +105,9 @@ bool InterfacePtrStateBase::InitializeEndpointClient(
|
||||
interface_name);
|
||||
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
|
||||
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), nullptr,
|
||||
- std::move(payload_validator), false, std::move(runner_),
|
||||
+ std::move(payload_validator),
|
||||
+ /* sync_method_ordinals= */ base::span<const uint32_t>(),
|
||||
+ std::move(runner_),
|
||||
// The version is only queried from the client so the value passed here
|
||||
// will not be used.
|
||||
0u, interface_name, ipc_hash_callback, method_name_callback);
|
||||
diff --git a/mojo/public/cpp/bindings/lib/interface_ptr_state.h b/mojo/public/cpp/bindings/lib/interface_ptr_state.h
|
||||
index 2d379a081e6731db5cd2182365529da2200e3d7b..5b7bb34ac5c9a4764ee9a41c1d3ce324c6a93b13 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/interface_ptr_state.h
|
||||
+++ b/mojo/public/cpp/bindings/lib/interface_ptr_state.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
||||
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
|
||||
#include "mojo/public/cpp/bindings/lib/pending_remote_state.h"
|
||||
+#include "mojo/public/cpp/bindings/lib/sync_method_traits.h"
|
||||
#include "mojo/public/cpp/bindings/pending_flush.h"
|
||||
#include "mojo/public/cpp/bindings/thread_safe_proxy.h"
|
||||
#include "mojo/public/cpp/system/message_pipe.h"
|
||||
@@ -249,6 +250,10 @@ class InterfacePtrState : public InterfacePtrStateBase {
|
||||
endpoint_client()->RaiseError();
|
||||
}
|
||||
|
||||
+ InterfaceEndpointClient* endpoint_client_for_test() {
|
||||
+ return endpoint_client();
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
void ConfigureProxyIfNecessary() {
|
||||
// The proxy has been configured.
|
||||
@@ -259,7 +264,8 @@ class InterfacePtrState : public InterfacePtrStateBase {
|
||||
}
|
||||
|
||||
if (InitializeEndpointClient(
|
||||
- Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_,
|
||||
+ Interface::PassesAssociatedKinds_,
|
||||
+ !SyncMethodTraits<Interface>::GetOrdinals().empty(),
|
||||
Interface::HasUninterruptableMethods_,
|
||||
std::make_unique<typename Interface::ResponseValidator_>(),
|
||||
Interface::Name_, Interface::MessageToStableIPCHash_,
|
||||
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
||||
index b9c92d5ec9eab57972cf870efff51fe09e381623..c04999f0ac8881cc86ed34761ddeb8e8dfc83164 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
||||
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
||||
@@ -1067,6 +1067,12 @@ bool MultiplexRouter::ProcessIncomingMessage(
|
||||
|
||||
bool can_direct_call;
|
||||
if (message->has_flag(Message::kFlagIsSync)) {
|
||||
+ if (!message->has_flag(Message::kFlagIsResponse) &&
|
||||
+ !base::Contains(endpoint->client()->sync_method_ordinals(),
|
||||
+ message->name())) {
|
||||
+ RaiseErrorInNonTestingMode();
|
||||
+ return true;
|
||||
+ }
|
||||
can_direct_call = client_call_behavior != NO_DIRECT_CLIENT_CALLS &&
|
||||
endpoint->task_runner()->RunsTasksInCurrentSequence();
|
||||
} else {
|
||||
diff --git a/mojo/public/cpp/bindings/lib/sync_method_traits.h b/mojo/public/cpp/bindings/lib/sync_method_traits.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2b334f8d01c2edb7c3e6b98fb8d35925aded11ab
|
||||
--- /dev/null
|
||||
+++ b/mojo/public/cpp/bindings/lib/sync_method_traits.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+// Copyright 2022 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SYNC_METHOD_TRAITS_H_
|
||||
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SYNC_METHOD_TRAITS_H_
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include <type_traits>
|
||||
+
|
||||
+#include "base/containers/span.h"
|
||||
+
|
||||
+namespace mojo::internal {
|
||||
+
|
||||
+template <typename Interface, typename SFINAE = void>
|
||||
+struct SyncMethodTraits {
|
||||
+ static constexpr base::span<const uint32_t> GetOrdinals() { return {}; }
|
||||
+};
|
||||
+
|
||||
+template <typename Interface>
|
||||
+struct SyncMethodTraits<Interface,
|
||||
+ std::void_t<decltype(Interface::kSyncMethodOrdinals)>> {
|
||||
+ static constexpr base::span<const uint32_t> GetOrdinals() {
|
||||
+ return Interface::kSyncMethodOrdinals;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+} // namespace mojo::internal
|
||||
+
|
||||
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SYNC_METHOD_TRAITS_H_
|
||||
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
|
||||
index 248176f6f350b57bb5138924c68c4393ba1c11a8..25cfe56438d099ddcb4ed04a4e83b9abb89b8d14 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
|
||||
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
|
||||
@@ -65,6 +65,7 @@ source_set("tests") {
|
||||
":mojo_public_bindings_test_utils",
|
||||
":test_extra_cpp_template_mojom",
|
||||
":test_mojom",
|
||||
+ ":test_mojom__generate_message_ids",
|
||||
"//base/test:test_support",
|
||||
"//mojo/core/test:test_support",
|
||||
"//mojo/public/cpp/bindings",
|
||||
diff --git a/mojo/public/cpp/bindings/tests/bindings_perftest.cc b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
|
||||
index 2c44aaedd8b1a9415d41d8215266aad5033e34e3..1bb2c2d7c03f3b2069e09c1746b17cfea0477b0b 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/bindings_perftest.cc
|
||||
+++ b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
|
||||
@@ -213,12 +213,12 @@ TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) {
|
||||
|
||||
InterfaceEndpointClient client0(
|
||||
router0->CreateLocalEndpointHandle(kPrimaryInterfaceId), &paddle0,
|
||||
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
|
||||
- kTestInterfaceName, MessageToStableIPCHash, MessageToMethodName);
|
||||
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ MessageToStableIPCHash, MessageToMethodName);
|
||||
InterfaceEndpointClient client1(
|
||||
router1->CreateLocalEndpointHandle(kPrimaryInterfaceId), &paddle1,
|
||||
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
|
||||
- kTestInterfaceName, MessageToStableIPCHash, MessageToMethodName);
|
||||
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ MessageToStableIPCHash, MessageToMethodName);
|
||||
|
||||
paddle0.set_sender(&client0);
|
||||
paddle1.set_sender(&client1);
|
||||
@@ -265,8 +265,8 @@ TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) {
|
||||
CounterReceiver receiver;
|
||||
InterfaceEndpointClient client(
|
||||
router->CreateLocalEndpointHandle(kPrimaryInterfaceId), &receiver,
|
||||
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
|
||||
- kTestInterfaceName, MessageToStableIPCHash, MessageToMethodName);
|
||||
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ MessageToStableIPCHash, MessageToMethodName);
|
||||
|
||||
static const uint32_t kIterations[] = {1000, 3000000};
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
|
||||
index 300ead4aefd2d5167c29c0afae4ea7c1a3f85426..1dcb7bcddc04cc8584300e4add052cb2059613cf 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
|
||||
+++ b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
|
||||
@@ -74,13 +74,13 @@ class MultiplexRouterTest : public testing::Test {
|
||||
|
||||
TEST_F(MultiplexRouterTest, BasicRequestResponse) {
|
||||
InterfaceEndpointClient client0(
|
||||
- std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(), {},
|
||||
+ base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
ResponseGenerator generator;
|
||||
InterfaceEndpointClient client1(
|
||||
std::move(endpoint1_), &generator, std::make_unique<PassThroughFilter>(),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
|
||||
Message request;
|
||||
@@ -123,13 +123,13 @@ TEST_F(MultiplexRouterTest, BasicRequestResponse) {
|
||||
|
||||
TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
|
||||
InterfaceEndpointClient client0(
|
||||
- std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(), {},
|
||||
+ base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
ResponseGenerator generator;
|
||||
InterfaceEndpointClient client1(
|
||||
std::move(endpoint1_), &generator, std::make_unique<PassThroughFilter>(),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
|
||||
Message request;
|
||||
@@ -173,15 +173,15 @@ TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
|
||||
TEST_F(MultiplexRouterTest, LazyResponses) {
|
||||
InterfaceEndpointClient client0(
|
||||
std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
base::RunLoop run_loop;
|
||||
LazyResponseGenerator generator(run_loop.QuitClosure());
|
||||
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
|
||||
- base::WrapUnique(new PassThroughFilter()),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(),
|
||||
- 0u, kTestInterfaceName,
|
||||
- MessageToStableIPCHash, MessageToMethodName);
|
||||
+ base::WrapUnique(new PassThroughFilter()), {},
|
||||
+ base::ThreadTaskRunnerHandle::Get(), 0u,
|
||||
+ kTestInterfaceName, MessageToStableIPCHash,
|
||||
+ MessageToMethodName);
|
||||
|
||||
Message request;
|
||||
AllocRequestMessage(1, "hello", &request);
|
||||
@@ -247,7 +247,7 @@ TEST_F(MultiplexRouterTest, MissingResponses) {
|
||||
base::RunLoop run_loop0, run_loop1;
|
||||
InterfaceEndpointClient client0(
|
||||
std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
bool error_handler_called0 = false;
|
||||
client0.set_connection_error_handler(base::BindOnce(
|
||||
@@ -256,10 +256,10 @@ TEST_F(MultiplexRouterTest, MissingResponses) {
|
||||
base::RunLoop run_loop3;
|
||||
LazyResponseGenerator generator(run_loop3.QuitClosure());
|
||||
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
|
||||
- base::WrapUnique(new PassThroughFilter()),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(),
|
||||
- 0u, kTestInterfaceName,
|
||||
- MessageToStableIPCHash, MessageToMethodName);
|
||||
+ base::WrapUnique(new PassThroughFilter()), {},
|
||||
+ base::ThreadTaskRunnerHandle::Get(), 0u,
|
||||
+ kTestInterfaceName, MessageToStableIPCHash,
|
||||
+ MessageToMethodName);
|
||||
bool error_handler_called1 = false;
|
||||
client1.set_connection_error_handler(base::BindOnce(
|
||||
&ForwardErrorHandler, &error_handler_called1, run_loop1.QuitClosure()));
|
||||
@@ -306,13 +306,13 @@ TEST_F(MultiplexRouterTest, LateResponse) {
|
||||
{
|
||||
InterfaceEndpointClient client0(
|
||||
std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
|
||||
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
- MessageToStableIPCHash, MessageToMethodName);
|
||||
- InterfaceEndpointClient client1(
|
||||
- std::move(endpoint1_), &generator,
|
||||
- std::make_unique<PassThroughFilter>(), false,
|
||||
- base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
|
||||
MessageToStableIPCHash, MessageToMethodName);
|
||||
+ InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
|
||||
+ std::make_unique<PassThroughFilter>(), {},
|
||||
+ base::ThreadTaskRunnerHandle::Get(), 0u,
|
||||
+ kTestInterfaceName, MessageToStableIPCHash,
|
||||
+ MessageToMethodName);
|
||||
|
||||
Message request;
|
||||
AllocRequestMessage(1, "hello", &request);
|
||||
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
||||
index d794d29df07d289d34b3b1aae9f8574fc914c050..6de90c8ec9619358e97d50726d7c8c6820df7990 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
||||
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
|
||||
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
+#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "base/barrier_closure.h"
|
||||
@@ -9,15 +10,21 @@
|
||||
#include "base/check.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/sequence_token.h"
|
||||
+#include "base/task/sequenced_task_runner.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "base/test/bind.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "base/threading/sequence_bound.h"
|
||||
+#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "base/time/time.h"
|
||||
#include "mojo/public/cpp/bindings/associated_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
|
||||
#include "mojo/public/cpp/bindings/associated_remote.h"
|
||||
+#include "mojo/public/cpp/bindings/lib/message_fragment.h"
|
||||
+#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
|
||||
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
|
||||
+#include "mojo/public/cpp/bindings/message.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
@@ -27,10 +34,16 @@
|
||||
#include "mojo/public/cpp/bindings/shared_remote.h"
|
||||
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
||||
#include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
|
||||
+#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom-shared-message-ids.h"
|
||||
#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom.h"
|
||||
#include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
+// This needs to be included last, since it forward declares a bunch of classes
|
||||
+// but depends on those definitions to be included by headers that sort
|
||||
+// lexicographically after.
|
||||
+#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom-params-data.h"
|
||||
+
|
||||
namespace mojo {
|
||||
namespace test {
|
||||
namespace sync_method_unittest {
|
||||
@@ -1703,6 +1716,237 @@ TEST_P(DisableSyncInterruptTest, SharedRemoteNoInterruptWhenDisabled) {
|
||||
INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(SyncInterruptTest);
|
||||
INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(DisableSyncInterruptTest);
|
||||
|
||||
+class OneSyncImpl;
|
||||
+
|
||||
+class NoSyncImpl : public mojom::NoSync {
|
||||
+ public:
|
||||
+ explicit NoSyncImpl(PendingReceiver<mojom::NoSync> receiver)
|
||||
+ : receiver_(this, std::move(receiver)) {}
|
||||
+
|
||||
+ explicit NoSyncImpl(
|
||||
+ PendingAssociatedReceiver<mojom::NoSync> associated_receiver)
|
||||
+ : associated_receiver_(this, std::move(associated_receiver)) {}
|
||||
+
|
||||
+ // mojom::NoSync implementation:
|
||||
+ void Method(MethodCallback callback) override;
|
||||
+ void BindNoSync(PendingAssociatedReceiver<mojom::NoSync> receiver) override;
|
||||
+ void BindOneSync(PendingAssociatedReceiver<mojom::OneSync> receiver) override;
|
||||
+
|
||||
+ private:
|
||||
+ Receiver<mojom::NoSync> receiver_{this};
|
||||
+ AssociatedReceiver<mojom::NoSync> associated_receiver_{this};
|
||||
+
|
||||
+ std::unique_ptr<NoSyncImpl> associated_no_sync_;
|
||||
+ std::unique_ptr<OneSyncImpl> associated_one_sync_;
|
||||
+};
|
||||
+
|
||||
+class OneSyncImpl : public mojom::OneSync {
|
||||
+ public:
|
||||
+ explicit OneSyncImpl(PendingReceiver<mojom::OneSync> receiver)
|
||||
+ : receiver_(this, std::move(receiver)) {}
|
||||
+
|
||||
+ explicit OneSyncImpl(
|
||||
+ PendingAssociatedReceiver<mojom::OneSync> associated_receiver)
|
||||
+ : associated_receiver_(this, std::move(associated_receiver)) {}
|
||||
+
|
||||
+ // mojom::OneSync implementation:
|
||||
+ void Method(MethodCallback callback) override;
|
||||
+ void SyncMethod(SyncMethodCallback callback) override;
|
||||
+ void BindNoSync(PendingAssociatedReceiver<mojom::NoSync> receiver) override;
|
||||
+ void BindOneSync(PendingAssociatedReceiver<mojom::OneSync> receiver) override;
|
||||
+
|
||||
+ private:
|
||||
+ Receiver<mojom::OneSync> receiver_{this};
|
||||
+ AssociatedReceiver<mojom::OneSync> associated_receiver_{this};
|
||||
+
|
||||
+ std::unique_ptr<NoSyncImpl> associated_no_sync_;
|
||||
+ std::unique_ptr<OneSyncImpl> associated_one_sync_;
|
||||
+};
|
||||
+
|
||||
+void NoSyncImpl::Method(MethodCallback callback) {
|
||||
+ EXPECT_TRUE(false);
|
||||
+ std::move(callback).Run();
|
||||
+}
|
||||
+
|
||||
+void NoSyncImpl::BindNoSync(PendingAssociatedReceiver<mojom::NoSync> receiver) {
|
||||
+ associated_no_sync_ = std::make_unique<NoSyncImpl>(std::move(receiver));
|
||||
+}
|
||||
+
|
||||
+void NoSyncImpl::BindOneSync(
|
||||
+ PendingAssociatedReceiver<mojom::OneSync> receiver) {
|
||||
+ associated_one_sync_ = std::make_unique<OneSyncImpl>(std::move(receiver));
|
||||
+}
|
||||
+
|
||||
+void OneSyncImpl::Method(MethodCallback callback) {
|
||||
+ EXPECT_TRUE(false);
|
||||
+ std::move(callback).Run();
|
||||
+}
|
||||
+
|
||||
+void OneSyncImpl::SyncMethod(MethodCallback callback) {
|
||||
+ std::move(callback).Run();
|
||||
+}
|
||||
+
|
||||
+void OneSyncImpl::BindNoSync(
|
||||
+ PendingAssociatedReceiver<mojom::NoSync> receiver) {
|
||||
+ associated_no_sync_ = std::make_unique<NoSyncImpl>(std::move(receiver));
|
||||
+}
|
||||
+
|
||||
+void OneSyncImpl::BindOneSync(
|
||||
+ PendingAssociatedReceiver<mojom::OneSync> receiver) {
|
||||
+ associated_one_sync_ = std::make_unique<OneSyncImpl>(std::move(receiver));
|
||||
+}
|
||||
+
|
||||
+class NoResponseExpectedResponder : public MessageReceiver {
|
||||
+ public:
|
||||
+ explicit NoResponseExpectedResponder() = default;
|
||||
+
|
||||
+ // MessageReceiver implementation:
|
||||
+ bool Accept(Message* message) override {
|
||||
+ EXPECT_TRUE(false);
|
||||
+ return true;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+class SyncFlagValidationTest : public ::testing::TestWithParam<uint32_t> {
|
||||
+ protected:
|
||||
+ Message MakeNoSyncMethodMessage() {
|
||||
+ const uint32_t flags =
|
||||
+ // Always set the sync flag, as that's the primary point of the test.
|
||||
+ Message::kFlagIsSync |
|
||||
+ // InterfaceEndpointClient requires this flag if sending a message with
|
||||
+ // a responder.
|
||||
+ Message::kFlagExpectsResponse | GetParam();
|
||||
+ Message message(mojom::internal::kNoSync_Method_Name, flags, 0, 0, nullptr);
|
||||
+ ::mojo::internal::MessageFragment<
|
||||
+ mojom::internal::NoSync_Method_Params_Data>
|
||||
+ params(message);
|
||||
+ params.Allocate();
|
||||
+ return message;
|
||||
+ }
|
||||
+
|
||||
+ Message MakeOneSyncMethodMessage() {
|
||||
+ const uint32_t flags =
|
||||
+ // Always set the sync flag, as that's the primary point of the test.
|
||||
+ Message::kFlagIsSync |
|
||||
+ // InterfaceEndpointClient requires this flag if sending a message with
|
||||
+ // a responder.
|
||||
+ Message::kFlagExpectsResponse | GetParam();
|
||||
+ Message message(mojom::internal::kOneSync_Method_Name, flags, 0, 0,
|
||||
+ nullptr);
|
||||
+ ::mojo::internal::MessageFragment<
|
||||
+ mojom::internal::NoSync_Method_Params_Data>
|
||||
+ params(message);
|
||||
+ params.Allocate();
|
||||
+ return message;
|
||||
+ }
|
||||
+
|
||||
+ void FlushPostedTasks() {
|
||||
+ base::RunLoop run_loop;
|
||||
+ base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
||||
+ run_loop.QuitClosure());
|
||||
+ run_loop.Run();
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ base::test::SingleThreadTaskEnvironment task_environment;
|
||||
+};
|
||||
+
|
||||
+TEST_P(SyncFlagValidationTest, NonSync) {
|
||||
+ Remote<mojom::NoSync> remote;
|
||||
+ NoSyncImpl impl(remote.BindNewPipeAndPassReceiver());
|
||||
+
|
||||
+ Message message = MakeNoSyncMethodMessage();
|
||||
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
|
||||
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
|
||||
+ ::mojo::internal::SendMojoMessage(
|
||||
+ *remote.internal_state()->endpoint_client_for_test(), message,
|
||||
+ std::move(responder));
|
||||
+}
|
||||
+
|
||||
+TEST_P(SyncFlagValidationTest, OneSync) {
|
||||
+ Remote<mojom::OneSync> remote;
|
||||
+ OneSyncImpl impl(remote.BindNewPipeAndPassReceiver());
|
||||
+
|
||||
+ Message message = MakeOneSyncMethodMessage();
|
||||
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
|
||||
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
|
||||
+ ::mojo::internal::SendMojoMessage(
|
||||
+ *remote.internal_state()->endpoint_client_for_test(), message,
|
||||
+ std::move(responder));
|
||||
+}
|
||||
+
|
||||
+TEST_P(SyncFlagValidationTest, NoSyncAssociatedWithNoSync) {
|
||||
+ Remote<mojom::NoSync> remote;
|
||||
+ NoSyncImpl impl(remote.BindNewPipeAndPassReceiver());
|
||||
+
|
||||
+ AssociatedRemote<mojom::NoSync> associated_remote;
|
||||
+ remote->BindNoSync(associated_remote.BindNewEndpointAndPassReceiver());
|
||||
+
|
||||
+ FlushPostedTasks();
|
||||
+
|
||||
+ Message message = MakeNoSyncMethodMessage();
|
||||
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
|
||||
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
|
||||
+ ::mojo::internal::SendMojoMessage(
|
||||
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
|
||||
+ std::move(responder));
|
||||
+}
|
||||
+
|
||||
+TEST_P(SyncFlagValidationTest, OneSyncAssociatedWithNoSync) {
|
||||
+ Remote<mojom::NoSync> remote;
|
||||
+ NoSyncImpl impl(remote.BindNewPipeAndPassReceiver());
|
||||
+
|
||||
+ AssociatedRemote<mojom::OneSync> associated_remote;
|
||||
+ remote->BindOneSync(associated_remote.BindNewEndpointAndPassReceiver());
|
||||
+
|
||||
+ FlushPostedTasks();
|
||||
+
|
||||
+ Message message = MakeOneSyncMethodMessage();
|
||||
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
|
||||
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
|
||||
+ ::mojo::internal::SendMojoMessage(
|
||||
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
|
||||
+ std::move(responder));
|
||||
+}
|
||||
+
|
||||
+TEST_P(SyncFlagValidationTest, NoSyncAssociatedWithOneSync) {
|
||||
+ Remote<mojom::OneSync> remote;
|
||||
+ OneSyncImpl impl(remote.BindNewPipeAndPassReceiver());
|
||||
+
|
||||
+ AssociatedRemote<mojom::NoSync> associated_remote;
|
||||
+ remote->BindNoSync(associated_remote.BindNewEndpointAndPassReceiver());
|
||||
+
|
||||
+ FlushPostedTasks();
|
||||
+
|
||||
+ Message message = MakeNoSyncMethodMessage();
|
||||
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
|
||||
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
|
||||
+ ::mojo::internal::SendMojoMessage(
|
||||
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
|
||||
+ std::move(responder));
|
||||
+}
|
||||
+
|
||||
+TEST_P(SyncFlagValidationTest, OneSyncAssociatedWithOneSync) {
|
||||
+ Remote<mojom::OneSync> remote;
|
||||
+ OneSyncImpl impl(remote.BindNewPipeAndPassReceiver());
|
||||
+
|
||||
+ AssociatedRemote<mojom::OneSync> associated_remote;
|
||||
+ remote->BindOneSync(associated_remote.BindNewEndpointAndPassReceiver());
|
||||
+
|
||||
+ FlushPostedTasks();
|
||||
+
|
||||
+ Message message = MakeOneSyncMethodMessage();
|
||||
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
|
||||
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
|
||||
+ ::mojo::internal::SendMojoMessage(
|
||||
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
|
||||
+ std::move(responder));
|
||||
+}
|
||||
+
|
||||
+INSTANTIATE_TEST_SUITE_P(,
|
||||
+ SyncFlagValidationTest,
|
||||
+ ::testing::Values(0, Message::kFlagIsResponse));
|
||||
+
|
||||
} // namespace
|
||||
} // namespace sync_method_unittest
|
||||
} // namespace test
|
||||
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
|
||||
index 951442b3585ad22f936568e211ad41f8ae358705..0cc5f7c6d288f988b6114ff6b5b80546558eb378 100644
|
||||
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
|
||||
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
|
||||
@@ -49,3 +49,20 @@ interface Ponger {
|
||||
interface SyncService {
|
||||
[Sync] SyncCall() => ();
|
||||
};
|
||||
+
|
||||
+interface NoSync {
|
||||
+ Method() => ();
|
||||
+
|
||||
+ BindNoSync(pending_associated_receiver<NoSync> no_sync);
|
||||
+ BindOneSync(pending_associated_receiver<OneSync> one_sync);
|
||||
+};
|
||||
+
|
||||
+interface OneSync {
|
||||
+ Method() => ();
|
||||
+
|
||||
+ [Sync]
|
||||
+ SyncMethod() => ();
|
||||
+
|
||||
+ BindNoSync(pending_associated_receiver<NoSync> no_sync);
|
||||
+ BindOneSync(pending_associated_receiver<OneSync> one_sync);
|
||||
+};
|
||||
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
|
||||
index c09a1ec210acbc8d09cdf4d4e09916a8809fa586..57d9f66922475c73f65b4d2713ad50cbb3ae0f23 100644
|
||||
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
|
||||
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
|
||||
@@ -29,7 +29,12 @@ class {{export_attribute}} {{interface.name}}
|
||||
{%- endif %}
|
||||
static constexpr uint32_t Version_ = {{interface.version}};
|
||||
static constexpr bool PassesAssociatedKinds_ = {% if interface|passes_associated_kinds %}true{% else %}false{% endif %};
|
||||
- static constexpr bool HasSyncMethods_ = {% if interface|has_sync_methods %}true{% else %}false{% endif %};
|
||||
+{%- set sync_method_ordinals = interface|get_sync_method_ordinals -%}
|
||||
+{%- if sync_method_ordinals %}
|
||||
+ static inline constexpr uint32_t kSyncMethodOrdinals[] = {
|
||||
+ {{sync_method_ordinals|sort|join(', \n')|indent(4)}}
|
||||
+ };
|
||||
+{%- endif %}
|
||||
static constexpr bool HasUninterruptableMethods_ =
|
||||
{%- if interface|has_uninterruptable_methods %} true
|
||||
{%- else %} false{% endif %};
|
||||
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
|
||||
index af3bc5168beb5f9e5b9cfe63354dbdb6b29ff8a1..ab71e91dab403f4c552165eba5da7e32a61b1b83 100644
|
||||
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
|
||||
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
|
||||
@@ -17,13 +17,15 @@
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
#endif
|
||||
|
||||
+namespace mojo::internal {
|
||||
+class ValidationContext;
|
||||
+}
|
||||
+
|
||||
{%- for namespace in namespaces_as_array %}
|
||||
namespace {{namespace}} {
|
||||
{%- endfor %}
|
||||
namespace internal {
|
||||
|
||||
-class ValidationContext;
|
||||
-
|
||||
{#--- Interface parameter definitions #}
|
||||
{%- for interface in interfaces %}
|
||||
{%- for method in interface.methods %}
|
||||
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
|
||||
index 014f2bf04da4f2e11a13d57d910ecc8a8b489113..add5a877cb7e38da4599d3ae76ea0bd9486637da 100644
|
||||
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
|
||||
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
|
||||
@@ -403,7 +403,7 @@ class Generator(generator.Generator):
|
||||
"get_qualified_name_for_kind": self._GetQualifiedNameForKind,
|
||||
"has_callbacks": mojom.HasCallbacks,
|
||||
"has_packed_method_ordinals": HasPackedMethodOrdinals,
|
||||
- "has_sync_methods": mojom.HasSyncMethods,
|
||||
+ "get_sync_method_ordinals": mojom.GetSyncMethodOrdinals,
|
||||
"has_uninterruptable_methods": mojom.HasUninterruptableMethods,
|
||||
"method_supports_lazy_serialization":
|
||||
self._MethodSupportsLazySerialization,
|
||||
diff --git a/mojo/public/tools/mojom/mojom/generate/module.py b/mojo/public/tools/mojom/mojom/generate/module.py
|
||||
index 160ad1ef37d7bab86fb15081e0b202845820f8b5..a34d9f0e8134281806a6dc7e7f21e649bce95674 100644
|
||||
--- a/mojo/public/tools/mojom/mojom/generate/module.py
|
||||
+++ b/mojo/public/tools/mojom/mojom/generate/module.py
|
||||
@@ -1739,11 +1739,8 @@ def MethodPassesInterfaces(method):
|
||||
return _AnyMethodParameterRecursive(method, IsInterfaceKind)
|
||||
|
||||
|
||||
-def HasSyncMethods(interface):
|
||||
- for method in interface.methods:
|
||||
- if method.sync:
|
||||
- return True
|
||||
- return False
|
||||
+def GetSyncMethodOrdinals(interface):
|
||||
+ return [method.ordinal for method in interface.methods if method.sync]
|
||||
|
||||
|
||||
def HasUninterruptableMethods(interface):
|
||||
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Bienvenu <davidbienvenu@chromium.org>
|
||||
Date: Fri, 10 Jun 2022 23:41:51 +0000
|
||||
Subject: win: Fix touch mode detection DCHECK in canary
|
||||
|
||||
Remove the DCHECK that the ConvertibleSlateMode key exists. If it does
|
||||
exist, and is set to 1 (physical keyboard available), then we're not
|
||||
in touch mode. If the key doesn't exist, or is set to the default (0),
|
||||
use IsDeviceUsedAsATablet() to determine if we're in touch mode.
|
||||
|
||||
Bug: 1330848
|
||||
Change-Id: Ic2d02979c4eb2d318fcc08b37a56163bb7cce55b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3696127
|
||||
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
|
||||
Reviewed-by: Jesse McKenna <jessemckenna@google.com>
|
||||
Cr-Commit-Position: refs/heads/main@{#1013189}
|
||||
|
||||
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
|
||||
index a5c20144f6b512ad5d3e2d6f911ab9ad5570bece..ba489fc83d4cc3e91a3c7c8938bf95de46ebe33c 100644
|
||||
--- a/base/win/win_util.cc
|
||||
+++ b/base/win/win_util.cc
|
||||
@@ -253,16 +253,19 @@ bool IsWindows10OrGreaterTabletMode(HWND hwnd) {
|
||||
// instead we check if we're in slate mode or not - 0 value means slate
|
||||
// mode. See
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-gpiobuttons-convertibleslatemode
|
||||
+
|
||||
+ constexpr int kKeyboardPresent = 1;
|
||||
base::win::RegKey registry_key(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
L"System\\CurrentControlSet\\Control\\PriorityControl", KEY_READ);
|
||||
DWORD slate_mode = 0;
|
||||
bool value_exists = registry_key.ReadValueDW(L"ConvertibleSlateMode",
|
||||
&slate_mode) == ERROR_SUCCESS;
|
||||
- DCHECK(value_exists) << "ConvertibleSlateMode value not in registry";
|
||||
- // Some devices don't set the reg key to 0 for non touch devices, so also
|
||||
- // check if the device is used as a tablet.
|
||||
- return value_exists && slate_mode == 0 &&
|
||||
+ // Some devices don't set the reg key to 1 for keyboard-only devices, so
|
||||
+ // also check if the device is used as a tablet if it is not 1. Some devices
|
||||
+ // don't set the registry key at all; fall back to checking if the device
|
||||
+ // is used as a tablet for them as well.
|
||||
+ return !(value_exists && slate_mode == kKeyboardPresent) &&
|
||||
IsDeviceUsedAsATablet(/*reason=*/nullptr);
|
||||
}
|
||||
|
||||
@@ -21,5 +21,9 @@
|
||||
|
||||
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
|
||||
|
||||
"src/electron/patches/sqlite": "src/third_party/sqlite/src"
|
||||
"src/electron/patches/sqlite": "src/third_party/sqlite/src",
|
||||
|
||||
"src/electron/patches/skia": "src/third_party/skia",
|
||||
|
||||
"src/electron/patches/libaom": "src/third_party/libaom/source/libaom"
|
||||
}
|
||||
|
||||
1
patches/libaom/.patches
Normal file
1
patches/libaom/.patches
Normal file
@@ -0,0 +1 @@
|
||||
rtc_avoid_scene_detection_on_resize.patch
|
||||
72
patches/libaom/rtc_avoid_scene_detection_on_resize.patch
Normal file
72
patches/libaom/rtc_avoid_scene_detection_on_resize.patch
Normal file
@@ -0,0 +1,72 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Paniconi <marpan@google.com>
|
||||
Date: Mon, 28 Nov 2022 14:25:08 -0800
|
||||
Subject: rtc: Avoid scene detection on resize
|
||||
|
||||
Don't enter scene detection under external resize.
|
||||
Add rc->prev_coded_width/height to track the
|
||||
previous encoded frame eweight/height.
|
||||
The rc is part of layer context so this will be
|
||||
per spatial layer for SVC.
|
||||
|
||||
This fixes the buffer overflow issue below.
|
||||
|
||||
Bug: chromium:1393384
|
||||
Change-Id: I4b11818a27c439c2d2c42036dff7b8777f70a86e
|
||||
(cherry picked from commit bee1caded272127a6d6b70ac79479083d183d5d0)
|
||||
|
||||
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
|
||||
index 40da4f4564e670a74353613620ce162d445f32f8..daadb3ee7d70066d2e38293c4b2029cfee2aab4d 100644
|
||||
--- a/av1/encoder/ratectrl.c
|
||||
+++ b/av1/encoder/ratectrl.c
|
||||
@@ -2128,6 +2128,9 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
|
||||
}
|
||||
#endif
|
||||
if (current_frame->frame_type == KEY_FRAME) rc->frames_since_key = 0;
|
||||
+
|
||||
+ rc->prev_coded_width = cm->width;
|
||||
+ rc->prev_coded_height = cm->height;
|
||||
// if (current_frame->frame_number == 1 && cm->show_frame)
|
||||
/*
|
||||
rc->this_frame_target =
|
||||
@@ -2144,6 +2147,8 @@ void av1_rc_postencode_update_drop_frame(AV1_COMP *cpi) {
|
||||
cpi->rc.rc_2_frame = 0;
|
||||
cpi->rc.rc_1_frame = 0;
|
||||
cpi->rc.prev_avg_frame_bandwidth = cpi->rc.avg_frame_bandwidth;
|
||||
+ cpi->rc.prev_coded_width = cpi->common.width;
|
||||
+ cpi->rc.prev_coded_height = cpi->common.height;
|
||||
}
|
||||
|
||||
int av1_find_qindex(double desired_q, aom_bit_depth_t bit_depth,
|
||||
@@ -3083,8 +3088,15 @@ void av1_get_one_pass_rt_params(AV1_COMP *cpi,
|
||||
}
|
||||
}
|
||||
// Check for scene change: for SVC check on base spatial layer only.
|
||||
- if (cpi->sf.rt_sf.check_scene_detection && svc->spatial_layer_id == 0)
|
||||
- rc_scene_detection_onepass_rt(cpi);
|
||||
+ if (cpi->sf.rt_sf.check_scene_detection && svc->spatial_layer_id == 0) {
|
||||
+ if (rc->prev_coded_width == cm->width &&
|
||||
+ rc->prev_coded_height == cm->height) {
|
||||
+ rc_scene_detection_onepass_rt(cpi);
|
||||
+ } else if (cpi->src_sad_blk_64x64) {
|
||||
+ aom_free(cpi->src_sad_blk_64x64);
|
||||
+ cpi->src_sad_blk_64x64 = NULL;
|
||||
+ }
|
||||
+ }
|
||||
// Check for dynamic resize, for single spatial layer for now.
|
||||
// For temporal layers only check on base temporal layer.
|
||||
if (cpi->oxcf.resize_cfg.resize_mode == RESIZE_DYNAMIC) {
|
||||
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
|
||||
index 5ac9660ab8d31440a5608bab6794286e63203da7..5291323ff4f1401a6a02a8332e552aa8c33b0b0f 100644
|
||||
--- a/av1/encoder/ratectrl.h
|
||||
+++ b/av1/encoder/ratectrl.h
|
||||
@@ -252,6 +252,9 @@ typedef struct {
|
||||
int frame_level_fast_extra_bits;
|
||||
|
||||
double frame_level_rate_correction_factors[RATE_FACTOR_LEVELS];
|
||||
+
|
||||
+ int prev_coded_width;
|
||||
+ int prev_coded_height;
|
||||
/*!\endcond */
|
||||
} RATE_CONTROL;
|
||||
|
||||
@@ -45,3 +45,6 @@ json_parse_errors_made_user-friendly.patch
|
||||
build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch
|
||||
build_ensure_native_module_compilation_fails_if_not_using_a_new.patch
|
||||
buffer_fix_atob_input_validation.patch
|
||||
fix_expose_the_built-in_electron_module_via_the_esm_loader.patch
|
||||
chore_enable_c_17_for_native_modules.patch
|
||||
cherry-pick-09ae62b.patch
|
||||
|
||||
236
patches/node/cherry-pick-09ae62b.patch
Normal file
236
patches/node/cherry-pick-09ae62b.patch
Normal file
@@ -0,0 +1,236 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Dawson <mdawson@devrus.com>
|
||||
Date: Tue, 25 Oct 2022 17:39:41 -0400
|
||||
Subject: node-api: handle no support for external buffers
|
||||
|
||||
Refs: https://github.com/electron/electron/issues/35801
|
||||
Refs: https://github.com/nodejs/abi-stable-node/issues/441
|
||||
|
||||
Electron recently dropped support for external
|
||||
buffers. Provide a way for addon authors to:
|
||||
- hide the methods to create external buffers so they can
|
||||
avoid using them if they want the broadest compatibility.
|
||||
- call the methods that create external buffers at runtime
|
||||
to check if external buffers are supported and either
|
||||
use them or not based on the return code.
|
||||
|
||||
Signed-off-by: Michael Dawson <mdawson@devrus.com>
|
||||
|
||||
PR-URL: https://github.com/nodejs/node/pull/45181
|
||||
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
|
||||
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
|
||||
|
||||
diff --git a/doc/api/n-api.md b/doc/api/n-api.md
|
||||
index 3d1741bad82359af6a258fb2a059656f1528bba0..d64f80e2635074df7f8ecd72d1fde7d1747786fa 100644
|
||||
--- a/doc/api/n-api.md
|
||||
+++ b/doc/api/n-api.md
|
||||
@@ -579,6 +579,7 @@ typedef enum {
|
||||
napi_arraybuffer_expected,
|
||||
napi_detachable_arraybuffer_expected,
|
||||
napi_would_deadlock, /* unused */
|
||||
+ napi_no_external_buffers_allowed
|
||||
} napi_status;
|
||||
```
|
||||
|
||||
@@ -2394,6 +2395,19 @@ napi_create_external_arraybuffer(napi_env env,
|
||||
|
||||
Returns `napi_ok` if the API succeeded.
|
||||
|
||||
+**Some runtimes other than Node.js have dropped support for external buffers**.
|
||||
+On runtimes other than Node.js this method may return
|
||||
+`napi_no_external_buffers_allowed` to indicate that external
|
||||
+buffers are not supported. One such runtime is Electron as
|
||||
+described in this issue
|
||||
+[electron/issues/35801](https://github.com/electron/electron/issues/35801).
|
||||
+
|
||||
+In order to maintain broadest compatibility with all runtimes
|
||||
+you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before
|
||||
+includes for the node-api headers. Doing so will hide the 2 functions
|
||||
+that create external buffers. This will ensure a compilation error
|
||||
+occurs if you accidentally use one of these methods.
|
||||
+
|
||||
This API returns a Node-API value corresponding to a JavaScript `ArrayBuffer`.
|
||||
The underlying byte buffer of the `ArrayBuffer` is externally allocated and
|
||||
managed. The caller must ensure that the byte buffer remains valid until the
|
||||
@@ -2438,6 +2452,19 @@ napi_status napi_create_external_buffer(napi_env env,
|
||||
|
||||
Returns `napi_ok` if the API succeeded.
|
||||
|
||||
+**Some runtimes other than Node.js have dropped support for external buffers**.
|
||||
+On runtimes other than Node.js this method may return
|
||||
+`napi_no_external_buffers_allowed` to indicate that external
|
||||
+buffers are not supported. One such runtime is Electron as
|
||||
+described in this issue
|
||||
+[electron/issues/35801](https://github.com/electron/electron/issues/35801).
|
||||
+
|
||||
+In order to maintain broadest compatibility with all runtimes
|
||||
+you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before
|
||||
+includes for the node-api headers. Doing so will hide the 2 functions
|
||||
+that create external buffers. This will ensure a compilation error
|
||||
+occurs if you accidentally use one of these methods.
|
||||
+
|
||||
This API allocates a `node::Buffer` object and initializes it with data
|
||||
backed by the passed in buffer. While this is still a fully-supported data
|
||||
structure, in most cases using a `TypedArray` will suffice.
|
||||
diff --git a/src/js_native_api.h b/src/js_native_api.h
|
||||
index 50ccf11e2405802f1c48764067b4010e8b9a0815..2ddf3780e8bde8df59b202c0913cf6434a6581ce 100644
|
||||
--- a/src/js_native_api.h
|
||||
+++ b/src/js_native_api.h
|
||||
@@ -404,6 +404,7 @@ NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env,
|
||||
size_t byte_length,
|
||||
void** data,
|
||||
napi_value* result);
|
||||
+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
||||
NAPI_EXTERN napi_status
|
||||
napi_create_external_arraybuffer(napi_env env,
|
||||
void* external_data,
|
||||
@@ -411,6 +412,7 @@ napi_create_external_arraybuffer(napi_env env,
|
||||
napi_finalize finalize_cb,
|
||||
void* finalize_hint,
|
||||
napi_value* result);
|
||||
+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
||||
NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
|
||||
napi_value arraybuffer,
|
||||
void** data,
|
||||
diff --git a/src/js_native_api_types.h b/src/js_native_api_types.h
|
||||
index 6aba06629b31543c13698dbb02b82db309587c4a..7529b853655a25dd6f945df77c9dd024a0403b26 100644
|
||||
--- a/src/js_native_api_types.h
|
||||
+++ b/src/js_native_api_types.h
|
||||
@@ -92,7 +92,8 @@ typedef enum {
|
||||
napi_date_expected,
|
||||
napi_arraybuffer_expected,
|
||||
napi_detachable_arraybuffer_expected,
|
||||
- napi_would_deadlock // unused
|
||||
+ napi_would_deadlock, // unused
|
||||
+ napi_no_external_buffers_allowed
|
||||
} napi_status;
|
||||
// Note: when adding a new enum value to `napi_status`, please also update
|
||||
// * `const int last_status` in the definition of `napi_get_last_error_info()'
|
||||
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
||||
index 1c29c43836a0c35a832e494f8eaebbbe1eee8ea4..108ba4bedbd1684b9a69834ae12347faf4670a27 100644
|
||||
--- a/src/js_native_api_v8.cc
|
||||
+++ b/src/js_native_api_v8.cc
|
||||
@@ -721,29 +721,30 @@ void Reference::SecondPassCallback(
|
||||
} // end of namespace v8impl
|
||||
|
||||
// Warning: Keep in-sync with napi_status enum
|
||||
-static
|
||||
-const char* error_messages[] = {nullptr,
|
||||
- "Invalid argument",
|
||||
- "An object was expected",
|
||||
- "A string was expected",
|
||||
- "A string or symbol was expected",
|
||||
- "A function was expected",
|
||||
- "A number was expected",
|
||||
- "A boolean was expected",
|
||||
- "An array was expected",
|
||||
- "Unknown failure",
|
||||
- "An exception is pending",
|
||||
- "The async work item was cancelled",
|
||||
- "napi_escape_handle already called on scope",
|
||||
- "Invalid handle scope usage",
|
||||
- "Invalid callback scope usage",
|
||||
- "Thread-safe function queue is full",
|
||||
- "Thread-safe function handle is closing",
|
||||
- "A bigint was expected",
|
||||
- "A date was expected",
|
||||
- "An arraybuffer was expected",
|
||||
- "A detachable arraybuffer was expected",
|
||||
- "Main thread would deadlock",
|
||||
+static const char* error_messages[] = {
|
||||
+ nullptr,
|
||||
+ "Invalid argument",
|
||||
+ "An object was expected",
|
||||
+ "A string was expected",
|
||||
+ "A string or symbol was expected",
|
||||
+ "A function was expected",
|
||||
+ "A number was expected",
|
||||
+ "A boolean was expected",
|
||||
+ "An array was expected",
|
||||
+ "Unknown failure",
|
||||
+ "An exception is pending",
|
||||
+ "The async work item was cancelled",
|
||||
+ "napi_escape_handle already called on scope",
|
||||
+ "Invalid handle scope usage",
|
||||
+ "Invalid callback scope usage",
|
||||
+ "Thread-safe function queue is full",
|
||||
+ "Thread-safe function handle is closing",
|
||||
+ "A bigint was expected",
|
||||
+ "A date was expected",
|
||||
+ "An arraybuffer was expected",
|
||||
+ "A detachable arraybuffer was expected",
|
||||
+ "Main thread would deadlock",
|
||||
+ "External buffers are not allowed",
|
||||
};
|
||||
|
||||
napi_status napi_get_last_error_info(napi_env env,
|
||||
@@ -755,7 +756,7 @@ napi_status napi_get_last_error_info(napi_env env,
|
||||
// message in the `napi_status` enum each time a new error message is added.
|
||||
// We don't have a napi_status_last as this would result in an ABI
|
||||
// change each time a message was added.
|
||||
- const int last_status = napi_would_deadlock;
|
||||
+ const int last_status = napi_no_external_buffers_allowed;
|
||||
|
||||
static_assert(
|
||||
NAPI_ARRAYSIZE(error_messages) == last_status + 1,
|
||||
diff --git a/src/node_api.cc b/src/node_api.cc
|
||||
index 60fbe96b8ef272768736ce029bac3ff72f3c84a5..6f8575bb8f289aab041bc126b2fd5f53b1116af5 100644
|
||||
--- a/src/node_api.cc
|
||||
+++ b/src/node_api.cc
|
||||
@@ -929,6 +929,10 @@ napi_status napi_create_external_buffer(napi_env env,
|
||||
NAPI_PREAMBLE(env);
|
||||
CHECK_ARG(env, result);
|
||||
|
||||
+#if defined(V8_ENABLE_SANDBOX)
|
||||
+ return napi_set_last_error(env, napi_no_external_buffers_allowed);
|
||||
+#endif
|
||||
+
|
||||
v8::Isolate* isolate = env->isolate;
|
||||
|
||||
// The finalizer object will delete itself after invoking the callback.
|
||||
diff --git a/src/node_api.h b/src/node_api.h
|
||||
index 1772c67c15afb2d2712b1900a584f627852e3d7e..47703198fed09a61c3e9e06fa5781d340cc39cf9 100644
|
||||
--- a/src/node_api.h
|
||||
+++ b/src/node_api.h
|
||||
@@ -138,12 +138,14 @@ NAPI_EXTERN napi_status napi_create_buffer(napi_env env,
|
||||
size_t length,
|
||||
void** data,
|
||||
napi_value* result);
|
||||
+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
||||
NAPI_EXTERN napi_status napi_create_external_buffer(napi_env env,
|
||||
size_t length,
|
||||
void* data,
|
||||
napi_finalize finalize_cb,
|
||||
void* finalize_hint,
|
||||
napi_value* result);
|
||||
+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
||||
NAPI_EXTERN napi_status napi_create_buffer_copy(napi_env env,
|
||||
size_t length,
|
||||
const void* data,
|
||||
diff --git a/test/js-native-api/test_general/test_general.c b/test/js-native-api/test_general/test_general.c
|
||||
index 7b755ce9a9f202eaf91e5103d6c0204925f99cac..b474ab442cb763cb84ec77901da91a6f1471c946 100644
|
||||
--- a/test/js-native-api/test_general/test_general.c
|
||||
+++ b/test/js-native-api/test_general/test_general.c
|
||||
@@ -1,3 +1,8 @@
|
||||
+// we define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED here to
|
||||
+// validate that it can be used as a form of test itself. It is
|
||||
+// not related to any of the other tests
|
||||
+// defined in the file
|
||||
+#define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
diff --git a/test/node-api/test_general/test_general.c b/test/node-api/test_general/test_general.c
|
||||
index d430e2df4f3520fddbc5ce8d260adba565e6c3c9..b8d837d5e45650fcb9ba04030721b0f51377f078 100644
|
||||
--- a/test/node-api/test_general/test_general.c
|
||||
+++ b/test/node-api/test_general/test_general.c
|
||||
@@ -1,4 +1,9 @@
|
||||
#define NAPI_EXPERIMENTAL
|
||||
+// we define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED here to validate that it can
|
||||
+// be used as a form of test itself. It is
|
||||
+// not related to any of the other tests
|
||||
+// defined in the file
|
||||
+#define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
|
||||
#include <node_api.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../js-native-api/common.h"
|
||||
54
patches/node/chore_enable_c_17_for_native_modules.patch
Normal file
54
patches/node/chore_enable_c_17_for_native_modules.patch
Normal file
@@ -0,0 +1,54 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Wed, 16 Nov 2022 13:18:23 +0900
|
||||
Subject: chore: enable c++17 for native modules
|
||||
|
||||
V8 headers shipped since 10.4 use C++17 featuers, update the compile flags
|
||||
correspondinly for native addons. C++ version in this file should be updated
|
||||
following the version bump in upstream.
|
||||
|
||||
Next update: crbug.com/1284275
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index 6bf1b3395250d05cad215bd56f6efea9abc7a7aa..d6b026511acf7a69b1e86093075db30e2f518e17 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -308,7 +308,10 @@
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
- 'AdditionalOptions': ['/Zc:__cplusplus'],
|
||||
+ 'AdditionalOptions': [
|
||||
+ '/Zc:__cplusplus',
|
||||
+ '-std:c++17',
|
||||
+ ],
|
||||
'BufferSecurityCheck': 'true',
|
||||
'DebugInformationFormat': 1, # /Z7 embed info in .obj files
|
||||
'ExceptionHandling': 0, # /EHsc
|
||||
@@ -440,7 +443,7 @@
|
||||
}],
|
||||
[ 'OS in "linux freebsd openbsd solaris android aix cloudabi"', {
|
||||
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ],
|
||||
- 'cflags_cc': [ '-fno-rtti', '-fno-exceptions', '-std=gnu++14' ],
|
||||
+ 'cflags_cc': [ '-fno-rtti', '-fno-exceptions', '-std=gnu++17' ],
|
||||
'defines': [ '__STDC_FORMAT_MACROS' ],
|
||||
'ldflags': [ '-rdynamic' ],
|
||||
'target_conditions': [
|
||||
@@ -580,7 +583,7 @@
|
||||
['clang==1', {
|
||||
'xcode_settings': {
|
||||
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
|
||||
- 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++14', # -std=gnu++14
|
||||
+ 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++17', # -std=gnu++17
|
||||
'CLANG_CXX_LIBRARY': 'libc++',
|
||||
},
|
||||
}],
|
||||
@@ -653,7 +656,7 @@
|
||||
'-qASM',
|
||||
],
|
||||
'cflags_cc': [
|
||||
- '-qxclang=-std=c++14',
|
||||
+ '-qxclang=-std=c++17',
|
||||
],
|
||||
'ldflags': [
|
||||
'-q64',
|
||||
@@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@salesforce.com>
|
||||
Date: Thu, 6 Oct 2022 04:09:16 -0700
|
||||
Subject: fix: expose the built-in electron module via the ESM loader
|
||||
|
||||
This allows usage of `import { app } from 'electron'` and `import('electron')` natively in the browser + non-sandboxed renderer
|
||||
|
||||
diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js
|
||||
index 5ae0e17dcfb5e24a1a117c33c4d42891686e693f..619fe6cef3b02eb575410225f41d3e7d51f37b93 100644
|
||||
--- a/lib/internal/modules/esm/get_format.js
|
||||
+++ b/lib/internal/modules/esm/get_format.js
|
||||
@@ -31,6 +31,7 @@ const protocolHandlers = ObjectAssign(ObjectCreate(null), {
|
||||
'http:': getHttpProtocolModuleFormat,
|
||||
'https:': getHttpProtocolModuleFormat,
|
||||
'node:'() { return 'builtin'; },
|
||||
+ 'electron:'() { return 'commonjs'; },
|
||||
});
|
||||
|
||||
function getDataProtocolModuleFormat(parsed) {
|
||||
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
||||
index 3576f75f0a40a64dceb7e2649b344b83ebc04b39..314fbb78931eef154a1e47c655e2d4bafe11bac3 100644
|
||||
--- a/lib/internal/modules/esm/resolve.js
|
||||
+++ b/lib/internal/modules/esm/resolve.js
|
||||
@@ -888,6 +888,8 @@ function parsePackageName(specifier, base) {
|
||||
return { packageName, packageSubpath, isScoped };
|
||||
}
|
||||
|
||||
+const electronSpecifiers = new SafeSet(['electron', 'electron/main', 'electron/common', 'electron/renderer']);
|
||||
+
|
||||
/**
|
||||
* @param {string} specifier
|
||||
* @param {string | URL | undefined} base
|
||||
@@ -898,6 +900,10 @@ function packageResolve(specifier, base, conditions) {
|
||||
if (NativeModule.canBeRequiredByUsers(specifier))
|
||||
return new URL('node:' + specifier);
|
||||
|
||||
+ if (electronSpecifiers.has(specifier)) {
|
||||
+ return new URL('electron:electron');
|
||||
+ }
|
||||
+
|
||||
const { packageName, packageSubpath, isScoped } =
|
||||
parsePackageName(specifier, base);
|
||||
|
||||
@@ -1099,7 +1105,7 @@ function checkIfDisallowedImport(specifier, parsed, parsedParentURL) {
|
||||
|
||||
function throwIfUnsupportedURLProtocol(url) {
|
||||
if (url.protocol !== 'file:' && url.protocol !== 'data:' &&
|
||||
- url.protocol !== 'node:') {
|
||||
+ url.protocol !== 'node:' && url.protocol !== 'electron:') {
|
||||
throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(url);
|
||||
}
|
||||
}
|
||||
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
|
||||
index d7f4c7edec63d3ce500955a37c6eac00e3e524fd..b97cac53365b121f8e232f0085ff166511c3dda3 100644
|
||||
--- a/lib/internal/modules/esm/translators.js
|
||||
+++ b/lib/internal/modules/esm/translators.js
|
||||
@@ -155,7 +155,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
|
||||
|
||||
if (!cjsParse) await initCJSParse();
|
||||
const { module, exportNames } = cjsPreparseModuleExports(filename);
|
||||
- const namesWithDefault = exportNames.has('default') ?
|
||||
+ const namesWithDefault = filename === 'electron' ? ['default', ...Object.keys(module.exports)] : exportNames.has('default') ?
|
||||
[...exportNames] : ['default', ...exportNames];
|
||||
|
||||
return new ModuleWrap(url, undefined, namesWithDefault, function() {
|
||||
@@ -174,7 +174,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
|
||||
}
|
||||
}
|
||||
|
||||
- for (const exportName of exportNames) {
|
||||
+ for (const exportName of namesWithDefault) {
|
||||
if (!ObjectPrototypeHasOwnProperty(exports, exportName) ||
|
||||
exportName === 'default')
|
||||
continue;
|
||||
diff --git a/lib/internal/url.js b/lib/internal/url.js
|
||||
index 939374a495856cf2b9c573fa98dc1895eee5e143..c37258ac29e8b7558c1f9a2af7ba6bdd0eab1355 100644
|
||||
--- a/lib/internal/url.js
|
||||
+++ b/lib/internal/url.js
|
||||
@@ -1418,6 +1418,8 @@ function fileURLToPath(path) {
|
||||
path = new URL(path);
|
||||
else if (!isURLInstance(path))
|
||||
throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);
|
||||
+ if (path.protocol === 'electron:')
|
||||
+ return 'electron';
|
||||
if (path.protocol !== 'file:')
|
||||
throw new ERR_INVALID_URL_SCHEME('file');
|
||||
return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);
|
||||
1
patches/skia/.patches
Normal file
1
patches/skia/.patches
Normal file
@@ -0,0 +1 @@
|
||||
cherry-pick-07a2ce61e31a.patch
|
||||
52
patches/skia/cherry-pick-07a2ce61e31a.patch
Normal file
52
patches/skia/cherry-pick-07a2ce61e31a.patch
Normal file
@@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Daniel <egdaniel@google.com>
|
||||
Date: Wed, 5 Oct 2022 15:28:56 -0400
|
||||
Subject: Fix GrDirectContext::fClinetMappedBuffer access in abandoned
|
||||
callbacks.
|
||||
|
||||
Bug: chromium:1364604
|
||||
Change-Id: I1ca44cab1c762e7f94ac94be94991ec94a7497be
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/583963
|
||||
Commit-Queue: Greg Daniel <egdaniel@google.com>
|
||||
Reviewed-by: Brian Salomon <bsalomon@google.com>
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/587879
|
||||
Auto-Submit: Greg Daniel <egdaniel@google.com>
|
||||
Commit-Queue: Brian Salomon <bsalomon@google.com>
|
||||
|
||||
diff --git a/src/gpu/ganesh/GrDirectContext.cpp b/src/gpu/ganesh/GrDirectContext.cpp
|
||||
index 0ff55edd47e9eaa7d9ac9912806fd29e0043a498..ad42f11b93b9e269a997f9e02e58078f03a51844 100644
|
||||
--- a/src/gpu/ganesh/GrDirectContext.cpp
|
||||
+++ b/src/gpu/ganesh/GrDirectContext.cpp
|
||||
@@ -144,9 +144,6 @@ void GrDirectContext::abandonContext() {
|
||||
|
||||
fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
|
||||
|
||||
- // Must be after GrResourceCache::abandonAll().
|
||||
- fMappedBufferManager.reset();
|
||||
-
|
||||
if (fSmallPathAtlasMgr) {
|
||||
fSmallPathAtlasMgr->reset();
|
||||
}
|
||||
diff --git a/src/gpu/ganesh/GrFinishCallbacks.cpp b/src/gpu/ganesh/GrFinishCallbacks.cpp
|
||||
index 5519d2ca639d31f86e33ff0f617246b785fbc779..172f07d4de4554663140fdc2ad30ceab9bf449aa 100644
|
||||
--- a/src/gpu/ganesh/GrFinishCallbacks.cpp
|
||||
+++ b/src/gpu/ganesh/GrFinishCallbacks.cpp
|
||||
@@ -35,10 +35,16 @@ void GrFinishCallbacks::check() {
|
||||
|
||||
void GrFinishCallbacks::callAll(bool doDelete) {
|
||||
while (!fCallbacks.empty()) {
|
||||
- fCallbacks.front().fCallback(fCallbacks.front().fContext);
|
||||
+ // While we are processing a proc we need to make sure to remove it from
|
||||
+ // the callback list before calling it. This is because the client could
|
||||
+ // trigger a call (e.g. calling flushAndSubmit(/*sync=*/true)) that has
|
||||
+ // us process the finished callbacks. We also must process deleting the
|
||||
+ // fence before a client may abandon the context.
|
||||
+ auto finishCallback = fCallbacks.front();
|
||||
if (doDelete) {
|
||||
- fGpu->deleteFence(fCallbacks.front().fFence);
|
||||
+ fGpu->deleteFence(finishCallback.fFence);
|
||||
}
|
||||
fCallbacks.pop_front();
|
||||
+ finishCallback.fCallback(finishCallback.fContext);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
utf-8_q_simplify_20the_20logic_20that_20converts_20the_20_1_20.patch
|
||||
utf-8_q_when_20applying_20the_20omit-order-by_20optimization.patch
|
||||
utf-8_q_m102-lts_20enhance_20defensive_20mode_20so_20that_20i.patch
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,3 +11,14 @@ revert_runtime_dhceck_terminating_exception_in_microtasks.patch
|
||||
allow_disabling_of_v8_sandboxed_pointers.patch
|
||||
chore_disable_is_execution_terminating_dcheck.patch
|
||||
ext-code-space_fix_coderange_allocation_logic.patch
|
||||
cherry-pick-8b040cb69e96.patch
|
||||
cherry-pick-2f6a2939514f.patch
|
||||
cherry-pick-194bcc127f21.patch
|
||||
cherry-pick-ec236fef54b8.patch
|
||||
cherry-pick-80ed4b917477.patch
|
||||
cherry-pick-2ac0620a5bbb.patch
|
||||
cherry-pick-177e8bcd3584.patch
|
||||
cherry-pick-27fa951ae4a3.patch
|
||||
cherry-pick-c79148742421.patch
|
||||
cherry-pick-0f481c9ddf2a.patch
|
||||
cherry-pick-28b9c1c04e78.patch
|
||||
|
||||
69
patches/v8/cherry-pick-0f481c9ddf2a.patch
Normal file
69
patches/v8/cherry-pick-0f481c9ddf2a.patch
Normal file
@@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Backes <clemensb@chromium.org>
|
||||
Date: Thu, 15 Dec 2022 11:58:50 +0100
|
||||
Subject: Merged: [wasm][turbofan] Load 32-bit values more efficiently
|
||||
|
||||
When loading a 32-bit value from the stack, just load 32 bit and
|
||||
zero-extend them into the target register, instead of loading the full
|
||||
64 bits.
|
||||
|
||||
As there are things to fix (see https://crbug.com/1356461), we only
|
||||
enable this optimization for Wasm for now.
|
||||
|
||||
Also include the related fix https://crrev.com/c/4096985.
|
||||
|
||||
R=mslekova@chromium.org
|
||||
|
||||
(cherry picked from commit 2ee52447c878721c89a55a780eb689ecba6817d3)
|
||||
(cherry picked from commit a38209949fcbf045231c316e2d790b8b70ccb7ef)
|
||||
|
||||
Bug: chromium:1395604
|
||||
Change-Id: I54a2182ada6fadbfcf5565f0dc8d4f477ecff393
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4110897
|
||||
Reviewed-by: Maya Lekova <mslekova@chromium.org>
|
||||
Commit-Queue: Clemens Backes <clemensb@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.8@{#46}
|
||||
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
|
||||
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
|
||||
|
||||
diff --git a/src/compiler/backend/x64/code-generator-x64.cc b/src/compiler/backend/x64/code-generator-x64.cc
|
||||
index 9fd4635d8911716019bf0116123b85a408e247ca..86e017936bab415c003476844cb981e8ad5d1e56 100644
|
||||
--- a/src/compiler/backend/x64/code-generator-x64.cc
|
||||
+++ b/src/compiler/backend/x64/code-generator-x64.cc
|
||||
@@ -5119,7 +5119,22 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
||||
case MoveType::kStackToRegister: {
|
||||
Operand src = g.ToOperand(source);
|
||||
if (source->IsStackSlot()) {
|
||||
- __ movq(g.ToRegister(destination), src);
|
||||
+ MachineRepresentation mr =
|
||||
+ LocationOperand::cast(source)->representation();
|
||||
+ const bool is_32_bit = mr == MachineRepresentation::kWord32 ||
|
||||
+ mr == MachineRepresentation::kCompressed ||
|
||||
+ mr == MachineRepresentation::kCompressedPointer;
|
||||
+ // TODO(13581): Fix this for other code kinds (see
|
||||
+ // https://crbug.com/1356461).
|
||||
+ if (code_kind() == CodeKind::WASM_FUNCTION && is_32_bit) {
|
||||
+ // When we need only 32 bits, move only 32 bits. Benefits:
|
||||
+ // - Save a byte here and there (depending on the destination
|
||||
+ // register; "movl eax, ..." is smaller than "movq rax, ...").
|
||||
+ // - Safeguard against accidental decompression of compressed slots.
|
||||
+ __ movl(g.ToRegister(destination), src);
|
||||
+ } else {
|
||||
+ __ movq(g.ToRegister(destination), src);
|
||||
+ }
|
||||
} else {
|
||||
DCHECK(source->IsFPStackSlot());
|
||||
XMMRegister dst = g.ToDoubleRegister(destination);
|
||||
diff --git a/src/wasm/graph-builder-interface.cc b/src/wasm/graph-builder-interface.cc
|
||||
index 3d899eded2d744731f2acfadce6f4d55b1417c4d..a9587d7548495dfdb0a6cf43ab22a3d06d1a76e7 100644
|
||||
--- a/src/wasm/graph-builder-interface.cc
|
||||
+++ b/src/wasm/graph-builder-interface.cc
|
||||
@@ -2061,7 +2061,7 @@ class WasmGraphBuildingInterface {
|
||||
if (exception_value != nullptr) {
|
||||
// TODO(manoskouk): Can we assign a wasm type to the exception value?
|
||||
*exception_value = builder_->LoopExitValue(
|
||||
- *exception_value, MachineRepresentation::kWord32);
|
||||
+ *exception_value, MachineRepresentation::kTaggedPointer);
|
||||
}
|
||||
if (wrap_exit_values) {
|
||||
WrapLocalsAtLoopExit(decoder, control);
|
||||
144
patches/v8/cherry-pick-177e8bcd3584.patch
Normal file
144
patches/v8/cherry-pick-177e8bcd3584.patch
Normal file
@@ -0,0 +1,144 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darius M <dmercadier@chromium.org>
|
||||
Date: Mon, 7 Nov 2022 08:40:11 +0100
|
||||
Subject: Merged: [compiler] fix bug in inlining of Array.At
|
||||
|
||||
The inlined version of Array.At was only checking the kind of the
|
||||
maps, rather than the maps themselves. When the feedback was
|
||||
containing an array map that "supports_fast_array_iteration", then its
|
||||
kind was added to the list of supported kinds. If this Array.at was
|
||||
later called with a non-array map with the same kind, then the object
|
||||
would be wrongly treated as an array.
|
||||
|
||||
This is now fixed: inlining Array.at checks the maps directly rather
|
||||
than only their kinds.
|
||||
|
||||
Bug: chromium:1377775
|
||||
(cherry picked from commit 0ce27310674150b46605c1e226b8f1a2503bac8c)
|
||||
|
||||
Change-Id: I2398f2f7a1ea37808962ba5eb3d1fe00a54fd614
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3990747
|
||||
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
|
||||
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#49}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc
|
||||
index 65d3dfe1db8e690a949f6ea3140dda4813a0b0d5..10f3301e3a10d215d731e8bd7d2ec67537d66989 100644
|
||||
--- a/src/compiler/js-call-reducer.cc
|
||||
+++ b/src/compiler/js-call-reducer.cc
|
||||
@@ -719,9 +719,8 @@ class IteratingArrayBuiltinReducerAssembler : public JSCallReducerAssembler {
|
||||
MapInference* inference, const bool has_stability_dependency,
|
||||
ElementsKind kind, const SharedFunctionInfoRef& shared,
|
||||
const NativeContextRef& native_context, ArrayEverySomeVariant variant);
|
||||
- TNode<Object> ReduceArrayPrototypeAt(ZoneVector<ElementsKind> kinds,
|
||||
- bool needs_fallback_builtin_call,
|
||||
- Node* receiver_kind);
|
||||
+ TNode<Object> ReduceArrayPrototypeAt(ZoneVector<const MapRef*> kinds,
|
||||
+ bool needs_fallback_builtin_call);
|
||||
TNode<Object> ReduceArrayPrototypeIndexOfIncludes(
|
||||
ElementsKind kind, ArrayIndexOfIncludesVariant variant);
|
||||
|
||||
@@ -1331,24 +1330,26 @@ TNode<String> JSCallReducerAssembler::ReduceStringPrototypeSlice() {
|
||||
}
|
||||
|
||||
TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeAt(
|
||||
- ZoneVector<ElementsKind> kinds, bool needs_fallback_builtin_call,
|
||||
- Node* receiver_kind) {
|
||||
+ ZoneVector<const MapRef*> maps, bool needs_fallback_builtin_call) {
|
||||
TNode<JSArray> receiver = ReceiverInputAs<JSArray>();
|
||||
TNode<Object> index = ArgumentOrZero(0);
|
||||
|
||||
TNode<Number> index_num = CheckSmi(index);
|
||||
TNode<FixedArrayBase> elements = LoadElements(receiver);
|
||||
|
||||
+ TNode<Map> receiver_map =
|
||||
+ TNode<Map>::UncheckedCast(LoadField(AccessBuilder::ForMap(), receiver));
|
||||
+
|
||||
auto out = MakeLabel(MachineRepresentation::kTagged);
|
||||
|
||||
- for (ElementsKind kind : kinds) {
|
||||
+ for (const MapRef* map : maps) {
|
||||
+ DCHECK(map->supports_fast_array_iteration());
|
||||
auto correct_map_label = MakeLabel(), wrong_map_label = MakeLabel();
|
||||
- Branch(NumberEqual(TNode<Number>::UncheckedCast(receiver_kind),
|
||||
- NumberConstant(kind)),
|
||||
- &correct_map_label, &wrong_map_label);
|
||||
+ TNode<Boolean> is_map_equal = ReferenceEqual(receiver_map, Constant(*map));
|
||||
+ Branch(is_map_equal, &correct_map_label, &wrong_map_label);
|
||||
Bind(&correct_map_label);
|
||||
|
||||
- TNode<Number> length = LoadJSArrayLength(receiver, kind);
|
||||
+ TNode<Number> length = LoadJSArrayLength(receiver, map->elements_kind());
|
||||
|
||||
// If index is less than 0, then subtract from length.
|
||||
TNode<Boolean> cond = NumberLessThan(index_num, ZeroConstant());
|
||||
@@ -1367,15 +1368,16 @@ TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeAt(
|
||||
|
||||
// Retrieving element at index.
|
||||
TNode<Object> element = LoadElement<Object>(
|
||||
- AccessBuilder::ForFixedArrayElement(kind), elements, real_index_num);
|
||||
- if (IsHoleyElementsKind(kind)) {
|
||||
+ AccessBuilder::ForFixedArrayElement(map->elements_kind()), elements,
|
||||
+ real_index_num);
|
||||
+ if (IsHoleyElementsKind(map->elements_kind())) {
|
||||
// This case is needed in particular for HOLEY_DOUBLE_ELEMENTS: raw
|
||||
// doubles are stored in the FixedDoubleArray, and need to be converted to
|
||||
// HeapNumber or to Smi so that this function can return an Object. The
|
||||
// automatic converstion performed by
|
||||
// RepresentationChanger::GetTaggedRepresentationFor does not handle
|
||||
// holes, so we convert manually a potential hole here.
|
||||
- element = TryConvertHoleToUndefined(element, kind);
|
||||
+ element = TryConvertHoleToUndefined(element, map->elements_kind());
|
||||
}
|
||||
Goto(&out, element);
|
||||
|
||||
@@ -5639,25 +5641,22 @@ Reduction JSCallReducer::ReduceArrayPrototypeAt(Node* node) {
|
||||
MapInference inference(broker(), receiver, effect);
|
||||
if (!inference.HaveMaps()) return NoChange();
|
||||
|
||||
- // Collecting kinds
|
||||
- ZoneVector<ElementsKind> kinds(broker()->zone());
|
||||
+ // Collecting maps, and checking if a fallback builtin call will be required
|
||||
+ // (it is required if at least one map doesn't support fast array iteration).
|
||||
+ ZoneVector<const MapRef*> maps(broker()->zone());
|
||||
bool needs_fallback_builtin_call = false;
|
||||
for (const MapRef& map : inference.GetMaps()) {
|
||||
if (map.supports_fast_array_iteration()) {
|
||||
- ElementsKind kind = map.elements_kind();
|
||||
- // Checking that |kind| isn't already in |kinds|. Using std::find should
|
||||
- // be fast enough since |kinds| can contain at most 4 items.
|
||||
- if (std::find(kinds.begin(), kinds.end(), kind) == kinds.end()) {
|
||||
- kinds.push_back(kind);
|
||||
- }
|
||||
+ maps.push_back(&map);
|
||||
} else {
|
||||
needs_fallback_builtin_call = true;
|
||||
}
|
||||
}
|
||||
+
|
||||
inference.RelyOnMapsPreferStability(dependencies(), jsgraph(), &effect,
|
||||
control, p.feedback());
|
||||
|
||||
- if (kinds.empty()) {
|
||||
+ if (maps.empty()) {
|
||||
// No map in the feedback supports fast iteration. Keeping the builtin call.
|
||||
return NoChange();
|
||||
}
|
||||
@@ -5666,13 +5665,11 @@ Reduction JSCallReducer::ReduceArrayPrototypeAt(Node* node) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
- Node* receiver_kind = LoadReceiverElementsKind(receiver, &effect, control);
|
||||
-
|
||||
IteratingArrayBuiltinReducerAssembler a(this, node);
|
||||
a.InitializeEffectControl(effect, control);
|
||||
|
||||
- TNode<Object> subgraph = a.ReduceArrayPrototypeAt(
|
||||
- kinds, needs_fallback_builtin_call, receiver_kind);
|
||||
+ TNode<Object> subgraph =
|
||||
+ a.ReduceArrayPrototypeAt(maps, needs_fallback_builtin_call);
|
||||
return ReplaceWithSubgraph(&a, subgraph);
|
||||
}
|
||||
|
||||
135
patches/v8/cherry-pick-194bcc127f21.patch
Normal file
135
patches/v8/cherry-pick-194bcc127f21.patch
Normal file
@@ -0,0 +1,135 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Tebbi <tebbi@chromium.org>
|
||||
Date: Thu, 6 Oct 2022 13:43:19 +0200
|
||||
Subject: Merged: [turbofan] validate more concurrent reads
|
||||
|
||||
Bug: chromium:1369871
|
||||
(cherry picked from commit ebe5675360e4735589a92a8836303822da79a8f4)
|
||||
|
||||
Change-Id: I49243d2c604cb4635d0d49a572245f7469eabffa
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3952937
|
||||
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#41}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/compiler/compilation-dependencies.cc b/src/compiler/compilation-dependencies.cc
|
||||
index 4fb04ae2bd8960deb7e978641d3cf75297f72bda..45aea59373067d1f0fe63d2fcc7059b788c8277b 100644
|
||||
--- a/src/compiler/compilation-dependencies.cc
|
||||
+++ b/src/compiler/compilation-dependencies.cc
|
||||
@@ -35,7 +35,8 @@ namespace compiler {
|
||||
V(Protector) \
|
||||
V(PrototypeProperty) \
|
||||
V(StableMap) \
|
||||
- V(Transition)
|
||||
+ V(Transition) \
|
||||
+ V(ObjectSlotValue)
|
||||
|
||||
CompilationDependencies::CompilationDependencies(JSHeapBroker* broker,
|
||||
Zone* zone)
|
||||
@@ -863,6 +864,42 @@ class ProtectorDependency final : public CompilationDependency {
|
||||
const PropertyCellRef cell_;
|
||||
};
|
||||
|
||||
+// Check that an object slot will not change during compilation.
|
||||
+class ObjectSlotValueDependency final : public CompilationDependency {
|
||||
+ public:
|
||||
+ explicit ObjectSlotValueDependency(const HeapObjectRef& object, int offset,
|
||||
+ const ObjectRef& value)
|
||||
+ : CompilationDependency(kObjectSlotValue),
|
||||
+ object_(object.object()),
|
||||
+ offset_(offset),
|
||||
+ value_(value.object()) {}
|
||||
+
|
||||
+ bool IsValid() const override {
|
||||
+ PtrComprCageBase cage_base = GetPtrComprCageBase(*object_);
|
||||
+ Object current_value =
|
||||
+ offset_ == HeapObject::kMapOffset
|
||||
+ ? object_->map()
|
||||
+ : TaggedField<Object>::Relaxed_Load(cage_base, *object_, offset_);
|
||||
+ return *value_ == current_value;
|
||||
+ }
|
||||
+ void Install(PendingDependencies* deps) const override {}
|
||||
+
|
||||
+ private:
|
||||
+ size_t Hash() const override {
|
||||
+ return base::hash_combine(object_.address(), offset_, value_.address());
|
||||
+ }
|
||||
+
|
||||
+ bool Equals(const CompilationDependency* that) const override {
|
||||
+ const ObjectSlotValueDependency* const zat = that->AsObjectSlotValue();
|
||||
+ return object_->address() == zat->object_->address() &&
|
||||
+ offset_ == zat->offset_ && value_.address() == zat->value_.address();
|
||||
+ }
|
||||
+
|
||||
+ Handle<HeapObject> object_;
|
||||
+ int offset_;
|
||||
+ Handle<Object> value_;
|
||||
+};
|
||||
+
|
||||
class ElementsKindDependency final : public CompilationDependency {
|
||||
public:
|
||||
ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
|
||||
@@ -1115,6 +1152,12 @@ void CompilationDependencies::DependOnElementsKind(
|
||||
}
|
||||
}
|
||||
|
||||
+void CompilationDependencies::DependOnObjectSlotValue(
|
||||
+ const HeapObjectRef& object, int offset, const ObjectRef& value) {
|
||||
+ RecordDependency(
|
||||
+ zone_->New<ObjectSlotValueDependency>(object, offset, value));
|
||||
+}
|
||||
+
|
||||
void CompilationDependencies::DependOnOwnConstantElement(
|
||||
const JSObjectRef& holder, uint32_t index, const ObjectRef& element) {
|
||||
RecordDependency(
|
||||
diff --git a/src/compiler/compilation-dependencies.h b/src/compiler/compilation-dependencies.h
|
||||
index 72ee5773abfcf344e3964d58ea855461ca1ca79d..e0f4eca359b2f7cdca326702d0181b83d3dc322c 100644
|
||||
--- a/src/compiler/compilation-dependencies.h
|
||||
+++ b/src/compiler/compilation-dependencies.h
|
||||
@@ -94,6 +94,10 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
|
||||
// Record the assumption that {site}'s {ElementsKind} doesn't change.
|
||||
void DependOnElementsKind(const AllocationSiteRef& site);
|
||||
|
||||
+ // Check that an object slot will not change during compilation.
|
||||
+ void DependOnObjectSlotValue(const HeapObjectRef& object, int offset,
|
||||
+ const ObjectRef& value);
|
||||
+
|
||||
void DependOnOwnConstantElement(const JSObjectRef& holder, uint32_t index,
|
||||
const ObjectRef& element);
|
||||
|
||||
diff --git a/src/compiler/js-create-lowering.cc b/src/compiler/js-create-lowering.cc
|
||||
index 1b4755e2db290701740cbcbaf6fcab2154c68132..241186706d9388fe6127c5cf1d1e6befecf229f7 100644
|
||||
--- a/src/compiler/js-create-lowering.cc
|
||||
+++ b/src/compiler/js-create-lowering.cc
|
||||
@@ -1677,6 +1677,10 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteral(
|
||||
|
||||
// Now that we hold the migration lock, get the current map.
|
||||
MapRef boilerplate_map = boilerplate.map();
|
||||
+ // Protect against concurrent changes to the boilerplate object by checking
|
||||
+ // for an identical value at the end of the compilation.
|
||||
+ dependencies()->DependOnObjectSlotValue(boilerplate, HeapObject::kMapOffset,
|
||||
+ boilerplate_map);
|
||||
{
|
||||
base::Optional<MapRef> current_boilerplate_map =
|
||||
boilerplate.map_direct_read();
|
||||
@@ -1841,10 +1845,18 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
|
||||
boilerplate.elements(kRelaxedLoad);
|
||||
if (!maybe_boilerplate_elements.has_value()) return {};
|
||||
FixedArrayBaseRef boilerplate_elements = maybe_boilerplate_elements.value();
|
||||
+ // Protect against concurrent changes to the boilerplate object by checking
|
||||
+ // for an identical value at the end of the compilation.
|
||||
+ dependencies()->DependOnObjectSlotValue(
|
||||
+ boilerplate, JSObject::kElementsOffset, boilerplate_elements);
|
||||
|
||||
// Empty or copy-on-write elements just store a constant.
|
||||
int const elements_length = boilerplate_elements.length();
|
||||
MapRef elements_map = boilerplate_elements.map();
|
||||
+ // Protect against concurrent changes to the boilerplate object by checking
|
||||
+ // for an identical value at the end of the compilation.
|
||||
+ dependencies()->DependOnObjectSlotValue(boilerplate_elements,
|
||||
+ HeapObject::kMapOffset, elements_map);
|
||||
if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
|
||||
if (allocation == AllocationType::kOld &&
|
||||
!boilerplate.IsElementsTenured(boilerplate_elements)) {
|
||||
209
patches/v8/cherry-pick-27fa951ae4a3.patch
Normal file
209
patches/v8/cherry-pick-27fa951ae4a3.patch
Normal file
@@ -0,0 +1,209 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Toon Verwaest <verwaest@chromium.org>
|
||||
Date: Wed, 30 Nov 2022 15:07:26 +0100
|
||||
Subject: Fix eval tracking
|
||||
|
||||
Due to mismatch in strictness we otherwise invalidly mark scopes as
|
||||
calling sloppy eval.
|
||||
|
||||
Bug: chromium:1394403
|
||||
Change-Id: Iece45df87f171616a2917c2aba5540636880a7c6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4066044
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#84575}
|
||||
|
||||
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
||||
index 679472c7c62916727735cbbcd7c6caf1fa7ae8bb..54709de5b747f0c6f450943e110c4f82b97c29ca 100644
|
||||
--- a/src/ast/scopes.cc
|
||||
+++ b/src/ast/scopes.cc
|
||||
@@ -888,9 +888,8 @@ void DeclarationScope::AddLocal(Variable* var) {
|
||||
}
|
||||
|
||||
void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
|
||||
- DCHECK(!IsCleared());
|
||||
- DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
|
||||
- DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
|
||||
+ DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
|
||||
+ DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
|
||||
DCHECK_EQ(new_parent, new_parent->GetClosureScope());
|
||||
DCHECK_NULL(new_parent->inner_scope_);
|
||||
DCHECK(new_parent->unresolved_list_.is_empty());
|
||||
@@ -915,12 +914,11 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
|
||||
new_parent->sibling_ = top_inner_scope_;
|
||||
}
|
||||
|
||||
- Scope* outer_scope = outer_scope_and_calls_eval_.GetPointer();
|
||||
- new_parent->unresolved_list_.MoveTail(&outer_scope->unresolved_list_,
|
||||
+ new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
|
||||
top_unresolved_);
|
||||
|
||||
// Move temporaries allocated for complex parameter initializers.
|
||||
- DeclarationScope* outer_closure = outer_scope->GetClosureScope();
|
||||
+ DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
|
||||
for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
|
||||
Variable* local = *it;
|
||||
DCHECK_EQ(VariableMode::kTemporary, local->mode());
|
||||
@@ -932,16 +930,10 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
|
||||
outer_closure->locals_.Rewind(top_local_);
|
||||
|
||||
// Move eval calls since Snapshot's creation into new_parent.
|
||||
- if (outer_scope_and_calls_eval_->calls_eval_) {
|
||||
- new_parent->RecordDeclarationScopeEvalCall();
|
||||
- new_parent->inner_scope_calls_eval_ = true;
|
||||
+ if (outer_scope_->calls_eval_) {
|
||||
+ new_parent->RecordEvalCall();
|
||||
+ declaration_scope_->sloppy_eval_can_extend_vars_ = false;
|
||||
}
|
||||
-
|
||||
- // We are in the arrow function case. The calls eval we may have recorded
|
||||
- // is intended for the inner scope and we should simply restore the
|
||||
- // original "calls eval" flag of the outer scope.
|
||||
- RestoreEvalFlag();
|
||||
- Clear();
|
||||
}
|
||||
|
||||
void Scope::ReplaceOuterScope(Scope* outer) {
|
||||
@@ -2579,6 +2571,9 @@ void Scope::AllocateVariablesRecursively() {
|
||||
this->ForEach([](Scope* scope) -> Iteration {
|
||||
DCHECK(!scope->already_resolved_);
|
||||
if (WasLazilyParsed(scope)) return Iteration::kContinue;
|
||||
+ if (scope->sloppy_eval_can_extend_vars_) {
|
||||
+ scope->num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
|
||||
+ }
|
||||
DCHECK_EQ(scope->ContextHeaderLength(), scope->num_heap_slots_);
|
||||
|
||||
// Allocate variables for this scope.
|
||||
diff --git a/src/ast/scopes.h b/src/ast/scopes.h
|
||||
index 9f4970931454e78468eba7bc2cf01289fa598289..29e329833f247d901e20fb227ceedbdd2ee4127a 100644
|
||||
--- a/src/ast/scopes.h
|
||||
+++ b/src/ast/scopes.h
|
||||
@@ -112,12 +112,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
|
||||
class Snapshot final {
|
||||
public:
|
||||
- Snapshot()
|
||||
- : outer_scope_and_calls_eval_(nullptr, false),
|
||||
- top_unresolved_(),
|
||||
- top_local_() {
|
||||
- DCHECK(IsCleared());
|
||||
- }
|
||||
inline explicit Snapshot(Scope* scope);
|
||||
|
||||
// Disallow copy and move.
|
||||
@@ -125,45 +119,31 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
Snapshot(Snapshot&&) = delete;
|
||||
|
||||
~Snapshot() {
|
||||
- // If we're still active, there was no arrow function. In that case outer
|
||||
- // calls eval if it already called eval before this snapshot started, or
|
||||
- // if the code during the snapshot called eval.
|
||||
- if (!IsCleared() && outer_scope_and_calls_eval_.GetPayload()) {
|
||||
- RestoreEvalFlag();
|
||||
+ // Restore eval flags from before the scope was active.
|
||||
+ if (sloppy_eval_can_extend_vars_) {
|
||||
+ declaration_scope_->sloppy_eval_can_extend_vars_ = true;
|
||||
}
|
||||
- }
|
||||
-
|
||||
- void RestoreEvalFlag() {
|
||||
- if (outer_scope_and_calls_eval_.GetPayload()) {
|
||||
- // This recreates both calls_eval and sloppy_eval_can_extend_vars.
|
||||
- outer_scope_and_calls_eval_.GetPointer()->RecordEvalCall();
|
||||
+ if (calls_eval_) {
|
||||
+ outer_scope_->calls_eval_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Reparent(DeclarationScope* new_parent);
|
||||
- bool IsCleared() const {
|
||||
- return outer_scope_and_calls_eval_.GetPointer() == nullptr;
|
||||
- }
|
||||
-
|
||||
- void Clear() {
|
||||
- outer_scope_and_calls_eval_.SetPointer(nullptr);
|
||||
-#ifdef DEBUG
|
||||
- outer_scope_and_calls_eval_.SetPayload(false);
|
||||
- top_inner_scope_ = nullptr;
|
||||
- top_local_ = base::ThreadedList<Variable>::Iterator();
|
||||
- top_unresolved_ = UnresolvedList::Iterator();
|
||||
-#endif
|
||||
- }
|
||||
|
||||
private:
|
||||
- // During tracking calls_eval caches whether the outer scope called eval.
|
||||
- // Upon move assignment we store whether the new inner scope calls eval into
|
||||
- // the move target calls_eval bit, and restore calls eval on the outer
|
||||
- // scope.
|
||||
- base::PointerWithPayload<Scope, bool, 1> outer_scope_and_calls_eval_;
|
||||
+ Scope* outer_scope_;
|
||||
+ Scope* declaration_scope_;
|
||||
Scope* top_inner_scope_;
|
||||
UnresolvedList::Iterator top_unresolved_;
|
||||
base::ThreadedList<Variable>::Iterator top_local_;
|
||||
+ // While the scope is active, the scope caches the flag values for
|
||||
+ // outer_scope_ / declaration_scope_ they can be used to know what happened
|
||||
+ // while parsing the arrow head. If this turns out to be an arrow head, new
|
||||
+ // values on the respective scopes will be cleared and moved to the inner
|
||||
+ // scope. Otherwise the cached flags will be merged with the flags from the
|
||||
+ // arrow head.
|
||||
+ bool calls_eval_;
|
||||
+ bool sloppy_eval_can_extend_vars_;
|
||||
};
|
||||
|
||||
enum class DeserializationMode { kIncludingVariables, kScopesOnly };
|
||||
@@ -909,8 +889,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
void RecordDeclarationScopeEvalCall() {
|
||||
calls_eval_ = true;
|
||||
|
||||
- // If this isn't a sloppy eval, we don't care about it.
|
||||
- if (language_mode() != LanguageMode::kSloppy) return;
|
||||
+ // The caller already checked whether we're in sloppy mode.
|
||||
+ CHECK(is_sloppy(language_mode()));
|
||||
|
||||
// Sloppy eval in script scopes can only introduce global variables anyway,
|
||||
// so we don't care that it calls sloppy eval.
|
||||
@@ -944,7 +924,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
}
|
||||
|
||||
sloppy_eval_can_extend_vars_ = true;
|
||||
- num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
|
||||
}
|
||||
|
||||
bool sloppy_eval_can_extend_vars() const {
|
||||
@@ -1369,7 +1348,9 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
|
||||
void Scope::RecordEvalCall() {
|
||||
calls_eval_ = true;
|
||||
- GetDeclarationScope()->RecordDeclarationScopeEvalCall();
|
||||
+ if (is_sloppy(language_mode())) {
|
||||
+ GetDeclarationScope()->RecordDeclarationScopeEvalCall();
|
||||
+ }
|
||||
RecordInnerScopeEvalCall();
|
||||
// The eval contents might access "super" (if it's inside a function that
|
||||
// binds super).
|
||||
@@ -1382,14 +1363,18 @@ void Scope::RecordEvalCall() {
|
||||
}
|
||||
|
||||
Scope::Snapshot::Snapshot(Scope* scope)
|
||||
- : outer_scope_and_calls_eval_(scope, scope->calls_eval_),
|
||||
+ : outer_scope_(scope),
|
||||
+ declaration_scope_(scope->GetDeclarationScope()),
|
||||
top_inner_scope_(scope->inner_scope_),
|
||||
top_unresolved_(scope->unresolved_list_.end()),
|
||||
- top_local_(scope->GetClosureScope()->locals_.end()) {
|
||||
- // Reset in order to record eval calls during this Snapshot's lifetime.
|
||||
- outer_scope_and_calls_eval_.GetPointer()->calls_eval_ = false;
|
||||
- outer_scope_and_calls_eval_.GetPointer()->sloppy_eval_can_extend_vars_ =
|
||||
- false;
|
||||
+ top_local_(scope->GetClosureScope()->locals_.end()),
|
||||
+ calls_eval_(outer_scope_->calls_eval_),
|
||||
+ sloppy_eval_can_extend_vars_(
|
||||
+ declaration_scope_->sloppy_eval_can_extend_vars_) {
|
||||
+ // Reset in order to record (sloppy) eval calls during this Snapshot's
|
||||
+ // lifetime.
|
||||
+ outer_scope_->calls_eval_ = false;
|
||||
+ declaration_scope_->sloppy_eval_can_extend_vars_ = false;
|
||||
}
|
||||
|
||||
class ModuleScope final : public DeclarationScope {
|
||||
77
patches/v8/cherry-pick-28b9c1c04e78.patch
Normal file
77
patches/v8/cherry-pick-28b9c1c04e78.patch
Normal file
@@ -0,0 +1,77 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Backes <clemensb@chromium.org>
|
||||
Date: Tue, 13 Dec 2022 22:37:27 +0100
|
||||
Subject: Merged: [arm] Do not emit the constant pool before a branch
|
||||
|
||||
After computing the branch offset but before emitting the actual branch,
|
||||
we should not emit a constant pool. Otherwise the previously computed
|
||||
offset would be off.
|
||||
|
||||
Instead of handling this indirectly via the Assembler::branch_offset
|
||||
method, do this directly in the Assembler::b method (and friends), so it
|
||||
is not missed on other call sites.
|
||||
|
||||
R=nicohartmann@chromium.org
|
||||
|
||||
(cherry picked from commit 9be597d194e108ba718610b9a611fe19a0fbfde5)
|
||||
Bug: chromium:1399424
|
||||
|
||||
Change-Id: Ie30ba70508b4fb8913f79e049a33108608915704
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4118864
|
||||
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Commit-Queue: Clemens Backes <clemensb@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.8@{#48}
|
||||
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
|
||||
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
|
||||
|
||||
diff --git a/src/codegen/arm/assembler-arm.cc b/src/codegen/arm/assembler-arm.cc
|
||||
index 645edb17a4892aec70f0221cec889996a6868242..a95d4df308fd4651093a4911ad1c50226e059ebb 100644
|
||||
--- a/src/codegen/arm/assembler-arm.cc
|
||||
+++ b/src/codegen/arm/assembler-arm.cc
|
||||
@@ -1462,10 +1462,6 @@ int Assembler::branch_offset(Label* L) {
|
||||
L->link_to(pc_offset());
|
||||
}
|
||||
|
||||
- // Block the emission of the constant pool, since the branch instruction must
|
||||
- // be emitted at the pc offset recorded by the label.
|
||||
- if (!is_const_pool_blocked()) BlockConstPoolFor(1);
|
||||
-
|
||||
return target_pos - (pc_offset() + Instruction::kPcLoadDelta);
|
||||
}
|
||||
|
||||
@@ -1476,6 +1472,11 @@ void Assembler::b(int branch_offset, Condition cond, RelocInfo::Mode rmode) {
|
||||
int imm24 = branch_offset >> 2;
|
||||
const bool b_imm_check = is_int24(imm24);
|
||||
CHECK(b_imm_check);
|
||||
+
|
||||
+ // Block the emission of the constant pool before the next instruction.
|
||||
+ // Otherwise the passed-in branch offset would be off.
|
||||
+ BlockConstPoolFor(1);
|
||||
+
|
||||
emit(cond | B27 | B25 | (imm24 & kImm24Mask));
|
||||
|
||||
if (cond == al) {
|
||||
@@ -1490,6 +1491,11 @@ void Assembler::bl(int branch_offset, Condition cond, RelocInfo::Mode rmode) {
|
||||
int imm24 = branch_offset >> 2;
|
||||
const bool bl_imm_check = is_int24(imm24);
|
||||
CHECK(bl_imm_check);
|
||||
+
|
||||
+ // Block the emission of the constant pool before the next instruction.
|
||||
+ // Otherwise the passed-in branch offset would be off.
|
||||
+ BlockConstPoolFor(1);
|
||||
+
|
||||
emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
|
||||
}
|
||||
|
||||
@@ -1499,6 +1505,11 @@ void Assembler::blx(int branch_offset) {
|
||||
int imm24 = branch_offset >> 2;
|
||||
const bool blx_imm_check = is_int24(imm24);
|
||||
CHECK(blx_imm_check);
|
||||
+
|
||||
+ // Block the emission of the constant pool before the next instruction.
|
||||
+ // Otherwise the passed-in branch offset would be off.
|
||||
+ BlockConstPoolFor(1);
|
||||
+
|
||||
emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
|
||||
}
|
||||
|
||||
49
patches/v8/cherry-pick-2ac0620a5bbb.patch
Normal file
49
patches/v8/cherry-pick-2ac0620a5bbb.patch
Normal file
@@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Thibaud Michaud <thibaudm@chromium.org>
|
||||
Date: Wed, 26 Oct 2022 17:03:36 +0200
|
||||
Subject: Merged: [wasm] Reload cached instance fields in catch handler
|
||||
|
||||
Bug: chromium:1377816
|
||||
(cherry picked from commit f517e518af26b7eac23c9e328b463eb1e8ee3499)
|
||||
|
||||
Change-Id: I993bcff0389a1ba134e89e8ac5299d742ddd150c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3999134
|
||||
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
|
||||
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#47}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/wasm/graph-builder-interface.cc b/src/wasm/graph-builder-interface.cc
|
||||
index 5b3256fe6d1c431adf4c10c84dfa9340d4e99754..3d899eded2d744731f2acfadce6f4d55b1417c4d 100644
|
||||
--- a/src/wasm/graph-builder-interface.cc
|
||||
+++ b/src/wasm/graph-builder-interface.cc
|
||||
@@ -91,6 +91,7 @@ class WasmGraphBuildingInterface {
|
||||
struct TryInfo : public ZoneObject {
|
||||
SsaEnv* catch_env;
|
||||
TFNode* exception = nullptr;
|
||||
+ bool first_catch = true;
|
||||
|
||||
bool might_throw() const { return exception != nullptr; }
|
||||
|
||||
@@ -937,6 +938,10 @@ class WasmGraphBuildingInterface {
|
||||
|
||||
TFNode* exception = block->try_info->exception;
|
||||
SetEnv(block->try_info->catch_env);
|
||||
+ if (block->try_info->first_catch) {
|
||||
+ LoadContextIntoSsa(ssa_env_, decoder);
|
||||
+ block->try_info->first_catch = false;
|
||||
+ }
|
||||
|
||||
TFNode* if_catch = nullptr;
|
||||
TFNode* if_no_catch = nullptr;
|
||||
@@ -1014,6 +1019,9 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
SetEnv(block->try_info->catch_env);
|
||||
+ if (block->try_info->first_catch) {
|
||||
+ LoadContextIntoSsa(ssa_env_, decoder);
|
||||
+ }
|
||||
}
|
||||
|
||||
void AtomicOp(FullDecoder* decoder, WasmOpcode opcode,
|
||||
33
patches/v8/cherry-pick-2f6a2939514f.patch
Normal file
33
patches/v8/cherry-pick-2f6a2939514f.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Tebbi <tebbi@chromium.org>
|
||||
Date: Thu, 1 Sep 2022 15:35:33 +0200
|
||||
Subject: Merged: [compiler] fix typing of [[DateValue]]
|
||||
|
||||
Bug: chromium:1356308
|
||||
(cherry picked from commit ae329407989f1e4689baba7a7827863057d688a9)
|
||||
|
||||
Change-Id: I1e132e96325296d180488774ef183daa36dc22c7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3915224
|
||||
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#25}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/compiler/type-cache.h b/src/compiler/type-cache.h
|
||||
index 6442b6f6b0ee39bf1a820168e9dd924e81bc0cb3..a34d094edaa4cb7dd7ac692e4a11d7c890744d7c 100644
|
||||
--- a/src/compiler/type-cache.h
|
||||
+++ b/src/compiler/type-cache.h
|
||||
@@ -131,9 +131,10 @@ class V8_EXPORT_PRIVATE TypeCache final {
|
||||
Type const kStringLengthType = CreateRange(0.0, String::kMaxLength);
|
||||
|
||||
// A time value always contains a tagged number in the range
|
||||
- // [-kMaxTimeInMs, kMaxTimeInMs].
|
||||
- Type const kTimeValueType =
|
||||
- CreateRange(-DateCache::kMaxTimeInMs, DateCache::kMaxTimeInMs);
|
||||
+ // [-kMaxTimeInMs, kMaxTimeInMs] or -0.
|
||||
+ Type const kTimeValueType = Type::Union(
|
||||
+ CreateRange(-DateCache::kMaxTimeInMs, DateCache::kMaxTimeInMs),
|
||||
+ Type::MinusZero(), zone());
|
||||
|
||||
// The JSDate::day property always contains a tagged number in the range
|
||||
// [1, 31] or NaN.
|
||||
111
patches/v8/cherry-pick-80ed4b917477.patch
Normal file
111
patches/v8/cherry-pick-80ed4b917477.patch
Normal file
@@ -0,0 +1,111 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maya Lekova <mslekova@chromium.org>
|
||||
Date: Wed, 2 Nov 2022 11:02:24 +0100
|
||||
Subject: Merged: [compiler] Fix mutable heap number object reference leak
|
||||
|
||||
(cherry picked from commit 64112122374c00a86771b4612d20ca5d88ad5bfb)
|
||||
|
||||
Bug: chromium:1380063
|
||||
No-Try: true
|
||||
No-Presubmit: true
|
||||
No-Tree-Checks: true
|
||||
Change-Id: Ifa1737af7fbc7e14d69a5080cbe0aabf7ef466fa
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4009978
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Commit-Queue: Maya Lekova <mslekova@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#51}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
|
||||
index 5825045052be450516b30e09a2cdf3e55c42c70e..909a6781d60729d7e21d9f8dfe265ff853855ed3 100644
|
||||
--- a/src/compiler/effect-control-linearizer.cc
|
||||
+++ b/src/compiler/effect-control-linearizer.cc
|
||||
@@ -5380,6 +5380,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
||||
|
||||
auto if_double = __ MakeDeferredLabel();
|
||||
auto done = __ MakeLabel(MachineRepresentation::kTagged);
|
||||
+ auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged);
|
||||
+ auto done_double = __ MakeLabel(MachineRepresentation::kFloat64);
|
||||
|
||||
// Check if field is a mutable double field.
|
||||
__ GotoIfNot(__ IntPtrEqual(__ WordAnd(index, one), zero), &if_double);
|
||||
@@ -5396,8 +5398,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
||||
Node* offset =
|
||||
__ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2 - 1)),
|
||||
__ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
|
||||
- Node* result = __ Load(MachineType::AnyTagged(), object, offset);
|
||||
- __ Goto(&done, result);
|
||||
+ Node* field = __ Load(MachineType::AnyTagged(), object, offset);
|
||||
+ __ Goto(&loaded_field, field);
|
||||
}
|
||||
|
||||
// The field is located in the properties backing store of {object}.
|
||||
@@ -5411,8 +5413,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
||||
__ IntPtrConstant(kTaggedSizeLog2 - 1)),
|
||||
__ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) -
|
||||
kHeapObjectTag));
|
||||
- Node* result = __ Load(MachineType::AnyTagged(), properties, offset);
|
||||
- __ Goto(&done, result);
|
||||
+ Node* field = __ Load(MachineType::AnyTagged(), properties, offset);
|
||||
+ __ Goto(&loaded_field, field);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5420,9 +5422,6 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
||||
// architectures, or a mutable HeapNumber.
|
||||
__ Bind(&if_double);
|
||||
{
|
||||
- auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged);
|
||||
- auto done_double = __ MakeLabel(MachineRepresentation::kFloat64);
|
||||
-
|
||||
index = __ WordSar(index, one);
|
||||
|
||||
// Check if field is in-object or out-of-object.
|
||||
@@ -5450,27 +5449,27 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
||||
Node* field = __ Load(MachineType::AnyTagged(), properties, offset);
|
||||
__ Goto(&loaded_field, field);
|
||||
}
|
||||
+ }
|
||||
|
||||
- __ Bind(&loaded_field);
|
||||
- {
|
||||
- Node* field = loaded_field.PhiAt(0);
|
||||
- // We may have transitioned in-place away from double, so check that
|
||||
- // this is a HeapNumber -- otherwise the load is fine and we don't need
|
||||
- // to copy anything anyway.
|
||||
- __ GotoIf(ObjectIsSmi(field), &done, field);
|
||||
- Node* field_map = __ LoadField(AccessBuilder::ForMap(), field);
|
||||
- __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done,
|
||||
- field);
|
||||
-
|
||||
- Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field);
|
||||
- __ Goto(&done_double, value);
|
||||
- }
|
||||
+ __ Bind(&loaded_field);
|
||||
+ {
|
||||
+ Node* field = loaded_field.PhiAt(0);
|
||||
+ // We may have transitioned in-place away from double, so check that
|
||||
+ // this is a HeapNumber -- otherwise the load is fine and we don't need
|
||||
+ // to copy anything anyway.
|
||||
+ __ GotoIf(ObjectIsSmi(field), &done, field);
|
||||
+ Node* field_map = __ LoadField(AccessBuilder::ForMap(), field);
|
||||
+ __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done,
|
||||
+ field);
|
||||
|
||||
- __ Bind(&done_double);
|
||||
- {
|
||||
- Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
|
||||
- __ Goto(&done, result);
|
||||
- }
|
||||
+ Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field);
|
||||
+ __ Goto(&done_double, value);
|
||||
+ }
|
||||
+
|
||||
+ __ Bind(&done_double);
|
||||
+ {
|
||||
+ Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
|
||||
+ __ Goto(&done, result);
|
||||
}
|
||||
|
||||
__ Bind(&done);
|
||||
47
patches/v8/cherry-pick-8b040cb69e96.patch
Normal file
47
patches/v8/cherry-pick-8b040cb69e96.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Date: Fri, 23 Sep 2022 13:13:37 +0200
|
||||
Subject: Fix a register reuse corner case
|
||||
|
||||
Fixed: chromium:1366399
|
||||
(cherry picked from commit 6c214db445827707d65be08d177c9a4257a03a7b)
|
||||
|
||||
Change-Id: I72cf30cbd31a21acb44b524a194acfb89d8fecbc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3925795
|
||||
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#29}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc
|
||||
index 2b269516dd302c06a3eebc1c9d70f4d36612b942..3f768f8f5adcc1bfd1d64e68c638a5bf2e737051 100644
|
||||
--- a/src/wasm/baseline/liftoff-compiler.cc
|
||||
+++ b/src/wasm/baseline/liftoff-compiler.cc
|
||||
@@ -1421,9 +1421,11 @@ class LiftoffCompiler {
|
||||
__ MergeFullStackWith(c->label_state, *__ cache_state());
|
||||
__ emit_jump(c->label.get());
|
||||
}
|
||||
- // Merge the else state into the end state.
|
||||
+ // Merge the else state into the end state. Set this state as the current
|
||||
+ // state first so helper functions know which registers are in use.
|
||||
__ bind(c->else_state->label.get());
|
||||
- __ MergeFullStackWith(c->label_state, c->else_state->state);
|
||||
+ __ cache_state()->Steal(c->else_state->state);
|
||||
+ __ MergeFullStackWith(c->label_state, *__ cache_state());
|
||||
__ cache_state()->Steal(c->label_state);
|
||||
} else if (c->reachable()) {
|
||||
// No merge yet at the end of the if, but we need to create a merge for
|
||||
@@ -1435,9 +1437,11 @@ class LiftoffCompiler {
|
||||
c->stack_depth + c->num_exceptions);
|
||||
__ MergeFullStackWith(c->label_state, *__ cache_state());
|
||||
__ emit_jump(c->label.get());
|
||||
- // Merge the else state into the end state.
|
||||
+ // Merge the else state into the end state. Set this state as the current
|
||||
+ // state first so helper functions know which registers are in use.
|
||||
__ bind(c->else_state->label.get());
|
||||
- __ MergeFullStackWith(c->label_state, c->else_state->state);
|
||||
+ __ cache_state()->Steal(c->else_state->state);
|
||||
+ __ MergeFullStackWith(c->label_state, *__ cache_state());
|
||||
__ cache_state()->Steal(c->label_state);
|
||||
} else {
|
||||
// No merge needed, just continue with the else state.
|
||||
122
patches/v8/cherry-pick-c79148742421.patch
Normal file
122
patches/v8/cherry-pick-c79148742421.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Fri, 28 Oct 2022 10:21:27 -0700
|
||||
Subject: Merged: Reland "[Promise.any] Fix errors allocation"
|
||||
|
||||
Bug: chromium:1379054
|
||||
|
||||
(cherry picked from commit 8b35091b2d244c975975e1c78e4cd09cb479b5dc)
|
||||
|
||||
Change-Id: Iec8f8bb51f4434d6ae86887cf742f2883a9b7bef
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4004804
|
||||
Reviewed-by: Adam Klein <adamk@chromium.org>
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.8@{#34}
|
||||
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
|
||||
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
|
||||
|
||||
diff --git a/include/v8-version.h b/include/v8-version.h
|
||||
index 7baa3bf9b725652ddaac1a3d39dd96a3520b9f26..fb1097518be399c6665d53c2be79ec81a210de71 100644
|
||||
--- a/include/v8-version.h
|
||||
+++ b/include/v8-version.h
|
||||
@@ -11,7 +11,7 @@
|
||||
#define V8_MAJOR_VERSION 10
|
||||
#define V8_MINOR_VERSION 4
|
||||
#define V8_BUILD_NUMBER 132
|
||||
-#define V8_PATCH_LEVEL 24
|
||||
+#define V8_PATCH_LEVEL 25
|
||||
|
||||
// Use 1 for candidates and 0 otherwise.
|
||||
// (Boolean macro values are not supported by all preprocessors.)
|
||||
diff --git a/src/builtins/promise-any.tq b/src/builtins/promise-any.tq
|
||||
index ffb285a06a83557d8657aef6c04acc5c65513a62..7e707e649f11bc946a6d1173180d7293fe94d8ce 100644
|
||||
--- a/src/builtins/promise-any.tq
|
||||
+++ b/src/builtins/promise-any.tq
|
||||
@@ -119,7 +119,19 @@ PromiseAnyRejectElementClosure(
|
||||
kPromiseAnyRejectElementRemainingSlot);
|
||||
|
||||
// 9. Set errors[index] to x.
|
||||
- const newCapacity = IntPtrMax(SmiUntag(remainingElementsCount), index + 1);
|
||||
+
|
||||
+ // The max computation below is an optimization to avoid excessive allocations
|
||||
+ // in the case of input promises being asynchronously rejected in ascending
|
||||
+ // index order.
|
||||
+ //
|
||||
+ // Note that subtracting 1 from remainingElementsCount is intentional. The
|
||||
+ // value of remainingElementsCount is 1 larger than the actual value during
|
||||
+ // iteration. So in the case of synchronous rejection, newCapacity is the
|
||||
+ // correct size by subtracting 1. In the case of asynchronous rejection this
|
||||
+ // is 1 smaller than the correct size, but is not incorrect as it is maxed
|
||||
+ // with index + 1.
|
||||
+ const newCapacity =
|
||||
+ IntPtrMax(SmiUntag(remainingElementsCount) - 1, index + 1);
|
||||
if (newCapacity > errors.length_intptr) deferred {
|
||||
errors = ExtractFixedArray(errors, 0, errors.length_intptr, newCapacity);
|
||||
*ContextSlot(
|
||||
@@ -306,6 +318,7 @@ Reject(JSAny) {
|
||||
PromiseAnyRejectElementContextSlots::
|
||||
kPromiseAnyRejectElementErrorsSlot);
|
||||
|
||||
+ check(errors.length == index - 1);
|
||||
const error = ConstructAggregateError(errors);
|
||||
// 3. Return ThrowCompletion(error).
|
||||
goto Reject(error);
|
||||
diff --git a/tools/v8heapconst.py b/tools/v8heapconst.py
|
||||
index 993785ec032917ba4004bc96366e55230dd60dbb..578388b5bb44672b000b95cdc89f573cbda72a00 100644
|
||||
--- a/tools/v8heapconst.py
|
||||
+++ b/tools/v8heapconst.py
|
||||
@@ -537,30 +537,30 @@ KNOWN_OBJECTS = {
|
||||
("old_space", 0x04b35): "StringSplitCache",
|
||||
("old_space", 0x04f3d): "RegExpMultipleCache",
|
||||
("old_space", 0x05345): "BuiltinsConstantsTable",
|
||||
- ("old_space", 0x05781): "AsyncFunctionAwaitRejectSharedFun",
|
||||
- ("old_space", 0x057a5): "AsyncFunctionAwaitResolveSharedFun",
|
||||
- ("old_space", 0x057c9): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
- ("old_space", 0x057ed): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
- ("old_space", 0x05811): "AsyncGeneratorYieldResolveSharedFun",
|
||||
- ("old_space", 0x05835): "AsyncGeneratorReturnResolveSharedFun",
|
||||
- ("old_space", 0x05859): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
- ("old_space", 0x0587d): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
- ("old_space", 0x058a1): "AsyncIteratorValueUnwrapSharedFun",
|
||||
- ("old_space", 0x058c5): "PromiseAllResolveElementSharedFun",
|
||||
- ("old_space", 0x058e9): "PromiseAllSettledResolveElementSharedFun",
|
||||
- ("old_space", 0x0590d): "PromiseAllSettledRejectElementSharedFun",
|
||||
- ("old_space", 0x05931): "PromiseAnyRejectElementSharedFun",
|
||||
- ("old_space", 0x05955): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
- ("old_space", 0x05979): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
- ("old_space", 0x0599d): "PromiseCatchFinallySharedFun",
|
||||
- ("old_space", 0x059c1): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
- ("old_space", 0x059e5): "PromiseThenFinallySharedFun",
|
||||
- ("old_space", 0x05a09): "PromiseThrowerFinallySharedFun",
|
||||
- ("old_space", 0x05a2d): "PromiseValueThunkFinallySharedFun",
|
||||
- ("old_space", 0x05a51): "ProxyRevokeSharedFun",
|
||||
- ("old_space", 0x05a75): "ShadowRealmImportValueFulfilledSFI",
|
||||
- ("old_space", 0x05a99): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
|
||||
- ("old_space", 0x05abd): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
|
||||
+ ("old_space", 0x05785): "AsyncFunctionAwaitRejectSharedFun",
|
||||
+ ("old_space", 0x057a9): "AsyncFunctionAwaitResolveSharedFun",
|
||||
+ ("old_space", 0x057cd): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
+ ("old_space", 0x057f1): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
+ ("old_space", 0x05815): "AsyncGeneratorYieldResolveSharedFun",
|
||||
+ ("old_space", 0x05839): "AsyncGeneratorReturnResolveSharedFun",
|
||||
+ ("old_space", 0x0585d): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
+ ("old_space", 0x05881): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
+ ("old_space", 0x058a5): "AsyncIteratorValueUnwrapSharedFun",
|
||||
+ ("old_space", 0x058c9): "PromiseAllResolveElementSharedFun",
|
||||
+ ("old_space", 0x058ed): "PromiseAllSettledResolveElementSharedFun",
|
||||
+ ("old_space", 0x05911): "PromiseAllSettledRejectElementSharedFun",
|
||||
+ ("old_space", 0x05935): "PromiseAnyRejectElementSharedFun",
|
||||
+ ("old_space", 0x05959): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
+ ("old_space", 0x0597d): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
+ ("old_space", 0x059a1): "PromiseCatchFinallySharedFun",
|
||||
+ ("old_space", 0x059c5): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
+ ("old_space", 0x059e9): "PromiseThenFinallySharedFun",
|
||||
+ ("old_space", 0x05a0d): "PromiseThrowerFinallySharedFun",
|
||||
+ ("old_space", 0x05a31): "PromiseValueThunkFinallySharedFun",
|
||||
+ ("old_space", 0x05a55): "ProxyRevokeSharedFun",
|
||||
+ ("old_space", 0x05a79): "ShadowRealmImportValueFulfilledSFI",
|
||||
+ ("old_space", 0x05a9d): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
|
||||
+ ("old_space", 0x05ac1): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
|
||||
}
|
||||
|
||||
# Lower 32 bits of first page addresses for various heap spaces.
|
||||
39
patches/v8/cherry-pick-ec236fef54b8.patch
Normal file
39
patches/v8/cherry-pick-ec236fef54b8.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Tebbi <tebbi@chromium.org>
|
||||
Date: Wed, 26 Oct 2022 11:19:59 +0200
|
||||
Subject: Merged: [turbofan] do not optimize any stores for field type None
|
||||
|
||||
Fixed: chromium:1378239
|
||||
(cherry picked from commit db83e72034c0d431ff2f73e3c4ae3130c0f3e4e1)
|
||||
|
||||
Change-Id: I061d5dfe6e4ee24e6d0e7df56e15fbe37752d51e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3982254
|
||||
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.6@{#45}
|
||||
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
|
||||
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
|
||||
|
||||
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
|
||||
index 307bf44cf42381ec820221806fbbc5705d71de3c..237734929f3e71e05312981506bb0735631b9451 100644
|
||||
--- a/src/compiler/access-info.cc
|
||||
+++ b/src/compiler/access-info.cc
|
||||
@@ -454,9 +454,15 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
|
||||
map, descriptor, details_representation));
|
||||
} else if (details_representation.IsHeapObject()) {
|
||||
if (descriptors_field_type->IsNone()) {
|
||||
- // Store is not safe if the field type was cleared.
|
||||
- if (access_mode == AccessMode::kStore) {
|
||||
- return Invalid();
|
||||
+ switch (access_mode) {
|
||||
+ case AccessMode::kStore:
|
||||
+ case AccessMode::kStoreInLiteral:
|
||||
+ case AccessMode::kDefine:
|
||||
+ // Store is not safe if the field type was cleared.
|
||||
+ return Invalid();
|
||||
+ case AccessMode::kLoad:
|
||||
+ case AccessMode::kHas:
|
||||
+ break;
|
||||
}
|
||||
|
||||
// The field type was cleared by the GC, so we don't know anything
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user