mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19e35495ee | ||
|
|
cfac858d65 | ||
|
|
545fd1c287 | ||
|
|
c73577ca99 | ||
|
|
82ff0acb11 | ||
|
|
5d530d31f4 | ||
|
|
e9b5cd7d2e | ||
|
|
61af436d78 | ||
|
|
d1e9dfdb75 | ||
|
|
54c11f7b10 | ||
|
|
5698beef8f | ||
|
|
846d6570ee | ||
|
|
023b4bb51f | ||
|
|
bd78e092d4 | ||
|
|
fa77a9da46 | ||
|
|
067c4c4dc6 | ||
|
|
8a150a2a3f | ||
|
|
fdf96debe1 | ||
|
|
ed8c8334f4 | ||
|
|
570c146fe3 | ||
|
|
5828a25dc6 | ||
|
|
88146b4140 | ||
|
|
a0701fd622 | ||
|
|
44e0345320 | ||
|
|
d77c0f2e23 | ||
|
|
86af860c29 | ||
|
|
4615e4afda | ||
|
|
4c2f91198b | ||
|
|
ef73a91f02 | ||
|
|
0d7537772d | ||
|
|
c9e67c38b7 | ||
|
|
5abed6e890 | ||
|
|
5f37729c17 | ||
|
|
f6e9ab2234 | ||
|
|
5312995148 | ||
|
|
c9590a7c3a | ||
|
|
6ea76082de | ||
|
|
6b571240ad | ||
|
|
ba93dc3c83 | ||
|
|
039a1852a2 | ||
|
|
12df0267eb | ||
|
|
f1500363dc | ||
|
|
4435461885 | ||
|
|
dcdfe231fc | ||
|
|
bc2c39e668 | ||
|
|
95d1cf0670 | ||
|
|
423cdb02a7 | ||
|
|
cc8d02db5d | ||
|
|
3afea231ca | ||
|
|
49b624ef1f | ||
|
|
d8a1298eaf | ||
|
|
3026615784 | ||
|
|
23a81e6e59 | ||
|
|
801cbe2ab3 | ||
|
|
e857073d65 | ||
|
|
86a1ee1e89 | ||
|
|
2212933858 | ||
|
|
c5346bde08 | ||
|
|
c678f7b872 | ||
|
|
3aac61e60c | ||
|
|
e91dba1730 |
@@ -568,6 +568,13 @@ step-electron-build: &step-electron-build
|
||||
ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
ninja -C out/Default tools/v8_context_snapshot -j $NUMBER_OF_NINJA_PROCESSES
|
||||
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
SEDOPTION=
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
SEDOPTION="-i ''"
|
||||
fi
|
||||
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
|
||||
(cd out/Default; zip mksnapshot.zip mksnapshot_args clang_x64_v8_arm64/gen/v8/embedded.S)
|
||||
rm -rf out/Default/clang_x64_v8_arm64/gen
|
||||
rm -rf out/Default/clang_x64_v8_arm64/obj
|
||||
@@ -758,6 +765,13 @@ step-mksnapshot-build: &step-mksnapshot-build
|
||||
if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" != "1" ]; then
|
||||
ninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
|
||||
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
SEDOPTION=
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
SEDOPTION="-i ''"
|
||||
fi
|
||||
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
|
||||
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
|
||||
fi
|
||||
if [ "`uname`" != "Darwin" ]; then
|
||||
if [ "$TARGET_ARCH" == "arm" ]; then
|
||||
@@ -873,12 +887,12 @@ step-touch-sync-done: &step-touch-sync-done
|
||||
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v15-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:
|
||||
- v15-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
|
||||
@@ -893,14 +907,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
|
||||
@@ -918,13 +924,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
|
||||
@@ -955,13 +954,15 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
|
||||
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: v15-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:
|
||||
@@ -971,7 +972,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
|
||||
save_cache:
|
||||
paths:
|
||||
- .src-cache-marker
|
||||
key: v15-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:
|
||||
@@ -1303,9 +1304,6 @@ commands:
|
||||
build:
|
||||
type: boolean
|
||||
default: true
|
||||
use-out-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
restore-src-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
@@ -1428,10 +1426,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
|
||||
@@ -1474,22 +1468,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
|
||||
|
||||
@@ -1643,7 +1621,6 @@ jobs:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-x64-testing-asan:
|
||||
executor:
|
||||
@@ -1660,7 +1637,6 @@ jobs:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
build-nonproprietary-ffmpeg: false
|
||||
|
||||
linux-x64-testing-no-run-as-node:
|
||||
@@ -1677,7 +1653,6 @@ jobs:
|
||||
- electron-build:
|
||||
persist: false
|
||||
checkout: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-x64-testing-gn-check:
|
||||
executor:
|
||||
@@ -1728,7 +1703,6 @@ jobs:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-arm-publish:
|
||||
executor:
|
||||
@@ -1771,7 +1745,6 @@ jobs:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
use-out-cache: false
|
||||
|
||||
linux-arm64-testing-gn-check:
|
||||
executor:
|
||||
@@ -2235,3 +2208,5 @@ workflows:
|
||||
lint:
|
||||
jobs:
|
||||
- lint
|
||||
|
||||
# VS Code Extension Version: 1.1.1
|
||||
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 }}.
|
||||
2
BUILD.gn
2
BUILD.gn
@@ -655,6 +655,8 @@ source_set("electron_lib") {
|
||||
if (enable_plugins) {
|
||||
deps += [ "chromium_src:plugins" ]
|
||||
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",
|
||||
]
|
||||
|
||||
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'106.0.5249.165',
|
||||
'106.0.5249.199',
|
||||
'node_version':
|
||||
'v16.16.0',
|
||||
'nan_version':
|
||||
|
||||
@@ -12,7 +12,7 @@ using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) an
|
||||
[Chromium](https://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
|
||||
|
||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||
Follow [@electronjs](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
|
||||
This project adheres to the Contributor Covenant
|
||||
|
||||
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'))
|
||||
282
appveyor-woa.yml
Normal file
282
appveyor-woa.yml
Normal file
@@ -0,0 +1,282 @@
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
init:
|
||||
- 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
|
||||
}
|
||||
|
||||
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
|
||||
- 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 {
|
||||
# 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 )
|
||||
372
appveyor.yml
372
appveyor.yml
@@ -1,3 +1,7 @@
|
||||
# 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,
|
||||
@@ -24,23 +28,24 @@
|
||||
# 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-106.0.5249.199
|
||||
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
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
matrix:
|
||||
|
||||
- job_name: Build
|
||||
|
||||
- job_name: Test
|
||||
job_depends_on: Build
|
||||
- job_name: Build
|
||||
- job_name: Test
|
||||
job_depends_on: Build
|
||||
|
||||
clone_folder: C:\projects\src\electron
|
||||
|
||||
@@ -50,164 +55,123 @@ matrix:
|
||||
|
||||
for:
|
||||
|
||||
-
|
||||
matrix:
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Build
|
||||
|
||||
init:
|
||||
- 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
|
||||
}
|
||||
|
||||
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 tests for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
$global:LASTEXITCODE = 0
|
||||
- cd ..
|
||||
- ps: Write-Host "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- update_depot_tools.bat
|
||||
- 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: |
|
||||
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
|
||||
}
|
||||
}
|
||||
- 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=14 -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"
|
||||
}
|
||||
$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
|
||||
- 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 {
|
||||
# update angle
|
||||
cd src\third_party\angle
|
||||
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
|
||||
git fetch
|
||||
cd ..\..\..
|
||||
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
|
||||
$host.SetShouldExit(1)
|
||||
}
|
||||
} else {
|
||||
# file does not exist, gclient sync, then zip
|
||||
}
|
||||
- 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 ($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\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"
|
||||
- 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
|
||||
}
|
||||
# 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"
|
||||
- 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
|
||||
}
|
||||
# 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
|
||||
- 7z a builtins-pgo.zip v8\tools\builtins-pgo
|
||||
- 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
|
||||
|
||||
- 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: >-
|
||||
@@ -219,12 +183,10 @@ for:
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python3 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'))
|
||||
# - 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)
|
||||
@@ -235,62 +197,55 @@ for:
|
||||
- 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)
|
||||
- if exist builtins-pgo.zip (appveyor-retry appveyor PushArtifact builtins-pgo.zip)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
|
||||
-
|
||||
matrix:
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
if ($env:RUN_TESTS -ne 'true') {
|
||||
Write-warning "Skipping tests for $env:APPVEYOR_PROJECT_NAME"; Exit-AppveyorBuild
|
||||
}
|
||||
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
|
||||
}
|
||||
- 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 tests for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
$global:LASTEXITCODE = 0
|
||||
- ps: |
|
||||
cd ..
|
||||
mkdir out\Default
|
||||
cd ..
|
||||
# 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','builtins-pgo.zip')
|
||||
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
|
||||
- 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
|
||||
}
|
||||
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
|
||||
- ps: 7z x -y -osrc builtins-pgo.zip
|
||||
- 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
|
||||
@@ -300,15 +255,22 @@ for:
|
||||
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 & python3 electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
- 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 & python3 electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
|
||||
- echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
|
||||
- echo "Done verifying mksnapshot"
|
||||
- echo Verifying chromedriver & python3 electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd%
|
||||
- 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 )
|
||||
@@ -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():
|
||||
|
||||
@@ -717,6 +717,8 @@ To set the locale, you'll want to use a command line switch at app startup, whic
|
||||
|
||||
**Note:** This API must be called after the `ready` event is emitted.
|
||||
|
||||
**Note:** To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
|
||||
|
||||
### `app.getLocaleCountryCode()`
|
||||
|
||||
Returns `string` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs.
|
||||
@@ -725,10 +727,42 @@ Returns `string` - User operating system's locale two-letter [ISO 3166](https://
|
||||
|
||||
### `app.getSystemLocale()`
|
||||
|
||||
Returns `string` - The current system locale. On Windows and Linux, it is fetched using Chromium's `i18n` library. On macOS, the `NSLocale` object is used instead.
|
||||
Returns `string` - The current system locale. On Windows and Linux, it is fetched using Chromium's `i18n` library. On macOS, `[NSLocale currentLocale]` is used instead. To get the user's current system language, which is not always the same as the locale, it is better to use [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
|
||||
|
||||
Different operating systems also use the regional data differently:
|
||||
|
||||
* Windows 11 uses the regional format for numbers, dates, and times.
|
||||
* macOS Monterey uses the region for formatting numbers, dates, times, and for selecting the currency symbol to use.
|
||||
|
||||
Therefore, this API can be used for purposes such as choosing a format for rendering dates and times in a calendar app, especially when the developer wants the format to be consistent with the OS.
|
||||
|
||||
**Note:** This API must be called after the `ready` event is emitted.
|
||||
|
||||
**Note:** To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
|
||||
|
||||
### `app.getPreferredSystemLanguages()`
|
||||
|
||||
Returns `string[]` - The user's preferred system languages from most preferred to least preferred, including the country codes if applicable. A user can modify and add to this list on Windows or macOS through the Language and Region settings.
|
||||
|
||||
The API uses `GlobalizationPreferences` (with a fallback to `GetSystemPreferredUILanguages`) on Windows, `\[NSLocale preferredLanguages\]` on macOS, and `g_get_language_names` on Linux.
|
||||
|
||||
This API can be used for purposes such as deciding what language to present the application in.
|
||||
|
||||
Here are some examples of return values of the various language and locale APIs with different configurations:
|
||||
|
||||
* For Windows, where the application locale is German, the regional format is Finnish (Finland), and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish (Latin America):
|
||||
* `app.getLocale()` returns `'de'`
|
||||
* `app.getSystemLocale()` returns `'fi-FI'`
|
||||
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-CN', 'fi', 'es-419']`
|
||||
* On macOS, where the application locale is German, the region is Finland, and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese, and Spanish (Latin America):
|
||||
* `app.getLocale()` returns `'de'`
|
||||
* `app.getSystemLocale()` returns `'fr-FI'`
|
||||
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']`
|
||||
|
||||
Both the available languages and regions and the possible return values differ between the two operating systems.
|
||||
|
||||
As can be seen with the example above, on Windows, it is possible that a preferred system language has no country code, and that one of the preferred system languages corresponds with the language used for the regional format. On macOS, the region serves more as a default country code: the user doesn't need to have Finnish as a preferred language to use Finland as the region,and the country code `FI` is used as the country code for preferred system languages that do not have associated countries in the language name.
|
||||
|
||||
### `app.addRecentDocument(path)` _macOS_ _Windows_
|
||||
|
||||
* `path` string
|
||||
@@ -1203,7 +1237,7 @@ For `infoType` equal to `basic`:
|
||||
}
|
||||
```
|
||||
|
||||
Using `basic` should be preferred if only basic information like `vendorId` or `driverId` is needed.
|
||||
Using `basic` should be preferred if only basic information like `vendorId` or `deviceId` is needed.
|
||||
|
||||
### `app.setBadgeCount([count])` _Linux_ _macOS_
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ work). Extensions are installed per-`session`. To load an extension, call
|
||||
```js
|
||||
const { session } = require('electron')
|
||||
|
||||
session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
|
||||
session.defaultSession.loadExtension('path/to/unpacked/extension').then(({ id }) => {
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
@@ -638,6 +638,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `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.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# WebRequestFilter Object
|
||||
|
||||
* `urls` string[] - Array of URL patterns that will be used to filter out the requests that do not match the URL patterns.
|
||||
* `urls` string[] - Array of [URL patterns](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns) that will be used to filter out the requests that do not match the URL patterns.
|
||||
|
||||
@@ -1180,7 +1180,7 @@ Ignore application menu shortcuts while this web contents is focused.
|
||||
|
||||
#### `contents.setWindowOpenHandler(handler)`
|
||||
|
||||
* `handler` Function<{action: 'deny'} | {action: 'allow', overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}>
|
||||
* `handler` Function<{action: 'deny'} | {action: 'allow', outlivesOpener?: boolean, overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}>
|
||||
* `details` Object
|
||||
* `url` string - The _resolved_ version of the URL passed to `window.open()`. e.g. opening a window with `window.open('foo')` will yield something like `https://the-origin/the/current/path/foo`.
|
||||
* `frameName` string - Name of the window provided in `window.open()`
|
||||
@@ -1195,8 +1195,11 @@ Ignore application menu shortcuts while this web contents is focused.
|
||||
be set. If no post data is to be sent, the value will be `null`. Only defined
|
||||
when the window is being created by a form that set `target=_blank`.
|
||||
|
||||
Returns `{action: 'deny'} | {action: 'allow', overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}` - `deny` cancels the creation of the new
|
||||
Returns `{action: 'deny'} | {action: 'allow', outlivesOpener?: boolean, overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}` - `deny` cancels the creation of the new
|
||||
window. `allow` will allow the new window to be created. Specifying `overrideBrowserWindowOptions` allows customization of the created window.
|
||||
By default, child windows are closed when their opener is closed. This can be
|
||||
changed by specifying `outlivesOpener: true`, in which case the opened window
|
||||
will not be closed when its opener is closed.
|
||||
Returning an unrecognized value such as a null, undefined, or an object
|
||||
without a recognized 'action' value will result in a console error and have
|
||||
the same effect as returning `{action: 'deny'}`.
|
||||
|
||||
@@ -100,7 +100,7 @@ requires unsafe mode), so Electron is unable to support this feature on Linux.
|
||||
|
||||
The handler invoked when `session.setDevicePermissionHandler(handler)` is used
|
||||
has a change to its arguments. This handler no longer is passed a frame
|
||||
`[WebFrameMain](api/web-frame-main.md)`, but instead is passed the `origin`, which
|
||||
[`WebFrameMain`](api/web-frame-main.md), but instead is passed the `origin`, which
|
||||
is the origin that is checking for device permission.
|
||||
|
||||
## Planned Breaking API Changes (19.0)
|
||||
|
||||
@@ -52,15 +52,17 @@ ways to get your application signed and notarized.
|
||||
If you're using Electron's favorite build tool, getting your application signed
|
||||
and notarized requires a few additions to your configuration. [Forge](https://electronforge.io) is a
|
||||
collection of the official Electron tools, using [`electron-packager`],
|
||||
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
|
||||
[`@electron/osx-sign`], and [`@electron/notarize`] under the hood.
|
||||
|
||||
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).
|
||||
Detailed instructions on how to configure your application can be found in the
|
||||
[Signing macOS Apps](https://www.electronforge.io/guides/code-signing/code-signing-macos) guide in
|
||||
the Electron Forge docs.
|
||||
|
||||
### Using Electron Packager
|
||||
|
||||
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`].
|
||||
are likely using [`electron-packager`], which includes [`@electron/osx-sign`] and
|
||||
[`@electron/notarize`].
|
||||
|
||||
If you're using Packager's API, you can pass [in configuration that both signs
|
||||
and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html).
|
||||
@@ -70,13 +72,7 @@ const packager = require('electron-packager')
|
||||
|
||||
packager({
|
||||
dir: '/path/to/my/app',
|
||||
osxSign: {
|
||||
identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
|
||||
'hardened-runtime': true,
|
||||
entitlements: 'entitlements.plist',
|
||||
'entitlements-inherit': 'entitlements.plist',
|
||||
'signature-flags': 'library'
|
||||
},
|
||||
osxSign: {},
|
||||
osxNotarize: {
|
||||
appleId: 'felix@felix.fun',
|
||||
appleIdPassword: 'my-apple-id-password'
|
||||
@@ -84,26 +80,6 @@ packager({
|
||||
})
|
||||
```
|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### Signing Mac App Store applications
|
||||
|
||||
See the [Mac App Store Guide].
|
||||
@@ -213,15 +189,14 @@ can find [its documentation here](https://www.electron.build/code-signing).
|
||||
See the [Windows Store Guide].
|
||||
|
||||
[apple developer program]: https://developer.apple.com/programs/
|
||||
[`electron-builder`]: https://github.com/electron-userland/electron-builder
|
||||
[`electron-forge`]: https://github.com/electron-userland/electron-forge
|
||||
[`electron-osx-sign`]: https://github.com/electron-userland/electron-osx-sign
|
||||
[`electron-forge`]: https://github.com/electron/forge
|
||||
[`@electron/osx-sign`]: https://github.com/electron/osx-sign
|
||||
[`electron-packager`]: https://github.com/electron/electron-packager
|
||||
[`electron-notarize`]: https://github.com/electron/electron-notarize
|
||||
[`@electron/notarize`]: https://github.com/electron/notarize
|
||||
[`electron-winstaller`]: https://github.com/electron/windows-installer
|
||||
[`electron-wix-msi`]: https://github.com/felixrieseberg/electron-wix-msi
|
||||
[`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi
|
||||
[xcode]: https://developer.apple.com/xcode
|
||||
[signing certificates]: https://github.com/electron/electron-osx-sign/wiki/1.-Getting-Started#certificates
|
||||
[signing certificates]: https://developer.apple.com/support/certificates/
|
||||
[mac app store guide]: ./mac-app-store-submission-guide.md
|
||||
[windows store guide]: ./windows-store-guide.md
|
||||
[maker-squirrel]: https://www.electronforge.io/config/makers/squirrel.windows
|
||||
|
||||
@@ -7,28 +7,29 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
## Timeline
|
||||
|
||||
| Electron | Alpha | Beta | Stable | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- |
|
||||
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | M61 | v8.9 | 🚫 |
|
||||
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 | 🚫 |
|
||||
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 | 🚫 |
|
||||
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 | 🚫 |
|
||||
| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 | 🚫 |
|
||||
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 | 🚫 |
|
||||
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 | 🚫 |
|
||||
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 | 🚫 |
|
||||
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 | 🚫 |
|
||||
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 | 🚫 |
|
||||
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | 🚫 |
|
||||
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | 🚫 |
|
||||
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
|
||||
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
|
||||
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 |
|
||||
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 |
|
||||
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | ✅ |
|
||||
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | ✅ |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | ✅ |
|
||||
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | TBD | ✅ |
|
||||
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
|
||||
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | TBD | M108 | TBD | ✅ |
|
||||
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | TBD | M106 | v16.17 | ✅ |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | TBD | M104 | v16.15 | ✅ |
|
||||
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | TBD | M102 | v16.14 | ✅ |
|
||||
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | 2022-Sep-27 | M100 | v16.13 | 🚫 |
|
||||
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | 2022-Aug-02 | M98 | v16.13 | 🚫 |
|
||||
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | 2022-May-24 | M96 | v16.9 | 🚫 |
|
||||
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | 2022-May-24 | M94 | v16.5 | 🚫 |
|
||||
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | 2022-Mar-29 | M93 | v14.17 | 🚫 |
|
||||
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | 2022-Feb-01 | M91 | v14.16 | 🚫 |
|
||||
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | 2021-Nov-16 | M89 | v14.16 | 🚫 |
|
||||
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | 2021-Aug-31 | M87 | v12.18 | 🚫 |
|
||||
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | 2021-May-25 | M85 | v12.16 | 🚫 |
|
||||
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | 2021-Mar-02 | M83 | v12.14 | 🚫 |
|
||||
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | 2020-Nov-17 | M80 | v12.13 | 🚫 |
|
||||
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | 2020-Aug-25 | M78 | v12.8 | 🚫 |
|
||||
| 6.0.0 | -- | 2019-Apr-25 | 2019-Jul-30 | 2020-May-19 | M76 | v12.14.0 | 🚫 |
|
||||
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-23 | 2020-Feb-04 | M73 | v12.0 | 🚫 |
|
||||
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | 2019-Oct-22 | M69 | v10.11 | 🚫 |
|
||||
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | 2019-Jul-30 | M66 | v10.2 | 🚫 |
|
||||
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | 2019-Apr-23 | M61 | v8.9 | 🚫 |
|
||||
|
||||
**Notes:**
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ This guide provides information on:
|
||||
To sign Electron apps, the following tools must be installed first:
|
||||
|
||||
* Xcode 11 or above.
|
||||
* The [electron-osx-sign][electron-osx-sign] npm module.
|
||||
* The [@electron/osx-sign] npm module.
|
||||
|
||||
You also have to register an Apple Developer account and join the
|
||||
[Apple Developer Program][developer-program].
|
||||
@@ -103,7 +103,7 @@ Apps submitted to the Mac App Store must run under Apple's
|
||||
the App Sandbox. The standard darwin build of Electron will fail to launch
|
||||
when run under App Sandbox.
|
||||
|
||||
When signing the app with `electron-osx-sign`, it will automatically add the
|
||||
When signing the app with `@electron/osx-sign`, it will automatically add the
|
||||
necessary entitlements to your app's entitlements, but if you are using custom
|
||||
entitlements, you must ensure App Sandbox capacity is added:
|
||||
|
||||
@@ -120,7 +120,7 @@ entitlements, you must ensure App Sandbox capacity is added:
|
||||
|
||||
#### Extra steps without `electron-osx-sign`
|
||||
|
||||
If you are signing your app without using `electron-osx-sign`, you must ensure
|
||||
If you are signing your app without using `@electron/osx-sign`, you must ensure
|
||||
the app bundle's entitlements have at least following keys:
|
||||
|
||||
```xml
|
||||
@@ -170,22 +170,22 @@ your Apple Developer account's Team ID as its value:
|
||||
</plist>
|
||||
```
|
||||
|
||||
When using `electron-osx-sign` the `ElectronTeamID` key will be added
|
||||
When using `@electron/osx-sign` the `ElectronTeamID` key will be added
|
||||
automatically by extracting the Team ID from the certificate's name. You may
|
||||
need to manually add this key if `electron-osx-sign` could not find the correct
|
||||
need to manually add this key if `@electron/osx-sign` could not find the correct
|
||||
Team ID.
|
||||
|
||||
### Sign apps for development
|
||||
|
||||
To sign an app that can run on your development machine, you must sign it with
|
||||
the "Apple Development" certificate and pass the provisioning profile to
|
||||
`electron-osx-sign`.
|
||||
`@electron/osx-sign`.
|
||||
|
||||
```bash
|
||||
electron-osx-sign YourApp.app --identity='Apple Development' --provisioning-profile=/path/to/yourapp.provisionprofile
|
||||
```
|
||||
|
||||
If you are signing without `electron-osx-sign`, you must place the provisioning
|
||||
If you are signing without `@electron/osx-sign`, you must place the provisioning
|
||||
profile to `YourApp.app/Contents/embedded.provisionprofile`.
|
||||
|
||||
The signed app can only run on the machines that registered by the provisioning
|
||||
@@ -213,7 +213,7 @@ use App Sandbox.
|
||||
electron-osx-sign YourApp.app --identity='Developer ID Application' --no-gatekeeper-assess
|
||||
```
|
||||
|
||||
By passing `--no-gatekeeper-assess`, the `electron-osx-sign` will skip the macOS
|
||||
By passing `--no-gatekeeper-assess`, `@electron/osx-sign` will skip the macOS
|
||||
GateKeeper check as your app usually has not been notarized yet by this step.
|
||||
|
||||
<!-- TODO(zcbenz): Add a chapter about App Notarization -->
|
||||
@@ -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.
|
||||
|
||||
@@ -341,11 +341,12 @@ Electron uses following cryptographic algorithms:
|
||||
* RIPEMD - [ISO/IEC 10118-3](https://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004)
|
||||
|
||||
[developer-program]: https://developer.apple.com/support/compare-memberships/
|
||||
[electron-osx-sign]: https://github.com/electron/electron-osx-sign
|
||||
[@electron/osx-sign]: https://github.com/electron/electron-osx-sign
|
||||
[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
|
||||
|
||||
@@ -26,6 +26,15 @@ work on Windows, macOS, and Linux with a single JavaScript codebase.
|
||||
This tutorial will guide you through the process of developing a desktop
|
||||
application with Electron and distributing it to end users.
|
||||
|
||||
## Goals
|
||||
|
||||
This tutorial starts by guiding you through the process of piecing together
|
||||
a minimal Electron application from scratch, then teaches you how to
|
||||
package and distribute it to users using Electron Forge.
|
||||
|
||||
If you prefer to get a project started with a single-command boilerplate, we recommend you start
|
||||
with Electron Forge's [`create-electron-app`](https://www.electronforge.io/) command.
|
||||
|
||||
## Assumptions
|
||||
|
||||
Electron is a native wrapper layer for web apps and is run in a Node.js environment.
|
||||
|
||||
@@ -70,10 +70,9 @@ the [Electron Forge CLI documentation].
|
||||
:::
|
||||
|
||||
You should also notice that your package.json now has a few more packages installed
|
||||
under your `devDependencies`, and contains an added `config.forge` field with an array
|
||||
of makers configured. **Makers** are Forge plugins that create distributables from
|
||||
your source code. You should see multiple makers in the pre-populated configuration,
|
||||
one for each target platform.
|
||||
under `devDependencies`, and a new `forge.config.js` file that exports a configuration
|
||||
object. You should see multiple makers (packages that generate distributable app bundles) in the
|
||||
pre-populated configuration, one for each target platform.
|
||||
|
||||
### Creating a distributable
|
||||
|
||||
@@ -111,13 +110,14 @@ Electron Forge can be configured to create distributables in different OS-specif
|
||||
|
||||
:::
|
||||
|
||||
:::tip Creating and Adding Application Icons
|
||||
:::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.
|
||||
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
|
||||
:::info Packaging without Electron Forge
|
||||
|
||||
If you want to manually package your code, or if you're just interested understanding the
|
||||
mechanics behind packaging an Electron app, check out the full [Application Packaging]
|
||||
@@ -136,64 +136,51 @@ Code signing is a security technology that you use to certify that a desktop app
|
||||
created by a known source. Windows and macOS have their own OS-specific code signing
|
||||
systems that will make it difficult for users to download or launch unsigned applications.
|
||||
|
||||
If you already have code signing certificates for Windows and macOS, you can set your
|
||||
credentials in your Forge configuration. Otherwise, please refer to the full
|
||||
[Code Signing] documentation to learn how to purchase a certificate and for more information
|
||||
on the desktop app code signing process.
|
||||
|
||||
On macOS, code signing is done at the app packaging level. On Windows, distributable installers
|
||||
are signed instead.
|
||||
are signed instead. If you already have code signing certificates for Windows and macOS, you can set
|
||||
your credentials in your Forge configuration.
|
||||
|
||||
:::info
|
||||
|
||||
For more information on code signing, check out the
|
||||
[Signing macOS Apps](https://www.electronforge.io/guides/code-signing) guide in the Forge docs.
|
||||
|
||||
:::
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="macos" label="macOS" default>
|
||||
|
||||
```json title='package.json' {6-18}
|
||||
{
|
||||
//...
|
||||
"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": "this-is-a-secret"
|
||||
}
|
||||
}
|
||||
//...
|
||||
```js title='forge.config.js'
|
||||
module.exports = {
|
||||
packagerConfig: {
|
||||
osxSign: {},
|
||||
//...
|
||||
osxNotarize: {
|
||||
tool: 'notarytool',
|
||||
appleId: process.env.APPLE_ID,
|
||||
appleIdPassword: process.env.APPLE_PASSWORD,
|
||||
teamId: process.env.APPLE_TEAM_ID,
|
||||
}
|
||||
//...
|
||||
}
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="windows" label="Windows">
|
||||
|
||||
```json title='package.json' {6-14}
|
||||
{
|
||||
```js title='forge.config.js'
|
||||
module.exports = {
|
||||
//...
|
||||
"config": {
|
||||
"forge": {
|
||||
//...
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"certificateFile": "./cert.pfx",
|
||||
"certificatePassword": "this-is-a-secret"
|
||||
}
|
||||
}
|
||||
]
|
||||
//...
|
||||
}
|
||||
}
|
||||
makers: [
|
||||
{
|
||||
name: '@electron-forge/maker-squirrel',
|
||||
config: {
|
||||
certificateFile: './cert.pfx',
|
||||
certificatePassword: process.env.CERTIFICATE_PASSWORD,
|
||||
},
|
||||
},
|
||||
],
|
||||
//...
|
||||
}
|
||||
```
|
||||
@@ -214,13 +201,12 @@ information.
|
||||
|
||||
[`@electron/osx-sign`]: https://github.com/electron/osx-sign
|
||||
[application packaging]: ./application-distribution.md
|
||||
[code signing]: ./code-signing.md
|
||||
[`electron-packager`]: https://github.com/electron/electron-packager
|
||||
[`electron-winstaller`]: https://github.com/electron/windows-installer
|
||||
[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
|
||||
[forge's icon tutorial]: https://www.electronforge.io/guides/create-and-add-icons
|
||||
|
||||
<!-- Tutorial links -->
|
||||
|
||||
|
||||
@@ -78,27 +78,21 @@ Once you have it installed, you need to set it up in your Forge
|
||||
configuration. A full list of options is documented in the Forge's
|
||||
[`PublisherGitHubConfig`] API docs.
|
||||
|
||||
```json title='package.json' {6-16}
|
||||
{
|
||||
//...
|
||||
"config": {
|
||||
"forge": {
|
||||
"publishers": [
|
||||
{
|
||||
"name": "@electron-forge/publisher-github",
|
||||
"config": {
|
||||
"repository": {
|
||||
"owner": "github-user-name",
|
||||
"name": "github-repo-name"
|
||||
},
|
||||
"prerelease": false,
|
||||
"draft": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
//...
|
||||
```js title='forge.config.js'
|
||||
module.exports = {
|
||||
publishers: [
|
||||
{
|
||||
name: '@electron-forge/publisher-github',
|
||||
config: {
|
||||
repository: {
|
||||
owner: 'github-user-name',
|
||||
name: 'github-repo-name',
|
||||
},
|
||||
prerelease: false,
|
||||
draft: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ auto_filenames = {
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/ipc-messages.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/api/crash-reporter.ts",
|
||||
"lib/renderer/api/ipc-renderer.ts",
|
||||
|
||||
@@ -671,8 +671,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",
|
||||
|
||||
@@ -70,29 +70,21 @@ function isInstalled () {
|
||||
|
||||
// unzips and makes path.txt point at the correct executable
|
||||
function extractFile (zipPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
|
||||
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
|
||||
|
||||
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);
|
||||
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) {
|
||||
try {
|
||||
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
if (hasTypeDefinitions) {
|
||||
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
|
||||
}
|
||||
|
||||
// Write a "path.txt" file.
|
||||
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
|
||||
})
|
||||
.catch((err) => reject(err));
|
||||
// Write a "path.txt" file.
|
||||
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"devDependencies": {
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/docs-parser": "^0.12.4",
|
||||
"@electron/typescript-definitions": "^8.9.5",
|
||||
"@octokit/auth-app": "^2.10.0",
|
||||
"@electron/docs-parser": "^1.0.0",
|
||||
"@electron/github-app-auth": "^1.5.0",
|
||||
"@electron/typescript-definitions": "^8.10.0",
|
||||
"@octokit/rest": "^18.0.3",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
"@types/basic-auth": "^1.1.3",
|
||||
@@ -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",
|
||||
|
||||
1
patches/angle/.patches
Normal file
1
patches/angle/.patches
Normal file
@@ -0,0 +1 @@
|
||||
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
|
||||
@@ -0,0 +1,66 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Milan Burda <milan.burda@gmail.com>
|
||||
Date: Mon, 10 Oct 2022 15:11:08 +0400
|
||||
Subject: fix: rename WebSwapCGLLayer to WebSwapCGLLayerChromium
|
||||
|
||||
Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x23c589b50)
|
||||
and src/out/testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib (0x1123f8488).
|
||||
One of the two will be used. Which one is undefined.
|
||||
|
||||
diff --git a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
|
||||
index 783a3dff46f04ed07934e516a3c39b061402cc84..056b242ab72eba87b036fc3e56c38a89800f1cdd 100644
|
||||
--- a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
|
||||
+++ b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
|
||||
@@ -18,7 +18,7 @@ struct __IOSurface;
|
||||
typedef __IOSurface *IOSurfaceRef;
|
||||
|
||||
// WebKit's build process requires that every Objective-C class name has the prefix "Web".
|
||||
-@class WebSwapCGLLayer;
|
||||
+@class WebSwapCGLLayerChromium;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
@@ -87,7 +87,7 @@ class WindowSurfaceCGL : public SurfaceGL
|
||||
const gl::FramebufferState &state) override;
|
||||
|
||||
private:
|
||||
- WebSwapCGLLayer *mSwapLayer;
|
||||
+ WebSwapCGLLayerChromium *mSwapLayer;
|
||||
SharedSwapState mSwapState;
|
||||
uint64_t mCurrentSwapId;
|
||||
|
||||
diff --git a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
|
||||
index 21894682d4a16f6c4133c4919aba8631f022d1ea..4a4be7f38abbe8242756a6abf810da80e98763c2 100644
|
||||
--- a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
|
||||
+++ b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
|
||||
@@ -24,7 +24,7 @@
|
||||
# include "libANGLE/renderer/gl/StateManagerGL.h"
|
||||
# include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
|
||||
|
||||
-@interface WebSwapCGLLayer : CAOpenGLLayer {
|
||||
+@interface WebSwapCGLLayerChromium : CAOpenGLLayer {
|
||||
CGLContextObj mDisplayContext;
|
||||
|
||||
bool initialized;
|
||||
@@ -38,7 +38,7 @@ - (id)initWithSharedState:(rx::SharedSwapState *)swapState
|
||||
withFunctions:(const rx::FunctionsGL *)functions;
|
||||
@end
|
||||
|
||||
-@implementation WebSwapCGLLayer
|
||||
+@implementation WebSwapCGLLayerChromium
|
||||
- (id)initWithSharedState:(rx::SharedSwapState *)swapState
|
||||
withContext:(CGLContextObj)displayContext
|
||||
withFunctions:(const rx::FunctionsGL *)functions
|
||||
@@ -213,9 +213,9 @@ - (void)drawInCGLContext:(CGLContextObj)glContext
|
||||
mSwapState.lastRendered = &mSwapState.textures[1];
|
||||
mSwapState.beingPresented = &mSwapState.textures[2];
|
||||
|
||||
- mSwapLayer = [[WebSwapCGLLayer alloc] initWithSharedState:&mSwapState
|
||||
- withContext:mContext
|
||||
- withFunctions:mFunctions];
|
||||
+ mSwapLayer = [[WebSwapCGLLayerChromium alloc] initWithSharedState:&mSwapState
|
||||
+ withContext:mContext
|
||||
+ withFunctions:mFunctions];
|
||||
[mLayer addSublayer:mSwapLayer];
|
||||
[mSwapLayer setContentsScale:[mLayer contentsScale]];
|
||||
|
||||
@@ -126,3 +126,18 @@ create_browser_v8_snapshot_file_name_fuse.patch
|
||||
cherry-pick-c83640db21b5.patch
|
||||
fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch
|
||||
build_allow_electron_to_use_exec_script.patch
|
||||
cherry-pick-67c9cbc784d6.patch
|
||||
cherry-pick-933cc81c6bad.patch
|
||||
cherry-pick-65d46507a0c9.patch
|
||||
cherry-pick-176c526846cb.patch
|
||||
cherry-pick-f46db6aac3e9.patch
|
||||
cherry-pick-9b3d0e2f1aab.patch
|
||||
cherry-pick-42e15c2055c4.patch
|
||||
cherry-pick-2ef09109c0ec.patch
|
||||
cherry-pick-f98adc846aad.patch
|
||||
cherry-pick-eed5a4de2c40.patch
|
||||
cherry-pick-d1d654d73222.patch
|
||||
cherry-pick-77208afba04d.patch
|
||||
cherry-pick-65ad70274d4b.patch
|
||||
cherry-pick-819d876e1bb8.patch
|
||||
cherry-pick-43637378b14e.patch
|
||||
|
||||
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 ce813f3d66a3d6841b4b04a625d8fd1a816b4a3e..344336b86d7ebb2df7be50db2d2f737320378342 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" {
|
||||
@@ -182,7 +183,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);
|
||||
@@ -222,7 +226,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();
|
||||
|
||||
@@ -330,7 +338,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_) {
|
||||
@@ -357,7 +365,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());
|
||||
@@ -452,7 +461,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);
|
||||
@@ -674,7 +684,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));
|
||||
@@ -716,17 +726,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 3842426dbf494615628d47f9d9d563a631d117ad..2f5c95d79450021a1cbe4b9289f658ba84813453 100644
|
||||
--- a/mojo/core/channel_unittest.cc
|
||||
+++ b/mojo/core/channel_unittest.cc
|
||||
@@ -714,6 +714,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
|
||||
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 0a978ee553cd3bf4b15b923fbf8b93789c441774..1a79fa26c069d10e9e03390f161d70d2adb7b07e 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
@@ -200,34 +200,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();
|
||||
|
||||
@@ -235,6 +210,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 c4be7a96144ac53be856fbf52dff8e990aa736aa..12183222040fd9ab3e202a510cc71f2ccbf2e4c4 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
@@ -418,6 +418,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 7091b979bed2c3ee375453ebc68aa83102745f35..b485bb1a08bc58bc1738c97c0311dc2d47d233e2 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"
|
||||
@@ -215,6 +216,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 4786257911cd9cb01222ef375698e0ae669d8ccb..94e04ff48d7a395cd673a9ececd598d00e735ff5 100644
|
||||
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
|
||||
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
|
||||
@@ -537,19 +537,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 7e73ad64a9b28396473adefaefd6430f81e61011..118ca880ffba6cc96a51b7b083119bd41f990e15 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 cd5f11083e268cdf0fca94c9fd9f8d56433b299b..38e0babfb9425d8611df97f8f6a325d6fca513fd 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
|
||||
@@ -86,6 +86,8 @@ ValidationMessageOverlayDelegate::~ValidationMessageOverlayDelegate() {
|
||||
EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
|
||||
page_->WillBeDestroyed();
|
||||
}
|
||||
+ if (destroyed_ptr_)
|
||||
+ *destroyed_ptr_ = true;
|
||||
}
|
||||
|
||||
LocalFrameView& ValidationMessageOverlayDelegate::FrameView() const {
|
||||
@@ -176,7 +178,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 105011c25861fe00cc8e72fe8f310ee5118725c3..86535284fedeb875b4958322fdddaa52507cfbaa 100644
|
||||
--- a/services/network/public/mojom/network_context.mojom
|
||||
+++ b/services/network/public/mojom/network_context.mojom
|
||||
@@ -561,11 +561,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 f2380053969cbb5292eaec3b4b01e7358788ef54..898d66ce5d9ce43ff55b426dca933014918c9339 100644
|
||||
--- a/media/capture/video/win/video_capture_device_win.cc
|
||||
+++ b/media/capture/video/win/video_capture_device_win.cc
|
||||
@@ -872,34 +872,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 98fc82b48ff020c49fdeab1adae947a84873f6b2..dad6051bc712e6b923ec26b0abc56625d8dcbed5 100644
|
||||
--- a/services/audio/stream_factory.cc
|
||||
+++ b/services/audio/stream_factory.cc
|
||||
@@ -184,8 +184,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();
|
||||
@@ -257,9 +258,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
|
||||
@@ -268,13 +270,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_);
|
||||
680
patches/chromium/cherry-pick-67c9cbc784d6.patch
Normal file
680
patches/chromium/cherry-pick-67c9cbc784d6.patch
Normal file
@@ -0,0 +1,680 @@
|
||||
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 0bbdc8c38a99986d5b8f70f5582f78c7f8be3fa0..7f8ed5f1e0eef6db0504ad3e075d76738bc07243 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"
|
||||
@@ -45,6 +46,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 {
|
||||
|
||||
// ExtensionFrameHostInterceptor is a helper for:
|
||||
@@ -280,6 +285,10 @@ class ExtensionSecurityExploitBrowserTest : public ExtensionBrowserTest {
|
||||
InstallTestExtensions();
|
||||
}
|
||||
|
||||
+ 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,
|
||||
@@ -293,36 +302,63 @@ class ExtensionSecurityExploitBrowserTest : 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>", "storage" ],
|
||||
+ "permissions": [
|
||||
+ "tabs",
|
||||
+ "<all_urls>",
|
||||
+ "nativeMessaging",
|
||||
+ "storage"
|
||||
+ ],
|
||||
"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());
|
||||
}
|
||||
|
||||
+ TestExtensionDir active_dir_;
|
||||
+ TestExtensionDir spoofed_dir_;
|
||||
raw_ptr<const Extension> active_extension_ = nullptr;
|
||||
raw_ptr<const Extension> spoofed_extension_ = nullptr;
|
||||
};
|
||||
@@ -333,48 +369,35 @@ class OpenChannelToExtensionExploitTest
|
||||
public:
|
||||
OpenChannelToExtensionExploitTest() = default;
|
||||
|
||||
+ using OpenChannelMessageWaiter =
|
||||
+ ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToExtension>;
|
||||
void SetUpOnMainThread() override {
|
||||
ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
|
||||
|
||||
- GURL test_page_url =
|
||||
- embedded_test_server()->GetURL("foo.com", "/title1.html");
|
||||
- ipc_message_waiter_ = StartInterceptingIpcs(test_page_url);
|
||||
- }
|
||||
-
|
||||
- // Waits for ExtensionHostMsg_OpenChannelToExtension IPC and returns its
|
||||
- // payload.
|
||||
- ExtensionHostMsg_OpenChannelToExtension::Param WaitForMessage() {
|
||||
- return ipc_message_waiter_->WaitForMessage();
|
||||
- }
|
||||
-
|
||||
- private:
|
||||
- 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.
|
||||
ExtensionId 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) {
|
||||
@@ -391,14 +414,16 @@ class OpenChannelToExtensionExploitTest
|
||||
|
||||
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_;
|
||||
-
|
||||
- raw_ptr<const Extension> active_extension_ = nullptr;
|
||||
- raw_ptr<const Extension> spoofed_extension_ = nullptr;
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
|
||||
@@ -412,24 +437,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(),
|
||||
@@ -443,24 +466,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(),
|
||||
@@ -473,24 +494,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(),
|
||||
@@ -504,25 +523,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(),
|
||||
@@ -536,18 +553,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,
|
||||
@@ -556,7 +571,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(),
|
||||
@@ -566,21 +581,115 @@ 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
|
||||
+
|
||||
IN_PROC_BROWSER_TEST_F(ExtensionSecurityExploitBrowserTest,
|
||||
SpoofedExtensionId_ExtensionFunctionDispatcher) {
|
||||
// Navigate to a test page.
|
||||
GURL test_page_url =
|
||||
embedded_test_server()->GetURL("foo.com", "/title1.html");
|
||||
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
|
||||
- content::WebContents* web_contents =
|
||||
- browser()->tab_strip_model()->GetActiveWebContents();
|
||||
- content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
|
||||
+ content::RenderFrameHost* main_frame =
|
||||
+ active_web_contents()->GetPrimaryMainFrame();
|
||||
|
||||
// Verify the test setup by checking if the non-intercepted `chrome.storage`
|
||||
// API call will succeed.
|
||||
{
|
||||
ExtensionTestMessageListener listener("Got chrome.storage response");
|
||||
- ExecuteProgrammaticContentScript(web_contents, active_extension_id(), R"(
|
||||
+ ExecuteProgrammaticContentScript(active_web_contents(),
|
||||
+ active_extension_id(), R"(
|
||||
chrome.storage.local.set(
|
||||
{ test_key: 'test value'},
|
||||
() => {
|
||||
@@ -607,7 +716,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionSecurityExploitBrowserTest,
|
||||
// terminating the misbehaving renderer process.
|
||||
content::RenderProcessHostBadMojoMessageWaiter kill_waiter(
|
||||
main_frame->GetProcess());
|
||||
- ExecuteProgrammaticContentScript(web_contents, active_extension_id(), R"(
|
||||
+ ExecuteProgrammaticContentScript(active_web_contents(), active_extension_id(),
|
||||
+ R"(
|
||||
chrome.storage.local.set({ test_key: 'test value2'}, () => {}); )");
|
||||
EXPECT_EQ(
|
||||
"Received bad user message: LocalFrameHost::Request: renderer never "
|
||||
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 25af213a4c02d7994eddb4dcb29a37871accd807..faf61a3b2bcb531934b8522b95b64930fff463dd 100644
|
||||
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
|
||||
@@ -146,6 +146,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;
|
||||
}
|
||||
|
||||
@@ -217,6 +227,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) {
|
||||
@@ -262,19 +284,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;
|
||||
@@ -293,7 +310,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_
|
||||
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 115f0e5774a3adde821bd34e5fac6645989e400e..4255884857a8d869a7a1e4f262f0f487dde16e24 100644
|
||||
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
|
||||
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
|
||||
@@ -893,8 +893,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)
|
||||
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 5aa120cd2e9fab1492f5d0993adbb2f80a4aa732..2acd2216331bd9be56eb9705f0e9c0d3bceb9e93 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 8183cb7e6547f42b27afc323fe136e2157e4dd03..dbdf244571956645c6494c4cdab514dd42dbb6c2 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.cc
|
||||
+++ b/content/test/content_browser_test_utils_internal.cc
|
||||
@@ -447,9 +447,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;
|
||||
|
||||
@@ -457,16 +462,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 6ae5e8f81a189702d5ed9bef003696f34c525dd3..3bf1bb93e15b0a5270262837802e140ad72a9231 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;
|
||||
}
|
||||
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()) {
|
||||
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 351bee9cfcc31dc6ca06f1fc502b70617105191a..d98e590beccfb19730528d598e32df4b4d00942b 100644
|
||||
--- a/content/browser/web_contents/web_contents_view_aura.cc
|
||||
+++ b/content/browser/web_contents/web_contents_view_aura.cc
|
||||
@@ -365,6 +365,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();
|
||||
}
|
||||
@@ -1461,7 +1462,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) {
|
||||
@@ -1482,24 +1483,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);
|
||||
}
|
||||
@@ -1510,10 +1510,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();
|
||||
@@ -1523,7 +1524,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()) {
|
||||
@@ -1534,13 +1534,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 2acd2216331bd9be56eb9705f0e9c0d3bceb9e93..d988e221688ee19493e43c0b5f736fa432843cd0 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 dbdf244571956645c6494c4cdab514dd42dbb6c2..70166cf3470595c928b202325f56f17abd0a61ac 100644
|
||||
--- a/content/test/content_browser_test_utils_internal.cc
|
||||
+++ b/content/test/content_browser_test_utils_internal.cc
|
||||
@@ -448,12 +448,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;
|
||||
@@ -462,6 +466,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_) {
|
||||
@@ -469,7 +476,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 3bf1bb93e15b0a5270262837802e140ad72a9231..6bd95d55add1c0da850be6078d02c3eae479ea62 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"))
|
||||
@@ -67,12 +67,12 @@ index ad34b6230f57ad906bae515aa73ea2aaf1bfeede..b5cff1fee2d14c02f2d67cf012b7ba24
|
||||
const WebSecurityOrigin& script_origin) {
|
||||
return false;
|
||||
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
|
||||
index 20d674166c78e316751bfa3ec7aed74656eea9b4..d289cfca8d8a9b093d8d30427e594c46b2f56c79 100644
|
||||
index 156d8d8184c4a69a9d8b8603027d7b398e2790bf..98fa13b35b0328eb436f2d146a8cda87438e6519 100644
|
||||
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
|
||||
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
|
||||
@@ -744,6 +744,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
|
||||
nested_runner_->QuitNow();
|
||||
@@ -746,6 +746,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
|
||||
}
|
||||
pause_handle_.reset();
|
||||
|
||||
+ {
|
||||
+ v8::HandleScope handle_scope(GetIsolate());
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"src/electron/patches/chromium": "src",
|
||||
|
||||
"src/electron/patches/angle": "src/third_party/angle",
|
||||
|
||||
"src/electron/patches/boringssl": "src/third_party/boringssl/src",
|
||||
|
||||
"src/electron/patches/devtools_frontend": "src/third_party/devtools-frontend/src",
|
||||
@@ -21,5 +23,7 @@
|
||||
|
||||
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
|
||||
|
||||
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC"
|
||||
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
|
||||
|
||||
"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 3e6939c5e1a5fbb1c52069a03c0317fa3e05aaf2..3c9498b8889bf0352aa0b640a82556daf36c62cc 100644
|
||||
--- a/av1/encoder/ratectrl.c
|
||||
+++ b/av1/encoder/ratectrl.c
|
||||
@@ -2136,6 +2136,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 =
|
||||
@@ -2152,6 +2155,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,
|
||||
@@ -3096,8 +3101,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 486fda38036226d0e92c0bb69a029b196f44b6c9..f9e9b8b0a506970f79bf1799d50f45abf9ecb684 100644
|
||||
--- a/av1/encoder/ratectrl.h
|
||||
+++ b/av1/encoder/ratectrl.h
|
||||
@@ -253,6 +253,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;
|
||||
|
||||
@@ -50,3 +50,5 @@ buffer_fix_atob_input_validation.patch
|
||||
v8_api_advance_api_deprecation.patch
|
||||
enable_-wunqualified-std-cast-call.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 c68cf1eb0f9cdd2a8fe314237c1e790fe3690272..b5f33411c68d56ae2a582b0defaa55bf10a830e0 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',
|
||||
@@ -9,3 +9,7 @@ fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
|
||||
revert_fix_cppgc_removed_deleted_cstors_in_cppheapcreateparams.patch
|
||||
revert_runtime_dhceck_terminating_exception_in_microtasks.patch
|
||||
chore_disable_is_execution_terminating_dcheck.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 3a882f8c7938820b787d0a59c1208ea9517dde15..87ac836d59a1901a5513cb14dc0c0d2e25922be3 100644
|
||||
--- a/src/compiler/backend/x64/code-generator-x64.cc
|
||||
+++ b/src/compiler/backend/x64/code-generator-x64.cc
|
||||
@@ -5215,7 +5215,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 31a06d5a138ac610b10f5eea6b338d44eac3373a..ca8394e5055889c81b57892c4efed53cc6bfa3bc 100644
|
||||
--- a/src/wasm/graph-builder-interface.cc
|
||||
+++ b/src/wasm/graph-builder-interface.cc
|
||||
@@ -2060,7 +2060,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);
|
||||
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 8d52d0792bcfc108141fc5d2016b5942ce93df07..7bf3bcc7796d60319c604e03d61a6c8a2b762581 100644
|
||||
--- a/src/ast/scopes.cc
|
||||
+++ b/src/ast/scopes.cc
|
||||
@@ -885,9 +885,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());
|
||||
@@ -912,12 +911,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());
|
||||
@@ -929,16 +927,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) {
|
||||
@@ -2576,6 +2568,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 32e16b80b261fbeffc1d4710f8a2119044cbf28e..3d062685643ad7bc31d9a45b92fa9dd924f83425 100644
|
||||
--- a/src/ast/scopes.h
|
||||
+++ b/src/ast/scopes.h
|
||||
@@ -110,12 +110,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.
|
||||
@@ -123,45 +117,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 };
|
||||
@@ -907,8 +887,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.
|
||||
@@ -942,7 +922,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 {
|
||||
@@ -1367,7 +1346,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).
|
||||
@@ -1380,14 +1361,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));
|
||||
}
|
||||
|
||||
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 40515772ef03946510aee70bb5f2d5cca4c74818..aa72539443e9ad05f56bfe10002632e621a09b43 100644
|
||||
--- a/include/v8-version.h
|
||||
+++ b/include/v8-version.h
|
||||
@@ -11,7 +11,7 @@
|
||||
#define V8_MAJOR_VERSION 10
|
||||
#define V8_MINOR_VERSION 6
|
||||
#define V8_BUILD_NUMBER 194
|
||||
-#define V8_PATCH_LEVEL 26
|
||||
+#define V8_PATCH_LEVEL 27
|
||||
|
||||
// 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 925c866c9ac5c9377f8ee75a312ce2710eb88f1c..2764c00a5ce1563a30f5927f722b36b91901036c 100644
|
||||
--- a/tools/v8heapconst.py
|
||||
+++ b/tools/v8heapconst.py
|
||||
@@ -544,30 +544,30 @@ KNOWN_OBJECTS = {
|
||||
("old_space", 0x04625): "StringSplitCache",
|
||||
("old_space", 0x04a2d): "RegExpMultipleCache",
|
||||
("old_space", 0x04e35): "BuiltinsConstantsTable",
|
||||
- ("old_space", 0x05285): "AsyncFunctionAwaitRejectSharedFun",
|
||||
- ("old_space", 0x052a9): "AsyncFunctionAwaitResolveSharedFun",
|
||||
- ("old_space", 0x052cd): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
- ("old_space", 0x052f1): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
- ("old_space", 0x05315): "AsyncGeneratorYieldResolveSharedFun",
|
||||
- ("old_space", 0x05339): "AsyncGeneratorReturnResolveSharedFun",
|
||||
- ("old_space", 0x0535d): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
- ("old_space", 0x05381): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
- ("old_space", 0x053a5): "AsyncIteratorValueUnwrapSharedFun",
|
||||
- ("old_space", 0x053c9): "PromiseAllResolveElementSharedFun",
|
||||
- ("old_space", 0x053ed): "PromiseAllSettledResolveElementSharedFun",
|
||||
- ("old_space", 0x05411): "PromiseAllSettledRejectElementSharedFun",
|
||||
- ("old_space", 0x05435): "PromiseAnyRejectElementSharedFun",
|
||||
- ("old_space", 0x05459): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
- ("old_space", 0x0547d): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
- ("old_space", 0x054a1): "PromiseCatchFinallySharedFun",
|
||||
- ("old_space", 0x054c5): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
- ("old_space", 0x054e9): "PromiseThenFinallySharedFun",
|
||||
- ("old_space", 0x0550d): "PromiseThrowerFinallySharedFun",
|
||||
- ("old_space", 0x05531): "PromiseValueThunkFinallySharedFun",
|
||||
- ("old_space", 0x05555): "ProxyRevokeSharedFun",
|
||||
- ("old_space", 0x05579): "ShadowRealmImportValueFulfilledSFI",
|
||||
- ("old_space", 0x0559d): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
|
||||
- ("old_space", 0x055c1): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
|
||||
+ ("old_space", 0x05289): "AsyncFunctionAwaitRejectSharedFun",
|
||||
+ ("old_space", 0x052ad): "AsyncFunctionAwaitResolveSharedFun",
|
||||
+ ("old_space", 0x052d1): "AsyncGeneratorAwaitRejectSharedFun",
|
||||
+ ("old_space", 0x052f5): "AsyncGeneratorAwaitResolveSharedFun",
|
||||
+ ("old_space", 0x05319): "AsyncGeneratorYieldResolveSharedFun",
|
||||
+ ("old_space", 0x0533d): "AsyncGeneratorReturnResolveSharedFun",
|
||||
+ ("old_space", 0x05361): "AsyncGeneratorReturnClosedRejectSharedFun",
|
||||
+ ("old_space", 0x05385): "AsyncGeneratorReturnClosedResolveSharedFun",
|
||||
+ ("old_space", 0x053a9): "AsyncIteratorValueUnwrapSharedFun",
|
||||
+ ("old_space", 0x053cd): "PromiseAllResolveElementSharedFun",
|
||||
+ ("old_space", 0x053f1): "PromiseAllSettledResolveElementSharedFun",
|
||||
+ ("old_space", 0x05415): "PromiseAllSettledRejectElementSharedFun",
|
||||
+ ("old_space", 0x05439): "PromiseAnyRejectElementSharedFun",
|
||||
+ ("old_space", 0x0545d): "PromiseCapabilityDefaultRejectSharedFun",
|
||||
+ ("old_space", 0x05481): "PromiseCapabilityDefaultResolveSharedFun",
|
||||
+ ("old_space", 0x054a5): "PromiseCatchFinallySharedFun",
|
||||
+ ("old_space", 0x054c9): "PromiseGetCapabilitiesExecutorSharedFun",
|
||||
+ ("old_space", 0x054ed): "PromiseThenFinallySharedFun",
|
||||
+ ("old_space", 0x05511): "PromiseThrowerFinallySharedFun",
|
||||
+ ("old_space", 0x05535): "PromiseValueThunkFinallySharedFun",
|
||||
+ ("old_space", 0x05559): "ProxyRevokeSharedFun",
|
||||
+ ("old_space", 0x0557d): "ShadowRealmImportValueFulfilledSFI",
|
||||
+ ("old_space", 0x055a1): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
|
||||
+ ("old_space", 0x055c5): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
|
||||
}
|
||||
|
||||
# Lower 32 bits of first page addresses for various heap spaces.
|
||||
@@ -1 +1,2 @@
|
||||
add_thread_local_to_x_error_trap_cc.patch
|
||||
cherry-pick-136ef25acbf7.patch
|
||||
|
||||
59
patches/webrtc/cherry-pick-136ef25acbf7.patch
Normal file
59
patches/webrtc/cherry-pick-136ef25acbf7.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakob Ivarsson <jakobi@webrtc.org>
|
||||
Date: Fri, 23 Sep 2022 22:03:09 +0200
|
||||
Subject: Fix crash when appending empty array to AudioMultiVector.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Bug: webrtc:14442,chromium:1367993
|
||||
Change-Id: I9453e300a6d3d78571d08cc65770787e13d43885
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/276620
|
||||
Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
|
||||
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#38208}
|
||||
|
||||
diff --git a/modules/audio_coding/neteq/audio_multi_vector.cc b/modules/audio_coding/neteq/audio_multi_vector.cc
|
||||
index 220d5a17d7d1d4e1ed7577d4a044af29f358f88b..14ae94649b52278656eb73d91b1e73cb5307a92d 100644
|
||||
--- a/modules/audio_coding/neteq/audio_multi_vector.cc
|
||||
+++ b/modules/audio_coding/neteq/audio_multi_vector.cc
|
||||
@@ -69,6 +69,9 @@ void AudioMultiVector::CopyTo(AudioMultiVector* copy_to) const {
|
||||
void AudioMultiVector::PushBackInterleaved(
|
||||
rtc::ArrayView<const int16_t> append_this) {
|
||||
RTC_DCHECK_EQ(append_this.size() % num_channels_, 0);
|
||||
+ if (append_this.empty()) {
|
||||
+ return;
|
||||
+ }
|
||||
if (num_channels_ == 1) {
|
||||
// Special case to avoid extra allocation and data shuffling.
|
||||
channels_[0]->PushBack(append_this.data(), append_this.size());
|
||||
@@ -78,11 +81,8 @@ void AudioMultiVector::PushBackInterleaved(
|
||||
int16_t* temp_array = new int16_t[length_per_channel]; // Temporary storage.
|
||||
for (size_t channel = 0; channel < num_channels_; ++channel) {
|
||||
// Copy elements to `temp_array`.
|
||||
- // Set `source_ptr` to first element of this channel.
|
||||
- const int16_t* source_ptr = &append_this[channel];
|
||||
for (size_t i = 0; i < length_per_channel; ++i) {
|
||||
- temp_array[i] = *source_ptr;
|
||||
- source_ptr += num_channels_; // Jump to next element of this channel.
|
||||
+ temp_array[i] = append_this[channel + i * num_channels_];
|
||||
}
|
||||
channels_[channel]->PushBack(temp_array, length_per_channel);
|
||||
}
|
||||
diff --git a/modules/audio_coding/neteq/audio_multi_vector_unittest.cc b/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
|
||||
index 329377a18edc2259dfc24dbaf82218ff69180916..386c3d48a398521730afad6642df355e29550d79 100644
|
||||
--- a/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
|
||||
+++ b/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
|
||||
@@ -309,6 +309,12 @@ TEST_P(AudioMultiVectorTest, CopyChannel) {
|
||||
}
|
||||
}
|
||||
|
||||
+TEST_P(AudioMultiVectorTest, PushBackEmptyArray) {
|
||||
+ AudioMultiVector vec(num_channels_);
|
||||
+ vec.PushBackInterleaved({});
|
||||
+ EXPECT_TRUE(vec.Empty());
|
||||
+}
|
||||
+
|
||||
INSTANTIATE_TEST_SUITE_P(TestNumChannels,
|
||||
AudioMultiVectorTest,
|
||||
::testing::Values(static_cast<size_t>(1),
|
||||
@@ -4,11 +4,11 @@ import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from lib.config import LINUX_BINARIES, PLATFORM
|
||||
from lib.util import execute, get_out_dir
|
||||
from lib.config import PLATFORM
|
||||
from lib.util import execute, get_linux_binaries, get_out_dir
|
||||
|
||||
def add_debug_link_into_binaries(directory, target_cpu, debug_dir):
|
||||
for binary in LINUX_BINARIES:
|
||||
for binary in get_linux_binaries():
|
||||
binary_path = os.path.join(directory, binary)
|
||||
if os.path.isfile(binary_path):
|
||||
add_debug_link_into_binary(binary_path, target_cpu, debug_dir)
|
||||
|
||||
@@ -4,12 +4,12 @@ import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from lib.config import LINUX_BINARIES, PLATFORM
|
||||
from lib.util import execute, get_out_dir, safe_mkdir
|
||||
from lib.config import PLATFORM
|
||||
from lib.util import execute, get_linux_binaries, get_out_dir, safe_mkdir
|
||||
|
||||
# It has to be done before stripping the binaries.
|
||||
def copy_debug_from_binaries(directory, out_dir, target_cpu, compress):
|
||||
for binary in LINUX_BINARIES:
|
||||
for binary in get_linux_binaries():
|
||||
binary_path = os.path.join(directory, binary)
|
||||
if os.path.isfile(binary_path):
|
||||
copy_debug_from_binary(binary_path, out_dir, target_cpu, compress)
|
||||
|
||||
17
script/create-api-json.js
Normal file
17
script/create-api-json.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const { parseDocs } = require('@electron/docs-parser');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const { getElectronVersion } = require('./lib/get-version');
|
||||
|
||||
parseDocs({
|
||||
baseDirectory: path.resolve(__dirname, '..'),
|
||||
packageMode: 'single',
|
||||
useReadme: false,
|
||||
moduleVersion: getElectronVersion()
|
||||
}).then((api) => {
|
||||
return fs.promises.writeFile(path.resolve(__dirname, '..', 'electron-api.json'), JSON.stringify(api, null, 2));
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -13,16 +13,6 @@ PLATFORM = {
|
||||
'win32': 'win32',
|
||||
}[sys.platform]
|
||||
|
||||
LINUX_BINARIES = [
|
||||
'chrome-sandbox',
|
||||
'chrome_crashpad_handler',
|
||||
'electron',
|
||||
'libEGL.so',
|
||||
'libGLESv2.so',
|
||||
'libffmpeg.so',
|
||||
'libvk_swiftshader.so',
|
||||
]
|
||||
|
||||
verbose_mode = False
|
||||
|
||||
|
||||
|
||||
@@ -215,3 +215,14 @@ def get_buildtools_executable(name):
|
||||
if sys.platform == 'win32':
|
||||
path += '.exe'
|
||||
return path
|
||||
|
||||
def get_linux_binaries():
|
||||
return [
|
||||
'chrome-sandbox',
|
||||
'chrome_crashpad_handler',
|
||||
get_electron_branding()['project_name'],
|
||||
'libEGL.so',
|
||||
'libGLESv2.so',
|
||||
'libffmpeg.so',
|
||||
'libvk_swiftshader.so',
|
||||
]
|
||||
|
||||
@@ -129,6 +129,7 @@ module.exports = {
|
||||
getElectronExec,
|
||||
getOutDir,
|
||||
getAbsoluteElectronExec,
|
||||
handleGitCall,
|
||||
ELECTRON_DIR,
|
||||
SRC_DIR
|
||||
};
|
||||
|
||||
219
script/prepare-appveyor.js
Normal file
219
script/prepare-appveyor.js
Normal file
@@ -0,0 +1,219 @@
|
||||
if (!process.env.CI) require('dotenv-safe').load();
|
||||
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const got = require('got');
|
||||
const path = require('path');
|
||||
const { handleGitCall, ELECTRON_DIR } = require('./lib/utils.js');
|
||||
const { Octokit } = require('@octokit/rest');
|
||||
const octokit = new Octokit();
|
||||
|
||||
const APPVEYOR_IMAGES_URL = 'https://ci.appveyor.com/api/build-clouds';
|
||||
const APPVEYOR_JOB_URL = 'https://ci.appveyor.com/api/builds';
|
||||
const ROLLER_BRANCH_PATTERN = /^roller\/chromium$/;
|
||||
|
||||
const DEFAULT_BUILD_CLOUD_ID = '1598';
|
||||
const DEFAULT_BUILD_CLOUD = 'electronhq-16-core';
|
||||
const DEFAULT_BAKE_BASE_IMAGE = 'Windows_Default_Appveyor';
|
||||
const DEFAULT_BUILD_IMAGE = 'Windows_Default_Appveyor';
|
||||
|
||||
const appveyorBakeJob = 'electron-bake-image';
|
||||
const appVeyorJobs = {
|
||||
'electron-x64': 'electron-x64-testing',
|
||||
'electron-woa': 'electron-woa-testing',
|
||||
'electron-ia32': 'electron-ia32-testing'
|
||||
};
|
||||
|
||||
async function makeRequest ({ auth, username, password, url, headers, body, method }) {
|
||||
const clonedHeaders = {
|
||||
...(headers || {})
|
||||
};
|
||||
if (auth?.bearer) {
|
||||
clonedHeaders.Authorization = `Bearer ${auth.bearer}`;
|
||||
}
|
||||
|
||||
const options = {
|
||||
headers: clonedHeaders,
|
||||
body,
|
||||
method
|
||||
};
|
||||
|
||||
if (username || password) {
|
||||
options.username = username;
|
||||
options.password = password;
|
||||
}
|
||||
|
||||
const response = await got(url, options);
|
||||
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
console.error('Error: ', `(status ${response.statusCode})`, response.body);
|
||||
throw new Error(`Unexpected status code ${response.statusCode} from ${url}`);
|
||||
}
|
||||
return JSON.parse(response.body);
|
||||
}
|
||||
|
||||
async function checkAppVeyorImage (options) {
|
||||
const IMAGE_URL = `${APPVEYOR_IMAGES_URL}/${options.cloudId}`;
|
||||
const requestOpts = {
|
||||
url: IMAGE_URL,
|
||||
auth: {
|
||||
bearer: process.env.APPVEYOR_TOKEN
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
try {
|
||||
const { settings } = await makeRequest(requestOpts);
|
||||
const { cloudSettings } = settings;
|
||||
return cloudSettings.images.find(image => image.name === `${options.imageVersion}`) || null;
|
||||
} catch (err) {
|
||||
console.log('Could not call AppVeyor: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function getPullRequestId (targetBranch) {
|
||||
const prsForBranch = await octokit.pulls.list({
|
||||
owner: 'electron',
|
||||
repo: 'electron',
|
||||
state: 'open',
|
||||
head: `electron:${targetBranch}`
|
||||
});
|
||||
if (prsForBranch.data.length === 1) {
|
||||
return prsForBranch.data[0].number;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function useAppVeyorImage (targetBranch, options) {
|
||||
const validJobs = Object.keys(appVeyorJobs);
|
||||
if (options.job) {
|
||||
assert(validJobs.includes(options.job), `Unknown AppVeyor CI job name: ${options.job}. Valid values are: ${validJobs}.`);
|
||||
callAppVeyorBuildJobs(targetBranch, options.job, options);
|
||||
} else {
|
||||
validJobs.forEach((job) => callAppVeyorBuildJobs(targetBranch, job, options));
|
||||
}
|
||||
}
|
||||
|
||||
async function callAppVeyorBuildJobs (targetBranch, job, options) {
|
||||
console.log(`Using AppVeyor image ${options.version} for ${job}`);
|
||||
|
||||
const pullRequestId = await getPullRequestId(targetBranch);
|
||||
const environmentVariables = {
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: DEFAULT_BUILD_CLOUD,
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: options.version,
|
||||
ELECTRON_OUT_DIR: 'Default',
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1,
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1,
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true,
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0,
|
||||
PYTHONIOENCODING: 'UTF-8'
|
||||
};
|
||||
|
||||
const requestOpts = {
|
||||
url: APPVEYOR_JOB_URL,
|
||||
auth: {
|
||||
bearer: process.env.APPVEYOR_TOKEN
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
accountName: 'electron-bot',
|
||||
projectSlug: appVeyorJobs[job],
|
||||
branch: targetBranch,
|
||||
pullRequestId: pullRequestId || undefined,
|
||||
commitId: options.commit || undefined,
|
||||
environmentVariables
|
||||
}),
|
||||
method: 'POST'
|
||||
};
|
||||
|
||||
try {
|
||||
const { version } = await makeRequest(requestOpts);
|
||||
const buildUrl = `https://ci.appveyor.com/project/electron-bot/${appVeyorJobs[job]}/build/${version}`;
|
||||
console.log(`AppVeyor CI request for ${job} successful. Check status at ${buildUrl}`);
|
||||
} catch (err) {
|
||||
console.log('Could not call AppVeyor: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function bakeAppVeyorImage (targetBranch, options) {
|
||||
console.log(`Baking a new AppVeyor image for ${options.version}, on build cloud ${options.cloudId}`);
|
||||
|
||||
const environmentVariables = {
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: DEFAULT_BUILD_CLOUD,
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: DEFAULT_BAKE_BASE_IMAGE,
|
||||
APPVEYOR_BAKE_IMAGE: options.version
|
||||
};
|
||||
|
||||
const requestOpts = {
|
||||
url: APPVEYOR_JOB_URL,
|
||||
auth: {
|
||||
bearer: process.env.APPVEYOR_TOKEN
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
accountName: 'electron-bot',
|
||||
projectSlug: appveyorBakeJob,
|
||||
branch: targetBranch,
|
||||
commitId: options.commit || undefined,
|
||||
environmentVariables
|
||||
}),
|
||||
method: 'POST'
|
||||
};
|
||||
|
||||
try {
|
||||
const { version } = await makeRequest(requestOpts);
|
||||
const bakeUrl = `https://ci.appveyor.com/project/electron-bot/${appveyorBakeJob}/build/${version}`;
|
||||
console.log(`AppVeyor image bake request for ${options.version} successful. Check bake status at ${bakeUrl}`);
|
||||
} catch (err) {
|
||||
console.log('Could not call AppVeyor: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function prepareAppVeyorImage (opts) {
|
||||
const branch = await handleGitCall(['rev-parse', '--abbrev-ref', 'HEAD'], ELECTRON_DIR);
|
||||
if (ROLLER_BRANCH_PATTERN.test(branch)) {
|
||||
useAppVeyorImage(branch, { ...opts, version: DEFAULT_BUILD_IMAGE, cloudId: DEFAULT_BUILD_CLOUD_ID });
|
||||
} else {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const versionRegex = new RegExp('chromium_version\':\n +\'(.+?)\',', 'm');
|
||||
const deps = fs.readFileSync(path.resolve(__dirname, '..', 'DEPS'), 'utf8');
|
||||
const [, CHROMIUM_VERSION] = versionRegex.exec(deps);
|
||||
|
||||
const cloudId = opts.cloudId || DEFAULT_BUILD_CLOUD_ID;
|
||||
const imageVersion = opts.imageVersion || `e-${CHROMIUM_VERSION}`;
|
||||
const image = await checkAppVeyorImage({ cloudId, imageVersion });
|
||||
|
||||
if (image && image.name) {
|
||||
console.log(`Image exists for ${image.name}. Continuing AppVeyor jobs using ${cloudId}.\n`);
|
||||
} else {
|
||||
console.log(`No AppVeyor image found for ${imageVersion} in ${cloudId}.
|
||||
Creating new image for ${imageVersion}, using Chromium ${CHROMIUM_VERSION} - job will run after image is baked.`);
|
||||
await bakeAppVeyorImage(branch, { ...opts, version: imageVersion, cloudId });
|
||||
|
||||
// write image to temp file if running on CI
|
||||
if (process.env.CI) fs.writeFileSync('./image_version.txt', imageVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = prepareAppVeyorImage;
|
||||
|
||||
// Load or bake AppVeyor images for Windows CI.
|
||||
// Usage: prepare-appveyor.js [--cloudId=CLOUD_ID] [--appveyorJobId=xxx] [--imageVersion=xxx]
|
||||
// [--commit=sha] [--branch=branch_name]
|
||||
if (require.main === module) {
|
||||
const args = require('minimist')(process.argv.slice(2));
|
||||
prepareAppVeyorImage(args)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
const { createAppAuth } = require('@octokit/auth-app');
|
||||
const { appCredentialsFromString, getTokenForRepo } = require('@electron/github-app-auth');
|
||||
const cp = require('child_process');
|
||||
|
||||
if (!process.env.CIRCLE_BRANCH) {
|
||||
@@ -11,17 +11,15 @@ if (process.env.CIRCLE_PR_NUMBER) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const auth = createAppAuth({
|
||||
appId: process.env.PATCH_UP_APP_ID,
|
||||
privateKey: Buffer.from(process.env.PATCH_UP_PRIVATE_KEY, 'base64').toString('utf8'),
|
||||
installationId: process.env.PATCH_UP_INSTALLATION_ID,
|
||||
clientId: process.env.PATCH_UP_CLIENT_ID,
|
||||
clientSecret: process.env.PATCH_UP_CLIENT_SECRET
|
||||
});
|
||||
|
||||
async function main () {
|
||||
const installationAuth = await auth({ type: 'installation' });
|
||||
const remoteURL = `https://x-access-token:${installationAuth.token}@github.com/electron/electron.git`;
|
||||
const token = await getTokenForRepo(
|
||||
{
|
||||
name: 'electron',
|
||||
owner: 'electron'
|
||||
},
|
||||
appCredentialsFromString(process.env.PATCH_UP_APP_CREDS)
|
||||
);
|
||||
const remoteURL = `https://x-access-token:${token}@github.com/electron/electron.git`;
|
||||
// NEVER LOG THE OUTPUT OF THIS COMMAND
|
||||
// GIT LEAKS THE ACCESS CREDENTIALS IN CONSOLE LOGS
|
||||
const { status } = cp.spawnSync('git', ['push', '--set-upstream', remoteURL], {
|
||||
|
||||
@@ -24,8 +24,6 @@ const circleCIPublishIndividualArches = {
|
||||
'linux-publish': ['arm', 'arm64', 'x64']
|
||||
};
|
||||
|
||||
const GHAJobs = ['electron-woa-testing'];
|
||||
|
||||
let jobRequestedCount = 0;
|
||||
|
||||
async function makeRequest ({ auth, username, password, url, headers, body, method }) {
|
||||
@@ -204,7 +202,7 @@ async function callAppVeyor (targetBranch, job, options) {
|
||||
console.log(`Triggering AppVeyor to run build job: ${job} on branch: ${targetBranch} with release flag.`);
|
||||
const environmentVariables = {
|
||||
ELECTRON_RELEASE: 1,
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: 'libcc-20'
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: 'electronhq-16-core'
|
||||
};
|
||||
|
||||
if (!options.ghRelease) {
|
||||
@@ -250,31 +248,6 @@ function buildCircleCI (targetBranch, options) {
|
||||
}
|
||||
}
|
||||
|
||||
async function buildGHA (targetBranch, options) {
|
||||
const { GHA_TOKEN } = process.env;
|
||||
assert(GHA_TOKEN, `${options.ci} requires the $GHA_TOKEN environment variable to be provided`);
|
||||
|
||||
const octokit = new Octokit({ auth: GHA_TOKEN });
|
||||
|
||||
assert(GHAJobs.includes(options.job), `Unknown GitHub Actions arm test job name: ${options.job}. Valid values are: ${GHAJobs}.`);
|
||||
assert(options.commit !== null, 'commit is a required option for GitHub Actions');
|
||||
|
||||
console.log(`Triggering GitHub Actions to run build on branch: ${targetBranch}.`);
|
||||
|
||||
jobRequestedCount++;
|
||||
|
||||
try {
|
||||
const response = await octokit.request('POST /repos/electron/electron/actions/workflows/electron_woa_testing.yml/dispatches', {
|
||||
ref: targetBranch,
|
||||
inputs: {
|
||||
appveyor_job_id: `${options.appveyorJobId}`
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Problem calling GitHub Actions to get build definitions: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
function runRelease (targetBranch, options) {
|
||||
if (options.ci) {
|
||||
switch (options.ci) {
|
||||
@@ -286,10 +259,6 @@ function runRelease (targetBranch, options) {
|
||||
buildAppVeyor(targetBranch, options);
|
||||
break;
|
||||
}
|
||||
case 'GHA': {
|
||||
buildGHA(targetBranch, options);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(`Error! Unknown CI: ${options.ci}.`);
|
||||
process.exit(1);
|
||||
@@ -311,7 +280,7 @@ if (require.main === module) {
|
||||
const targetBranch = args._[0];
|
||||
if (args._.length < 1) {
|
||||
console.log(`Trigger CI to build release builds of electron.
|
||||
Usage: ci-release-build.js [--job=CI_JOB_NAME] [--arch=INDIVIDUAL_ARCH] [--ci=CircleCI|AppVeyor|GHA]
|
||||
Usage: ci-release-build.js [--job=CI_JOB_NAME] [--arch=INDIVIDUAL_ARCH] [--ci=CircleCI|AppVeyor]
|
||||
[--ghRelease] [--circleBuildNum=xxx] [--appveyorJobId=xxx] [--commit=sha] TARGET_BRANCH
|
||||
`);
|
||||
process.exit(0);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
REM Parameters vs_buildtools.exe download link and wsdk version
|
||||
@ECHO OFF
|
||||
|
||||
SET buildtools_link=https://download.visualstudio.microsoft.com/download/pr/d7691cc1-82e6-434f-8e9f-a612f85b4b76/c62179f8cbbb58d4af22c21e8d4e122165f21615f529c94fad5cc7e012f1ef08/vs_BuildTools.exe
|
||||
SET wsdk10_link=https://go.microsoft.com/fwlink/p/?LinkId=845298
|
||||
SET wsdk=10SDK.18362
|
||||
SET wsdk=10SDK.20348
|
||||
|
||||
REM Check for disk space
|
||||
Rem 543210987654321
|
||||
@@ -44,24 +42,6 @@ IF NOT "%1"=="" (
|
||||
|
||||
if not exist "C:\TEMP\" mkdir C:\TEMP
|
||||
|
||||
REM Download vs_buildtools.exe to C:\TEMP\vs_buildtools.exe
|
||||
powershell -command "& { iwr %buildtools_link% -OutFile C:\TEMP\vs_buildtools.exe }"
|
||||
|
||||
REM Install Visual Studio Toolchain
|
||||
C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache ^
|
||||
--installPath "%ProgramFiles(x86)%/Microsoft Visual Studio/2019/Community" ^
|
||||
--add Microsoft.VisualStudio.Workload.VCTools ^
|
||||
--add Microsoft.VisualStudio.Component.VC.140 ^
|
||||
--add Microsoft.VisualStudio.Component.VC.ATLMFC ^
|
||||
--add Microsoft.VisualStudio.Component.VC.Tools.ARM64 ^
|
||||
--add Microsoft.VisualStudio.Component.VC.MFC.ARM64 ^
|
||||
--add Microsoft.VisualStudio.Component.Windows%wsdk% ^
|
||||
--includeRecommended
|
||||
|
||||
REM Install Windows SDK
|
||||
powershell -command "& { iwr %wsdk10_link% -OutFile C:\TEMP\wsdk10.exe }"
|
||||
C:\TEMP\wsdk10.exe /features /quiet
|
||||
|
||||
REM Install chocolatey to further install dependencies
|
||||
set chocolateyUseWindowsCompression='true'
|
||||
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" ^
|
||||
@@ -69,15 +49,22 @@ set chocolateyUseWindowsCompression='true'
|
||||
-Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"
|
||||
SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
|
||||
|
||||
REM Install nodejs python git and yarn needed dependencies
|
||||
choco install -y nodejs python2 git yarn windows-sdk-10-version-1903-windbg
|
||||
call C:\ProgramData\chocolatey\bin\RefreshEnv.cmd
|
||||
SET PATH=C:\Python27\;C:\Python27\Scripts;%PATH%
|
||||
REM Install Visual Studio Toolchain
|
||||
choco install visualstudio2019buildtools --package-parameters "--quiet --wait --norestart --nocache --installPath ""%ProgramFiles(x86)%/Microsoft Visual Studio/2019/Community"" --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.140 --add Microsoft.VisualStudio.Component.VC.ATLMFC --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 --add Microsoft.VisualStudio.Component.VC.MFC.ARM64 --add Microsoft.VisualStudio.Component.Windows%wsdk% --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended"
|
||||
|
||||
pip install pywin32
|
||||
REM Install Windows SDK
|
||||
choco install windows-sdk-10-version-2104-all
|
||||
|
||||
REM Install nodejs python git and yarn needed dependencies
|
||||
choco install -y nodejs-lts --version=16.15.0
|
||||
choco install -y python2 git yarn
|
||||
choco install python --version 3.7.9
|
||||
call C:\ProgramData\chocolatey\bin\RefreshEnv.cmd
|
||||
pip2 install pywin32
|
||||
SET PATH=C:\Python27\;C:\Python27\Scripts;C:\Python39\;C:\Python39\Scripts;%PATH%
|
||||
|
||||
REM Setup Depot Tools
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git C:\depot_tools
|
||||
SET PATH=%PATH%;C:\depot_tools\
|
||||
SET PATH=%PATH%;C:\depot_tools\
|
||||
|
||||
REM Add symstore to PATH permanently
|
||||
setx path "%%path%%;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64"
|
||||
@@ -4,11 +4,11 @@ import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from lib.config import LINUX_BINARIES, enable_verbose_mode
|
||||
from lib.util import execute, get_out_dir
|
||||
from lib.config import enable_verbose_mode
|
||||
from lib.util import execute, get_linux_binaries, get_out_dir
|
||||
|
||||
def strip_binaries(directory, target_cpu):
|
||||
for binary in LINUX_BINARIES:
|
||||
for binary in get_linux_binaries():
|
||||
binary_path = os.path.join(directory, binary)
|
||||
if os.path.isfile(binary_path):
|
||||
strip_binary(binary_path, target_cpu)
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/language_util.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/platform_util.h"
|
||||
@@ -1790,6 +1791,7 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
||||
.SetMethod("setAppLogsPath", &App::SetAppLogsPath)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||
.SetMethod("getLocale", &App::GetLocale)
|
||||
.SetMethod("getPreferredSystemLanguages", &GetPreferredLanguages)
|
||||
.SetMethod("getSystemLocale", &App::GetSystemLocale)
|
||||
.SetMethod("getLocaleCountryCode", &App::GetLocaleCountryCode)
|
||||
#if BUILDFLAG(USE_NSS_CERTS)
|
||||
|
||||
@@ -202,6 +202,8 @@ class Browser : public WindowListObserver {
|
||||
bool UpdateUserActivityState(const std::string& type,
|
||||
base::Value::Dict user_info);
|
||||
|
||||
void ApplyForcedRTL();
|
||||
|
||||
// Bounce the dock icon.
|
||||
enum class BounceType{
|
||||
kCritical = 0, // NSCriticalRequest
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
#include "shell/browser/badging/badge_manager.h"
|
||||
#include "shell/browser/mac/dict_util.h"
|
||||
@@ -36,6 +38,13 @@ namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsAppRTL() {
|
||||
const std::string& locale = g_browser_process->GetApplicationLocale();
|
||||
base::i18n::TextDirection text_direction =
|
||||
base::i18n::GetTextDirectionForLocaleInStartUp(locale.c_str());
|
||||
return text_direction == base::i18n::RIGHT_TO_LEFT;
|
||||
}
|
||||
|
||||
NSString* GetAppPathForProtocol(const GURL& url) {
|
||||
NSURL* ns_url = [NSURL
|
||||
URLWithString:base::SysUTF8ToNSString(url.possibly_invalid_spec())];
|
||||
@@ -306,6 +315,32 @@ bool Browser::UpdateUserActivityState(const std::string& type,
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
// Modified from chrome/browser/ui/cocoa/l10n_util.mm.
|
||||
void Browser::ApplyForcedRTL() {
|
||||
NSUserDefaults* defaults = NSUserDefaults.standardUserDefaults;
|
||||
|
||||
auto dir = base::i18n::GetForcedTextDirection();
|
||||
|
||||
// An Electron app should respect RTL behavior of application locale over
|
||||
// system locale.
|
||||
auto should_be_rtl = dir == base::i18n::RIGHT_TO_LEFT || IsAppRTL();
|
||||
auto should_be_ltr = dir == base::i18n::LEFT_TO_RIGHT || !IsAppRTL();
|
||||
|
||||
// -registerDefaults: won't do the trick here because these defaults exist
|
||||
// (in the global domain) to reflect the system locale. They need to be set
|
||||
// in Chrome's domain to supersede the system value.
|
||||
if (should_be_rtl) {
|
||||
[defaults setBool:YES forKey:@"AppleTextDirection"];
|
||||
[defaults setBool:YES forKey:@"NSForceRightToLeftWritingDirection"];
|
||||
} else if (should_be_ltr) {
|
||||
[defaults setBool:YES forKey:@"AppleTextDirection"];
|
||||
[defaults setBool:NO forKey:@"NSForceRightToLeftWritingDirection"];
|
||||
} else {
|
||||
[defaults removeObjectForKey:@"AppleTextDirection"];
|
||||
[defaults removeObjectForKey:@"NSForceRightToLeftWritingDirection"];
|
||||
}
|
||||
}
|
||||
|
||||
Browser::LoginItemSettings Browser::GetLoginItemSettings(
|
||||
const LoginItemSettings& options) {
|
||||
LoginItemSettings settings;
|
||||
@@ -447,6 +482,13 @@ void Browser::DockSetIcon(v8::Isolate* isolate, v8::Local<v8::Value> icon) {
|
||||
image = native_image->image();
|
||||
}
|
||||
|
||||
// This is needed when this fn is called before the browser
|
||||
// process is ready, since supported scales are normally set
|
||||
// by ui::ResourceBundle::InitSharedInstance
|
||||
// during browser process startup.
|
||||
if (!is_ready())
|
||||
gfx::ImageSkia::SetSupportedScales({1.0f});
|
||||
|
||||
[[AtomApplication sharedApplication]
|
||||
setApplicationIconImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
@@ -353,6 +353,7 @@ int ElectronBrowserMainParts::PreCreateThreads() {
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
ui::InitIdleMonitor();
|
||||
Browser::Get()->ApplyForcedRTL();
|
||||
#endif
|
||||
|
||||
fake_browser_process_->PreCreateThreads();
|
||||
|
||||
@@ -172,7 +172,11 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
|
||||
int max_width = max_size.width() > 0 ? max_size.width() : INT_MAX;
|
||||
int max_height = max_size.height() > 0 ? max_size.height() : INT_MAX;
|
||||
bool have_max_width = options.Get(options::kMaxWidth, &max_width);
|
||||
if (have_max_width && max_width <= 0)
|
||||
max_width = INT_MAX;
|
||||
bool have_max_height = options.Get(options::kMaxHeight, &max_height);
|
||||
if (have_max_height && max_height <= 0)
|
||||
max_height = INT_MAX;
|
||||
|
||||
// By default the window has a default maximum size that prevents it
|
||||
// from being resized larger than the screen, so we should only set this
|
||||
|
||||
@@ -1122,9 +1122,12 @@ void NativeWindowMac::SetKiosk(bool kiosk) {
|
||||
is_kiosk_ = true;
|
||||
SetFullScreen(true);
|
||||
} else if (!kiosk && is_kiosk_) {
|
||||
[NSApp setPresentationOptions:kiosk_options_];
|
||||
is_kiosk_ = false;
|
||||
SetFullScreen(false);
|
||||
|
||||
// Set presentation options *after* asynchronously exiting
|
||||
// fullscreen to ensure they take effect.
|
||||
[NSApp setPresentationOptions:kiosk_options_];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ void OnWebNotificationAllowed(base::WeakPtr<Notification> notification,
|
||||
options.icon = icon;
|
||||
options.silent = audio_muted ? true : data.silent;
|
||||
options.has_reply = false;
|
||||
if (data.require_interaction)
|
||||
options.timeout_type = u"never";
|
||||
|
||||
notification->Show(options);
|
||||
} else {
|
||||
notification->Destroy();
|
||||
|
||||
@@ -71,9 +71,6 @@ NSAlert* CreateNSAlert(const MessageBoxSettings& settings) {
|
||||
int button_count = static_cast<int>([ns_buttons count]);
|
||||
|
||||
if (settings.default_id >= 0 && settings.default_id < button_count) {
|
||||
// Highlight the button at default_id
|
||||
[[ns_buttons objectAtIndex:settings.default_id] highlight:YES];
|
||||
|
||||
// The first button added gets set as the default selected, so remove
|
||||
// that and set the button @ default_id to be default.
|
||||
[[ns_buttons objectAtIndex:0] setKeyEquivalent:@""];
|
||||
@@ -86,6 +83,11 @@ NSAlert* CreateNSAlert(const MessageBoxSettings& settings) {
|
||||
[[ns_buttons objectAtIndex:settings.cancel_id] setKeyEquivalent:@"\e"];
|
||||
}
|
||||
|
||||
// TODO(@codebytere): This behavior violates HIG & should be deprecated.
|
||||
if (settings.cancel_id >= 0 && settings.cancel_id == settings.default_id) {
|
||||
[[ns_buttons objectAtIndex:settings.default_id] highlight:YES];
|
||||
}
|
||||
|
||||
if (!settings.checkbox_label.empty()) {
|
||||
alert.showsSuppressionButton = YES;
|
||||
alert.suppressionButton.title =
|
||||
|
||||
@@ -39,7 +39,7 @@ class Archive : public node::ObjectWrap {
|
||||
Archive& operator=(const Archive&) = delete;
|
||||
|
||||
protected:
|
||||
explicit Archive(std::unique_ptr<asar::Archive> archive)
|
||||
explicit Archive(std::shared_ptr<asar::Archive> archive)
|
||||
: archive_(std::move(archive)) {}
|
||||
|
||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
@@ -52,8 +52,8 @@ class Archive : public node::ObjectWrap {
|
||||
return;
|
||||
}
|
||||
|
||||
auto archive = std::make_unique<asar::Archive>(path);
|
||||
if (!archive->Init()) {
|
||||
std::shared_ptr<asar::Archive> archive = asar::GetOrCreateAsarArchive(path);
|
||||
if (!archive) {
|
||||
isolate->ThrowException(v8::Exception::Error(node::FIXED_ONE_BYTE_STRING(
|
||||
isolate, "failed to initialize archive")));
|
||||
return;
|
||||
@@ -190,7 +190,7 @@ class Archive : public node::ObjectWrap {
|
||||
isolate, wrap->archive_ ? wrap->archive_->GetUnsafeFD() : -1));
|
||||
}
|
||||
|
||||
std::unique_ptr<asar::Archive> archive_;
|
||||
std::shared_ptr<asar::Archive> archive_;
|
||||
};
|
||||
|
||||
static void InitAsarSupport(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
@@ -4,14 +4,31 @@
|
||||
|
||||
#include "shell/common/language_util.h"
|
||||
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include <glib.h>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/i18n/rtl.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
std::vector<std::string> GetPreferredLanguages() {
|
||||
// Return empty as there's no API to use. You may be able to use
|
||||
// GetApplicationLocale() of a browser process.
|
||||
return std::vector<std::string>{};
|
||||
std::vector<std::string> preferredLanguages;
|
||||
|
||||
// Based on
|
||||
// https://source.chromium.org/chromium/chromium/src/+/refs/tags/108.0.5329.0:ui/base/l10n/l10n_util.cc;l=543-554
|
||||
// GLib implements correct environment variable parsing with
|
||||
// the precedence order: LANGUAGE, LC_ALL, LC_MESSAGES and LANG.
|
||||
const char* const* languages = g_get_language_names();
|
||||
DCHECK(languages); // A valid pointer is guaranteed.
|
||||
DCHECK(*languages); // At least one entry, "C", is guaranteed.
|
||||
|
||||
for (; *languages; ++languages) {
|
||||
if (strcmp(*languages, "C") != 0) {
|
||||
preferredLanguages.push_back(base::i18n::GetCanonicalLocale(*languages));
|
||||
}
|
||||
}
|
||||
|
||||
return preferredLanguages;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -124,6 +124,19 @@ describe('app module', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('app.getPreferredSystemLanguages()', () => {
|
||||
ifit(process.platform !== 'linux')('should not be empty', () => {
|
||||
expect(app.getPreferredSystemLanguages().length).to.not.equal(0);
|
||||
});
|
||||
|
||||
ifit(process.platform === 'linux')('should be empty or contain C entry', () => {
|
||||
const languages = app.getPreferredSystemLanguages();
|
||||
if (languages.length) {
|
||||
expect(languages).to.not.include('C');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('app.getLocaleCountryCode()', () => {
|
||||
it('should be empty or have length of two', () => {
|
||||
const localeCountryCode = app.getLocaleCountryCode();
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('BrowserView module', () => {
|
||||
});
|
||||
|
||||
// Linux and arm64 platforms (WOA and macOS) do not return any capture sources
|
||||
ifit(process.platform !== 'linux' && process.arch !== 'arm64')('sets the background color to transparent if none is set', async () => {
|
||||
ifit(process.platform === 'darwin' && process.arch === 'x64')('sets the background color to transparent if none is set', async () => {
|
||||
const display = screen.getPrimaryDisplay();
|
||||
const WINDOW_BACKGROUND_COLOR = '#55ccbb';
|
||||
|
||||
@@ -87,7 +87,7 @@ describe('BrowserView module', () => {
|
||||
});
|
||||
|
||||
// Linux and arm64 platforms (WOA and macOS) do not return any capture sources
|
||||
ifit(process.platform !== 'linux' && process.arch !== 'arm64')('successfully applies the background color', async () => {
|
||||
ifit(process.platform === 'darwin' && process.arch === 'x64')('successfully applies the background color', async () => {
|
||||
const WINDOW_BACKGROUND_COLOR = '#55ccbb';
|
||||
const VIEW_BACKGROUND_COLOR = '#ff00ff';
|
||||
const display = screen.getPrimaryDisplay();
|
||||
|
||||
@@ -5583,7 +5583,7 @@ describe('BrowserWindow module', () => {
|
||||
});
|
||||
|
||||
// Linux and arm64 platforms (WOA and macOS) do not return any capture sources
|
||||
ifit(process.platform !== 'linux' && process.arch !== 'arm64')('should not display a visible background', async () => {
|
||||
ifit(process.platform === 'darwin' && process.arch !== 'arm64')('should not display a visible background', async () => {
|
||||
const display = screen.getPrimaryDisplay();
|
||||
|
||||
const backgroundWindow = new BrowserWindow({
|
||||
@@ -5625,7 +5625,7 @@ describe('BrowserWindow module', () => {
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
// Linux/WOA doesn't return any capture sources.
|
||||
ifit(process.platform !== 'linux' && (process.platform !== 'win32' || process.arch !== 'arm64'))('should display the set color', async () => {
|
||||
ifit(process.platform === 'darwin')('should display the set color', async () => {
|
||||
const display = screen.getPrimaryDisplay();
|
||||
|
||||
const w = new BrowserWindow({
|
||||
|
||||
@@ -375,6 +375,7 @@ describe('command line switches', () => {
|
||||
describe('--lang switch', () => {
|
||||
const currentLocale = app.getLocale();
|
||||
const currentSystemLocale = app.getSystemLocale();
|
||||
const currentPreferredLanguages = JSON.stringify(app.getPreferredSystemLanguages());
|
||||
const testLocale = async (locale: string, result: string, printEnv: boolean = false) => {
|
||||
const appPath = path.join(fixturesPath, 'api', 'locale-check');
|
||||
const args = [appPath, `--set-lang=${locale}`];
|
||||
@@ -397,9 +398,9 @@ describe('command line switches', () => {
|
||||
expect(output).to.equal(result);
|
||||
};
|
||||
|
||||
it('should set the locale', async () => testLocale('fr', `fr|${currentSystemLocale}`));
|
||||
it('should set the locale with country code', async () => testLocale('zh-CN', `zh-CN|${currentSystemLocale}`));
|
||||
it('should not set an invalid locale', async () => testLocale('asdfkl', `${currentLocale}|${currentSystemLocale}`));
|
||||
it('should set the locale', async () => testLocale('fr', `fr|${currentSystemLocale}|${currentPreferredLanguages}`));
|
||||
it('should set the locale with country code', async () => testLocale('zh-CN', `zh-CN|${currentSystemLocale}|${currentPreferredLanguages}`));
|
||||
it('should not set an invalid locale', async () => testLocale('asdfkl', `${currentLocale}|${currentSystemLocale}|${currentPreferredLanguages}`));
|
||||
|
||||
const lcAll = String(process.env.LC_ALL);
|
||||
ifit(process.platform === 'linux')('current process has a valid LC_ALL env', async () => {
|
||||
@@ -2065,6 +2066,54 @@ describe('navigator.serial', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('window.getScreenDetails', () => {
|
||||
let w: BrowserWindow;
|
||||
before(async () => {
|
||||
w = new BrowserWindow({
|
||||
show: false
|
||||
});
|
||||
await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
|
||||
});
|
||||
|
||||
after(closeAllWindows);
|
||||
afterEach(() => {
|
||||
session.defaultSession.setPermissionRequestHandler(null);
|
||||
});
|
||||
|
||||
const getScreenDetails: any = () => {
|
||||
return w.webContents.executeJavaScript('window.getScreenDetails().then(data => data.screens).catch(err => err.message)', true);
|
||||
};
|
||||
|
||||
it('returns screens when a PermissionRequestHandler is not defined', async () => {
|
||||
const screens = await getScreenDetails();
|
||||
expect(screens).to.not.equal('Read permission denied.');
|
||||
});
|
||||
|
||||
it('returns an error when permission denied', async () => {
|
||||
session.defaultSession.setPermissionRequestHandler((wc, permission, callback) => {
|
||||
if (permission === 'window-placement') {
|
||||
callback(false);
|
||||
} else {
|
||||
callback(true);
|
||||
}
|
||||
});
|
||||
const screens = await getScreenDetails();
|
||||
expect(screens).to.equal('Permission denied.');
|
||||
});
|
||||
|
||||
it('returns screens when permission is granted', async () => {
|
||||
session.defaultSession.setPermissionRequestHandler((wc, permission, callback) => {
|
||||
if (permission === 'window-placement') {
|
||||
callback(true);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
const screens = await getScreenDetails();
|
||||
expect(screens).to.not.equal('Permission denied.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('navigator.clipboard', () => {
|
||||
let w: BrowserWindow;
|
||||
before(async () => {
|
||||
|
||||
2
spec/fixtures/api/locale-check/main.js
vendored
2
spec/fixtures/api/locale-check/main.js
vendored
@@ -9,7 +9,7 @@ app.whenReady().then(() => {
|
||||
if (process.argv[3] === '--print-env') {
|
||||
process.stdout.write(String(process.env.LC_ALL));
|
||||
} else {
|
||||
process.stdout.write(`${app.getLocale()}|${app.getSystemLocale()}`);
|
||||
process.stdout.write(`${app.getLocale()}|${app.getSystemLocale()}|${JSON.stringify(app.getPreferredSystemLanguages())}`);
|
||||
}
|
||||
process.stdout.end();
|
||||
|
||||
|
||||
291
yarn.lock
291
yarn.lock
@@ -118,10 +118,10 @@
|
||||
optionalDependencies:
|
||||
"@types/glob" "^7.1.1"
|
||||
|
||||
"@electron/docs-parser@^0.12.4":
|
||||
version "0.12.4"
|
||||
resolved "https://registry.yarnpkg.com/@electron/docs-parser/-/docs-parser-0.12.4.tgz#cca403c8c2200181339c3115cdd25f3fbfc7dea3"
|
||||
integrity sha512-vdkjcvkI7zTd2v1A8qsl5+HY+9AQCrW5Eh60I9rhPtUPoxo2V1pQwogTW6kzc3XZ54crTa7R3KxwkZpSbcGCug==
|
||||
"@electron/docs-parser@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@electron/docs-parser/-/docs-parser-1.0.0.tgz#1844ed2e18528ea56aaef0ace1cfa0633a6fa1b1"
|
||||
integrity sha512-nIqEO8Ga6LavdaY2aJMPfq2vSOPVlgOvNv7jpiyaoqsAz5vYnWNUnxeCyaalCaDyFiKhVeHbKwP8Kt2TENwneg==
|
||||
dependencies:
|
||||
"@types/markdown-it" "^10.0.0"
|
||||
chai "^4.2.0"
|
||||
@@ -133,10 +133,18 @@
|
||||
ora "^4.0.3"
|
||||
pretty-ms "^5.1.0"
|
||||
|
||||
"@electron/typescript-definitions@^8.9.5":
|
||||
version "8.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@electron/typescript-definitions/-/typescript-definitions-8.9.5.tgz#e6cb08e0e7c9656e178b892eab50866a8a80bf7a"
|
||||
integrity sha512-xDLFl6joGpA8c9cGSPWC3DFHyIGf9+OWZmDrPbGJW1URt6C1ukdQWKSmjb1Rttb94QQxBrGuUlSyz27IQgLFsw==
|
||||
"@electron/github-app-auth@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@electron/github-app-auth/-/github-app-auth-1.5.0.tgz#426e64ba50143417d9b68f2795a1b119cb62108b"
|
||||
integrity sha512-t6Za+3E7jdIf1CX06nNV/avZhqSXNEkCLJ1xeAt5FKU9HdGbjzwSfirM+UlHO7lMGyuf13BGCZOCB1kODhDLWQ==
|
||||
dependencies:
|
||||
"@octokit/auth-app" "^3.6.1"
|
||||
"@octokit/rest" "^18.12.0"
|
||||
|
||||
"@electron/typescript-definitions@^8.10.0":
|
||||
version "8.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@electron/typescript-definitions/-/typescript-definitions-8.10.0.tgz#e9cf2b329ec4b0b76947ef751725383a6cf8994d"
|
||||
integrity sha512-FVc2y0GUfxFZDoma0scYiMxkoalle19Fq332fNFGWoCJ9rCj5OUvriewSjPtGBsRuHv2xaMS5MhBuy2/pRuFuQ==
|
||||
dependencies:
|
||||
"@types/node" "^11.13.7"
|
||||
chalk "^2.4.2"
|
||||
@@ -170,20 +178,79 @@
|
||||
"@nodelib/fs.scandir" "2.1.3"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@octokit/auth-app@^2.10.0":
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-2.10.0.tgz#ad79369fca1cc3035859f797310d5e81cc6e49c4"
|
||||
integrity sha512-mKFU7O5wI651iWgecs4fmJ2aLqOM3sWD1FJsUTm7nx21I4ePDhS+rGQmS5TZk5yz75Va6wEXesxUNFzuqCbP2A==
|
||||
"@octokit/auth-app@^3.6.1":
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-3.6.1.tgz#aa5b02cc211175cbc28ce6c03c73373c1206d632"
|
||||
integrity sha512-6oa6CFphIYI7NxxHrdVOzhG7hkcKyGyYocg7lNDSJVauVOLtylg8hNJzoUyPAYKKK0yUeoZamE/lMs2tG+S+JA==
|
||||
dependencies:
|
||||
"@octokit/request" "^5.3.0"
|
||||
"@octokit/request-error" "^2.0.0"
|
||||
"@octokit/types" "^5.0.0"
|
||||
"@octokit/auth-oauth-app" "^4.3.0"
|
||||
"@octokit/auth-oauth-user" "^1.2.3"
|
||||
"@octokit/request" "^5.6.0"
|
||||
"@octokit/request-error" "^2.1.0"
|
||||
"@octokit/types" "^6.0.3"
|
||||
"@types/lru-cache" "^5.1.0"
|
||||
deprecation "^2.3.1"
|
||||
lru-cache "^6.0.0"
|
||||
universal-github-app-jwt "^1.0.1"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/auth-oauth-app@^4.3.0":
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-4.3.4.tgz#7030955b1a59d4d977904775c606477d95fcfe8e"
|
||||
integrity sha512-OYOTSSINeUAiLMk1uelaGB/dEkReBqHHr8+hBejzMG4z1vA4c7QSvDAS0RVZSr4oD4PEUPYFzEl34K7uNrXcWA==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-device" "^3.1.1"
|
||||
"@octokit/auth-oauth-user" "^2.0.0"
|
||||
"@octokit/request" "^5.6.3"
|
||||
"@octokit/types" "^6.0.3"
|
||||
"@types/btoa-lite" "^1.0.0"
|
||||
btoa-lite "^1.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/auth-oauth-device@^3.1.1":
|
||||
version "3.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-3.1.4.tgz#703c42f27a1e2eb23498a7001ad8e9ecf4a2f477"
|
||||
integrity sha512-6sHE/++r+aEFZ/BKXOGPJcH/nbgbBjS1A4CHfq/PbPEwb0kZEt43ykW98GBO/rYBPAYaNpCPvXfGwzgR9yMCXg==
|
||||
dependencies:
|
||||
"@octokit/oauth-methods" "^2.0.0"
|
||||
"@octokit/request" "^6.0.0"
|
||||
"@octokit/types" "^6.10.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/auth-oauth-device@^4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.3.tgz#00ce77233517e0d7d39e42a02652f64337d9df81"
|
||||
integrity sha512-KPTx5nMntKjNZzzltO3X4T68v22rd7Cp/TcLJXQE2U8aXPcZ9LFuww9q9Q5WUNSu3jwi3lRwzfkPguRfz1R8Vg==
|
||||
dependencies:
|
||||
"@octokit/oauth-methods" "^2.0.0"
|
||||
"@octokit/request" "^6.0.0"
|
||||
"@octokit/types" "^8.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/auth-oauth-user@^1.2.3":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-1.3.0.tgz#da4e4529145181a6aa717ae858afb76ebd6e3360"
|
||||
integrity sha512-3QC/TAdk7onnxfyZ24BnJRfZv8TRzQK7SEFUS9vLng4Vv6Hv6I64ujdk/CUkREec8lhrwU764SZ/d+yrjjqhaQ==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-device" "^3.1.1"
|
||||
"@octokit/oauth-methods" "^1.1.0"
|
||||
"@octokit/request" "^5.4.14"
|
||||
"@octokit/types" "^6.12.2"
|
||||
btoa-lite "^1.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/auth-oauth-user@^2.0.0":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-2.0.4.tgz#88f060ec678d7d493695af8d827e115dd064e212"
|
||||
integrity sha512-HrbDzTPqz6GcGSOUkR+wSeF3vEqsb9NMsmPja/qqqdiGmlk/Czkxctc3KeWYogHonp62Ml4kjz2VxKawrFsadQ==
|
||||
dependencies:
|
||||
"@octokit/auth-oauth-device" "^4.0.0"
|
||||
"@octokit/oauth-methods" "^2.0.0"
|
||||
"@octokit/request" "^6.0.0"
|
||||
"@octokit/types" "^8.0.0"
|
||||
btoa-lite "^1.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/auth-token@^2.4.0":
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.2.tgz#10d0ae979b100fa6b72fa0e8e63e27e6d0dbff8a"
|
||||
@@ -191,6 +258,13 @@
|
||||
dependencies:
|
||||
"@octokit/types" "^5.0.0"
|
||||
|
||||
"@octokit/auth-token@^2.4.4":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36"
|
||||
integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.0.3"
|
||||
|
||||
"@octokit/core@^3.0.0":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.1.1.tgz#1856745aa8fb154cf1544a2a1b82586c809c5e66"
|
||||
@@ -203,6 +277,19 @@
|
||||
before-after-hook "^2.1.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/core@^3.5.1":
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.6.0.tgz#3376cb9f3008d9b3d110370d90e0a1fcd5fe6085"
|
||||
integrity sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==
|
||||
dependencies:
|
||||
"@octokit/auth-token" "^2.4.4"
|
||||
"@octokit/graphql" "^4.5.8"
|
||||
"@octokit/request" "^5.6.3"
|
||||
"@octokit/request-error" "^2.0.5"
|
||||
"@octokit/types" "^6.0.3"
|
||||
before-after-hook "^2.2.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/endpoint@^6.0.1":
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.5.tgz#43a6adee813c5ffd2f719e20cfd14a1fee7c193a"
|
||||
@@ -212,6 +299,15 @@
|
||||
is-plain-object "^4.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/endpoint@^7.0.0":
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.3.tgz#0b96035673a9e3bedf8bab8f7335de424a2147ed"
|
||||
integrity sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw==
|
||||
dependencies:
|
||||
"@octokit/types" "^8.0.0"
|
||||
is-plain-object "^5.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/graphql@^4.3.1":
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.5.3.tgz#d5ff0d4a8a33e98614a2a7359dac98bc285e062f"
|
||||
@@ -221,6 +317,64 @@
|
||||
"@octokit/types" "^5.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/graphql@^4.5.8":
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3"
|
||||
integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==
|
||||
dependencies:
|
||||
"@octokit/request" "^5.6.0"
|
||||
"@octokit/types" "^6.0.3"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/oauth-authorization-url@^4.3.1":
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-4.3.3.tgz#6a6ef38f243086fec882b62744f39b517528dfb9"
|
||||
integrity sha512-lhP/t0i8EwTmayHG4dqLXgU+uPVys4WD/qUNvC+HfB1S1dyqULm5Yx9uKc1x79aP66U1Cb4OZeW8QU/RA9A4XA==
|
||||
|
||||
"@octokit/oauth-authorization-url@^5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz#029626ce87f3b31addb98cd0d2355c2381a1c5a1"
|
||||
integrity sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==
|
||||
|
||||
"@octokit/oauth-methods@^1.1.0":
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-1.2.6.tgz#b9ac65e374b2cc55ee9dd8dcdd16558550438ea7"
|
||||
integrity sha512-nImHQoOtKnSNn05uk2o76om1tJWiAo4lOu2xMAHYsNr0fwopP+Dv+2MlGvaMMlFjoqVd3fF3X5ZDTKCsqgmUaQ==
|
||||
dependencies:
|
||||
"@octokit/oauth-authorization-url" "^4.3.1"
|
||||
"@octokit/request" "^5.4.14"
|
||||
"@octokit/request-error" "^2.0.5"
|
||||
"@octokit/types" "^6.12.2"
|
||||
btoa-lite "^1.0.0"
|
||||
|
||||
"@octokit/oauth-methods@^2.0.0":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-2.0.4.tgz#6abd9593ca7f91fe5068375a363bd70abd5516dc"
|
||||
integrity sha512-RDSa6XL+5waUVrYSmOlYROtPq0+cfwppP4VaQY/iIei3xlFb0expH6YNsxNrZktcLhJWSpm9uzeom+dQrXlS3A==
|
||||
dependencies:
|
||||
"@octokit/oauth-authorization-url" "^5.0.0"
|
||||
"@octokit/request" "^6.0.0"
|
||||
"@octokit/request-error" "^3.0.0"
|
||||
"@octokit/types" "^8.0.0"
|
||||
btoa-lite "^1.0.0"
|
||||
|
||||
"@octokit/openapi-types@^12.11.0":
|
||||
version "12.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-12.11.0.tgz#da5638d64f2b919bca89ce6602d059f1b52d3ef0"
|
||||
integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==
|
||||
|
||||
"@octokit/openapi-types@^14.0.0":
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a"
|
||||
integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==
|
||||
|
||||
"@octokit/plugin-paginate-rest@^2.16.8":
|
||||
version "2.21.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz#7f12532797775640dbb8224da577da7dc210c87e"
|
||||
integrity sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.40.0"
|
||||
|
||||
"@octokit/plugin-paginate-rest@^2.2.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.3.0.tgz#7d1073e56cfd15d3f99dcfe81fa5d2b466f3a6f6"
|
||||
@@ -233,6 +387,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz#eef87a431300f6148c39a7f75f8cfeb218b2547e"
|
||||
integrity sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==
|
||||
|
||||
"@octokit/plugin-request-log@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85"
|
||||
integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@4.1.2":
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.1.2.tgz#546a8f3e0b514f434a4ad4ef926005f1c81a5a5a"
|
||||
@@ -241,6 +400,14 @@
|
||||
"@octokit/types" "^5.1.1"
|
||||
deprecation "^2.3.1"
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@^5.12.0":
|
||||
version "5.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz#7ee8bf586df97dd6868cf68f641354e908c25342"
|
||||
integrity sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.39.0"
|
||||
deprecation "^2.3.1"
|
||||
|
||||
"@octokit/request-error@^2.0.0":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.2.tgz#0e76b83f5d8fdda1db99027ea5f617c2e6ba9ed0"
|
||||
@@ -250,6 +417,24 @@
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677"
|
||||
integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.0.3"
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request-error@^3.0.0":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.2.tgz#f74c0f163d19463b87528efe877216c41d6deb0a"
|
||||
integrity sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==
|
||||
dependencies:
|
||||
"@octokit/types" "^8.0.0"
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request@^5.3.0", "@octokit/request@^5.4.0":
|
||||
version "5.4.7"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.7.tgz#fd703ee092e0463ceba49ff7a3e61cb4cf8a0fde"
|
||||
@@ -264,6 +449,30 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/request@^5.4.14", "@octokit/request@^5.6.0", "@octokit/request@^5.6.3":
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.3.tgz#19a022515a5bba965ac06c9d1334514eb50c48b0"
|
||||
integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^6.0.1"
|
||||
"@octokit/request-error" "^2.1.0"
|
||||
"@octokit/types" "^6.16.1"
|
||||
is-plain-object "^5.0.0"
|
||||
node-fetch "^2.6.7"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/request@^6.0.0":
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.2.tgz#a2ba5ac22bddd5dcb3f539b618faa05115c5a255"
|
||||
integrity sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^7.0.0"
|
||||
"@octokit/request-error" "^3.0.0"
|
||||
"@octokit/types" "^8.0.0"
|
||||
is-plain-object "^5.0.0"
|
||||
node-fetch "^2.6.7"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/rest@^18.0.3":
|
||||
version "18.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.0.3.tgz#96a15ddb3a38dca5de9d75121378d6aa4a234fa5"
|
||||
@@ -274,6 +483,16 @@
|
||||
"@octokit/plugin-request-log" "^1.0.0"
|
||||
"@octokit/plugin-rest-endpoint-methods" "4.1.2"
|
||||
|
||||
"@octokit/rest@^18.12.0":
|
||||
version "18.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.12.0.tgz#f06bc4952fc87130308d810ca9d00e79f6988881"
|
||||
integrity sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==
|
||||
dependencies:
|
||||
"@octokit/core" "^3.5.1"
|
||||
"@octokit/plugin-paginate-rest" "^2.16.8"
|
||||
"@octokit/plugin-request-log" "^1.0.4"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^5.12.0"
|
||||
|
||||
"@octokit/types@^5.0.0", "@octokit/types@^5.0.1", "@octokit/types@^5.1.1", "@octokit/types@^5.2.0":
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-5.2.0.tgz#d075dc23bf293f540739250b6879e2c1be2fc20c"
|
||||
@@ -281,6 +500,20 @@
|
||||
dependencies:
|
||||
"@types/node" ">= 8"
|
||||
|
||||
"@octokit/types@^6.0.3", "@octokit/types@^6.10.0", "@octokit/types@^6.12.2", "@octokit/types@^6.16.1", "@octokit/types@^6.39.0", "@octokit/types@^6.40.0":
|
||||
version "6.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.41.0.tgz#e58ef78d78596d2fb7df9c6259802464b5f84a04"
|
||||
integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^12.11.0"
|
||||
|
||||
"@octokit/types@^8.0.0":
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-8.0.0.tgz#93f0b865786c4153f0f6924da067fe0bb7426a9f"
|
||||
integrity sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^14.0.0"
|
||||
|
||||
"@opentelemetry/api@^1.0.1":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.4.tgz#a167e46c10d05a07ab299fc518793b0cff8f6924"
|
||||
@@ -337,6 +570,11 @@
|
||||
"@types/connect" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/btoa-lite@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/btoa-lite/-/btoa-lite-1.0.0.tgz#e190a5a548e0b348adb0df9ac7fa5f1151c7cca4"
|
||||
integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==
|
||||
|
||||
"@types/busboy@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/busboy/-/busboy-0.2.3.tgz#6697ad29873246c530f09a3ff5a40861824230d5"
|
||||
@@ -1325,6 +1563,11 @@ before-after-hook@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
|
||||
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
|
||||
|
||||
before-after-hook@^2.2.0:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c"
|
||||
integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==
|
||||
|
||||
big.js@^5.2.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
||||
@@ -1461,6 +1704,11 @@ browserify-zlib@^0.2.0:
|
||||
dependencies:
|
||||
pako "~1.0.5"
|
||||
|
||||
btoa-lite@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
|
||||
integrity sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
@@ -1910,7 +2158,7 @@ compress-brotli@^1.3.8:
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
concat-stream@^1.5.0:
|
||||
version "1.6.2"
|
||||
@@ -4030,6 +4278,11 @@ is-plain-object@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-4.1.1.tgz#1a14d6452cbd50790edc7fdaa0aed5a40a35ebb5"
|
||||
integrity sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==
|
||||
|
||||
is-plain-object@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
|
||||
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
|
||||
|
||||
is-regex@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
|
||||
@@ -5037,9 +5290,9 @@ minimalistic-crypto-utils@^1.0.1:
|
||||
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
||||
|
||||
minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1"
|
||||
integrity sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user