Compare commits

...

71 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
0b804177fa Bump v15.5.7 2022-05-24 07:51:39 -07:00
trop[bot]
77478353c6 fix: crash on navigator.serial.getPorts() (#34333)
(cherry picked from commit 7f9431764f)
(cherry picked from commit 1b5738e308)

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-24 10:46:50 -04:00
Sudowoodo Release Bot
30e8011b9f Bump v15.5.6 2022-05-23 08:04:01 -07:00
Keeley Hammond
54432ab8b2 build: fix index upload error on 15-x-y (#34314) 2022-05-23 14:04:05 +02:00
trop[bot]
37558a6215 revert: some frameless windows showing a frame on Windows (#33608)
Revert "fix: some frameless windows showing a frame on Windows (#32692)"

This reverts commit 7c701367c0.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-05-19 10:15:03 +02:00
Darshan Sen
d5ba5c8e0a fix: crash in safeStorage on Linux (#34263) 2022-05-19 10:04:19 +02:00
Sudowoodo Release Bot
b1b83f79b7 Revert "Bump v15.5.6"
This reverts commit ade9151181.
2022-05-18 11:38:29 -07:00
trop[bot]
a85b38847e fix: building with printing disabled (#34273)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-18 09:42:13 -07:00
Sudowoodo Release Bot
ade9151181 Bump v15.5.6 2022-05-18 08:32:28 -07:00
Pedro Pontes
9d2961868c chore: cherry-pick 99c3f3bfd507 from chromium (#34227)
* chore: cherry-pick 99c3f3bfd507 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-17 15:15:47 -04:00
Pedro Pontes
cdd6fc93b2 chore: cherry-pick d49484c21e3c from angle (#34014)
Co-authored-by: Electron Bot <electron@github.com>
2022-05-17 13:30:48 -04:00
Pedro Pontes
1e21b7c910 chore: cherry-pick 14e51893e5 from icu (#34224)
* chore: cherry-pick 14e51893e5 from icu

* chore: fixup patch for lint

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-17 11:26:59 -04:00
trop[bot]
c224431ae8 docs: add missing explanation for [angle|dawn]_enable_vulkan_validation_layers = false (#34255)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-17 11:24:32 -04:00
Pedro Pontes
9e0fda8393 chore: cherry-pick ec0cce63f47d from chromium (#34234)
* chore: cherry-pick ec0cce63f47d from chromium

* chore: update patches

* Trigger Build

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-16 18:12:09 -04:00
Pedro Pontes
36b72ba5ee chore: cherry-pick a4f71e40e5 from angle (#34231) 2022-05-16 14:58:12 -04:00
Darshan Sen
dd8c63e15a docs: note safeStorage.isEncryptionAvailable() needs ready event (#34220)
docs: note safeStorage.isEncryptionAvailable() needs ready event (#33724)

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-05-16 12:12:14 -04:00
Pedro Pontes
6bfa54fcf2 chore: cherry-pick a602a068e022 from angle (#34201)
* chore: cherry-pick a602a068e022 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-12 20:19:44 -04:00
Samuel Attard
6d9f3a4945 fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#34191)
fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#33367)

* Make ElectronBrowser mojo interface frame associated. (#32815)

Co-authored-by: Marek Haranczyk <marek@openfin.co>

* fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#33323) (#33350)

* fix: ensure ElectronBrowser mojo service is only bound to authorized render frames

Notes: no-notes

* refactor: extract electron API IPC to its own mojo interface

* fix: just check main frame not primary main frame

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Marek Haranczyk <marek@openfin.co>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Marek Haranczyk <marek@openfin.co>
2022-05-12 15:26:59 -07:00
Samuel Attard
a20396588a build: improve CI speeds and reduce CI costs (#34184)
build: improve CI speeds and reduce CI costs (#33904) (#33953)

* build: improve CI speeds and reduce CI costs (#33904)

* remove third_party/electron_node:overlapped-checker

target isn't present in older versions

* build: use original arch logic

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Samuel Attard <sattard@salesforce.com>

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-11 12:38:19 -07:00
Sudowoodo Release Bot
f988853128 Bump v15.5.5 2022-05-11 08:31:43 -07:00
trop[bot]
8bc25e8a9d build: change upload-to-s3 vars to upload-to-storage (#34142)
* build: change upload-to-s3 vars to upload-to-az

* build: change upload-to-az to upload-to-storage

* build: change linux-ia32-publish var

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-05-11 10:02:03 -04:00
trop[bot]
a8f8b507aa build: use azure function to hash assets instead of lambda (#34119)
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-05-08 09:30:23 -07:00
trop[bot]
eb320cbbf9 build: stop uploading assets to S3 (#34112)
* build: remove S3 uploads

* build: remove ending slash upload-index-json (#34125)

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2022-05-07 14:48:27 -07:00
Pedro Pontes
37eab5c66e chore: cherry-pick 5be8e065f43e from chromium (#34040)
* chore: cherry-pick 5be8e065f43e from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-05 09:58:08 -04:00
Pedro Pontes
fc912026e2 chore: cherry-pick 5361d836ae from chromium (#34009) 2022-05-04 16:53:02 -07:00
Pedro Pontes
6aa0609a97 chore: cherry-pick 6b66a45021 from chromium (#34075) 2022-05-04 16:30:38 -07:00
trop[bot]
620d615fe0 test: fix nativeModulesEnabled in spec/webview-spec.js (#34063)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-04 11:57:24 -04:00
Sudowoodo Release Bot
ec7baba401 Bump v15.5.4 2022-05-04 08:34:57 -07:00
Pedro Pontes
f8ba4d6012 chore: cherry-pick d27d9d059b51 from angle (#34045)
* chore: cherry-pick d27d9d059b51 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-04 16:28:55 +02:00
Pedro Pontes
79af6f3493 chore: cherry-pick 5ff02e4d7368 from chromium (#34019)
* chore: cherry-pick 5ff02e4d7368 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-05-03 23:57:14 -07:00
Pedro Pontes
6a952c4ff1 chore: cherry-pick d24570fb65 from angle (#34037)
* chore: cherry-pick d24570fb65 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-03 16:16:03 -07:00
Pedro Pontes
ce7c83e8d6 chore: cherry-pick 12ba78f3fa7a from chromium (#34051)
* chore: cherry-pick 12ba78f3fa7a from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-03 16:15:53 -07:00
Pedro Pontes
a686f7e102 chore: cherry-pick 1665a1d16d46 from chromium (#33682)
* chore: cherry-pick 1665a1d16d46 from chromium

* chore: update patches

* Trigger Build

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-05-03 16:40:38 +09:00
trop[bot]
fa07b74836 build: allow script/spec-runner.js with empty list of runners (#33999)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-02 11:09:21 -04:00
trop[bot]
587353dbc9 spec: allow connections to port 2049 (#33989)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-05-02 14:47:39 +09:00
Samuel Attard
21b8b3064d build: use dev-cdn instead of sysroots s3 bucket (#33987)
* build: use dev-cdn instead of sysroots s3 bucket (#33922)

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-05-02 10:31:34 +09:00
Sudowoodo Release Bot
0f05991c3e Bump v15.5.3 2022-04-29 15:16:22 -07:00
Keeley Hammond
6bdab4a353 build: revert migrate urllib to python3 (#33980)
This reverts commit a29136950e.
2022-04-29 15:04:24 -07:00
Sudowoodo Release Bot
6e5f02426a Revert "Bump v15.5.3"
This reverts commit 30da5dee2a.
2022-04-29 12:33:33 -07:00
Sudowoodo Release Bot
30da5dee2a Bump v15.5.3 2022-04-29 09:14:26 -07:00
Pedro Pontes
bd9c7c41ba chore: cherry-pick 2004594a46c8 from v8 (#33884)
* chore: cherry-pick 2004594a46c8 from v8

* chore: update patches

* Trigger Build

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-04-29 01:51:41 -07:00
Pedro Pontes
76f4ced8d4 chore: cherry-pick 4d26949260aa from chromium (#33676)
* chore: cherry-pick 4d26949260aa from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-28 20:36:58 -04:00
Pedro Pontes
cac38cb6ea chore: cherry-pick 4deb522c22 and d88e959e01 from chromium (#33852)
* chore: cherry-pick d88e959e01 from chromium

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-28 20:27:49 -04:00
trop[bot]
e8f89da1c4 build: ensure sync-done file exists during git cache save (#33954)
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-04-27 18:27:13 -07:00
Samuel Attard
a0f73938cd build: upload to AZ as well as S3 (#33927)
* build: upload to AZ as well as S3

* build: actually verify az urls too
2022-04-27 10:44:28 -07:00
Samuel Attard
1bf71fa81f build: improve circleci config (#33945)
* build: improve circleci config (#33881)

* build: fix conditional restore of git cache

* build: split lint out of setup.yml

* ci: update release script to handle new CircleCI configs (#33914)

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-04-27 10:13:01 -07:00
Sudowoodo Release Bot
0de8079b33 Revert "Bump v15.5.3"
This reverts commit 52fd3da443.
2022-04-27 09:34:00 -07:00
Sudowoodo Release Bot
52fd3da443 Bump v15.5.3 2022-04-27 08:32:55 -07:00
Pedro Pontes
742aab764e chore: cherry-pick 1a31e2110440 from chromium (#33856)
* chore: cherry-pick 1a31e2110440 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-25 09:36:28 +09:00
trop[bot]
1f669c3cc5 chore: use semantic-commit-action (#33863)
* chore: use semantic-commit-action

* Update semantic.yml

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-04-21 14:55:29 -07:00
Pedro Pontes
d26d064082 chore: cherry-pick e42dbcdedb7a from v8 (#33831)
* chore: cherry-pick e42dbcdedb7a from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2022-04-21 17:24:26 +09:00
Pedro Pontes
a31e722d43 chore: cherry-pick 5cb934a23d from chromium (#33860) 2022-04-21 15:09:55 +09:00
Sudowoodo Release Bot
81b923c8f5 Revert "Bump v15.5.3"
This reverts commit 91cf2e2163.
2022-04-20 16:24:29 -07:00
Pedro Pontes
b745364907 chore: cherry-pick b2d3ef69ef99 from v8 (#33836) 2022-04-20 13:51:53 -07:00
Sudowoodo Release Bot
91cf2e2163 Bump v15.5.3 2022-04-20 08:32:27 -07:00
Pedro Pontes
53af38ad54 chore: cherry-pick 652dd12a85 from chromium (#33670)
Co-authored-by: Electron Bot <electron@github.com>
2022-04-18 12:37:00 +09:00
trop[bot]
2fef020e06 chore: interpret bytes to string (#33772)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-04-14 06:28:46 -07:00
Pedro Pontes
b60dfe4117 chore: cherry-pick a1dc371d66 from chromium (#33679) 2022-04-14 12:35:40 +02:00
Pedro Pontes
7e123ac6e5 chore: cherry-pick f546ac11eec7 from v8 (#33763)
* chore: cherry-pick f546ac11eec7 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-14 19:17:23 +09:00
trop[bot]
a29136950e build: migrate urllib to python3 (#33741)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-04-13 10:55:10 -07:00
Jeremy Rose
458a843174 chore: cherry-pick a48de319c521 from pdfium (#33715)
* chore: cherry-pick a48de319c521 from pdfium

* Update config.json

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-04-12 12:00:25 +02:00
Pedro Pontes
e11e12d5b3 chore: cherry-pick ac341df436 from webrtc (#33673) 2022-04-12 11:04:40 +02:00
trop[bot]
25ed65150d fix: report more detailed errors in shell.openExternal() on Windows (#33656)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-04-11 08:52:27 -07:00
Jeremy Rose
8737aa046d fix: prevent UAF crash in setCertificateVerifyProc (#33256) 2022-04-06 12:37:25 -07:00
Sudowoodo Release Bot
0d94bdda50 Bump v15.5.2 2022-04-06 08:31:42 -07:00
Jeremy Rose
2c3081afb8 chore: cherry-pick f599381978f2 from v8 (#33606) 2022-04-05 09:42:19 -07:00
John Kleinschmidt
f583acff46 test: disable newly added/failing test on Windows (#33615) 2022-04-05 12:23:31 -04:00
Milan Burda
271e98c059 fix: building with printing disabled (#33603) 2022-04-04 16:40:01 -07:00
trop[bot]
8279c02e9a fix: gn check when //printing component is disabled (#33601)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-04-04 16:39:40 -07:00
David Sanders
ef4cbe86af fix: on macOS show BrowserWindow on maximize if not currently shown (#33523) 2022-03-30 19:20:28 -04:00
Jeremy Rose
300a40f939 chore: cherry-pick a1427aad7cef from v8 (#33525)
* chore: cherry-pick a1427aad7cef from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-03-30 19:06:49 -04:00
99 changed files with 5215 additions and 767 deletions

1
.circleci/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
config-staging

View File

@@ -6,6 +6,7 @@ setup: true
# Orbs
orbs:
path-filtering: circleci/path-filtering@0.1.0
continuation: circleci/continuation@0.2.0
# All input parameters to pass to build config
parameters:
@@ -13,7 +14,7 @@ parameters:
type: boolean
default: false
upload-to-s3:
upload-to-storage:
type: string
default: '1'
@@ -43,103 +44,33 @@ parameters:
default: all
enum: ["all", "osx-x64", "osx-arm64", "mas-x64", "mas-arm64"]
# Envs
env-global: &env-global
ELECTRON_OUT_DIR: Default
env-linux-medium: &env-linux-medium
<<: *env-global
NUMBER_OF_NINJA_PROCESSES: 3
# Executors
executors:
linux-docker:
parameters:
size:
description: "Docker executor size"
default: 2xlarge+
type: enum
enum: ["medium", "xlarge", "2xlarge+"]
docker:
- image: ghcr.io/electron/build:27db4a3e3512bfd2e47f58cea69922da0835f1d9
resource_class: << parameters.size >>
# List of always run steps
step-checkout-electron: &step-checkout-electron
checkout:
path: src/electron
steps-lint: &steps-lint
steps:
- *step-checkout-electron
- run:
name: Setup third_party Depot Tools
command: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
- run:
name: Download GN Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . \<<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@Subdir src/buildtools/linux64
gn/gn/linux-amd64 $gn_version
CIPD
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
- run:
name: Download clang-format Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
sha1_path='buildtools/linux64/clang-format.sha1'
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/${sha1_path}?format=TEXT" | base64 -d > "src/${sha1_path}"
download_from_google_storage.py --no_resume --no_auth --bucket chromium-clang-format -s "src/${sha1_path}"
- run:
name: Run Lint
command: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
- run:
name: Run Script Typechecker
command: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json
# List of always run jobs.
jobs:
lint:
executor:
name: linux-docker
size: medium
environment:
<<: *env-linux-medium
<<: *steps-lint
# Initial setup workflow
workflows:
lint:
jobs:
# Job inherited from path-filtering orb
- path-filtering/filter:
generate-config:
docker:
- image: cimg/node:16.14
steps:
- checkout
- path-filtering/set-parameters:
base-revision: main
# Params for mapping; `path-to-test parameter-to-set value-for-parameter` for each row
mapping: |
^((?!docs/).)*$ run-build-mac true
^((?!docs/).)*$ run-build-linux true
docs/.* run-docs-only true
^((?!docs/).)*$ run-docs-only false
config-path: .circleci/build_config.yml
- lint
- run:
command: |
cd .circleci/config
yarn
export CIRCLECI_BINARY="$HOME/circleci"
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | DESTDIR=$CIRCLECI_BINARY bash
node build.js
name: Pack config.yml
- continuation/continue:
configuration_path: .circleci/config-staging/built.yml
parameters: /tmp/pipeline-parameters.json
# Initial setup workflow
workflows:
setup:
jobs:
- generate-config

View File

@@ -5,7 +5,7 @@ parameters:
type: boolean
default: false
upload-to-s3:
upload-to-storage:
type: string
default: '1'
@@ -330,6 +330,19 @@ step-setup-goma-for-build: &step-setup-goma-for-build
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
cd ..
touch "${TMPDIR:=/tmp}"/.goma-ready
background: true
step-wait-for-goma: &step-wait-for-goma
run:
name: Wait for Goma
command: |
until [ -f "${TMPDIR:=/tmp}"/.goma-ready ]
do
sleep 5
done
echo "Goma ready"
no_output_timeout: 2m
step-restore-brew-cache: &step-restore-brew-cache
restore_cache:
@@ -543,14 +556,6 @@ step-electron-build: &step-electron-build
cp out/Default/.ninja_log out/electron_ninja_log
node electron/script/check-symlinks.js
step-native-unittests-build: &step-native-unittests-build
run:
name: Build native test targets
no_output_timeout: 30m
command: |
cd src
ninja -C out/Default shell_browser_ui_unittests -j $NUMBER_OF_NINJA_PROCESSES
step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
run:
name: Strip electron binaries
@@ -569,40 +574,6 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
electron/script/add-debug-link.py --target-cpu="$target_cpu" --debug-dir=out/Default/debug
fi
step-electron-dist-build: &step-electron-dist-build
run:
name: Build dist.zip
command: |
cd src
if [ "$SKIP_DIST_ZIP" != "1" ]; then
ninja -C out/Default electron:electron_dist_zip
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
if [ "$TARGET_ARCH" == "arm64" ]; then
target_cpu=arm64
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
fi
fi
step-electron-chromedriver-build: &step-electron-chromedriver-build
run:
name: Build chromedriver.zip
@@ -639,9 +610,9 @@ step-electron-publish: &step-electron-publish
fi
cd src/electron
if [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Uploading Electron release distribution to S3'
script/release/uploaders/upload.py --verbose --upload_to_s3
if [ "$UPLOAD_TO_STORAGE" == "1" ]; then
echo 'Uploading Electron release distribution to Azure'
script/release/uploaders/upload.py --verbose --UPLOAD_TO_STORAGE
else
echo 'Uploading Electron release distribution to Github releases'
script/release/uploaders/upload.py --verbose
@@ -655,7 +626,6 @@ step-persist-data-for-tests: &step-persist-data-for-tests
- src/out/Default/dist.zip
- src/out/Default/mksnapshot.zip
- src/out/Default/chromedriver.zip
- src/out/Default/shell_browser_ui_unittests
- src/out/Default/gen/node_headers
- src/out/ffmpeg/ffmpeg.zip
- src/electron
@@ -766,6 +736,7 @@ step-show-goma-stats: &step-show-goma-stats
$LOCAL_GOMA_DIR/diagnose_goma_log.py
true
when: always
background: true
step-mksnapshot-build: &step-mksnapshot-build
run:
@@ -890,12 +861,12 @@ step-touch-sync-done: &step-touch-sync-done
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
keys:
- v8-src-cache-{{ checksum "src/electron/.depshash" }}
- v14-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:
- v1-src-cache-marker-{{ checksum "src/electron/.depshash" }}
- v14-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
@@ -904,10 +875,10 @@ step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
step-maybe-restore-git-cache: &step-maybe-restore-git-cache
restore_cache:
paths:
- ~/.gclient-cache
- git-cache
keys:
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
step-restore-out-cache: &step-restore-out-cache
@@ -924,15 +895,15 @@ step-set-git-cache-path: &step-set-git-cache-path
command: |
# CircleCI does not support interpolation when setting environment variables.
# https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-shell-command
echo 'export GIT_CACHE_PATH="$HOME/.gclient-cache"' >> $BASH_ENV
echo 'export GIT_CACHE_PATH="$PWD/git-cache"' >> $BASH_ENV
# Persist the git cache based on the hash of DEPS and .circle-sync-done
# If the src cache was restored above then this will persist an empty cache
step-save-git-cache: &step-save-git-cache
save_cache:
paths:
- ~/.gclient-cache
key: v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- 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
@@ -977,7 +948,7 @@ step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- /var/portal
key: v8-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v14-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
name: Persisting src cache
step-make-src-cache-marker: &step-make-src-cache-marker
run:
@@ -987,7 +958,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
save_cache:
paths:
- .src-cache-marker
key: v1-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v14-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
run:
@@ -1008,11 +979,15 @@ step-ts-compile: &step-ts-compile
# List of all steps.
steps-electron-gn-check: &steps-electron-gn-check
steps:
- attach_workspace:
at: .
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-generate-deps-hash
- *step-touch-sync-done
- maybe-restore-portaled-src-cache
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
@@ -1025,6 +1000,7 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- *step-get-more-space-on-mac
- *step-setup-goma-for-build
- *step-generate-deps-hash
- *step-touch-sync-done
- maybe-restore-portaled-src-cache
@@ -1044,7 +1020,7 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-get-more-space-on-mac
- *step-install-npm-deps-on-mac
- *step-fix-sync-on-mac
@@ -1060,6 +1036,7 @@ steps-native-tests: &steps-native-tests
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- run:
@@ -1245,7 +1222,6 @@ commands:
fi
}
mv_if_exist src/out/Default/dist.zip
mv_if_exist src/out/Default/shell_browser_ui_unittests
mv_if_exist src/out/Default/gen/node_headers.tar.gz
mv_if_exist src/out/Default/symbols.zip
mv_if_exist src/out/Default/mksnapshot.zip
@@ -1282,6 +1258,46 @@ commands:
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
step-electron-dist-build:
parameters:
additional-targets:
type: string
default: ''
steps:
- run:
name: Build dist.zip
command: |
cd src
if [ "$SKIP_DIST_ZIP" != "1" ]; then
ninja -C out/Default electron:electron_dist_zip << parameters.additional-targets >>
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
if [ "$TARGET_ARCH" == "arm64" ]; then
target_cpu=arm64
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
fi
fi
electron-build:
parameters:
attach:
@@ -1327,6 +1343,10 @@ commands:
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- *step-save-brew-cache
- when:
condition: << parameters.build >>
steps:
- *step-setup-goma-for-build
- when:
condition: << parameters.checkout-and-assume-cache >>
steps:
@@ -1363,6 +1383,40 @@ commands:
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-touch-sync-done
- when:
condition: << parameters.save-git-cache >>
steps:
- *step-save-git-cache
# Mark sync as done _after_ saving the git cache so that it is uploaded
# only when the src cache was not present
# Their are theoretically two cases for this cache key
# 1. `vX-git-cache-DONE-{deps_hash}
# 2. `vX-git-cache-EMPTY-{deps_hash}
#
# Case (1) occurs when the flag file has "DONE" in it
# which only occurs when "step-mark-sync-done" is run
# or when the src cache was restored successfully as that
# flag file contains "DONE" in the src cache.
#
# Case (2) occurs when the flag file is empty, this occurs
# when the src cache was not restored and "step-mark-sync-done"
# has not run yet.
#
# Notably both of these cases also have completely different
# gclient cache states.
# In (1) the git cache is completely empty as we didn't run
# "gclient sync" because the src cache was restored.
# In (2) the git cache is full as we had to run "gclient sync"
#
# This allows us to do make the follow transitive assumption:
# In cases where the src cache is restored, saving the git cache
# will save an empty cache. In cases where the src cache is built
# during this build the git cache will save a full cache.
#
# In order words if there is a src cache for a given DEPS hash
# the git cache restored will be empty. But if the src cache
# is missing we will restore a useful git cache.
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- *step-delete-git-directories
@@ -1392,7 +1446,7 @@ commands:
steps:
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-get-more-space-on-mac
- *step-fix-sync-on-mac
- *step-delete-git-directories
@@ -1405,13 +1459,8 @@ commands:
- *step-gn-gen-default
- *step-electron-build
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
# Native test targets
- *step-native-unittests-build
# Node.js headers
- *step-nodejs-headers-build
- step-electron-dist-build:
additional-targets: shell_browser_ui_unittests third_party/electron_node:headers electron:hunspell_dictionaries_zip
- *step-show-goma-stats
@@ -1429,13 +1478,14 @@ commands:
- *step-ffmpeg-gn-gen
- *step-ffmpeg-build
# hunspell
- *step-hunspell-build
# Save all data needed for a further tests run.
- when:
condition: << parameters.persist >>
steps:
- *step-minimize-workspace-size-from-checkout
- run: |
rm -rf src/third_party/electron_node/deps/openssl
rm -rf src/third_party/electron_node/deps/v8
- *step-persist-data-for-tests
- when:
@@ -1501,6 +1551,7 @@ commands:
- *step-fix-sync-on-mac
- *step-setup-env-for-build
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-gn-gen-default
# Electron app
@@ -1508,7 +1559,7 @@ commands:
- *step-show-goma-stats
- *step-maybe-generate-breakpad-symbols
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- step-electron-dist-build
- *step-maybe-zip-symbols
# mksnapshot
@@ -1551,20 +1602,10 @@ jobs:
<<: *steps-electron-ts-compile-for-doc-change
# Layer 1: Checkout.
linux-checkout-for-workspace:
executor: linux-docker
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
linux-make-src-cache:
executor: linux-docker
executor:
name: linux-docker
size: xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1615,22 +1656,10 @@ jobs:
persist-checkout: true
restore-src-cache: false
mac-checkout-for-workspace:
executor: linux-docker
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
mac-make-src-cache:
executor: linux-docker
executor:
name: linux-docker
size: xlarge
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
@@ -1655,7 +1684,8 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-x64-testing-asan:
@@ -1695,6 +1725,7 @@ jobs:
environment:
<<: *env-linux-medium
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
linux-x64-release:
@@ -1715,7 +1746,7 @@ jobs:
environment:
<<: *env-linux-2xlarge-release
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1764,7 +1795,7 @@ jobs:
<<: *env-ia32
<<: *env-release-build
<<: *env-32bit-release
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1791,7 +1822,8 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm-release:
@@ -1816,7 +1848,7 @@ jobs:
<<: *env-release-build
<<: *env-32bit-release
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1843,7 +1875,8 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm64-testing-gn-check:
@@ -1854,6 +1887,7 @@ jobs:
<<: *env-linux-medium
<<: *env-arm64
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
linux-arm64-release:
@@ -1877,7 +1911,7 @@ jobs:
<<: *env-arm64
<<: *env-release-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1913,6 +1947,7 @@ jobs:
environment:
<<: *env-machine-mac
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-electron-gn-check
osx-publish-x64-skip-checkout:
@@ -1920,7 +1955,7 @@ jobs:
environment:
<<: *env-mac-large-release
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1940,7 +1975,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-release-build
<<: *env-apple-silicon
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -1995,6 +2030,7 @@ jobs:
<<: *env-machine-mac
<<: *env-mas
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-electron-gn-check
mas-publish-x64-skip-checkout:
@@ -2003,7 +2039,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-mas
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
steps:
- run: echo running
- when:
@@ -2022,7 +2058,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-mas-apple-silicon
<<: *env-release-build
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
UPLOAD_TO_STORAGE: << pipeline.parameters.upload-to-storage >>
<<: *env-ninja-status
steps:
- run: echo running
@@ -2321,14 +2357,19 @@ workflows:
- equal: [false, << pipeline.parameters.run-linux-publish >>]
- equal: [true, << pipeline.parameters.run-build-linux >>]
jobs:
- linux-checkout-for-workspace
- linux-make-src-cache
- linux-x64-testing
- linux-x64-testing-asan
- linux-x64-testing-no-run-as-node
- linux-x64-testing:
requires:
- linux-make-src-cache
- linux-x64-testing-asan:
requires:
- linux-make-src-cache
- linux-x64-testing-no-run-as-node:
requires:
- linux-make-src-cache
- linux-x64-testing-gn-check:
requires:
- linux-checkout-for-workspace
- linux-make-src-cache
- linux-x64-testing-tests:
requires:
- linux-x64-testing
@@ -2341,7 +2382,9 @@ workflows:
- linux-x64-testing-node:
requires:
- linux-x64-testing
- linux-ia32-testing
- linux-ia32-testing:
requires:
- linux-make-src-cache
- linux-ia32-testing-tests:
requires:
- linux-ia32-testing
@@ -2351,7 +2394,9 @@ workflows:
- linux-ia32-testing-node:
requires:
- linux-ia32-testing
- linux-arm-testing
- linux-arm-testing:
requires:
- linux-make-src-cache
- linux-arm-testing-tests:
filters:
branches:
@@ -2359,7 +2404,9 @@ workflows:
ignore: /pull\/[0-9]+/
requires:
- linux-arm-testing
- linux-arm64-testing
- linux-arm64-testing:
requires:
- linux-make-src-cache
- linux-arm64-testing-tests:
filters:
branches:
@@ -2369,7 +2416,7 @@ workflows:
- linux-arm64-testing
- linux-arm64-testing-gn-check:
requires:
- linux-checkout-for-workspace
- linux-make-src-cache
build-mac:
when:
@@ -2378,14 +2425,13 @@ workflows:
- equal: [false, << pipeline.parameters.run-linux-publish >>]
- equal: [true, << pipeline.parameters.run-build-mac >>]
jobs:
- mac-checkout-for-workspace
- mac-make-src-cache
- osx-testing-x64:
requires:
- mac-make-src-cache
- osx-testing-x64-gn-check:
requires:
- mac-checkout-for-workspace
- mac-make-src-cache
- osx-testing-x64-tests:
requires:
- osx-testing-x64
@@ -2404,7 +2450,7 @@ workflows:
- mac-make-src-cache
- mas-testing-x64-gn-check:
requires:
- mac-checkout-for-workspace
- mac-make-src-cache
- mas-testing-x64-tests:
requires:
- mas-testing-x64
@@ -2418,3 +2464,6 @@ workflows:
ignore: /pull\/[0-9]+/
requires:
- mas-testing-arm64
lint:
jobs:
- lint

34
.circleci/config/build.js Normal file
View File

@@ -0,0 +1,34 @@
const cp = require('child_process');
const fs = require('fs-extra');
const path = require('path');
const yaml = require('js-yaml');
const STAGING_DIR = path.resolve(__dirname, '..', 'config-staging');
function copyAndExpand(dir = './') {
const absDir = path.resolve(__dirname, dir);
const targetDir = path.resolve(STAGING_DIR, dir);
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir);
}
for (const file of fs.readdirSync(absDir)) {
if (!file.endsWith('.yml')) {
if (fs.statSync(path.resolve(absDir, file)).isDirectory()) {
copyAndExpand(path.join(dir, file));
}
continue;
}
fs.writeFileSync(path.resolve(targetDir, file), yaml.dump(yaml.load(fs.readFileSync(path.resolve(absDir, file), 'utf8')), {
noRefs: true,
}));
}
}
if (fs.pathExists(STAGING_DIR)) fs.removeSync(STAGING_DIR);
copyAndExpand();
const output = cp.spawnSync(process.env.CIRCLECI_BINARY || 'circleci', ['config', 'pack', STAGING_DIR]);
fs.writeFileSync(path.resolve(STAGING_DIR, 'built.yml'), output.stdout.toString());

View File

@@ -0,0 +1,51 @@
executor:
name: linux-docker
size: medium
steps:
- checkout:
path: src/electron
- run:
name: Setup third_party Depot Tools
command: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
- run:
name: Download GN Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . \<<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@Subdir src/buildtools/linux64
gn/gn/linux-amd64 $gn_version
CIPD
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
- run:
name: Download clang-format Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
sha1_path='buildtools/linux64/clang-format.sha1'
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/${sha1_path}?format=TEXT" | base64 -d > "src/${sha1_path}"
download_from_google_storage.py --no_resume --no_auth --bucket chromium-clang-format -s "src/${sha1_path}"
- run:
name: Run Lint
command: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
- run:
name: Run Script Typechecker
command: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json

View File

@@ -0,0 +1,10 @@
{
"name": "@electron/circleci-config",
"version": "0.0.0",
"private": true,
"license": "MIT",
"dependencies": {
"fs-extra": "^10.1.0",
"js-yaml": "^4.1.0"
}
}

View File

@@ -0,0 +1,43 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
fs-extra@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
dependencies:
universalify "^2.0.0"
optionalDependencies:
graceful-fs "^4.1.6"
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==

20
.github/workflows/semantic.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: "Check Semantic Commit"
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
main:
name: Validate PR Title
runs-on: ubuntu-latest
steps:
- name: semantic-pull-request
uses: amannn/action-semantic-pull-request@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
validateSingleCommit: false

View File

@@ -1231,6 +1231,10 @@ if (is_mac) {
if (!is_component_build && is_component_ffmpeg) {
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}
if (is_linux) {
deps += [ "//sandbox/linux:chrome_sandbox" ]
}
}
}

View File

@@ -1 +1 @@
15.5.1
15.5.7

View File

@@ -11,7 +11,7 @@
# - "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_S3" Set it to '1' upload a release to the S3 bucket.
# - "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.)
#
@@ -231,9 +231,9 @@ deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_S3) {
Write-Output "Uploading Electron release distribution to s3"
& python script\release\uploaders\upload.py --verbose --upload_to_s3
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py --verbose

View File

@@ -16,6 +16,9 @@ proprietary_codecs = true
ffmpeg_branding = "Chrome"
enable_basic_printing = true
# Removes DLLs from the build, which are only meant to be used for Chromium development.
# See https://github.com/electron/electron/pull/17985
angle_enable_vulkan_validation_layers = false
dawn_enable_vulkan_validation_layers = false

View File

@@ -18,9 +18,9 @@ The `safeStorage` module has the following methods:
Returns `Boolean` - Whether encryption is available.
On Linux, returns true if the secret key is
available. On MacOS, returns true if Keychain is available.
On Windows, returns true with no other preconditions.
On Linux, returns true if the app has emitted the `ready` event and the secret key is available.
On MacOS, returns true if Keychain is available.
On Windows, returns true once the app has emitted the `ready` event.
### `safeStorage.encryptString(plainText)`

View File

@@ -352,6 +352,8 @@ filenames = {
"shell/browser/child_web_contents_tracker.h",
"shell/browser/cookie_change_notifier.cc",
"shell/browser/cookie_change_notifier.h",
"shell/browser/electron_api_ipc_handler_impl.cc",
"shell/browser/electron_api_ipc_handler_impl.h",
"shell/browser/electron_autofill_driver.cc",
"shell/browser/electron_autofill_driver.h",
"shell/browser/electron_autofill_driver_factory.cc",
@@ -360,8 +362,6 @@ filenames = {
"shell/browser/electron_browser_client.h",
"shell/browser/electron_browser_context.cc",
"shell/browser/electron_browser_context.h",
"shell/browser/electron_browser_handler_impl.cc",
"shell/browser/electron_browser_handler_impl.h",
"shell/browser/electron_browser_main_parts.cc",
"shell/browser/electron_browser_main_parts.h",
"shell/browser/electron_download_manager_delegate.cc",
@@ -378,6 +378,8 @@ filenames = {
"shell/browser/electron_quota_permission_context.h",
"shell/browser/electron_speech_recognition_manager_delegate.cc",
"shell/browser/electron_speech_recognition_manager_delegate.h",
"shell/browser/electron_web_contents_utility_handler_impl.cc",
"shell/browser/electron_web_contents_utility_handler_impl.h",
"shell/browser/electron_web_ui_controller_factory.cc",
"shell/browser/electron_web_ui_controller_factory.h",
"shell/browser/event_emitter_mixin.cc",

View File

@@ -1,9 +1,10 @@
{
"name": "electron",
"version": "15.5.1",
"version": "15.5.7",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/docs-parser": "^0.12.2",
"@electron/typescript-definitions": "^8.9.5",
"@octokit/auth-app": "^2.10.0",

View File

@@ -12,3 +12,8 @@ m99_vulkan_prevent_out_of_bounds_read_in_divisor_emulation_path.patch
m99_vulkan_streamvertexdatawithdivisor_write_beyond_buffer_boundary.patch
m98_protect_against_deleting_a_current_xfb_buffer.patch
m96-lts_vulkan_fix_issue_with_redefining_a_layered_attachment.patch
cherry-pick-d27d9d059b51.patch
m100_fix_crash_when_pausing_xfb_then_deleting_a_buffer.patch
cherry-pick-d49484c21e3c.patch
cherry-pick-a602a068e022.patch
fix_checkednumeric_using_the_wrong_type.patch

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Tue, 19 Apr 2022 17:01:20 -0400
Subject: Fix validate state cache after XFB buffer deleted.
Bug: chromium:1317650
Change-Id: Iec9f1167c3b2957091dd0f4ef3efcfcd7c4bf3c0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3594250
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Auto-Submit: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 4efc4ee6830a8a53a0daf9daa3c7aa835db4220f)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3621779
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 182709c348f7490e1ee990a05570c13d7e9d0dd7..dc2b1728e3a7ab494e616940565f08692a9ff028 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2115,10 +2115,7 @@ angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
if (curTransformFeedback)
{
ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
- if (isTransformFeedbackActiveUnpaused())
- {
- context->getStateCache().onActiveTransformFeedbackChange(context);
- }
+ context->getStateCache().onActiveTransformFeedbackChange(context);
}
if (getVertexArray()->detachBuffer(context, bufferID))

View File

@@ -0,0 +1,100 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charlie Lao <cclao@google.com>
Date: Tue, 15 Mar 2022 09:39:36 -0700
Subject: Vulkan: Update mCurrentElementArrayBuffersync based on dirty bit
M96 merge issues:
ContextVk.cpp:
ContextVk::setupIndexedDraw: vertexArrayVk/getVertexArray() isn't present in M96
ContextVk::syncState: M96 uses mVertexArray instead of vertexArrayVk
VertexArrayVk.cpp:
VertexArrayVk::updateCurrentElementArrayBuffer doesn't exist in M9
Created it and kept M96 logic for retrieving buffer/offset
The previous fix crrev.com/c/3513553 has run into corner case that
requires more follow up change crrev.com/c/3522565. But with that, there
is report that now we are hitting assertion in
handleDirtyGraphicsIndexBuffer(). This becomes a bit fragile This new
fix relies on the DIRTY_BIT_INDEX_BUFFER dirty bit and should be more
reliable as long as the dirty bit is set properly (if not, then we have
other bug that it won't even send down vulkan command to bind the
correct element buffer). We could further optimize the code path and
create a fast path for most common usages in the future.
Bug: chromium:1299261
Change-Id: Ifa8f86d431798c9ca4c128ed71a3e9e0a3537ccb
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3526021
Commit-Queue: Charlie Lao <cclao@google.com>
(cherry picked from commit 349636a05a3577a127adb6c79a1e947890bbe462)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3605834
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Charlie Lao <cclao@google.com>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 15243f0c5a42949c2ce94dbd415089b77a7e39bc..2ff2fd75a73b50e3bce5d72e64d5d3064f30bd66 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -954,6 +954,17 @@ angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
mLastIndexBufferOffset = indices;
}
+
+ // When you draw with LineLoop mode or GL_UNSIGNED_BYTE type, we may allocate its own
+ // element buffer and modify mCurrentElementArrayBuffer. When we switch out of that draw
+ // mode, we must reset mCurrentElementArrayBuffer back to the vertexArray's element buffer.
+ // Since in either case we set DIRTY_BIT_INDEX_BUFFER dirty bit, we use this bit to re-sync
+ // mCurrentElementArrayBuffer.
+ if (mGraphicsDirtyBits[DIRTY_BIT_INDEX_BUFFER])
+ {
+ mVertexArray->updateCurrentElementArrayBuffer();
+ }
+
if (shouldConvertUint8VkIndexType(indexType) && mGraphicsDirtyBits[DIRTY_BIT_INDEX_BUFFER])
{
ANGLE_PERF_WARNING(getDebug(), GL_DEBUG_SEVERITY_LOW,
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 93378c4b24495872405fc06ea01e15254229ab63..035c80a5ba95492247bd87e4189de602ffb47da1 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -492,6 +492,17 @@ angle::Result VertexArrayVk::convertVertexBufferCPU(ContextVk *contextVk,
return angle::Result::Continue;
}
+void VertexArrayVk::updateCurrentElementArrayBuffer()
+{
+ ASSERT(mState.getElementArrayBuffer() != nullptr);
+ ASSERT(mState.getElementArrayBuffer()->getSize() > 0);
+ gl::Buffer *bufferGL = mState.getElementArrayBuffer();
+ BufferVk *bufferVk = vk::GetImpl(bufferGL);
+ mCurrentElementArrayBuffer =
+ &bufferVk->getBufferAndOffset(&mCurrentElementArrayBufferOffset);
+
+}
+
angle::Result VertexArrayVk::syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits,
gl::VertexArray::DirtyAttribBitsArray *attribBits,
@@ -516,9 +527,7 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
{
// Note that just updating buffer data may still result in a new
// vk::BufferHelper allocation.
- BufferVk *bufferVk = vk::GetImpl(bufferGL);
- mCurrentElementArrayBuffer =
- &bufferVk->getBufferAndOffset(&mCurrentElementArrayBufferOffset);
+ updateCurrentElementArrayBuffer();
}
else
{
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.h b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
index c198265bf8ba2017a13fce558826862f450218b5..0b98a9ed46b7cd4b9588973c74b0bbaf9172ab6c 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.h
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
@@ -34,6 +34,8 @@ class VertexArrayVk : public VertexArrayImpl
angle::Result updateActiveAttribInfo(ContextVk *contextVk);
+ void updateCurrentElementArrayBuffer();
+
angle::Result updateDefaultAttrib(ContextVk *contextVk,
size_t attribIndex,
VkBuffer bufferHandle,

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 11 Apr 2022 12:29:00 -0400
Subject: Add error check on resuming XFB with deleted buffer.
Bug: chromium:1313905
Change-Id: I22c6f6400b05ca32c922fba9a3b9d4b5841ca8b8
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3578378
Auto-Submit: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 5c85fd4e11a3835a0719223a7cedb978d309da21)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3594103
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 1523cd5f0093b7b4b03bf0cd5432ee0a15f17dab..5f42d4b418fe6ae2f8c7473ef7a8954ef128ff99 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -4286,6 +4286,13 @@ bool ValidateUniformBlockBinding(const Context *context,
return false;
}
+ if (!ValidateProgramExecutableXFBBuffersPresent(context,
+ context->getState().getProgramExecutable()))
+ {
+ context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
+ return false;
+ }
+
return true;
}

View File

@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@google.com>
Date: Fri, 1 Apr 2022 11:38:17 -0400
Subject: Fix CheckedNumeric using the wrong type.
Validation for glBufferSubData checks that the buffer is large enough
for size+offset but verifies they fit in a size_t which is a different
type than the deduced type for size+offset on 32-bit systems.
Use decltype to ensure that we always verify there is no overflow on the
correct type.
Bug: chromium:1298867
Change-Id: I82f534b2d227d3273a763e626ebeae068dc918dc
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3563515
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jonah Ryan-Davis <jonahr@google.com>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
(cherry picked from commit c458b5add432c3da98ef370680518d0af7e4d4e3)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3630020
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 9802a3385d5f042df8b643b9b452de29b41ba868..e0add8edaac527fac374afefbebce216d21182e9 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -3779,7 +3779,7 @@ bool ValidateBufferSubData(const Context *context,
}
// Check for possible overflow of size + offset
- angle::CheckedNumeric<size_t> checkedSize(size);
+ angle::CheckedNumeric<decltype(size + offset)> checkedSize(size);
checkedSize += offset;
if (!checkedSize.IsValid())
{
diff --git a/src/tests/gl_tests/BufferDataTest.cpp b/src/tests/gl_tests/BufferDataTest.cpp
index b3e70c797ace1fbcaf0002fe7d63e4b4ac418e97..bad538962d262f81b3e6e78c820a28e114ea75fa 100644
--- a/src/tests/gl_tests/BufferDataTest.cpp
+++ b/src/tests/gl_tests/BufferDataTest.cpp
@@ -746,6 +746,19 @@ void main()
EXPECT_PIXEL_COLOR_EQ(3, 3, GLColor::green);
}
+// Verify that buffer sub data uploads are properly validated within the buffer size range on 32-bit
+// systems.
+TEST_P(BufferDataTest, BufferSizeValidation32Bit)
+{
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ glBufferData(GL_ARRAY_BUFFER, 100, nullptr, GL_STATIC_DRAW);
+
+ GLubyte data = 0;
+ glBufferSubData(GL_ARRAY_BUFFER, std::numeric_limits<uint32_t>::max(), 1, &data);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
// Tests a null crash bug caused by copying from null back-end buffer pointer
// when calling bufferData again after drawing without calling bufferData in D3D11.
TEST_P(BufferDataTestES3, DrawWithNotCallingBufferData)

View File

@@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 14 Mar 2022 10:37:31 -0400
Subject: Fix crash when pausing XFB then deleting a buffer.
Fix is to validate XFB buffer bindings even if we're paused.
This is undefined behaviour so we can use any non-crashing solution.
Bug: chromium:1305190
Change-Id: Ib95404cdb13adbde7f34d6cc77473a8b3cbf1de7
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3522283
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 708ce9cfd63bc8eab7c48987612a2dedce78c69a)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3594105
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index d5732741dff989b8b8f6f669511bf7bc001c4eaa..eb571bb2de3c4568810026e0364bf069bd8ca681 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -3949,7 +3949,7 @@ const char *ValidateDrawStates(const Context *context)
}
}
- if (state.isTransformFeedbackActiveUnpaused())
+ if (state.isTransformFeedbackActive())
{
if (!ValidateProgramExecutableXFBBuffersPresent(context, executable))
{
diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp
index 63dd230829716b7a95b7917b47fb1fc278c1098a..e6ed494e89c0a0c48af4789be91d240df769281f 100644
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -3660,6 +3660,25 @@ void main() {
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
+// Same as the above, with a paused transform feedback.
+TEST_P(TransformFeedbackTest, DeletePausedTransformFeedbackBuffer)
+{
+ ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(testProgram, essl1_shaders::vs::Simple(),
+ essl1_shaders::fs::Green(), {"gl_Position"},
+ GL_INTERLEAVED_ATTRIBS);
+ glUseProgram(testProgram);
+
+ GLBuffer buffer;
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, 3, nullptr, GL_STATIC_DRAW);
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
+
+ glBeginTransformFeedback(GL_POINTS);
+ glPauseTransformFeedback();
+ buffer.reset();
+ glDrawArrays(GL_POINTS, 0, 1);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TransformFeedbackTest);
ANGLE_INSTANTIATE_TEST_ES3(TransformFeedbackTest);

View File

@@ -166,3 +166,19 @@ remove_incorrect_width_height_adjustments.patch
fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
fixed_terminate_caused_by_binding_to_wrong_version.patch
follow_wayland_specification_regarding_xkb_keymap.patch
cherry-pick-1665a1d16d46.patch
cherry-pick-4d26949260aa.patch
use-after-free_of_id_and_idref_attributes.patch
fix_--without-valid_build.patch
usb_fix_oob_access_with_non-sequential_interfaces.patch
skia_renderer_-_don_t_explicitly_clip_scissor_for_large_transforms.patch
skia_renderer_use_rectf_intersect_in_applyscissor.patch
cherry-pick-1a31e2110440.patch
m100_change_ownership_of_blobbytesprovider.patch
cherry-pick-5be8e065f43e.patch
m96-lts_add_bounds_check_to_webgpudecoderimpl_dorequestdevice.patch
cherry-pick-5ff02e4d7368.patch
cherry-pick-12ba78f3fa7a.patch
reland_fix_noopener_case_for_user_activation_consumption.patch
cherry-pick-99c3f3bfd507.patch
cherry-pick-ec0cce63f47d.patch

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Mon, 25 Apr 2022 20:57:43 +0000
Subject: Sanitize DragData markup before inserting it into document
(cherry picked from commit 5164a0fe3391283663e1196cf4576ec233985e89)
Fixed: 1315040
Change-Id: I8a0ddfb983d12c185f7e943d3d5277788199b011
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3579670
Quick-Run: Xiaocheng Hu <xiaochengh@chromium.org>
Auto-Submit: Xiaocheng Hu <xiaochengh@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#991324}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3589799
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1602}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/core/page/drag_data.cc b/third_party/blink/renderer/core/page/drag_data.cc
index d5ace3a879ab5ab00557ba380d9470d9eb937286..36ad9f68d3a79fe3d7d948276a654aacf5db019b 100644
--- a/third_party/blink/renderer/core/page/drag_data.cc
+++ b/third_party/blink/renderer/core/page/drag_data.cc
@@ -131,8 +131,8 @@ DocumentFragment* DragData::AsFragment(LocalFrame* frame) const {
platform_drag_data_->HtmlAndBaseURL(html, base_url);
DCHECK(frame->GetDocument());
if (DocumentFragment* fragment =
- CreateFragmentFromMarkup(*frame->GetDocument(), html, base_url,
- kDisallowScriptingAndPluginContent))
+ CreateSanitizedFragmentFromMarkupWithContext(
+ *frame->GetDocument(), html, 0, html.length(), base_url))
return fragment;
}
diff --git a/third_party/blink/web_tests/editing/pasteboard/drag-and-drop-svg-use-sanitize.html b/third_party/blink/web_tests/editing/pasteboard/drag-and-drop-svg-use-sanitize.html
new file mode 100644
index 0000000000000000000000000000000000000000..58551d28341d851dbd99322e2a5d3af68b3b0c72
--- /dev/null
+++ b/third_party/blink/web_tests/editing/pasteboard/drag-and-drop-svg-use-sanitize.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<div id="drag-from" draggable=true>Drag from</div>
+<div id="drag-to" contenteditable>Drag to</div>
+
+<script>
+function computePoint(element) {
+ return {
+ x: element.offsetLeft + element.offsetWidth / 2,
+ y: element.offsetTop + element.offsetHeight / 2
+ };
+}
+
+let dragged = false;
+let executed = false;
+const payload = `
+ <svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg'&gt;&lt;image href='fake' onerror='executed=true' /&gt;&lt;/svg&gt;#x" />
+`;
+
+const dragFrom = document.getElementById('drag-from');
+dragFrom.ondragstart = event => {
+ dragged = true;
+ event.dataTransfer.setData('text/html', payload);
+}
+
+const dragTo = document.getElementById('drag-to');
+
+promise_test(async test => {
+ assert_own_property(window, 'eventSender', 'This test requires eventSender to simulate drag and drop');
+
+ const fromPoint = computePoint(dragFrom);
+ eventSender.mouseMoveTo(fromPoint.x, fromPoint.y);
+ eventSender.mouseDown();
+
+ const toPoint = computePoint(dragTo);
+ eventSender.mouseMoveTo(toPoint.x, toPoint.y);
+ eventSender.mouseUp();
+
+ assert_true(dragged, 'Element should be dragged');
+
+ // The 'error' event is dispatched asynchronously.
+ await new Promise(resolve => test.step_timeout(resolve, 100));
+ assert_false(executed, 'Script should be blocked');
+}, 'Script in SVG use href should be sanitized');
+</script>

View File

@@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "msw@chromium.org" <msw@chromium.org>
Date: Tue, 1 Feb 2022 21:16:10 +0000
Subject: Reland "Make web cursor size limits match on browser and renderer"
This reverts commit 38a8343085e53889eba48fcff78a6c2295927333.
Reason for revert: Fix without regressing https://crbug.com/1292426
(Increased WebCursor limit 128->150px to support DevToolsEyeDropper)
Original change's description:
> Revert "Make web cursor size limits match on browser and renderer"
>
> This reverts commit 868b44dd8b4a1a3b9698f561ca17f75e4ec78dd2.
>
> Reason for revert: https://crbug.com/1292426
>
> Original change's description:
> > Make web cursor size limits match on browser and renderer
> >
> > Use NSCursor arrowCursor on Mac for ui::mojom::CursorType::kNull.
> > (i.e. when WebCursor is constructed with an overly large custom cursor)
> >
> > Bug: 1246188
> > Test: Automated unit tests and WPTs
> > Change-Id: I89627fa13cba96b755b8f80adbc91cfc865b6b1b
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3413912
> > Reviewed-by: Henrique Ferreiro <hferreiro@igalia.com>
> > Reviewed-by: Charlie Harrison <csharrison@chromium.org>
> > Commit-Queue: Mike Wasserman <msw@chromium.org>
> > Auto-Submit: Mike Wasserman <msw@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#964378}
>
> Bug: 1246188
> Change-Id: Id7b3b88e65c012993537ce96c2b5064b7b76646e
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428347
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Mike Wasserman <msw@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#965475}
Fixed: 1246188
Bug: 1292426
Change-Id: I5a490603c3e21e17f3136a3d792a18429eb3f633
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428624
Auto-Submit: Mike Wasserman <msw@chromium.org>
Reviewed-by: Charlie Harrison <csharrison@chromium.org>
Commit-Queue: Mike Wasserman <msw@chromium.org>
Reviewed-by: Henrique Ferreiro <hferreiro@igalia.com>
Cr-Commit-Position: refs/heads/main@{#965857}
diff --git a/content/common/cursors/webcursor.cc b/content/common/cursors/webcursor.cc
index c8b6b9d3f75d0cac98cc4ab8e71b68117837c1dc..4c80616e41e6ba5b171ae09d06d7f4110589f70a 100644
--- a/content/common/cursors/webcursor.cc
+++ b/content/common/cursors/webcursor.cc
@@ -22,16 +22,19 @@ WebCursor::WebCursor(const ui::Cursor& cursor) {
WebCursor::WebCursor(const WebCursor& other) = default;
bool WebCursor::SetCursor(const ui::Cursor& cursor) {
- static constexpr int kMaxSize = 1024;
+ // This value is just large enough to accommodate:
+ // - kMaximumCursorSize in Blink's EventHandler
+ // - kCursorSize in Chrome's DevToolsEyeDropper
+ static constexpr int kMaximumCursorSize = 150;
if (cursor.image_scale_factor() < 0.01f ||
cursor.image_scale_factor() > 100.f ||
(cursor.type() == ui::mojom::CursorType::kCustom &&
- (cursor.custom_bitmap().width() > kMaxSize ||
- cursor.custom_bitmap().height() > kMaxSize ||
+ (cursor.custom_bitmap().width() > kMaximumCursorSize ||
+ cursor.custom_bitmap().height() > kMaximumCursorSize ||
cursor.custom_bitmap().width() / cursor.image_scale_factor() >
- kMaxSize ||
+ kMaximumCursorSize ||
cursor.custom_bitmap().height() / cursor.image_scale_factor() >
- kMaxSize))) {
+ kMaximumCursorSize))) {
return false;
}
diff --git a/content/common/cursors/webcursor_mac.mm b/content/common/cursors/webcursor_mac.mm
index f85c421f8581abe191738eaee133004b729a817d..fdc70bdff2ddc517f3e341dd16263ae89d8b153f 100644
--- a/content/common/cursors/webcursor_mac.mm
+++ b/content/common/cursors/webcursor_mac.mm
@@ -265,6 +265,7 @@ - (CrCoreCursorType)_coreCursorType {
case ui::mojom::CursorType::kCustom:
return CreateCustomCursor(cursor_);
case ui::mojom::CursorType::kNull:
+ return [NSCursor arrowCursor];
case ui::mojom::CursorType::kDndNone:
case ui::mojom::CursorType::kDndMove:
case ui::mojom::CursorType::kDndCopy:
diff --git a/content/common/cursors/webcursor_unittest.cc b/content/common/cursors/webcursor_unittest.cc
index 530f0e2cc0e7255fb120ebdef45c57d01c0f2b5f..b948e52da81d2d12543d76575c49bfa8a09288c4 100644
--- a/content/common/cursors/webcursor_unittest.cc
+++ b/content/common/cursors/webcursor_unittest.cc
@@ -122,11 +122,11 @@ TEST(WebCursorTest, SetCursor) {
// SetCursor should return false when the image width is too large.
cursor.set_image_scale_factor(1.f);
- cursor.set_custom_bitmap(CreateTestBitmap(1025, 3));
+ cursor.set_custom_bitmap(CreateTestBitmap(151, 3));
EXPECT_FALSE(webcursor.SetCursor(cursor));
// SetCursor should return false when the image height is too large.
- cursor.set_custom_bitmap(CreateTestBitmap(3, 1025));
+ cursor.set_custom_bitmap(CreateTestBitmap(3, 151));
EXPECT_FALSE(webcursor.SetCursor(cursor));
// SetCursor should return false when the scaled image width is too large.
@@ -136,7 +136,7 @@ TEST(WebCursorTest, SetCursor) {
// SetCursor should return false when the scaled image height is too large.
cursor.set_image_scale_factor(0.1f);
- cursor.set_custom_bitmap(CreateTestBitmap(5, 200));
+ cursor.set_custom_bitmap(CreateTestBitmap(5, 20));
EXPECT_FALSE(webcursor.SetCursor(cursor));
}

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anders Hartvoll Ruud <andruud@chromium.org>
Date: Tue, 5 Apr 2022 20:44:33 +0000
Subject: Disallow CSS-wide keywords for StylePropertyMap.set
We don't support this properly, and the spec does not handle CSS-keywords
either. Disallow it until we can add proper support for this.
(cherry picked from commit 02e4b18febb37de8baea718bc2f62cfb5fe56e23)
Fixed: 1292905
Bug: 1310761
Change-Id: Ieb3d20edfea72c2ccb0928536fdfd86d10aad1a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3551609
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#986411}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3572186
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Auto-Submit: Srinivas Sista <srinivassista@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/branch-heads/4896@{#1041}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
index 87caef2cf5cf56b7bf72752410648ef1d7bb9f9a..59c505707216362d3a3b662a6a531398b8f5009e 100644
--- a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
@@ -21,8 +21,10 @@ bool CSSOMKeywords::ValidKeywordForProperty(CSSPropertyID id,
return false;
}
- if (css_parsing_utils::IsCSSWideKeyword(valueID))
- return true;
+ if (css_parsing_utils::IsCSSWideKeyword(valueID)) {
+ // TODO(crbug.com/1310761): Support CSS-wide keywords in custom props.
+ return id != CSSPropertyID::kVariable;
+ }
switch (id) {
{% for property in properties if property.keywordIDs and 'Keyword' in property.typedom_types %}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-css-wide-in-custom-property-crash.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-css-wide-in-custom-property-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..bc977c9889889bd8a35eccc48ac28e25871b1ec9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-css-wide-in-custom-property-crash.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Don't crash when setting a CSS-wide keyword on a custom property</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
+<link rel="help" href="https://crbug.com/1310761<">
+<div id="target">
+ Don't crash
+</div>
+<script>
+ for (let keyword of ['initial', 'inherit', 'unset', 'revert', 'revert-layer']) {
+ try {
+ target.attributeStyleMap.set('--x', new CSSKeywordValue(keyword));
+ } catch (e) {
+ }
+ }
+</script>

View File

@@ -0,0 +1,154 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yutaka Hirano <yhirano@chromium.org>
Date: Fri, 4 Feb 2022 10:16:05 +0000
Subject: Don't interpret informational response body as HTTP/0.9 response
An informational (1xx) response with body can be interpreted as an
informational response followed by an HTTP/0.9 response. It is confusing
so let's stop doing that.
Bug: 1291482
Change-Id: Ic3823838614330d761f11360a783859e5baa260e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3428433
Reviewed-by: Matt Menke <mmenke@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/main@{#967169}
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index 8fe9a4e507aa5b081af4b48fe80ee38275dee84e..8ec7bbc1ed065b84afd22a4223e2359344876c47 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -1013,15 +1013,23 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) {
base::StringPiece(read_buf_->StartOfBuffer(), end_offset));
if (!headers)
return net::ERR_INVALID_HTTP_RESPONSE;
+ has_seen_status_line_ = true;
} else {
// Enough data was read -- there is no status line, so this is HTTP/0.9, or
// the server is broken / doesn't speak HTTP.
- // If the port is not the default for the scheme, assume it's not a real
- // HTTP/0.9 response, and fail the request.
+ if (has_seen_status_line_) {
+ // If we saw a status line previously, the server can speak HTTP/1.x so it
+ // is not reasonable to interpret the response as an HTTP/0.9 response.
+ return ERR_INVALID_HTTP_RESPONSE;
+ }
+
base::StringPiece scheme = request_->url.scheme_piece();
if (url::DefaultPortForScheme(scheme.data(), scheme.length()) !=
request_->url.EffectiveIntPort()) {
+ // If the port is not the default for the scheme, assume it's not a real
+ // HTTP/0.9 response, and fail the request.
+
// Allow Shoutcast responses over HTTP, as it's somewhat common and relies
// on HTTP/0.9 on weird ports to work.
// See
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
index 0a415338f3396e1fce75b691911aa77c28d8bdf9..ff0e1508326c92ecd46546755c030a906c6eac28 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -271,6 +271,11 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// True if reading a keep-alive response. False if not, or if don't yet know.
bool response_is_keep_alive_;
+ // True if we've seen a response that has an HTTP status line. This is
+ // persistent across multiple response parsing. If we see a status line
+ // for a response, this will remain true forever.
+ bool has_seen_status_line_ = false;
+
// Keep track of the number of response body bytes read so far.
int64_t response_body_read_;
diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
index 545b9f11b43b37456ccab54a63eeb76034c934ef..07f94e6bb6aefe3777a71afed80b22eedea2999e 100644
--- a/net/http/http_stream_parser_unittest.cc
+++ b/net/http/http_stream_parser_unittest.cc
@@ -1395,6 +1395,25 @@ TEST(HttpStreamParser, Http09PortTests) {
}
}
+TEST(HttpStreamParser, ContinueWithBody) {
+ const std::string kResponse =
+ "HTTP/1.1 100 Continue\r\n\r\nhello\r\nworld\r\n";
+
+ SimpleGetRunner get_runner;
+ get_runner.set_url(GURL("http://foo.com/"));
+ get_runner.AddRead(kResponse);
+ get_runner.SetupParserAndSendRequest();
+
+ get_runner.ReadHeadersExpectingError(OK);
+ ASSERT_TRUE(get_runner.response_info()->headers);
+ EXPECT_EQ("HTTP/1.1 100 Continue",
+ get_runner.response_info()->headers->GetStatusLine());
+
+ // We ignore informational responses and start reading the next response in
+ // the stream. This simulates the behavior.
+ get_runner.ReadHeadersExpectingError(ERR_INVALID_HTTP_RESPONSE);
+}
+
TEST(HttpStreamParser, NullFails) {
const char kTestHeaders[] =
"HTTP/1.1 200 OK\r\n"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ac068363a83816939013bbde88a7584aca4f307
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS Status(100) should be ignored.
+FAIL Status(101) should be accepted, with removing body. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Status(103) should be ignored.
+PASS Status(199) should be ignored.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js
new file mode 100644
index 0000000000000000000000000000000000000000..df4dafcd80b38af93b688dcb318cfaf1978a939f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.js
@@ -0,0 +1,28 @@
+promise_test(async (t) => {
+ // The 100 response should be ignored, then the transaction ends, which
+ // should lead to an error.
+ await promise_rejects_js(
+ t, TypeError, fetch('/common/text-plain.txt?pipe=status(100)'));
+}, 'Status(100) should be ignored.');
+
+// This behavior is being discussed at https://github.com/whatwg/fetch/issues/1397.
+promise_test(async (t) => {
+ const res = await fetch('/common/text-plain.txt?pipe=status(101)');
+ assert_equals(res.status, 101);
+ const body = await res.text();
+ assert_equals(body, '');
+}, 'Status(101) should be accepted, with removing body.');
+
+promise_test(async (t) => {
+ // The 103 response should be ignored, then the transaction ends, which
+ // should lead to an error.
+ await promise_rejects_js(
+ t, TypeError, fetch('/common/text-plain.txt?pipe=status(103)'));
+}, 'Status(103) should be ignored.');
+
+promise_test(async (t) => {
+ // The 199 response should be ignored, then the transaction ends, which
+ // should lead to an error.
+ await promise_rejects_js(
+ t, TypeError, fetch('/common/text-plain.txt?pipe=status(199)'));
+}, 'Status(199) should be ignored.');
diff --git a/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ac068363a83816939013bbde88a7584aca4f307
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/security/1xx-response.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS Status(100) should be ignored.
+FAIL Status(101) should be accepted, with removing body. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS Status(103) should be ignored.
+PASS Status(199) should be ignored.
+Harness: the test ran to completion.
+

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gregg Tavares <gman@chromium.org>
Date: Fri, 29 Apr 2022 15:23:33 +0000
Subject: Check for error when calling ComputeImageSizeInBytes
(cherry picked from commit f3244fe50ba6c64ab6a75f1370d8dd983927fae6)
Bug: chromium:1304987
Change-Id: I8311231156fca3200ce74d79db59d910a1a0e33a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3556686
Commit-Queue: Gregg Tavares <gman@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#986304}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3597078
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1609}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
index 16babfa9bcf98d640bc32be99fc8641e3f459a4b..767b477d50d79b2bca8dcb09d21d3c474d825fca 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -3996,8 +3996,10 @@ bool WebGLImageConversion::ExtractTextureData(
data.resize(width * height * bytes_per_pixel);
unsigned image_size_in_bytes, skip_size_in_bytes;
- ComputeImageSizeInBytes(format, type, width, height, 1, unpack_params,
- &image_size_in_bytes, nullptr, &skip_size_in_bytes);
+ if (ComputeImageSizeInBytes(format, type, width, height, 1, unpack_params,
+ &image_size_in_bytes, nullptr,
+ &skip_size_in_bytes) != GL_NO_ERROR)
+ return false;
const uint8_t* src_data = static_cast<const uint8_t*>(pixels);
if (skip_size_in_bytes) {
src_data += skip_size_in_bytes;

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: UwU UwU <uwu7586@gmail.com>
Date: Tue, 19 Apr 2022 15:10:38 +0000
Subject: NavigatorManagedData: Prevent iterator invalidation during Promise
resolution
(cherry picked from commit 6083135252280d9b43e26169eb35154a9ac861ea)
Bug: 1307223
Change-Id: Iead6cf8c6236a95dbdfe7877c912f6ba86b370ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3532439
Commit-Queue: Anqing Zhao <anqing@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#984230}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3577263
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Owners-Override: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1591}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
index 2df64ff2c51dfe080cd50b46199e9c1d77ea26db..32b48ca0157a52d322aa4e00d18d4e662d3b1c4a 100644
--- a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
+++ b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
@@ -108,8 +108,14 @@ void NavigatorManagedData::OnServiceConnectionError() {
!managed_configuration_service_.is_connected()) {
managed_configuration_service_.reset();
}
+
+ // Move the set to a local variable to prevent script execution in Reject()
+ // from invalidating the iterator used by the loop.
+ HeapHashSet<Member<ScriptPromiseResolver>> pending_promises;
+ pending_promises_.swap(pending_promises);
+
// Resolve all pending promises with a failure.
- for (ScriptPromiseResolver* resolver : pending_promises_) {
+ for (ScriptPromiseResolver* resolver : pending_promises) {
resolver->Reject(
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError,
kNotHighTrustedAppExceptionMessage));

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Fri, 8 Apr 2022 23:28:35 +0000
Subject: Only destroy successfully created compression session in VT encoder
This is a defensive change, since we don't have a repro on hand.
My guess is that VTCompressionSessionCreate() might fail to create a
compression session, but still write a value to compressionSessionOut.
It makes VTCompressionSessionInvalidate() access uninitialized memory.
That's why this CL makes sure that we only destroy a compression session
if VTCompressionSessionCreate() reports success.
Bug: 1312563
Change-Id: I468ce0e10bad251ca0b62b568607dbc5c32ba8bc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3575680
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Cr-Commit-Position: refs/heads/main@{#990654}
diff --git a/media/gpu/mac/vt_video_encode_accelerator_mac.cc b/media/gpu/mac/vt_video_encode_accelerator_mac.cc
index 8a49e706890a173a3e09ae16b8e88500aefb0499..39384b426a38f2210040cb3f2cbba85893496a7b 100644
--- a/media/gpu/mac/vt_video_encode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_encode_accelerator_mac.cc
@@ -120,13 +120,13 @@ VTVideoEncodeAccelerator::GetSupportedProfiles() {
SupportedProfiles profiles;
const bool rv = CreateCompressionSession(
gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight));
- DestroyCompressionSession();
if (!rv) {
VLOG(1)
<< "Hardware encode acceleration is not available on this platform.";
return profiles;
}
+ DestroyCompressionSession();
SupportedProfile profile;
profile.max_framerate_numerator = kMaxFrameRateNumerator;
profile.max_framerate_denominator = kMaxFrameRateDenominator;
@@ -505,10 +505,8 @@ bool VTVideoEncodeAccelerator::ResetCompressionSession() {
DestroyCompressionSession();
bool session_rv = CreateCompressionSession(input_visible_size_);
- if (!session_rv) {
- DestroyCompressionSession();
+ if (!session_rv)
return false;
- }
const bool configure_rv = ConfigureCompressionSession();
if (configure_rv)
@@ -544,6 +542,12 @@ bool VTVideoEncodeAccelerator::CreateCompressionSession(
&VTVideoEncodeAccelerator::CompressionCallback,
reinterpret_cast<void*>(this), compression_session_.InitializeInto());
if (status != noErr) {
+ // IMPORTANT: ScopedCFTypeRef::release() doesn't call CFRelease().
+ // In case of an error VTCompressionSessionCreate() is not supposed to
+ // write a non-null value into compression_session_, but just in case,
+ // we'll clear it without calling CFRelease() because it can be unsafe
+ // to call on a not fully created session.
+ (void)compression_session_.release();
DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status;
return false;
}

View File

@@ -0,0 +1,160 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Corentin Pescheloche <cpescheloche@fb.com>
Date: Tue, 10 May 2022 14:05:53 +0000
Subject: Cleanup profiler group detached profilers
ProfilerGroup keeps track of detached profilers to be able to gracefully
stop leaked profilers when the corresponding ExecutionContext is
destroyed.
(cherry picked from commit 9f9d5fd2f3085414fc8776bf556fb5c4fa2dac2c)
Change-Id: I4fdbbc3a5208819397d742c9ecbff117f839691c
Bug: chromium:1297283
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3594570
Commit-Queue: Corentin Pescheloche <cpescheloche@fb.com>
Cr-Original-Commit-Position: refs/heads/main@{#994316}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3620956
Reviewed-by: Oleh Lamzin <lamzin@google.com>
Owners-Override: Oleh Lamzin <lamzin@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Auto-Submit: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1629}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/third_party/blink/renderer/core/timing/profiler_group.cc b/third_party/blink/renderer/core/timing/profiler_group.cc
index 090068ee1dc22a0c823a4817e6c6e748fcec354b..466e4f76fce71787b78c2d24624e60184f1d1f36 100644
--- a/third_party/blink/renderer/core/timing/profiler_group.cc
+++ b/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -110,8 +110,7 @@ ProfilerGroup::ProfilerGroup(v8::Isolate* isolate)
: isolate_(isolate),
cpu_profiler_(nullptr),
next_profiler_id_(0),
- num_active_profilers_(0) {
-}
+ num_active_profilers_(0) {}
void DiscardedSamplesDelegate::Notify() {
if (profiler_group_) {
@@ -234,6 +233,8 @@ void ProfilerGroup::WillBeDestroyed() {
DCHECK(!profilers_.Contains(profiler));
}
+ StopDetachedProfilers();
+
if (cpu_profiler_)
TeardownV8Profiler();
}
@@ -304,18 +305,49 @@ void ProfilerGroup::CancelProfiler(Profiler* profiler) {
void ProfilerGroup::CancelProfilerAsync(ScriptState* script_state,
Profiler* profiler) {
+ DCHECK(IsMainThread());
DCHECK(cpu_profiler_);
DCHECK(!profiler->stopped());
profilers_.erase(profiler);
+ // register the profiler to be cleaned up in case its associated context
+ // gets destroyed before the cleanup task is executed.
+ detached_profiler_ids_.push_back(profiler->ProfilerId());
+
// Since it's possible for the profiler to get destructed along with its
// associated context, dispatch a task to cleanup context-independent isolate
// resources (rather than use the context's task runner).
ThreadScheduler::Current()->V8TaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&ProfilerGroup::CancelProfilerImpl,
+ FROM_HERE, WTF::Bind(&ProfilerGroup::StopDetachedProfiler,
WrapPersistent(this), profiler->ProfilerId()));
}
+void ProfilerGroup::StopDetachedProfiler(String profiler_id) {
+ DCHECK(IsMainThread());
+
+ // we use a vector instead of a map because the expected number of profiler
+ // is expected to be very small
+ auto* it = std::find(detached_profiler_ids_.begin(),
+ detached_profiler_ids_.end(), profiler_id);
+
+ if (it == detached_profiler_ids_.end()) {
+ // Profiler already stopped
+ return;
+ }
+
+ CancelProfilerImpl(profiler_id);
+ detached_profiler_ids_.erase(it);
+}
+
+void ProfilerGroup::StopDetachedProfilers() {
+ DCHECK(IsMainThread());
+
+ for (auto& detached_profiler_id : detached_profiler_ids_) {
+ CancelProfilerImpl(detached_profiler_id);
+ }
+ detached_profiler_ids_.clear();
+}
+
void ProfilerGroup::CancelProfilerImpl(String profiler_id) {
if (!cpu_profiler_)
return;
diff --git a/third_party/blink/renderer/core/timing/profiler_group.h b/third_party/blink/renderer/core/timing/profiler_group.h
index d673d0d6ec63a042a6b08149ba7c2b3fc505e221..8c27d41b160876e0347186958f0e9f08efd41e01 100644
--- a/third_party/blink/renderer/core/timing/profiler_group.h
+++ b/third_party/blink/renderer/core/timing/profiler_group.h
@@ -81,6 +81,10 @@ class CORE_EXPORT ProfilerGroup
// Internal implementation of cancel.
void CancelProfilerImpl(String profiler_id);
+ // Clean context independent resources for leaked profilers
+ void StopDetachedProfiler(String profiler_id);
+ void StopDetachedProfilers();
+
// Generates an unused string identifier to use for a new profiling session.
String NextProfilerId();
@@ -88,9 +92,11 @@ class CORE_EXPORT ProfilerGroup
v8::CpuProfiler* cpu_profiler_;
int next_profiler_id_;
int num_active_profilers_;
-
HeapHashSet<WeakMember<Profiler>> profilers_;
+ // Store the ids of leaked collected profilers that needs to be stopped
+ Vector<String> detached_profiler_ids_;
+
// A set of observers, one for each ExecutionContext that has profiling
// enabled.
HeapHashSet<Member<ProfilingContextObserver>> context_observers_;
diff --git a/third_party/blink/renderer/core/timing/profiler_group_test.cc b/third_party/blink/renderer/core/timing/profiler_group_test.cc
index fadab535bc3f8de7173e329e4d514e648e0f5817..1879523e9f18c41b448957d906c1684c024814da 100644
--- a/third_party/blink/renderer/core/timing/profiler_group_test.cc
+++ b/third_party/blink/renderer/core/timing/profiler_group_test.cc
@@ -268,4 +268,29 @@ TEST(ProfilerGroupTest, LeakProfilerWithContext) {
test::RunPendingTasks();
}
+// Tests that a ProfilerGroup doesn't crash if the ProfilerGroup is destroyed
+// before a Profiler::Dispose is ran.
+TEST(ProfilerGroupTest, Bug1297283) {
+ {
+ V8TestingScope scope;
+ ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
+ profiler_group->OnProfilingContextAdded(scope.GetExecutionContext());
+
+ ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
+ init_options->setSampleInterval(0);
+ init_options->setMaxBufferSize(0);
+ Profiler* profiler = profiler_group->CreateProfiler(
+ scope.GetScriptState(), *init_options, base::TimeTicks(),
+ scope.GetExceptionState());
+ EXPECT_FALSE(profiler->stopped());
+
+ // Force a collection of the underlying Profiler
+ profiler = nullptr;
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ // Exit Scope deallocating Context triggering ProfilerGroup::WillBeDestroyed
+ // Ensure doesn't crash.
+ }
+ test::RunPendingTasks();
+}
+
} // namespace blink

View File

@@ -33,10 +33,10 @@ index 0ccfe130f00ec3b6c75cd8ee04d5a2777e1fd00c..653829457d58bf92057cc36aa8a28970
DISALLOW_COPY_AND_ASSIGN(StaticHttpUserAgentSettings);
};
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 00af87f13c9f819e4d56a3c2ecbac9337be88dec..b48f88f20f54bdd5521528882158fe1864becbbe 100644
index 24298fa4c35fec195e0e1b15422b97e2cf89daa8..8f20984763357a95c3d86be228e9bbf5e17bc9e9 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1195,6 +1195,13 @@ void NetworkContext::SetNetworkConditions(
@@ -1207,6 +1207,13 @@ void NetworkContext::SetNetworkConditions(
std::move(network_conditions));
}

View File

@@ -0,0 +1,83 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 22 Feb 2022 11:51:08 +0100
Subject: Fix --without-valid build
Regressed in commit 652dd12a.
diff --git a/third_party/libxml/src/valid.c b/third_party/libxml/src/valid.c
index 8e596f1db3db40a5decc5f4b529abc7588c6bd66..9684683a08018ca1185f85414f358791bfb1264b 100644
--- a/third_party/libxml/src/valid.c
+++ b/third_party/libxml/src/valid.c
@@ -479,35 +479,6 @@ nodeVPop(xmlValidCtxtPtr ctxt)
return (ret);
}
-/**
- * xmlValidNormalizeString:
- * @str: a string
- *
- * Normalize a string in-place.
- */
-static void
-xmlValidNormalizeString(xmlChar *str) {
- xmlChar *dst;
- const xmlChar *src;
-
- if (str == NULL)
- return;
- src = str;
- dst = str;
-
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
-}
-
#ifdef DEBUG_VALID_ALGO
static void
xmlValidPrintNode(xmlNodePtr cur) {
@@ -2636,6 +2607,35 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
+/**
+ * xmlValidNormalizeString:
+ * @str: a string
+ *
+ * Normalize a string in-place.
+ */
+static void
+xmlValidNormalizeString(xmlChar *str) {
+ xmlChar *dst;
+ const xmlChar *src;
+
+ if (str == NULL)
+ return;
+ src = str;
+ dst = str;
+
+ while (*src == 0x20) src++;
+ while (*src != 0) {
+ if (*src == 0x20) {
+ while (*src == 0x20) src++;
+ if (*src != 0)
+ *dst++ = 0x20;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
static int
xmlIsStreaming(xmlValidCtxtPtr ctxt) {
xmlParserCtxtPtr pctxt;

View File

@@ -0,0 +1,431 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Tue, 5 Apr 2022 20:09:23 +0000
Subject: M100: Change ownership of BlobBytesProvider.
Rather than immediately passing ownership to a cross-thread
SelfOwnedReceiver while retaining a raw pointer, instead maintain
ownership in a unique_ptr as long as it is needed, only transferring
ownership to a SelfOwnedReceiver when BlobData is done with the
BlobBytesProvider.
Also clean-up/tighten down sequence checks for BlobBytesProvider a bit.
(cherry picked from commit 7222e9825fc02acc962e005c59885ee2f26df185)
Bug: 1285234
Change-Id: I7273e886a0bab2ae489b680d786991c9e4ff1dbb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3553304
Reviewed-by: Austin Sullivan <asully@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#986111}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3568972
Auto-Submit: Marijn Kruisselbrink <mek@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4896@{#1040}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
index fc723d2dd83aae8f2b1abdf9d5a00990bbee5293..04f2b584d20a37c0b7bd2fb6a0d3a7095f7d8a38 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
@@ -31,13 +31,10 @@ class BlobBytesStreamer {
public:
BlobBytesStreamer(Vector<scoped_refptr<RawData>> data,
- mojo::ScopedDataPipeProducerHandle pipe,
- scoped_refptr<base::SequencedTaskRunner> task_runner)
+ mojo::ScopedDataPipeProducerHandle pipe)
: data_(std::move(data)),
pipe_(std::move(pipe)),
- watcher_(FROM_HERE,
- mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC,
- std::move(task_runner)) {
+ watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {
watcher_.Watch(pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_WATCH_CONDITION_SATISFIED,
WTF::BindRepeating(&BlobBytesStreamer::OnWritable,
@@ -45,6 +42,8 @@ class BlobBytesStreamer {
}
void OnWritable(MojoResult result, const mojo::HandleSignalsState& state) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
if (result == MOJO_RESULT_CANCELLED ||
result == MOJO_RESULT_FAILED_PRECONDITION) {
delete this;
@@ -84,15 +83,18 @@ class BlobBytesStreamer {
private:
// The index of the item currently being written.
- wtf_size_t current_item_ = 0;
+ wtf_size_t current_item_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
// The offset into the current item of the first byte not yet written to the
// data pipe.
- size_t current_item_offset_ = 0;
+ size_t current_item_offset_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
// The data being written.
- Vector<scoped_refptr<RawData>> data_;
+ Vector<scoped_refptr<RawData>> data_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ mojo::ScopedDataPipeProducerHandle pipe_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+ mojo::SimpleWatcher watcher_ GUARDED_BY_CONTEXT(sequence_checker_);
- mojo::ScopedDataPipeProducerHandle pipe_;
- mojo::SimpleWatcher watcher_;
+ SEQUENCE_CHECKER(sequence_checker_);
};
// This keeps the process alive while blobs are being transferred.
@@ -118,31 +120,8 @@ void DecreaseChildProcessRefCount() {
constexpr size_t BlobBytesProvider::kMaxConsolidatedItemSizeInBytes;
-// static
-BlobBytesProvider* BlobBytesProvider::CreateAndBind(
- mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
- auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
- auto provider = base::WrapUnique(new BlobBytesProvider(task_runner));
- auto* result = provider.get();
- // TODO(mek): Consider binding BytesProvider on the IPC thread instead, only
- // using the MayBlock taskrunner for actual file operations.
- PostCrossThreadTask(
- *task_runner, FROM_HERE,
- CrossThreadBindOnce(
- [](std::unique_ptr<BlobBytesProvider> provider,
- mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
- mojo::MakeSelfOwnedReceiver(std::move(provider),
- std::move(receiver));
- },
- std::move(provider), std::move(receiver)));
- return result;
-}
-
-// static
-std::unique_ptr<BlobBytesProvider> BlobBytesProvider::CreateForTesting(
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
- return base::WrapUnique(new BlobBytesProvider(std::move(task_runner)));
+BlobBytesProvider::BlobBytesProvider() {
+ IncreaseChildProcessRefCount();
}
BlobBytesProvider::~BlobBytesProvider() {
@@ -150,6 +129,8 @@ BlobBytesProvider::~BlobBytesProvider() {
}
void BlobBytesProvider::AppendData(scoped_refptr<RawData> data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
if (!data_.IsEmpty()) {
uint64_t last_offset = offsets_.IsEmpty() ? 0 : offsets_.back();
offsets_.push_back(last_offset + data_.back()->length());
@@ -158,6 +139,8 @@ void BlobBytesProvider::AppendData(scoped_refptr<RawData> data) {
}
void BlobBytesProvider::AppendData(base::span<const char> data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
if (data_.IsEmpty() ||
data_.back()->length() + data.size() > kMaxConsolidatedItemSizeInBytes) {
AppendData(RawData::Create());
@@ -166,8 +149,32 @@ void BlobBytesProvider::AppendData(base::span<const char> data) {
data.data(), base::checked_cast<wtf_size_t>(data.size()));
}
+// static
+void BlobBytesProvider::Bind(
+ std::unique_ptr<BlobBytesProvider> provider,
+ mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(provider->sequence_checker_);
+ DETACH_FROM_SEQUENCE(provider->sequence_checker_);
+
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+ // TODO(mek): Consider binding BytesProvider on the IPC thread instead, only
+ // using the MayBlock taskrunner for actual file operations.
+ PostCrossThreadTask(
+ *task_runner, FROM_HERE,
+ CrossThreadBindOnce(
+ [](std::unique_ptr<BlobBytesProvider> provider,
+ mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(provider->sequence_checker_);
+ mojo::MakeSelfOwnedReceiver(std::move(provider),
+ std::move(receiver));
+ },
+ std::move(provider), std::move(receiver)));
+}
+
void BlobBytesProvider::RequestAsReply(RequestAsReplyCallback callback) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
// TODO(mek): Once better metrics are created we could experiment with ways
// to reduce the number of copies of data that are made here.
Vector<uint8_t> result;
@@ -178,9 +185,10 @@ void BlobBytesProvider::RequestAsReply(RequestAsReplyCallback callback) {
void BlobBytesProvider::RequestAsStream(
mojo::ScopedDataPipeProducerHandle pipe) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
// BlobBytesStreamer will self delete when done.
- new BlobBytesStreamer(std::move(data_), std::move(pipe), task_runner_);
+ new BlobBytesStreamer(std::move(data_), std::move(pipe));
}
void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
@@ -188,7 +196,7 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
base::File file,
uint64_t file_offset,
RequestAsFileCallback callback) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!file.IsValid()) {
std::move(callback).Run(absl::nullopt);
@@ -256,10 +264,4 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset,
std::move(callback).Run(info.last_modified);
}
-BlobBytesProvider::BlobBytesProvider(
- scoped_refptr<base::SequencedTaskRunner> task_runner)
- : task_runner_(std::move(task_runner)) {
- IncreaseChildProcessRefCount();
-}
-
} // namespace blink
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider.h b/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
index 59b019a6ce9c6db896ab20f4684e8db117c289f8..eb4f778e72dcc32043628d5f03da17d27f34d062 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_
+#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/blob/data_element.mojom-blink.h"
@@ -16,8 +17,8 @@ namespace blink {
// making up a blob to the browser process, at the request of the blob service.
//
// Typical usage of this class creates and calls AppendData on one thread, and
-// then transfers ownership of the class to a different thread where it will be
-// bound to a mojo pipe, such that the various Request* methods are called on a
+// then transfers ownership of the class to a different thread using the `Bind`
+// method. This ensures that the various Request* methods are called on a
// thread that is allowed to do File IO.
class PLATFORM_EXPORT BlobBytesProvider : public mojom::blink::BytesProvider {
public:
@@ -25,19 +26,17 @@ class PLATFORM_EXPORT BlobBytesProvider : public mojom::blink::BytesProvider {
// data appended to the same item.
static constexpr size_t kMaxConsolidatedItemSizeInBytes = 15 * 1024;
- // Creates a new instance, and binds it on a new SequencedTaskRunner. The
- // returned instance should only be considered valid as long as the request
- // passed in to this method is still known to be valid.
- static BlobBytesProvider* CreateAndBind(
- mojo::PendingReceiver<mojom::blink::BytesProvider>);
- static std::unique_ptr<BlobBytesProvider> CreateForTesting(
- scoped_refptr<base::SequencedTaskRunner>);
-
+ BlobBytesProvider();
~BlobBytesProvider() override;
void AppendData(scoped_refptr<RawData>);
void AppendData(base::span<const char>);
+ // Binds `provider` to `receiver` on a threadpool task runner, transferring
+ // ownership.
+ static void Bind(std::unique_ptr<BlobBytesProvider> provider,
+ mojo::PendingReceiver<mojom::blink::BytesProvider> receiver);
+
// BytesProvider implementation:
void RequestAsReply(RequestAsReplyCallback) override;
void RequestAsStream(mojo::ScopedDataPipeProducerHandle) override;
@@ -50,17 +49,13 @@ class PLATFORM_EXPORT BlobBytesProvider : public mojom::blink::BytesProvider {
private:
FRIEND_TEST_ALL_PREFIXES(BlobBytesProviderTest, Consolidation);
- BlobBytesProvider(scoped_refptr<base::SequencedTaskRunner>);
-
- // The task runner this class is bound on, as well as what is used by the
- // RequestAsStream method to monitor the data pipe.
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
- Vector<scoped_refptr<RawData>> data_;
+ Vector<scoped_refptr<RawData>> data_ GUARDED_BY_CONTEXT(sequence_checker_);
// |offsets_| always contains exactly one fewer item than |data_| (except when
// |data_| itself is empty).
// offsets_[x] is equal to the sum of data_[i].length for all i <= x.
- Vector<uint64_t> offsets_;
+ Vector<uint64_t> offsets_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace blink
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc b/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
index 227955f6c0762ab7015597fc3c6a6dada823b507..27bdebcbd7a96b579efdb9372d1de4e543b55f4d 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider_test.cc
@@ -52,8 +52,7 @@ class BlobBytesProviderTest : public testing::Test {
std::unique_ptr<BlobBytesProvider> CreateProvider(
scoped_refptr<RawData> data = nullptr) {
- auto result = BlobBytesProvider::CreateForTesting(
- blink::scheduler::GetSequencedTaskRunnerForTesting());
+ auto result = std::make_unique<BlobBytesProvider>();
if (data)
result->AppendData(std::move(data));
return result;
@@ -73,6 +72,8 @@ class BlobBytesProviderTest : public testing::Test {
TEST_F(BlobBytesProviderTest, Consolidation) {
auto data = CreateProvider();
+ DCHECK_CALLED_ON_VALID_SEQUENCE(data->sequence_checker_);
+
data->AppendData(base::make_span("abc", 3));
data->AppendData(base::make_span("def", 3));
data->AppendData(base::make_span("ps1", 3));
diff --git a/third_party/blink/renderer/platform/blob/blob_data.cc b/third_party/blink/renderer/platform/blob/blob_data.cc
index b62dca5e303898fbdbc4c931dfcbc7361504194a..75c769665148d8530742586f4cdd6eb98cf96e50 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -106,6 +106,12 @@ BlobData::BlobData(FileCompositionStatus composition)
BlobData::~BlobData() = default;
Vector<mojom::blink::DataElementPtr> BlobData::ReleaseElements() {
+ if (last_bytes_provider_) {
+ DCHECK(last_bytes_provider_receiver_);
+ BlobBytesProvider::Bind(std::move(last_bytes_provider_),
+ std::move(last_bytes_provider_receiver_));
+ }
+
return std::move(elements_);
}
@@ -140,16 +146,6 @@ std::unique_ptr<BlobData> BlobData::CreateForFileSystemURLWithUnknownSize(
return data;
}
-void BlobData::DetachFromCurrentThread() {
- content_type_ = content_type_.IsolatedCopy();
- for (auto& element : elements_) {
- if (element->is_file_filesystem()) {
- auto& file_element = element->get_file_filesystem();
- file_element->url = file_element->url.Copy();
- }
- }
-}
-
void BlobData::SetContentType(const String& content_type) {
if (IsValidBlobType(content_type))
content_type_ = content_type;
@@ -273,6 +269,7 @@ void BlobData::AppendDataInternal(base::span<const char> data,
if (!elements_.IsEmpty() && elements_.back()->is_bytes()) {
// Append bytes to previous element.
DCHECK(last_bytes_provider_);
+ DCHECK(last_bytes_provider_receiver_);
const auto& bytes_element = elements_.back()->get_bytes();
bytes_element->length += data.size();
if (should_embed_bytes && bytes_element->embedded_data) {
@@ -284,9 +281,18 @@ void BlobData::AppendDataInternal(base::span<const char> data,
bytes_element->embedded_data = absl::nullopt;
}
} else {
+ if (last_bytes_provider_) {
+ // If `last_bytes_provider_` is set, but the previous element is not a
+ // bytes element, a new BytesProvider will be created and we need to
+ // make sure to bind the previous one first.
+ DCHECK(last_bytes_provider_receiver_);
+ BlobBytesProvider::Bind(std::move(last_bytes_provider_),
+ std::move(last_bytes_provider_receiver_));
+ }
mojo::PendingRemote<BytesProvider> bytes_provider_remote;
- last_bytes_provider_ = BlobBytesProvider::CreateAndBind(
- bytes_provider_remote.InitWithNewPipeAndPassReceiver());
+ last_bytes_provider_ = std::make_unique<BlobBytesProvider>();
+ last_bytes_provider_receiver_ =
+ bytes_provider_remote.InitWithNewPipeAndPassReceiver();
auto bytes_element = DataElementBytes::New(
data.size(), absl::nullopt, std::move(bytes_provider_remote));
diff --git a/third_party/blink/renderer/platform/blob/blob_data.h b/third_party/blink/renderer/platform/blob/blob_data.h
index fa905f87ed4cee14909827e8f078f51bb91cfa61..805da754eb510224f67f719bb43ab281d702f5fb 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.h
+++ b/third_party/blink/renderer/platform/blob/blob_data.h
@@ -44,6 +44,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/mojom/blob/data_element.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -120,13 +121,10 @@ class PLATFORM_EXPORT BlobData {
const KURL& file_system_url,
const absl::optional<base::Time>& expected_modification_time);
- // Detaches from current thread so that it can be passed to another thread.
- void DetachFromCurrentThread();
-
const String& ContentType() const { return content_type_; }
void SetContentType(const String&);
- const Vector<mojom::blink::DataElementPtr>& Elements() const {
+ const Vector<mojom::blink::DataElementPtr>& ElementsForTesting() const {
return elements_;
}
Vector<mojom::blink::DataElementPtr> ReleaseElements();
@@ -168,7 +166,15 @@ class PLATFORM_EXPORT BlobData {
Vector<mojom::blink::DataElementPtr> elements_;
size_t current_memory_population_ = 0;
- BlobBytesProvider* last_bytes_provider_ = nullptr;
+
+ // These two members are used to combine multiple consecutive 'bytes' elements
+ // (as created by `AppendBytes`, `AppendData` or `AppendText`) into a single
+ // element. When one has a value the other also has a value. Before using
+ // `elements_` to actually create a blob, `last_bytes_provider_` should be
+ // bound to `last_bytes_provider_receiver_`.
+ std::unique_ptr<BlobBytesProvider> last_bytes_provider_;
+ mojo::PendingReceiver<mojom::blink::BytesProvider>
+ last_bytes_provider_receiver_;
};
class PLATFORM_EXPORT BlobDataHandle
diff --git a/third_party/blink/renderer/platform/blob/blob_data_test.cc b/third_party/blink/renderer/platform/blob/blob_data_test.cc
index 8f1d08efa8e505fdb098742bd5b778a8b2b82213..9b8927b18bbe261afa2990ef7695cc33bdea53c5 100644
--- a/third_party/blink/renderer/platform/blob/blob_data_test.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data_test.cc
@@ -315,7 +315,7 @@ TEST_F(BlobDataHandleTest, CreateFromMergedBytes) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(medium_test_data_.data(), medium_test_data_.size());
data->AppendBytes(small_test_data_.data(), small_test_data_.size());
- EXPECT_EQ(1u, data->Elements().size());
+ EXPECT_EQ(1u, data->ElementsForTesting().size());
Vector<uint8_t> expected_data = medium_test_data_;
expected_data.AppendVector(small_test_data_);
@@ -331,7 +331,7 @@ TEST_F(BlobDataHandleTest, CreateFromMergedLargeAndSmallBytes) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(large_test_data_.data(), large_test_data_.size());
data->AppendBytes(small_test_data_.data(), small_test_data_.size());
- EXPECT_EQ(1u, data->Elements().size());
+ EXPECT_EQ(1u, data->ElementsForTesting().size());
Vector<uint8_t> expected_data = large_test_data_;
expected_data.AppendVector(small_test_data_);
@@ -347,7 +347,7 @@ TEST_F(BlobDataHandleTest, CreateFromMergedSmallAndLargeBytes) {
auto data = std::make_unique<BlobData>();
data->AppendBytes(small_test_data_.data(), small_test_data_.size());
data->AppendBytes(large_test_data_.data(), large_test_data_.size());
- EXPECT_EQ(1u, data->Elements().size());
+ EXPECT_EQ(1u, data->ElementsForTesting().size());
Vector<uint8_t> expected_data = small_test_data_;
expected_data.AppendVector(large_test_data_);

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Eng <enga@chromium.org>
Date: Mon, 25 Apr 2022 21:01:40 +0000
Subject: Add bounds check to WebGPUDecoderImpl::DoRequestDevice
(cherry picked from commit bee4701c99cbbbb25c0bd6c5c79a40f63f1b1e47)
Fixed: chromium:1314754
Change-Id: Id23af9cc3df08cca3ce7d627e3761c9a65a2c802
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3580555
Commit-Queue: Austin Eng <enga@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#991510}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3589810
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4664@{#1603}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 703dd4c1aee81aa8b05733b91d1de05b87ff1c0b..507595e2bb5d47128fc6e08dbadf21c43d36cdf0 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -582,13 +582,13 @@ error::Error WebGPUDecoderImpl::InitDawnDevice(
uint32_t device_generation,
const WGPUDeviceProperties& request_device_properties,
bool* creation_succeeded) {
- DCHECK_LE(0, requested_adapter_index);
-
- DCHECK_LT(static_cast<size_t>(requested_adapter_index),
- dawn_adapters_.size());
-
*creation_succeeded = false;
+ if (requested_adapter_index < 0 ||
+ static_cast<uint32_t>(requested_adapter_index) >= dawn_adapters_.size()) {
+ return error::kOutOfBounds;
+ }
+
dawn_native::DeviceDescriptor device_descriptor;
if (request_device_properties.textureCompressionBC) {
device_descriptor.requiredExtensions.push_back("texture_compression_bc");

View File

@@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement
session.setCertificateVerifyCallback.
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac9337be88dec 100644
index 7c64f63ad0661497103839f172dc7ef8286af86a..24298fa4c35fec195e0e1b15422b97e2cf89daa8 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -117,6 +117,11 @@
@@ -22,12 +22,38 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
#if BUILDFLAG(IS_CT_SUPPORTED)
#include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
#include "components/certificate_transparency/chrome_require_ct_delegate.h"
@@ -400,6 +405,79 @@ void GetCTPolicyConfigForCTLogInfo(
@@ -400,6 +405,91 @@ void GetCTPolicyConfigForCTLogInfo(
} // namespace
+class RemoteCertVerifier : public net::CertVerifier {
+ public:
+ class Request : public net::CertVerifier::Request {
+ public:
+ Request() {}
+ ~Request() override = default;
+ void OnRemoteResponse(
+ const RequestParams& params,
+ net::CertVerifyResult* verify_result,
+ int error_from_upstream,
+ net::CompletionOnceCallback callback,
+ int error_from_client,
+ const net::CertVerifyResult& verify_result_from_client) {
+ if (error_from_client == net::ERR_ABORTED) {
+ // use the default
+ std::move(callback).Run(error_from_upstream);
+ } else {
+ // use the override
+ verify_result->Reset();
+ verify_result->verified_cert = verify_result_from_client.verified_cert;
+ std::move(callback).Run(error_from_client);
+ }
+ }
+ base::WeakPtr<Request> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+ private:
+ base::WeakPtrFactory<Request> weak_factory_{this};
+ };
+
+ RemoteCertVerifier(std::unique_ptr<net::CertVerifier> upstream): upstream_(std::move(upstream)) {
+ }
+ ~RemoteCertVerifier() override = default;
@@ -44,20 +70,14 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
+ int Verify(const RequestParams& params,
+ net::CertVerifyResult* verify_result,
+ net::CompletionOnceCallback callback,
+ std::unique_ptr<Request>* out_req,
+ std::unique_ptr<CertVerifier::Request>* out_req,
+ const net::NetLogWithSource& net_log) override {
+ out_req->reset();
+
+ net::CompletionOnceCallback callback2 = base::BindOnce(
+ &RemoteCertVerifier::OnRequestFinished, base::Unretained(this),
+ params, std::move(callback), verify_result);
+ int result = upstream_->Verify(params, verify_result,
+ std::move(callback2), out_req, net_log);
+ if (result != net::ERR_IO_PENDING) {
+ // Synchronous completion
+ }
+
+ return result;
+ params, std::move(callback), verify_result, out_req);
+ return upstream_->Verify(params, verify_result, std::move(callback2), out_req, net_log);
+ }
+
+
@@ -65,35 +85,27 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
+ upstream_->SetConfig(config);
+ }
+
+ void OnRequestFinished(const RequestParams& params, net::CompletionOnceCallback callback, net::CertVerifyResult* verify_result, int error) {
+ void OnRequestFinished(const RequestParams& params,
+ net::CompletionOnceCallback callback,
+ net::CertVerifyResult* verify_result,
+ std::unique_ptr<CertVerifier::Request>* out_req,
+ int error) {
+ if (client_.is_bound()) {
+ // We take a weak pointer to the request because deletion of the request
+ // is what signals cancellation. Thus if the request is cancelled, the
+ // callback won't be called, thus avoiding UAF, because |verify_result|
+ // is freed when the request is cancelled.
+ *out_req = std::make_unique<Request>();
+ base::WeakPtr<Request> weak_req = static_cast<Request*>(out_req->get())->GetWeakPtr();
+ client_->Verify(error, *verify_result, params.certificate(),
+ params.hostname(), params.flags(), params.ocsp_response(),
+ base::BindOnce(&RemoteCertVerifier::OnRemoteResponse,
+ base::Unretained(this), params, verify_result, error,
+ std::move(callback)));
+ base::BindOnce(&Request::OnRemoteResponse,
+ weak_req, params, verify_result, error, std::move(callback)));
+ } else {
+ std::move(callback).Run(error);
+ }
+ }
+
+ void OnRemoteResponse(
+ const RequestParams& params,
+ net::CertVerifyResult* verify_result,
+ int error,
+ net::CompletionOnceCallback callback,
+ int error2,
+ const net::CertVerifyResult& verify_result2) {
+ if (error2 == net::ERR_ABORTED) {
+ // use the default
+ std::move(callback).Run(error);
+ } else {
+ // use the override
+ verify_result->Reset();
+ verify_result->verified_cert = verify_result2.verified_cert;
+ std::move(callback).Run(error2);
+ }
+ }
+ private:
+ std::unique_ptr<net::CertVerifier> upstream_;
+ mojo::Remote<mojom::CertVerifierClient> client_;
@@ -102,7 +114,7 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
NetworkContext::PendingCertVerify::PendingCertVerify() = default;
@@ -612,6 +690,13 @@ void NetworkContext::SetClient(
@@ -612,6 +702,13 @@ void NetworkContext::SetClient(
client_.Bind(std::move(client));
}
@@ -116,7 +128,7 @@ index 7c64f63ad0661497103839f172dc7ef8286af86a..00af87f13c9f819e4d56a3c2ecbac933
void NetworkContext::CreateURLLoaderFactory(
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
mojom::URLLoaderFactoryParamsPtr params) {
@@ -1998,6 +2083,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
@@ -1998,6 +2095,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
std::move(cert_verifier));
cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)

View File

@@ -0,0 +1,242 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Garrett Tanzer <gtanzer@chromium.org>
Date: Wed, 2 Mar 2022 18:33:42 +0000
Subject: Reland "Fix noopener case for user activation consumption"
This is a reland of e9828a82b5c182dc9a7fb0ae7226c35ba1726e7d
The MSAN error is from checking status before err in
content/renderer/render_view_impl.cc .
https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20ChromiumOS%20MSan%20Tests/b8821495655905086193/overview
The fix is to split the check for err and kIgnore into two checks,
and put the err check before kBlocked.
It is probably possible for the browser to consume user activation
but then eventually mojo returns an error and the renderer doesn't
consume activation, but that seems pretty marginal.
Original change's description:
> Fix noopener case for user activation consumption
>
>
> The flow for user activation consumption in window.open was as follows:
>
> Renderer: ask the browser to create a new window
> Browser: consume transient user activation (in the browser, and via RPC
> to remote frames only)
> Browser: return success for opener, return ignore for noopener
> Renderer: consume transient user activation upon success
>
> So in the noopener case, the renderer with the local frame where the
> window.open originated didn't have its transient user activation
> consumed.
>
>
> The new behavior is to consume user activation in the calling renderer
> whenever it is consumed in the browser. We accomplish this by returning
> a distinct value kBlocked to represent failure before the browser
> consumes user activation.
>
> Bug: 1264543, 1291210
> Change-Id: Iffb6e3fd772bef625d3d28e600e6fb73d70ab29f
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3468171
> Reviewed-by: Dominic Farolino <dom@chromium.org>
> Reviewed-by: Ken Buchanan <kenrb@chromium.org>
> Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
> Reviewed-by: Charles Reis <creis@chromium.org>
> Reviewed-by: Jonathan Ross <jonross@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Commit-Queue: Garrett Tanzer <gtanzer@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#973876}
Bug: 1264543, 1291210
Change-Id: Ie27c4d68db34dfd98adee7cc5c743953dad59834
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3481666
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: Charles Reis <creis@chromium.org>
Commit-Queue: Garrett Tanzer <gtanzer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#976745}
diff --git a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
index a6061a9c5bf1ebb37fb18ecabfb12af3c45ffdf5..f254061d1c118d6505eb1989f65b77b81839b752 100644
--- a/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
+++ b/chrome/browser/site_isolation/chrome_site_per_process_browsertest.cc
@@ -1189,6 +1189,52 @@ IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
EXPECT_FALSE(frame_c_popup_opened);
}
+// Test that opening a window with `noopener` consumes user activation.
+// crbug.com/1264543, crbug.com/1291210
+IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
+ UserActivationConsumptionNoopener) {
+ // Start on a page a.com.
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a"));
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
+ content::WebContents* web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Activate the frame by executing a dummy script.
+ const std::string no_op_script = "// No-op script";
+ EXPECT_TRUE(ExecuteScript(web_contents, no_op_script));
+
+ // Add a popup observer.
+ content::TestNavigationObserver popup_observer(nullptr);
+ popup_observer.StartWatchingNewWebContents();
+
+ // Open a popup from the frame, with `noopener`. This should consume
+ // transient user activation.
+ GURL popup_url(embedded_test_server()->GetURL("popup.com", "/"));
+ EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
+ web_contents,
+ base::StringPrintf(
+ "window.w = window.open('%s'+'title1.html', '_blank', 'noopener');",
+ popup_url.spec().c_str())));
+
+ // Try to open another popup.
+ EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
+ web_contents,
+ base::StringPrintf(
+ "window.w = window.open('%s'+'title2.html', '_blank', 'noopener');",
+ popup_url.spec().c_str())));
+
+ // Wait and check that only one popup was opened.
+ popup_observer.Wait();
+ EXPECT_EQ(2, browser()->tab_strip_model()->count());
+
+ content::WebContents* popup =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ EXPECT_EQ(embedded_test_server()->GetURL("popup.com", "/title1.html"),
+ popup->GetLastCommittedURL());
+ EXPECT_NE(popup, web_contents);
+}
+
// TODO(crbug.com/1021895): Flaky.
// Tests that a cross-site iframe runs its beforeunload handler when closing a
// tab. See https://crbug.com/853021.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 0652dca43b5b5a7b37d96817e5818ec3e9cc9824..bc44948de39c56cbd94305d7b73433da45237ddd 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6446,17 +6446,22 @@ void RenderFrameHostImpl::CreateNewWindow(
effective_transient_activation_state, params->opener_suppressed,
&no_javascript_access);
- bool was_consumed = false;
- if (can_create_window) {
- // Consume activation even w/o User Activation v2, to sync other renderers
- // with calling renderer.
- was_consumed = frame_tree_node_->UpdateUserActivationState(
- blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
- blink::mojom::UserActivationNotificationType::kNone);
- } else {
- std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
- return;
- }
+ // If this frame isn't allowed to create a window, return early (before we
+ // consume transient user activation).
+ if (!can_create_window) {
+ std::move(callback).Run(mojom::CreateNewWindowStatus::kBlocked, nullptr);
+ return;
+ }
+
+ // Otherwise, consume user activation before we proceed. In particular, it is
+ // important to do this before we return from the |opener_suppressed| case
+ // below.
+ // NB: This call will consume activations in the browser and the remote frame
+ // proxies for this frame. The initiating renderer will consume its view of
+ // the activations after we return.
+ bool was_consumed = frame_tree_node_->UpdateUserActivationState(
+ blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
+ blink::mojom::UserActivationNotificationType::kNone);
// For Android WebView, we support a pop-up like behavior for window.open()
// even if the embedding app doesn't support multiple windows. In this case,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 63f53ff39240ea59a03f1a6f9d032444b0e4214d..db8f3e3c9794163feea2c020fc100e7f6cc9c73b 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -531,8 +531,10 @@ struct CreateNewWindowParams {
// Operation result when the renderer asks the browser to create a new window.
enum CreateNewWindowStatus {
- // Ignore creation of the new window. This can happen because creation is
- // blocked or because the new window should have no opener relationship.
+ // Creation of the new window was blocked, e.g. because the source frame
+ // doesn't have user activation.
+ kBlocked,
+ // Ignore creation of the new window, e.g. because noopener is in effect.
kIgnore,
// Reuse the current window rather than creating a new window.
kReuse,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 57f970d15bf03f817680982fa8605c333485804b..7244d1a7f2b4c706c8dc56fafaed2d4b7f7c1c04 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -302,8 +302,27 @@ WebView* RenderViewImpl::CreateView(
mojom::CreateNewWindowStatus status;
mojom::CreateNewWindowReplyPtr reply;
auto* frame_host = creator_frame->GetFrameHost();
- bool err = !frame_host->CreateNewWindow(std::move(params), &status, &reply);
- if (err || status == mojom::CreateNewWindowStatus::kIgnore)
+ if (!frame_host->CreateNewWindow(std::move(params), &status, &reply)) {
+ // The sync IPC failed, e.g. maybe the render process is in the middle of
+ // shutting down. Can't create a new window without the browser process,
+ // so just bail out.
+ return nullptr;
+ }
+
+ // If creation of the window was blocked (e.g. because this frame doesn't
+ // have user activation), return before consuming user activation. A frame
+ // that isn't allowed to open a window shouldn't be able to consume the
+ // activation for the rest of the frame tree.
+ if (status == mojom::CreateNewWindowStatus::kBlocked)
+ return nullptr;
+
+ // Consume the transient user activation in the current renderer.
+ consumed_user_gesture = creator->ConsumeTransientUserActivation(
+ blink::UserActivationUpdateSource::kBrowser);
+
+ // If we should ignore the new window (e.g. because of `noopener`), return
+ // now that user activation was consumed.
+ if (status == mojom::CreateNewWindowStatus::kIgnore)
return nullptr;
// For Android WebView, we support a pop-up like behavior for window.open()
@@ -323,11 +342,6 @@ WebView* RenderViewImpl::CreateView(
DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_route_id);
DCHECK_NE(MSG_ROUTING_NONE, reply->widget_params->routing_id);
- // The browser allowed creation of a new window and consumed the user
- // activation.
- consumed_user_gesture = creator->ConsumeTransientUserActivation(
- blink::UserActivationUpdateSource::kBrowser);
-
// While this view may be a background extension page, it can spawn a visible
// render view. So we just assume that the new one is not another background
// page instead of passing on our own value.
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/restrict-size.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/restrict-size.https.html
new file mode 100644
index 0000000000000000000000000000000000000000..5668407d7e1e6ac7840fc47b76869787cb3f3d63
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/restrict-size.https.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Test fencedframe size restrictions in opaque ads mode.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script>
+promise_test(async () => {
+ const frame = attachFencedFrameContext();
+}, 'restrict fencedframe size');
+</script>
+</body>

View File

@@ -0,0 +1,271 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Ludwig <michaelludwig@google.com>
Date: Tue, 7 Dec 2021 20:49:07 +0000
Subject: - Don't explicitly clip scissor for large transforms
This adds a check to CanExplicitlyScissor that confirms that the device
space scissor rect, transformed to the quad's local space, can be
transformed back to device space and equal the same pixel bounds.
Without this check, sufficiently large scales and translates could
cause the local-space coordinates of the scissor rect to be in a float
range that does not have single-pixel precision, meaning it could round
significantly. Clipping the quad's coordinates to those rounded edges
and then transforming to device space can result in coordinates that
fall outside the original device-space scissor rect.
If however, we ensure we can round-trip the scissor coordinates, then
any clipping to the quad's coordinates will also be projected to within
the scissor rect as well.
(cherry picked from commit ab1b76f3e7cdad702c562f0b43bf3367caff4812)
Bug: 1272250
Change-Id: I7c37c54efd082723797ccf32b5d19ef285c520c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3306893
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#946552}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3320870
Auto-Submit: Michael Ludwig <michaelludwig@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4692@{#786}
Cr-Branched-From: 038cd96142d384c0d2238973f1cb277725a62eba-refs/heads/main@{#938553}
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 67d8f6b28a4edee1764660ede8eb48581c2b897e..054b18016922520a5545de64fb1243888117dd9c 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -125,45 +125,6 @@ bool IsTextureResource(DisplayResourceProviderSkia* resource_provider,
return !resource_provider->IsResourceSoftwareBacked(resource_id);
}
-void ApplyExplicitScissor(const DrawQuad* quad,
- const gfx::Rect& scissor_rect,
- const gfx::Transform& device_transform,
- unsigned* aa_flags,
- gfx::RectF* vis_rect) {
- // Inset rectangular edges and turn off the AA for clipped edges. Operates in
- // the quad's space, so apply inverse of transform to get new scissor
- gfx::RectF scissor(scissor_rect);
- device_transform.TransformRectReverse(&scissor);
-
- float left_inset = scissor.x() - vis_rect->x();
- float top_inset = scissor.y() - vis_rect->y();
- float right_inset = vis_rect->right() - scissor.right();
- float bottom_inset = vis_rect->bottom() - scissor.bottom();
-
- if (left_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kLeft_QuadAAFlag;
- } else {
- left_inset = 0;
- }
- if (top_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kTop_QuadAAFlag;
- } else {
- top_inset = 0;
- }
- if (right_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kRight_QuadAAFlag;
- } else {
- right_inset = 0;
- }
- if (bottom_inset >= kAAEpsilon) {
- *aa_flags &= ~SkCanvas::kBottom_QuadAAFlag;
- } else {
- bottom_inset = 0;
- }
-
- vis_rect->Inset(left_inset, top_inset, right_inset, bottom_inset);
-}
-
unsigned GetCornerAAFlags(const DrawQuad* quad,
const SkPoint& vertex,
unsigned edge_mask) {
@@ -556,6 +517,10 @@ struct SkiaRenderer::DrawQuadParams {
p.setAntiAlias(aa_flags != SkCanvas::kNone_QuadAAFlags);
return p;
}
+
+ void ApplyScissor(const SkiaRenderer* renderer,
+ const DrawQuad* quad,
+ const gfx::Rect* scissor_to_apply);
};
SkiaRenderer::DrawQuadParams::DrawQuadParams(const gfx::Transform& cdt,
@@ -1324,18 +1289,7 @@ SkiaRenderer::DrawQuadParams SkiaRenderer::CalculateDrawQuadParams(
params.opacity = 1.f;
}
- // Applying the scissor explicitly means avoiding a clipRect() call and
- // allows more quads to be batched together in a DrawEdgeAAImageSet call
- if (scissor_rect) {
- if (CanExplicitlyScissor(quad, draw_region, params.content_device_transform,
- *scissor_rect)) {
- ApplyExplicitScissor(quad, *scissor_rect, params.content_device_transform,
- &params.aa_flags, &params.visible_rect);
- params.vis_tex_coords = params.visible_rect;
- } else {
- params.scissor_rect = *scissor_rect;
- }
- }
+ params.ApplyScissor(this, quad, scissor_rect);
// Determine final rounded rect clip geometry. We transform it from target
// space to window space to make batching and canvas preparation easier
@@ -1365,28 +1319,40 @@ SkiaRenderer::DrawQuadParams SkiaRenderer::CalculateDrawQuadParams(
return params;
}
-bool SkiaRenderer::CanExplicitlyScissor(
+void SkiaRenderer::DrawQuadParams::ApplyScissor(
+ const SkiaRenderer* renderer,
const DrawQuad* quad,
- const gfx::QuadF* draw_region,
- const gfx::Transform& contents_device_transform,
- const gfx::Rect& scissor_rect) const {
+ const gfx::Rect* scissor_to_apply) {
+ // No scissor should have been set before calling ApplyScissor
+ DCHECK(!scissor_rect.has_value());
+
+ if (!scissor_to_apply) {
+ // No scissor at all, which matches the DCHECK'ed state above
+ return;
+ }
+
+ // Assume at start that the scissor will be applied through the canvas clip,
+ // so that this can simply return when it detects the scissor cannot be
+ // applied explicitly to |visible_rect|.
+ scissor_rect = *scissor_to_apply;
+
// PICTURE_CONTENT is not like the others, since it is executing a list of
// draw calls into the canvas.
if (quad->material == DrawQuad::Material::kPictureContent)
- return false;
+ return;
// Intersection with scissor and a quadrilateral is not necessarily a quad,
// so don't complicate things
- if (draw_region)
- return false;
+ if (draw_region.has_value())
+ return;
// This is slightly different than
// gfx::Transform::IsPositiveScaleAndTranslation in that it also allows zero
// scales. This is because in the common orthographic case the z scale is 0.
- if (!contents_device_transform.IsScaleOrTranslation() ||
- contents_device_transform.matrix().get(0, 0) < 0.0f ||
- contents_device_transform.matrix().get(1, 1) < 0.0f ||
- contents_device_transform.matrix().get(2, 2) < 0.0f) {
- return false;
+ if (!content_device_transform.IsScaleOrTranslation() ||
+ content_device_transform.matrix().get(0, 0) < 0.0f ||
+ content_device_transform.matrix().get(1, 1) < 0.0f ||
+ content_device_transform.matrix().get(2, 2) < 0.0f) {
+ return;
}
// State check: should not have a CompositorRenderPassDrawQuad if we got here.
@@ -1396,22 +1362,69 @@ bool SkiaRenderer::CanExplicitlyScissor(
// geometry beyond the quad's visible_rect, so it's not safe to pre-clip.
auto pass_id =
AggregatedRenderPassDrawQuad::MaterialCast(quad)->render_pass_id;
- if (FiltersForPass(pass_id) || BackdropFiltersForPass(pass_id))
- return false;
+ if (renderer->FiltersForPass(pass_id) ||
+ renderer->BackdropFiltersForPass(pass_id))
+ return;
}
// If the intersection of the scissor and the quad's visible_rect results in
// subpixel device-space geometry, do not drop the scissor. Otherwise Skia
// sees an unclipped anti-aliased hairline and uses different AA methods that
// would cause the rasterized result to extend beyond the scissor.
- gfx::RectF device_bounds(quad->visible_rect);
- contents_device_transform.TransformRect(&device_bounds);
- device_bounds.Intersect(gfx::RectF(scissor_rect));
+ gfx::RectF device_bounds(visible_rect);
+ content_device_transform.TransformRect(&device_bounds);
+ device_bounds.Intersect(gfx::RectF(*scissor_rect));
if (device_bounds.width() < 1.0f || device_bounds.height() < 1.0f) {
- return false;
+ return;
+ }
+
+ // The explicit scissor is applied in the quad's local space. If the transform
+ // does not leave sufficient precision to round-trip the scissor rect to-from
+ // device->local->device space, the explicitly "clipped" geometry does not
+ // necessarily respect the original scissor.
+ gfx::RectF local_scissor(*scissor_rect);
+ content_device_transform.TransformRectReverse(&local_scissor);
+ gfx::RectF remapped_scissor(local_scissor);
+ content_device_transform.TransformRect(&remapped_scissor);
+ if (gfx::ToRoundedRect(remapped_scissor) != *scissor_rect) {
+ return;
+ }
+
+ // At this point, we've determined that we can transform the scissor rect into
+ // the quad's local space and adjust |vis_rect|, such that when it's mapped to
+ // device space, it will be contained in in the original scissor.
+ // Applying the scissor explicitly means avoiding a clipRect() call and
+ // allows more quads to be batched together in a DrawEdgeAAImageSet call
+ float left_inset = local_scissor.x() - visible_rect.x();
+ float top_inset = local_scissor.y() - visible_rect.y();
+ float right_inset = visible_rect.right() - local_scissor.right();
+ float bottom_inset = visible_rect.bottom() - local_scissor.bottom();
+
+ // The scissor is a non-AA clip, so we unset the bit flag for clipped edges.
+ if (left_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kLeft_QuadAAFlag;
+ } else {
+ left_inset = 0;
+ }
+ if (top_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kTop_QuadAAFlag;
+ } else {
+ top_inset = 0;
+ }
+ if (right_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kRight_QuadAAFlag;
+ } else {
+ right_inset = 0;
+ }
+ if (bottom_inset >= kAAEpsilon) {
+ aa_flags &= ~SkCanvas::kBottom_QuadAAFlag;
+ } else {
+ bottom_inset = 0;
}
- return true;
+ visible_rect.Inset(left_inset, top_inset, right_inset, bottom_inset);
+ vis_tex_coords = visible_rect;
+ scissor_rect.reset();
}
const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h
index b94ffe0bae845928db4f3dc05d71fef72e4b3523..933c63fa4625797eb00ec256fcb7abc41a4c88ad 100644
--- a/components/viz/service/display/skia_renderer.h
+++ b/components/viz/service/display/skia_renderer.h
@@ -139,6 +139,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const gfx::Rect* scissor_rect,
const DrawQuad* quad,
const gfx::QuadF* draw_region) const;
+
DrawRPDQParams CalculateRPDQParams(const AggregatedRenderPassDrawQuad* quad,
DrawQuadParams* params);
// Modifies |params| and |rpdq_params| to apply correctly when drawing the
@@ -156,12 +157,6 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const SkImage* image,
const gfx::RectF& valid_texel_bounds,
DrawQuadParams* params) const;
- // True or false if the DrawQuad can have the scissor rect applied by
- // modifying the quad's visible_rect instead of as a separate clip operation.
- bool CanExplicitlyScissor(const DrawQuad* quad,
- const gfx::QuadF* draw_region,
- const gfx::Transform& contents_device_transform,
- const gfx::Rect& scissor_rect) const;
bool MustFlushBatchedQuads(const DrawQuad* new_quad,
const DrawRPDQParams* rpdq_params,

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Ludwig <michaelludwig@google.com>
Date: Sat, 2 Apr 2022 01:05:15 +0000
Subject: Use RectF::Intersect in ApplyScissor
(cherry picked from commit 540e2ecde447b0757dd5bb079a59d8faef3183c1)
Bug: 1299287, 1307317
Change-Id: I026090466ebfb3dee0e9daf0609f04babcf42092
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3516507
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Reviewed-by: Brian Sheedy <bsheedy@chromium.org>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#982400}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3564640
Cr-Commit-Position: refs/branch-heads/4896@{#1017}
Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766}
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 054b18016922520a5545de64fb1243888117dd9c..07b45ac958ef609ad8a103240e3c06edb0eaefc6 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -1395,34 +1395,20 @@ void SkiaRenderer::DrawQuadParams::ApplyScissor(
// device space, it will be contained in in the original scissor.
// Applying the scissor explicitly means avoiding a clipRect() call and
// allows more quads to be batched together in a DrawEdgeAAImageSet call
- float left_inset = local_scissor.x() - visible_rect.x();
- float top_inset = local_scissor.y() - visible_rect.y();
- float right_inset = visible_rect.right() - local_scissor.right();
- float bottom_inset = visible_rect.bottom() - local_scissor.bottom();
+ float x_epsilon = kAAEpsilon / content_device_transform.matrix().get(0, 0);
+ float y_epsilon = kAAEpsilon / content_device_transform.matrix().get(1, 1);
- // The scissor is a non-AA clip, so we unset the bit flag for clipped edges.
- if (left_inset >= kAAEpsilon) {
+ // The scissor is a non-AA clip, so unset the bit flag for clipped edges.
+ if (local_scissor.x() - visible_rect.x() >= x_epsilon)
aa_flags &= ~SkCanvas::kLeft_QuadAAFlag;
- } else {
- left_inset = 0;
- }
- if (top_inset >= kAAEpsilon) {
+ if (local_scissor.y() - visible_rect.y() >= y_epsilon)
aa_flags &= ~SkCanvas::kTop_QuadAAFlag;
- } else {
- top_inset = 0;
- }
- if (right_inset >= kAAEpsilon) {
+ if (visible_rect.right() - local_scissor.right() >= x_epsilon)
aa_flags &= ~SkCanvas::kRight_QuadAAFlag;
- } else {
- right_inset = 0;
- }
- if (bottom_inset >= kAAEpsilon) {
+ if (visible_rect.bottom() - local_scissor.bottom() >= y_epsilon)
aa_flags &= ~SkCanvas::kBottom_QuadAAFlag;
- } else {
- bottom_inset = 0;
- }
- visible_rect.Inset(left_inset, top_inset, right_inset, bottom_inset);
+ visible_rect.Intersect(local_scissor);
vis_tex_coords = visible_rect;
scissor_rect.reset();
}
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 37559380e8a3a8f857100bea9e1a5f6e53ecdc08..5f3e220642451609fd587c98475d6a3b8f347e0c 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -369,6 +369,9 @@ crbug.com/1086687 [ chromeos chromeos-board-kevin ] Pixel_PrecisionRoundedCorner
crbug.com/1218288 [ fuchsia-board-astro ] Pixel_PrecisionRoundedCorner [ Skip ]
crbug.com/1136875 [ fuchsia-board-qemu-x64 ] Pixel_PrecisionRoundedCorner [ RetryOnFailure ]
+# Fails on Nexus 5X.
+crbug.com/1307317 [ android android-chromium android-nexus-5x ] Pixel_PrecisionRoundedCorner [ Failure ]
+
# Still fails on Nexus 5 after all other Pixel_CanvasLowLatency* pass.
crbug.com/1097752 [ android android-nexus-5 ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Skip ]

View File

@@ -7,7 +7,7 @@ Make chrome's install-sysroot scripts point to our custom sysroot builds,
which include extra deps that Electron needs (e.g. libnotify)
diff --git a/build/linux/sysroot_scripts/install-sysroot.py b/build/linux/sysroot_scripts/install-sysroot.py
index ada6208644cb22c9f51c571f9509e335c0836163..86b55223fc21adf0e01cb276ebc613f6ea24f8b2 100755
index ada6208644cb22c9f51c571f9509e335c0836163..8f7169a0837a80c05faebce85ab4feac9e02bde2 100755
--- a/build/linux/sysroot_scripts/install-sysroot.py
+++ b/build/linux/sysroot_scripts/install-sysroot.py
@@ -41,9 +41,11 @@ except ImportError:
@@ -19,8 +19,8 @@ index ada6208644cb22c9f51c571f9509e335c0836163..86b55223fc21adf0e01cb276ebc613f6
-URL_PREFIX = 'https://commondatastorage.googleapis.com'
-URL_PATH = 'chrome-linux-sysroot/toolchain'
+URL_PREFIX = 'https://s3.amazonaws.com'
+URL_PATH = 'electronjs-sysroots/toolchain'
+URL_PREFIX = 'https://dev-cdn.electronjs.org'
+URL_PATH = 'linux-sysroots'
VALID_ARCHS = ('arm', 'arm64', 'i386', 'amd64', 'mips', 'mips64el')

View File

@@ -0,0 +1,413 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jack Hsieh <chengweih@chromium.org>
Date: Fri, 21 Jan 2022 00:01:43 +0000
Subject: usb: Fix OOB access with non-sequential interfaces
When accessing a usb device with non-sequential interface number or
alternative setting value, it might end up using index out of the
internal array allocated size. It is caused by using incorrect
parameters (i.e interface_number and alternate_setting) into the
callback which expects taking interface_index and alternate_index. Fix
it by passing the correct parameters which are already available in the
function to the callback.
Bug: 1286816
Change-Id: I6b3533f944f94e94e63959b99718858e089449da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3384715
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Commit-Queue: Jack Hsieh <chengweih@chromium.org>
Cr-Commit-Position: refs/heads/main@{#961679}
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index 7c9fa09a12516e2a866bd2e64b85d9643189ef5d..178781a3346c3271ba2592e472ec1d45afe42e61 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -132,9 +132,9 @@ bool USBDevice::IsInterfaceClaimed(wtf_size_t configuration_index,
claimed_interfaces_[interface_index];
}
-wtf_size_t USBDevice::SelectedAlternateInterface(
+wtf_size_t USBDevice::SelectedAlternateInterfaceIndex(
wtf_size_t interface_index) const {
- return selected_alternates_[interface_index];
+ return selected_alternate_indices_[interface_index];
}
USBConfiguration* USBDevice::configuration() const {
@@ -302,7 +302,7 @@ ScriptPromise USBDevice::selectAlternateInterface(ScriptState* script_state,
device_->SetInterfaceAlternateSetting(
interface_number, alternate_setting,
WTF::Bind(&USBDevice::AsyncSelectAlternateInterface,
- WrapPersistent(this), interface_number, alternate_setting,
+ WrapPersistent(this), interface_index, alternate_index,
WrapPersistent(resolver)));
}
}
@@ -744,7 +744,7 @@ void USBDevice::SetEndpointsForInterface(wtf_size_t interface_index, bool set) {
const auto& configuration = *Info().configurations[configuration_index_];
const auto& interface = *configuration.interfaces[interface_index];
const auto& alternate =
- *interface.alternates[selected_alternates_[interface_index]];
+ *interface.alternates[selected_alternate_indices_[interface_index]];
for (const auto& endpoint : alternate.endpoints) {
uint8_t endpoint_number = endpoint->endpoint_number;
if (endpoint_number == 0 || endpoint_number >= kEndpointsBitsNumber)
@@ -792,7 +792,7 @@ void USBDevice::OnDeviceOpenedOrClosed(bool opened) {
opened_ = opened;
if (!opened_) {
claimed_interfaces_.Fill(false);
- selected_alternates_.Fill(0);
+ selected_alternate_indices_.Fill(0);
in_endpoints_.reset();
out_endpoints_.reset();
}
@@ -825,8 +825,8 @@ void USBDevice::OnConfigurationSelected(bool success,
claimed_interfaces_.Fill(false);
interface_state_change_in_progress_.resize(num_interfaces);
interface_state_change_in_progress_.Fill(false);
- selected_alternates_.resize(num_interfaces);
- selected_alternates_.Fill(0);
+ selected_alternate_indices_.resize(num_interfaces);
+ selected_alternate_indices_.Fill(0);
in_endpoints_.reset();
out_endpoints_.reset();
}
@@ -887,7 +887,7 @@ void USBDevice::OnInterfaceClaimedOrUnclaimed(bool claimed,
claimed_interfaces_[interface_index] = true;
} else {
claimed_interfaces_[interface_index] = false;
- selected_alternates_[interface_index] = 0;
+ selected_alternate_indices_[interface_index] = 0;
}
SetEndpointsForInterface(interface_index, claimed);
interface_state_change_in_progress_[interface_index] = false;
@@ -901,7 +901,7 @@ void USBDevice::AsyncSelectAlternateInterface(wtf_size_t interface_index,
return;
if (success)
- selected_alternates_[interface_index] = alternate_index;
+ selected_alternate_indices_[interface_index] = alternate_index;
SetEndpointsForInterface(interface_index, success);
interface_state_change_in_progress_[interface_index] = false;
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.h b/third_party/blink/renderer/modules/webusb/usb_device.h
index 21231db5f4d6f949b4d371143c631a6f33dcb1e4..cb199d2f2ac4c27f2db7f153d51408e604b5f6f0 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -40,7 +40,7 @@ class USBDevice : public ScriptWrappable,
}
bool IsInterfaceClaimed(wtf_size_t configuration_index,
wtf_size_t interface_index) const;
- wtf_size_t SelectedAlternateInterface(wtf_size_t interface_index) const;
+ wtf_size_t SelectedAlternateInterfaceIndex(wtf_size_t interface_index) const;
// USBDevice.idl
uint8_t usbVersionMajor() const { return Info().usb_version_major; }
@@ -179,7 +179,7 @@ class USBDevice : public ScriptWrappable,
// configured. Use the index returned by FindInterfaceIndex().
WTF::Vector<bool> claimed_interfaces_;
WTF::Vector<bool> interface_state_change_in_progress_;
- WTF::Vector<wtf_size_t> selected_alternates_;
+ WTF::Vector<wtf_size_t> selected_alternate_indices_;
// These bit sets have one entry for each endpoint. Index using the endpoint
// number (lower 4 bits of the endpoint address).
diff --git a/third_party/blink/renderer/modules/webusb/usb_interface.cc b/third_party/blink/renderer/modules/webusb/usb_interface.cc
index ee7b79b351e5002cb02842097b89156f6e407a54..8187282e09b0f11e2a0f704555e8f557aa97f920 100644
--- a/third_party/blink/renderer/modules/webusb/usb_interface.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_interface.cc
@@ -53,7 +53,7 @@ const device::mojom::blink::UsbInterfaceInfo& USBInterface::Info() const {
USBAlternateInterface* USBInterface::alternate() const {
if (device_->IsInterfaceClaimed(configuration_index_, interface_index_))
return USBAlternateInterface::Create(
- this, device_->SelectedAlternateInterface(interface_index_));
+ this, device_->SelectedAlternateInterfaceIndex(interface_index_));
return nullptr;
}
diff --git a/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js b/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js
index 975d2242c949740217c050beea72db908ef46fc7..c5c5cadaa6af48f676565775d1dc8e27efffc3a2 100644
--- a/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js
+++ b/third_party/blink/web_tests/external/wpt/webusb/resources/fake-devices.js
@@ -16,75 +16,160 @@ let fakeDeviceInit = {
productName: 'The amazing imaginary printer',
serialNumber: '4',
activeConfigurationValue: 0,
- configurations: [{
- configurationValue: 1,
- configurationName: 'Printer Mode',
- interfaces: [{
- interfaceNumber: 0,
- alternates: [{
- alternateSetting: 0,
- interfaceClass: 0xff,
- interfaceSubclass: 0x01,
- interfaceProtocol: 0x01,
- interfaceName: 'Control',
- endpoints: [{
- endpointNumber: 1,
- direction: 'in',
- type: 'interrupt',
- packetSize: 8
- }]
+ configurations: [
+ {
+ configurationValue: 1,
+ configurationName: 'Printer Mode',
+ interfaces: [
+ {
+ interfaceNumber: 0,
+ alternates: [{
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x01,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Control',
+ endpoints: [{
+ endpointNumber: 1,
+ direction: 'in',
+ type: 'interrupt',
+ packetSize: 8
+ }]
+ }]
+ },
+ {
+ interfaceNumber: 1,
+ alternates: [{
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x02,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Data',
+ endpoints: [
+ {
+ endpointNumber: 2,
+ direction: 'in',
+ type: 'bulk',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 2,
+ direction: 'out',
+ type: 'bulk',
+ packetSize: 1024
+ }
+ ]
+ }]
+ }
+ ]
+ },
+ {
+ configurationValue: 2,
+ configurationName: 'Fighting Robot Mode',
+ interfaces: [{
+ interfaceNumber: 0,
+ alternates: [
+ {
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x42,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Disabled',
+ endpoints: []
+ },
+ {
+ alternateSetting: 1,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x42,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Activate!',
+ endpoints: [
+ {
+ endpointNumber: 1,
+ direction: 'in',
+ type: 'isochronous',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 1,
+ direction: 'out',
+ type: 'isochronous',
+ packetSize: 1024
+ }
+ ]
+ }
+ ]
}]
- }, {
- interfaceNumber: 1,
- alternates: [{
- alternateSetting: 0,
- interfaceClass: 0xff,
- interfaceSubclass: 0x02,
- interfaceProtocol: 0x01,
- interfaceName: 'Data',
- endpoints: [{
- endpointNumber: 2,
- direction: 'in',
- type: 'bulk',
- packetSize: 1024
- }, {
- endpointNumber: 2,
- direction: 'out',
- type: 'bulk',
- packetSize: 1024
- }]
- }]
- }]
- }, {
- configurationValue: 2,
- configurationName: 'Fighting Robot Mode',
- interfaces: [{
- interfaceNumber: 0,
- alternates: [{
- alternateSetting: 0,
- interfaceClass: 0xff,
- interfaceSubclass: 0x42,
- interfaceProtocol: 0x01,
- interfaceName: 'Disabled',
- endpoints: []
- }, {
- alternateSetting: 1,
- interfaceClass: 0xff,
- interfaceSubclass: 0x42,
- interfaceProtocol: 0x01,
- interfaceName: 'Activate!',
- endpoints: [{
- endpointNumber: 1,
- direction: 'in',
- type: 'isochronous',
- packetSize: 1024
- }, {
- endpointNumber: 1,
- direction: 'out',
- type: 'isochronous',
- packetSize: 1024
- }]
- }]
- }]
- }]
+ },
+ {
+ configurationValue: 3,
+ configurationName: 'Non-sequential interface number and alternate ' +
+ 'setting Mode',
+ interfaces: [
+ {
+ interfaceNumber: 0,
+ alternates: [
+ {
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x01,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Control',
+ endpoints: [{
+ endpointNumber: 1,
+ direction: 'in',
+ type: 'interrupt',
+ packetSize: 8
+ }]
+ },
+ {
+ alternateSetting: 2,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x02,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Data',
+ endpoints: [
+ {
+ endpointNumber: 2,
+ direction: 'in',
+ type: 'bulk',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 2,
+ direction: 'out',
+ type: 'bulk',
+ packetSize: 1024
+ }
+ ]
+ }
+ ]
+ },
+ {
+ interfaceNumber: 2,
+ alternates: [{
+ alternateSetting: 0,
+ interfaceClass: 0xff,
+ interfaceSubclass: 0x02,
+ interfaceProtocol: 0x01,
+ interfaceName: 'Data',
+ endpoints: [
+ {
+ endpointNumber: 2,
+ direction: 'in',
+ type: 'bulk',
+ packetSize: 1024
+ },
+ {
+ endpointNumber: 2,
+ direction: 'out',
+ type: 'bulk',
+ packetSize: 1024
+ }
+ ]
+ }]
+ }
+ ]
+ }
+ ]
};
diff --git a/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js b/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js
index 5bfd841d5248e91a5cabf10d00d78db23d11f0e5..527d238d69b703b1fcf5d8a001d02e9f87b5689a 100644
--- a/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webusb/usbDevice.https.any.js
@@ -236,10 +236,11 @@ usb_test(() => {
return getFakeDevice().then(({ device }) => {
assert_equals(device.configuration, null);
return device.open()
- .then(() => assertRejectsWithError(
- device.selectConfiguration(3), 'NotFoundError',
- 'The configuration value provided is not supported by the device.'))
- .then(() => device.close());
+ .then(
+ () => assertRejectsWithError(
+ device.selectConfiguration(10), 'NotFoundError',
+ 'The configuration value provided is not supported by the device.'))
+ .then(() => device.close());
});
}, 'selectConfiguration rejects on invalid configurations');
@@ -431,6 +432,30 @@ usb_test(() => {
});
}, 'can select an alternate interface');
+usb_test(
+ async () => {
+ const {device} = await getFakeDevice();
+ await device.open();
+ await device.selectConfiguration(3);
+ await device.claimInterface(2);
+ await device.selectAlternateInterface(2, 0);
+ await device.close();
+ },
+ 'can select an alternate interface on a setting with non-sequential ' +
+ 'interface number');
+
+usb_test(
+ async () => {
+ const {device} = await getFakeDevice();
+ await device.open();
+ await device.selectConfiguration(3);
+ await device.claimInterface(0);
+ await device.selectAlternateInterface(0, 2);
+ await device.close();
+ },
+ 'can select an alternate interface on a setting with non-sequential ' +
+ 'alternative setting value');
+
usb_test(() => {
return getFakeDevice().then(({ device }) => {
return device.open()

View File

@@ -0,0 +1,190 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 8 Feb 2022 03:29:24 +0100
Subject: Use-after-free of ID and IDREF attributes
If a document is parsed with XML_PARSE_DTDVALID and without
XML_PARSE_NOENT, the value of ID attributes has to be normalized after
potentially expanding entities in xmlRemoveID. Otherwise, later calls
to xmlGetID can return a pointer to previously freed memory.
ID attributes which are empty or contain only whitespace after
entity expansion are affected in a similar way. This is fixed by
not storing such attributes in the ID table.
The test to detect streaming mode when validating against a DTD was
broken. In connection with the defects above, this could result in a
use-after-free when using the xmlReader interface with validation.
Fix detection of streaming mode to avoid similar issues. (This changes
the expected result of a test case. But as far as I can tell, using the
XML reader with XIncludes referencing the root document never worked
properly, anyway.)
All of these issues can result in denial of service. Using xmlReader
with validation could result in disclosure of memory via the error
channel, typically stderr. The security impact of xmlGetID returning
a pointer to freed memory depends on the application. The typical use
case of calling xmlGetID on an unmodified document is not affected.
diff --git a/third_party/libxml/src/valid.c b/third_party/libxml/src/valid.c
index 5ee391c0418327f5e46293aedafdb353550f6f5b..8e596f1db3db40a5decc5f4b529abc7588c6bd66 100644
--- a/third_party/libxml/src/valid.c
+++ b/third_party/libxml/src/valid.c
@@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt)
return (ret);
}
+/**
+ * xmlValidNormalizeString:
+ * @str: a string
+ *
+ * Normalize a string in-place.
+ */
+static void
+xmlValidNormalizeString(xmlChar *str) {
+ xmlChar *dst;
+ const xmlChar *src;
+
+ if (str == NULL)
+ return;
+ src = str;
+ dst = str;
+
+ while (*src == 0x20) src++;
+ while (*src != 0) {
+ if (*src == 0x20) {
+ while (*src == 0x20) src++;
+ if (*src != 0)
+ *dst++ = 0x20;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
#ifdef DEBUG_VALID_ALGO
static void
xmlValidPrintNode(xmlNodePtr cur) {
@@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
+static int
+xmlIsStreaming(xmlValidCtxtPtr ctxt) {
+ xmlParserCtxtPtr pctxt;
+
+ if (ctxt == NULL)
+ return(0);
+ /*
+ * These magic values are also abused to detect whether we're validating
+ * while parsing a document. In this case, userData points to the parser
+ * context.
+ */
+ if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
+ (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
+ return(0);
+ pctxt = ctxt->userData;
+ return(pctxt->parseMode == XML_PARSE_READER);
+}
+
/**
* xmlFreeID:
* @not: A id
@@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
if (doc == NULL) {
return(NULL);
}
- if (value == NULL) {
+ if ((value == NULL) || (value[0] == 0)) {
return(NULL);
}
if (attr == NULL) {
@@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
*/
ret->value = xmlStrdup(value);
ret->doc = doc;
- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
+ if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
@@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
ID = xmlNodeListGetString(doc, attr->children, 1);
if (ID == NULL)
return(-1);
+ xmlValidNormalizeString(ID);
id = xmlHashLookup(table, ID);
if (id == NULL || id->attr != attr) {
@@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
* fill the structure.
*/
ret->value = xmlStrdup(value);
- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
+ if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
@@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar *
xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
- xmlChar *ret, *dst;
- const xmlChar *src;
+ xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
int extsubset = 0;
@@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
ret = xmlStrdup(value);
if (ret == NULL)
return(NULL);
- src = value;
- dst = ret;
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
+ xmlValidNormalizeString(ret);
if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
"standalone: %s on %s value had to be normalized based on external subset declaration\n",
@@ -4114,8 +4149,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar *
xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
const xmlChar *name, const xmlChar *value) {
- xmlChar *ret, *dst;
- const xmlChar *src;
+ xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
if (doc == NULL) return(NULL);
@@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
ret = xmlStrdup(value);
if (ret == NULL)
return(NULL);
- src = value;
- dst = ret;
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
+ xmlValidNormalizeString(ret);
return(ret);
}

View File

@@ -5,6 +5,8 @@
"src/electron/patches/webrtc": "src/third_party/webrtc",
"src/electron/patches/pdfium": "src/third_party/pdfium",
"src/electron/patches/v8": "src/v8",
"src/electron/patches/node": "src/third_party/electron_node",
@@ -15,5 +17,7 @@
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/angle": "src/third_party/angle"
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/icu": "src/third_party/icu"
}

1
patches/icu/.patches Normal file
View File

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

View File

@@ -0,0 +1,349 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Frank Tang <ftang@chromium.org>
Date: Fri, 29 Apr 2022 16:50:59 -0700
Subject: CP PR 2070 fix int32 overflow
https://github.com/unicode-org/icu/pull/2070
https://unicode-org.atlassian.net/browse/ICU-22005
Bug: chromium:1316946
Change-Id: I6cd7d687a55b6cc157b1afa52365908be2992fa6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/deps/icu/+/3614280
Reviewed-by: Jungshik Shin <jshin@chromium.org>
(cherry picked from commit 85814e1af52482199a13d284545623ffbc9eef83)
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/deps/icu/+/3632709
diff --git a/README.chromium b/README.chromium
index 269fc7263ca642b24fd709312d6ecb70a9c8f48a..33c642b49be7fbebbe9b0f43edea565317e4c8ca 100644
--- a/README.chromium
+++ b/README.chromium
@@ -282,3 +282,7 @@ D. Local Modifications
- upstream PR:
https://github.com/unicode-org/icu/pull/1762
+12. Patch i18n/formatted_string_builder to fix int32_t overflow bug
+ patches/formatted_string_builder.patch
+ - https://github.com/unicode-org/icu/pull/2070
+ - https://unicode-org.atlassian.net/browse/ICU-22005
diff --git a/patches/formatted_string_builder.patch b/patches/formatted_string_builder.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4fad6f18601f7b4097e2d46bfe6660bec2e2882d
--- /dev/null
+++ b/patches/formatted_string_builder.patch
@@ -0,0 +1,191 @@
+diff --git a/source/i18n/formatted_string_builder.cpp b/source/i18n/formatted_string_builder.cpp
+index 73407864..628fbea8 100644
+--- a/source/i18n/formatted_string_builder.cpp
++++ b/source/i18n/formatted_string_builder.cpp
+@@ -6,6 +6,7 @@
+ #if !UCONFIG_NO_FORMATTING
+
+ #include "formatted_string_builder.h"
++#include "putilimp.h"
+ #include "unicode/ustring.h"
+ #include "unicode/utf16.h"
+ #include "unicode/unum.h" // for UNumberFormatFields literals
+@@ -197,6 +198,9 @@ FormattedStringBuilder::splice(int32_t startThis, int32_t endThis, const Unicod
+ int32_t thisLength = endThis - startThis;
+ int32_t otherLength = endOther - startOther;
+ int32_t count = otherLength - thisLength;
++ if (U_FAILURE(status)) {
++ return count;
++ }
+ int32_t position;
+ if (count > 0) {
+ // Overall, chars need to be added.
+@@ -221,6 +225,9 @@ int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErr
+
+ int32_t
+ FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) {
++ if (U_FAILURE(status)) {
++ return 0;
++ }
+ if (this == &other) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+@@ -255,12 +262,18 @@ int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, U
+ U_ASSERT(index >= 0);
+ U_ASSERT(index <= fLength);
+ U_ASSERT(count >= 0);
++ U_ASSERT(fZero >= 0);
++ U_ASSERT(fLength >= 0);
++ U_ASSERT(getCapacity() - fZero >= fLength);
++ if (U_FAILURE(status)) {
++ return count;
++ }
+ if (index == 0 && fZero - count >= 0) {
+ // Append to start
+ fZero -= count;
+ fLength += count;
+ return fZero;
+- } else if (index == fLength && fZero + fLength + count < getCapacity()) {
++ } else if (index == fLength && count <= getCapacity() - fZero - fLength) {
+ // Append to end
+ fLength += count;
+ return fZero + fLength - count;
+@@ -275,18 +288,26 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+ int32_t oldZero = fZero;
+ char16_t *oldChars = getCharPtr();
+ Field *oldFields = getFieldPtr();
+- if (fLength + count > oldCapacity) {
+- if ((fLength + count) > INT32_MAX / 2) {
+- // If we continue, then newCapacity will overflow int32_t in the next line.
++ int32_t newLength;
++ if (uprv_add32_overflow(fLength, count, &newLength)) {
++ status = U_INPUT_TOO_LONG_ERROR;
++ return -1;
++ }
++ int32_t newZero;
++ if (newLength > oldCapacity) {
++ if (newLength > INT32_MAX / 2) {
++ // We do not support more than 1G char16_t in this code because
++ // dealing with >2G *bytes* can cause subtle bugs.
+ status = U_INPUT_TOO_LONG_ERROR;
+ return -1;
+ }
+- int32_t newCapacity = (fLength + count) * 2;
+- int32_t newZero = newCapacity / 2 - (fLength + count) / 2;
++ // Keep newCapacity also to at most 1G char16_t.
++ int32_t newCapacity = newLength * 2;
++ newZero = (newCapacity - newLength) / 2;
+
+ // C++ note: malloc appears in two places: here and in the assignment operator.
+- auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * newCapacity));
+- auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * newCapacity));
++ auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * static_cast<size_t>(newCapacity)));
++ auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * static_cast<size_t>(newCapacity)));
+ if (newChars == nullptr || newFields == nullptr) {
+ uprv_free(newChars);
+ uprv_free(newFields);
+@@ -315,10 +336,8 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+ fChars.heap.capacity = newCapacity;
+ fFields.heap.ptr = newFields;
+ fFields.heap.capacity = newCapacity;
+- fZero = newZero;
+- fLength += count;
+ } else {
+- int32_t newZero = oldCapacity / 2 - (fLength + count) / 2;
++ newZero = (oldCapacity - newLength) / 2;
+
+ // C++ note: memmove is required because src and dest may overlap.
+ // First copy the entire string to the location of the prefix, and then move the suffix
+@@ -331,18 +350,20 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+ uprv_memmove2(oldFields + newZero + index + count,
+ oldFields + newZero + index,
+ sizeof(Field) * (fLength - index));
+-
+- fZero = newZero;
+- fLength += count;
+ }
+- U_ASSERT((fZero + index) >= 0);
++ fZero = newZero;
++ fLength = newLength;
+ return fZero + index;
+ }
+
+ int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
+- // TODO: Reset the heap here? (If the string after removal can fit on stack?)
++ U_ASSERT(0 <= index);
++ U_ASSERT(index <= fLength);
++ U_ASSERT(count <= (fLength - index));
++ U_ASSERT(index <= getCapacity() - fZero);
++
+ int32_t position = index + fZero;
+- U_ASSERT(position >= 0);
++ // TODO: Reset the heap here? (If the string after removal can fit on stack?)
+ uprv_memmove2(getCharPtr() + position,
+ getCharPtr() + position + count,
+ sizeof(char16_t) * (fLength - index - count));
+diff --git a/source/test/intltest/formatted_string_builder_test.cpp b/source/test/intltest/formatted_string_builder_test.cpp
+index 45721a32..57294e24 100644
+--- a/source/test/intltest/formatted_string_builder_test.cpp
++++ b/source/test/intltest/formatted_string_builder_test.cpp
+@@ -22,6 +22,7 @@ class FormattedStringBuilderTest : public IntlTest {
+ void testFields();
+ void testUnlimitedCapacity();
+ void testCodePoints();
++ void testInsertOverflow();
+
+ void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
+
+@@ -50,6 +51,7 @@ void FormattedStringBuilderTest::runIndexedTest(int32_t index, UBool exec, const
+ TESTCASE_AUTO(testFields);
+ TESTCASE_AUTO(testUnlimitedCapacity);
+ TESTCASE_AUTO(testCodePoints);
++ TESTCASE_AUTO(testInsertOverflow);
+ TESTCASE_AUTO_END;
+ }
+
+@@ -308,6 +310,45 @@ void FormattedStringBuilderTest::testCodePoints() {
+ assertEquals("Code point count is 2", 2, nsb.codePointCount());
+ }
+
++void FormattedStringBuilderTest::testInsertOverflow() {
++ if (quick) return;
++ // Setup the test fixture in sb, sb2, ustr.
++ UErrorCode status = U_ZERO_ERROR;
++ FormattedStringBuilder sb;
++ int32_t data_length = INT32_MAX / 2;
++ UnicodeString ustr(data_length, u'a', data_length);
++ sb.append(ustr, kUndefinedField, status);
++ assertSuccess("Setup the first FormattedStringBuilder", status);
++
++ FormattedStringBuilder sb2;
++ sb2.append(ustr, kUndefinedField, status);
++ sb2.insert(0, ustr, 0, data_length / 2, kUndefinedField, status);
++ sb2.writeTerminator(status);
++ assertSuccess("Setup the second FormattedStringBuilder", status);
++
++ ustr = sb2.toUnicodeString();
++ // Complete setting up the test fixture in sb, sb2 and ustr.
++
++ // Test splice() of the second UnicodeString
++ sb.splice(0, 1, ustr, 1, ustr.length(),
++ kUndefinedField, status);
++ assertEquals(
++ "splice() long text should not crash but return U_INPUT_TOO_LONG_ERROR",
++ U_INPUT_TOO_LONG_ERROR, status);
++
++ // Test sb.insert() of the first FormattedStringBuilder with the second one.
++ sb.insert(0, sb2, status);
++ assertEquals(
++ "insert() long FormattedStringBuilder should not crash but return "
++ "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
++
++ // Test sb.insert() of the first FormattedStringBuilder with UnicodeString.
++ sb.insert(0, ustr, 0, ustr.length(), kUndefinedField, status);
++ assertEquals(
++ "insert() long UnicodeString should not crash but return "
++ "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
++}
++
+ void FormattedStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const FormattedStringBuilder &b) {
+ // TODO: Why won't this compile without the IntlTest:: qualifier?
+ IntlTest::assertEquals("Lengths should be the same", a.length(), b.length());
diff --git a/source/i18n/formatted_string_builder.cpp b/source/i18n/formatted_string_builder.cpp
index b370f14f2ac4ff0873e5614376ae51fe0232b02d..628fbea871167619f60cc6eed0ee4b7776dab7fe 100644
--- a/source/i18n/formatted_string_builder.cpp
+++ b/source/i18n/formatted_string_builder.cpp
@@ -6,6 +6,7 @@
#if !UCONFIG_NO_FORMATTING
#include "formatted_string_builder.h"
+#include "putilimp.h"
#include "unicode/ustring.h"
#include "unicode/utf16.h"
#include "unicode/unum.h" // for UNumberFormatFields literals
@@ -197,6 +198,9 @@ FormattedStringBuilder::splice(int32_t startThis, int32_t endThis, const Unicod
int32_t thisLength = endThis - startThis;
int32_t otherLength = endOther - startOther;
int32_t count = otherLength - thisLength;
+ if (U_FAILURE(status)) {
+ return count;
+ }
int32_t position;
if (count > 0) {
// Overall, chars need to be added.
@@ -221,6 +225,9 @@ int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErr
int32_t
FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) {
+ if (U_FAILURE(status)) {
+ return 0;
+ }
if (this == &other) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
@@ -255,12 +262,18 @@ int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, U
U_ASSERT(index >= 0);
U_ASSERT(index <= fLength);
U_ASSERT(count >= 0);
+ U_ASSERT(fZero >= 0);
+ U_ASSERT(fLength >= 0);
+ U_ASSERT(getCapacity() - fZero >= fLength);
+ if (U_FAILURE(status)) {
+ return count;
+ }
if (index == 0 && fZero - count >= 0) {
// Append to start
fZero -= count;
fLength += count;
return fZero;
- } else if (index == fLength && fZero + fLength + count < getCapacity()) {
+ } else if (index == fLength && count <= getCapacity() - fZero - fLength) {
// Append to end
fLength += count;
return fZero + fLength - count;
@@ -275,18 +288,26 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
int32_t oldZero = fZero;
char16_t *oldChars = getCharPtr();
Field *oldFields = getFieldPtr();
- if (fLength + count > oldCapacity) {
- if ((fLength + count) > INT32_MAX / 2) {
- // If we continue, then newCapacity will overlow int32_t in the next line.
+ int32_t newLength;
+ if (uprv_add32_overflow(fLength, count, &newLength)) {
+ status = U_INPUT_TOO_LONG_ERROR;
+ return -1;
+ }
+ int32_t newZero;
+ if (newLength > oldCapacity) {
+ if (newLength > INT32_MAX / 2) {
+ // We do not support more than 1G char16_t in this code because
+ // dealing with >2G *bytes* can cause subtle bugs.
status = U_INPUT_TOO_LONG_ERROR;
return -1;
}
- int32_t newCapacity = (fLength + count) * 2;
- int32_t newZero = newCapacity / 2 - (fLength + count) / 2;
+ // Keep newCapacity also to at most 1G char16_t.
+ int32_t newCapacity = newLength * 2;
+ newZero = (newCapacity - newLength) / 2;
// C++ note: malloc appears in two places: here and in the assignment operator.
- auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * newCapacity));
- auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * newCapacity));
+ auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * static_cast<size_t>(newCapacity)));
+ auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * static_cast<size_t>(newCapacity)));
if (newChars == nullptr || newFields == nullptr) {
uprv_free(newChars);
uprv_free(newFields);
@@ -315,10 +336,8 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
fChars.heap.capacity = newCapacity;
fFields.heap.ptr = newFields;
fFields.heap.capacity = newCapacity;
- fZero = newZero;
- fLength += count;
} else {
- int32_t newZero = oldCapacity / 2 - (fLength + count) / 2;
+ newZero = (oldCapacity - newLength) / 2;
// C++ note: memmove is required because src and dest may overlap.
// First copy the entire string to the location of the prefix, and then move the suffix
@@ -331,18 +350,20 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
uprv_memmove2(oldFields + newZero + index + count,
oldFields + newZero + index,
sizeof(Field) * (fLength - index));
-
- fZero = newZero;
- fLength += count;
}
- U_ASSERT((fZero + index) >= 0);
+ fZero = newZero;
+ fLength = newLength;
return fZero + index;
}
int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
- // TODO: Reset the heap here? (If the string after removal can fit on stack?)
+ U_ASSERT(0 <= index);
+ U_ASSERT(index <= fLength);
+ U_ASSERT(count <= (fLength - index));
+ U_ASSERT(index <= getCapacity() - fZero);
+
int32_t position = index + fZero;
- U_ASSERT(position >= 0);
+ // TODO: Reset the heap here? (If the string after removal can fit on stack?)
uprv_memmove2(getCharPtr() + position,
getCharPtr() + position + count,
sizeof(char16_t) * (fLength - index - count));

1
patches/pdfium/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-a48de319c521.patch

View File

@@ -0,0 +1,93 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 16 Dec 2021 23:53:35 +0000
Subject: Use safe arithmetic in CJBig2_Context::ParseSymbolDict()
These should be mitigated by size checks higher up, but it wouldn't
hurt to be sure.
Bug: chromium:1280743
Change-Id: I03c46e3d11316a9f9634256bd0e2394548d2681e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/88290
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/jbig2/JBig2_Context.cpp b/core/fxcodec/jbig2/JBig2_Context.cpp
index 083e95ba4c16c21f5f3934df92e54dbb6ee4fe88..08bdb253f32a2a6c393af6246b88440d837876d9 100644
--- a/core/fxcodec/jbig2/JBig2_Context.cpp
+++ b/core/fxcodec/jbig2/JBig2_Context.cpp
@@ -409,28 +409,31 @@ JBig2_Result CJBig2_Context::ParseSymbolDict(CJBig2_Segment* pSegment) {
return JBig2_Result::kFailure;
}
CJBig2_Segment* pLRSeg = nullptr;
- pSymbolDictDecoder->SDNUMINSYMS = 0;
+ FX_SAFE_UINT32 dwNumSyms = 0;
for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) {
CJBig2_Segment* pSeg =
FindSegmentByNumber(pSegment->m_Referred_to_segment_numbers[i]);
if (pSeg->m_cFlags.s.type == 0) {
- pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_SymbolDict->NumImages();
+ dwNumSyms += pSeg->m_SymbolDict->NumImages();
pLRSeg = pSeg;
}
}
+ pSymbolDictDecoder->SDNUMINSYMS = dwNumSyms.ValueOrDie();
std::unique_ptr<CJBig2_Image*, FxFreeDeleter> SDINSYMS;
if (pSymbolDictDecoder->SDNUMINSYMS != 0) {
SDINSYMS.reset(FX_Alloc(CJBig2_Image*, pSymbolDictDecoder->SDNUMINSYMS));
- uint32_t dwTemp = 0;
+ dwNumSyms = 0;
for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) {
CJBig2_Segment* pSeg =
FindSegmentByNumber(pSegment->m_Referred_to_segment_numbers[i]);
if (pSeg->m_cFlags.s.type == 0) {
const CJBig2_SymbolDict& dict = *pSeg->m_SymbolDict;
- for (size_t j = 0; j < dict.NumImages(); ++j)
- SDINSYMS.get()[dwTemp + j] = dict.GetImage(j);
- dwTemp += dict.NumImages();
+ for (uint32_t j = 0; j < dict.NumImages(); ++j) {
+ uint32_t dwTemp = (dwNumSyms + j).ValueOrDie();
+ SDINSYMS.get()[dwTemp] = dict.GetImage(j);
+ }
+ dwNumSyms += dict.NumImages();
}
}
}
@@ -624,27 +627,30 @@ JBig2_Result CJBig2_Context::ParseTextRegion(CJBig2_Segment* pSegment) {
return JBig2_Result::kFailure;
}
- pTRD->SBNUMSYMS = 0;
+ FX_SAFE_UINT32 dwNumSyms = 0;
for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) {
CJBig2_Segment* pSeg =
FindSegmentByNumber(pSegment->m_Referred_to_segment_numbers[i]);
if (pSeg->m_cFlags.s.type == 0) {
- pTRD->SBNUMSYMS += pSeg->m_SymbolDict->NumImages();
+ dwNumSyms += pSeg->m_SymbolDict->NumImages();
}
}
+ pTRD->SBNUMSYMS = dwNumSyms.ValueOrDie();
std::unique_ptr<CJBig2_Image*, FxFreeDeleter> SBSYMS;
if (pTRD->SBNUMSYMS > 0) {
SBSYMS.reset(FX_Alloc(CJBig2_Image*, pTRD->SBNUMSYMS));
- dwTemp = 0;
+ dwNumSyms = 0;
for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) {
CJBig2_Segment* pSeg =
FindSegmentByNumber(pSegment->m_Referred_to_segment_numbers[i]);
if (pSeg->m_cFlags.s.type == 0) {
const CJBig2_SymbolDict& dict = *pSeg->m_SymbolDict;
- for (size_t j = 0; j < dict.NumImages(); ++j)
- SBSYMS.get()[dwTemp + j] = dict.GetImage(j);
- dwTemp += dict.NumImages();
+ for (uint32_t j = 0; j < dict.NumImages(); ++j) {
+ uint32_t dwIndex = (dwNumSyms + j).ValueOrDie();
+ SBSYMS.get()[dwIndex] = dict.GetImage(j);
+ }
+ dwNumSyms += dict.NumImages();
}
}
pTRD->SBSYMS = SBSYMS.get();

View File

@@ -21,3 +21,9 @@ cherry-pick-27bc67f761e6.patch
regexp_fix_uaf_in_regexpmacroassembler.patch
cherry-pick-26b7ad6967b1.patch
cherry-pick-c46fb3a15ec2.patch
cherry-pick-a1427aad7cef.patch
cherry-pick-f599381978f2.patch
cherry-pick-f546ac11eec7.patch
cherry-pick-e42dbcdedb7a.patch
cherry-pick-b2d3ef69ef99.patch
cherry-pick-2004594a46c8.patch

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nico Hartmann <nicohartmann@chromium.org>
Date: Thu, 17 Mar 2022 17:03:12 +0100
Subject: Fix NumberConstant used with Word32 rep in ISel
Bug: chromium:1304658
(cherry picked from commit bbea5909c797dec7c620b9fee43d80a1420c2e08)
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I6a82603a7c5de5ae8f5a895990c1a904bbdd39b2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3532263
Auto-Submit: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79526}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3541919
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/9.6@{#58}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/compiler/backend/instruction-selector.cc b/src/compiler/backend/instruction-selector.cc
index f279ea15900976fd57ef577b67e4cbeca3eb6374..92c11e09b4445e1fe477ca1614166dd6999baf64 100644
--- a/src/compiler/backend/instruction-selector.cc
+++ b/src/compiler/backend/instruction-selector.cc
@@ -30,6 +30,14 @@ namespace v8 {
namespace internal {
namespace compiler {
+Smi NumberConstantToSmi(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kNumberConstant);
+ const double d = OpParameter<double>(node->op());
+ Smi smi = Smi::FromInt(static_cast<int32_t>(d));
+ CHECK_EQ(smi.value(), d);
+ return smi;
+}
+
InstructionSelector::InstructionSelector(
Zone* zone, size_t node_count, Linkage* linkage,
InstructionSequence* sequence, Schedule* schedule,
@@ -502,11 +510,17 @@ InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
switch (input->opcode()) {
case IrOpcode::kInt32Constant:
case IrOpcode::kInt64Constant:
- case IrOpcode::kNumberConstant:
case IrOpcode::kFloat32Constant:
case IrOpcode::kFloat64Constant:
case IrOpcode::kDelayedStringConstant:
return g->UseImmediate(input);
+ case IrOpcode::kNumberConstant:
+ if (rep == MachineRepresentation::kWord32) {
+ Smi smi = NumberConstantToSmi(input);
+ return g->UseImmediate(static_cast<int32_t>(smi.ptr()));
+ } else {
+ return g->UseImmediate(input);
+ }
case IrOpcode::kCompressedHeapConstant:
case IrOpcode::kHeapConstant: {
if (!CanBeTaggedOrCompressedPointer(rep)) {

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Patrick Thier <pthier@chromium.org>
Date: Fri, 15 Oct 2021 15:04:15 +0000
Subject: Assert that we never copy properties from an object itself
When copying properties, it should never happen that source == target.
Add a CHECK to assert this assumption.
Bug: chromium:1260129
Change-Id: Ia5248e4363d85e13052db726fb7143897cea9c87
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3226779
Commit-Queue: Patrick Thier <pthier@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77418}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index cdd16a65a6a94bdae2c245639ac4616fd22e38d2..e329cba144b271e2e35af67deb324bc7834e7a2a 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -229,6 +229,9 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
return Just(false);
}
+ // We should never try to copy properties from an object itself.
+ CHECK_IMPLIES(!use_set, !target.is_identical_to(from));
+
Handle<DescriptorArray> descriptors(map->instance_descriptors(isolate),
isolate);

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Wed, 13 Apr 2022 16:30:36 +0000
Subject: mark receiver and function as escaping
(cherry picked from commit 8081a5ffa7ebdb0e5b35cf63aa0490ad3578b940)
Bug: chromium:1315901
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: Ic44bfcae32aba202ba25c5f59fe579214a444584
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584117
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79968}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584531
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/9.6@{#62}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
index 7ff6ab684fcf405b956d8dcca506f6b3e116244e..316db298da86cedf8e550a39f6f7ee9413f02c86 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -5,10 +5,12 @@
#include "src/compiler/escape-analysis.h"
#include "src/codegen/tick-counter.h"
+#include "src/compiler/frame-states.h"
#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
+#include "src/compiler/state-values-utils.h"
#include "src/handles/handles-inl.h"
#include "src/init/bootstrapper.h"
#include "src/objects/map-inl.h"
@@ -224,6 +226,11 @@ class EscapeAnalysisTracker : public ZoneObject {
return tracker_->ResolveReplacement(
NodeProperties::GetContextInput(current_node()));
}
+ // Accessing the current node is fine for `FrameState nodes.
+ Node* CurrentNode() {
+ DCHECK_EQ(current_node()->opcode(), IrOpcode::kFrameState);
+ return current_node();
+ }
void SetReplacement(Node* replacement) {
replacement_ = replacement;
@@ -796,9 +803,25 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current,
break;
}
case IrOpcode::kStateValues:
- case IrOpcode::kFrameState:
// These uses are always safe.
break;
+ case IrOpcode::kFrameState: {
+ // We mark the receiver as escaping due to the non-standard `.getThis`
+ // API.
+ FrameState frame_state{current->CurrentNode()};
+ if (frame_state.frame_state_info().type() !=
+ FrameStateType::kUnoptimizedFunction)
+ break;
+ StateValuesAccess::iterator it =
+ StateValuesAccess(frame_state.parameters()).begin();
+ if (!it.done()) {
+ if (Node* receiver = it.node()) {
+ current->SetEscaped(receiver);
+ }
+ current->SetEscaped(frame_state.function());
+ }
+ break;
+ }
default: {
// For unknown nodes, treat all value inputs as escaping.
int value_input_count = op->ValueInputCount();

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brendon Tiszka <btiszka@gmail.com>
Date: Fri, 18 Mar 2022 01:32:54 -0400
Subject: Merged: Update write barrier when storing HeapNumber to last index.
(cherry picked from commit bdc4f54a50293507d9ef51573bab537883560cc8)
No-Try: true
No-Presubmit: true
No-Treechecks: true
Bug: chromium:1307610
Change-Id: I60aaa0e58e13b705b5eff4b57411a0ad4a2e9b3f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3534849
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79538}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3565716
Reviewed-by: Patrick Thier <pthier@chromium.org>
Commit-Queue: Jakob Linke <jgruber@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.0@{#18}
Cr-Branched-From: 6ea73a738c467dc26abbbe84e27a36aac1c6e119-refs/heads/10.0.139@{#1}
Cr-Branched-From: ccc689011280419901e6ee42cae39980c0e96030-refs/heads/main@{#79131}
diff --git a/src/regexp/regexp-utils.cc b/src/regexp/regexp-utils.cc
index 1e72a124c95729ebf9c4a7caed52b5551408a525..9ddf82e95a7c07bbb7a529167bbf30058a1cbd14 100644
--- a/src/regexp/regexp-utils.cc
+++ b/src/regexp/regexp-utils.cc
@@ -49,7 +49,8 @@ MaybeHandle<Object> RegExpUtils::SetLastIndex(Isolate* isolate,
Handle<Object> value_as_object =
isolate->factory()->NewNumberFromInt64(value);
if (HasInitialRegExpMap(isolate, *recv)) {
- JSRegExp::cast(*recv).set_last_index(*value_as_object, SKIP_WRITE_BARRIER);
+ JSRegExp::cast(*recv).set_last_index(*value_as_object,
+ UPDATE_WRITE_BARRIER);
return recv;
} else {
return Object::SetProperty(

View File

@@ -0,0 +1,92 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= <marja@chromium.org>
Date: Thu, 24 Mar 2022 17:30:16 +0100
Subject: Turn off super ICs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
M96 merge issues:
Conflicts in the bytecode test expectations
They make assumptions which don't hold for API handlers.
(cherry picked from commit c6b68cbfbd49a24bd9d343d718132125370da729)
Bug: v8:9237,chromium:1308360
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I9f122c4e75a24d83ef3653cbf7a223ed522e4d13
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3548899
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#79614}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3553109
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/9.6@{#60}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/flags/flag-definitions.h b/src/flags/flag-definitions.h
index 312d17b52f314c6d77799c280f22888317d58e7d..1f20909cc247fc68f103eb2025235892eefdce8d 100644
--- a/src/flags/flag-definitions.h
+++ b/src/flags/flag-definitions.h
@@ -1552,7 +1552,7 @@ DEFINE_INT(max_valid_polymorphic_map_count, 4,
DEFINE_BOOL(native_code_counters, DEBUG_BOOL,
"generate extra code for manipulating stats counters")
-DEFINE_BOOL(super_ic, true, "use an IC for super property loads")
+DEFINE_BOOL(super_ic, false, "use an IC for super property loads")
DEFINE_BOOL(enable_mega_dom_ic, false, "use MegaDOM IC state for API objects")
diff --git a/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden b/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
index 82b6e16be98d8dd9d8fe6b8419653d2c02f7bf79..c433538d8ed52c52277f2ad7163fc4b15c29591c 100644
--- a/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
+++ b/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
@@ -20,14 +20,18 @@ snippet: "
test();
})();
"
-frame size: 1
+frame size: 5
parameter count: 1
-bytecode array length: 16
+bytecode array length: 24
bytecodes: [
/* 104 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
- /* 117 E> */ B(LdaNamedPropertyFromSuper), R(this), U8(0), U8(1),
+ B(Star3),
+ B(LdaConstant), U8(0),
+ B(Star4),
+ B(Mov), R(this), R(2),
+ /* 117 E> */ B(CallRuntime), U16(Runtime::kLoadFromSuper), R(2), U8(3),
B(Star0),
- /* 117 E> */ B(CallAnyReceiver), R(0), R(this), U8(1), U8(3),
+ /* 117 E> */ B(CallAnyReceiver), R(0), R(this), U8(1), U8(1),
/* 126 E> */ B(AddSmi), I8(1), U8(0),
/* 130 S> */ B(Return),
]
@@ -54,7 +58,7 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 24
+bytecode array length: 32
bytecodes: [
/* 130 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star1),
@@ -65,7 +69,11 @@ bytecodes: [
B(Mov), R(this), R(0),
/* 138 E> */ B(CallRuntime), U16(Runtime::kStoreToSuper), R(0), U8(4),
/* 143 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
- /* 156 E> */ B(LdaNamedPropertyFromSuper), R(this), U8(0), U8(0),
+ B(Star1),
+ B(LdaConstant), U8(0),
+ B(Star2),
+ B(Mov), R(this), R(0),
+ /* 156 E> */ B(CallRuntime), U16(Runtime::kLoadFromSuper), R(0), U8(3),
/* 158 S> */ B(Return),
]
constant pool: [

View File

@@ -0,0 +1,153 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Mon, 4 Apr 2022 14:42:56 +0200
Subject: Fix handling of interceptors, pt.3
... in JSObject::DefineOwnPropertyIgnoreAttributes().
Don't execute interceptor again if it declined to handle the operation.
(cherry picked from commit c4e66b89b4ecd0e90b31e9e4ed08d38085a84c49)
Bug: chromium:1311641
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: Ie9aef5a98959403f6a26e6bef7f4a77d312bd62a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3568921
Reviewed-by: Lutz Vahl <vahl@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.6@{#56}
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index e329cba144b271e2e35af67deb324bc7834e7a2a..91c4949b136ac74d55e4ce4cfb929aacd9828dcc 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -3348,13 +3348,24 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
// TODO(verwaest): JSProxy afterwards verify the attributes that the
// JSProxy claims it has, and verifies that they are compatible. If not,
// they throw. Here we should do the same.
- case LookupIterator::INTERCEPTOR:
+ case LookupIterator::INTERCEPTOR: {
if (handling == DONT_FORCE_FIELD) {
Maybe<bool> result =
JSObject::SetPropertyWithInterceptor(it, should_throw, value);
if (result.IsNothing() || result.FromJust()) return result;
}
- break;
+
+ // The interceptor declined to handle the operation, so proceed defining
+ // own property without the interceptor.
+ Isolate* isolate = it->isolate();
+ Handle<Object> receiver = it->GetReceiver();
+ LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
+ LookupIterator own_lookup =
+ it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
+ : LookupIterator(isolate, receiver, it->name(), c);
+ return JSObject::DefineOwnPropertyIgnoreAttributes(
+ &own_lookup, value, attributes, should_throw, handling);
+ }
case LookupIterator::ACCESSOR: {
Handle<Object> accessors = it->GetAccessors();
diff --git a/test/cctest/test-api-interceptors.cc b/test/cctest/test-api-interceptors.cc
index 475003f73c49b8e462ef1896f3fad97857e24574..393dd7192542d299dfa4fe332c5fcff2dff79903 100644
--- a/test/cctest/test-api-interceptors.cc
+++ b/test/cctest/test-api-interceptors.cc
@@ -60,6 +60,16 @@ void EmptyInterceptorDeleter(
void EmptyInterceptorEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {}
+void EmptyInterceptorDefinerWithSideEffect(
+ Local<Name> name, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ v8::Local<v8::Value> result = CompileRun("interceptor_definer_side_effect()");
+ if (!result->IsNull()) {
+ info.GetReturnValue().Set(result);
+ }
+}
+
void SimpleAccessorGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
Local<Object> self = info.This().As<Object>();
@@ -869,13 +879,17 @@ THREADED_TEST(InterceptorHasOwnPropertyCausingGC) {
namespace {
void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
+ v8::GenericNamedPropertySetterCallback setter,
v8::GenericNamedPropertyQueryCallback query,
- const char* source, int expected) {
+ v8::GenericNamedPropertyDefinerCallback definer,
+ v8::PropertyHandlerFlags flags, const char* source,
+ int expected) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
- getter, nullptr, query, nullptr, nullptr, v8_str("data")));
+ getter, setter, query, nullptr /* deleter */, nullptr /* enumerator */,
+ definer, nullptr /* descriptor */, v8_str("data"), flags));
LocalContext context;
context->Global()
->Set(context.local(), v8_str("o"),
@@ -885,9 +899,17 @@ void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
CHECK_EQ(expected, value->Int32Value(context.local()).FromJust());
}
+void CheckInterceptorIC(v8::GenericNamedPropertyGetterCallback getter,
+ v8::GenericNamedPropertyQueryCallback query,
+ const char* source, int expected) {
+ CheckInterceptorIC(getter, nullptr, query, nullptr,
+ v8::PropertyHandlerFlags::kNone, source, expected);
+}
+
void CheckInterceptorLoadIC(v8::GenericNamedPropertyGetterCallback getter,
const char* source, int expected) {
- CheckInterceptorIC(getter, nullptr, source, expected);
+ CheckInterceptorIC(getter, nullptr, nullptr, nullptr,
+ v8::PropertyHandlerFlags::kNone, source, expected);
}
void InterceptorLoadICGetter(Local<Name> name,
@@ -1581,6 +1603,38 @@ THREADED_TEST(InterceptorStoreICWithSideEffectfulCallbacks) {
19);
}
+THREADED_TEST(InterceptorDefineICWithSideEffectfulCallbacks) {
+ CheckInterceptorIC(EmptyInterceptorGetter, EmptyInterceptorSetter,
+ EmptyInterceptorQuery,
+ EmptyInterceptorDefinerWithSideEffect,
+ v8::PropertyHandlerFlags::kNonMasking,
+ "let inside_side_effect = false;"
+ "let interceptor_definer_side_effect = function() {"
+ " if (!inside_side_effect) {"
+ " inside_side_effect = true;"
+ " o.y = 153;"
+ " inside_side_effect = false;"
+ " }"
+ " return null;"
+ "};"
+ "class Base {"
+ " constructor(arg) {"
+ " return arg;"
+ " }"
+ "}"
+ "class ClassWithField extends Base {"
+ " y = (() => {"
+ " return 42;"
+ " })();"
+ " constructor(arg) {"
+ " super(arg);"
+ " }"
+ "}"
+ "new ClassWithField(o);"
+ "o.y",
+ 42);
+}
+
static void InterceptorStoreICSetter(
Local<Name> key, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {

View File

@@ -1,2 +1,3 @@
add_thread_local_to_x_error_trap_cc.patch
merge_to_m96_sdp_reject_large_number_of_channels.patch
adding_fuzzer_for_pcm16b_decoder_and_fixing_a_fuzzer_problem.patch

View File

@@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Henrik Lundin <henrik.lundin@webrtc.org>
Date: Tue, 15 Feb 2022 15:13:34 +0000
Subject: Adding fuzzer for PCM16b decoder and fixing a fuzzer problem
Bug: chromium:1280852
Change-Id: I7f6c5de86ceee01156743c0389c59f875e53bb5f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/251580
Reviewed-by: Minyue Li <minyue@webrtc.org>
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36005}
diff --git a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
index 1dd2ff289ee10280963c3db5de58545886c60d49..7761efe8b3b2d1627021e9f19dfb25ca871be049 100644
--- a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
+++ b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc
@@ -42,7 +42,12 @@ int AudioDecoderPcm16B::DecodeInternal(const uint8_t* encoded,
int16_t* decoded,
SpeechType* speech_type) {
RTC_DCHECK_EQ(sample_rate_hz_, sample_rate_hz);
- size_t ret = WebRtcPcm16b_Decode(encoded, encoded_len, decoded);
+ // Adjust the encoded length down to ensure the same number of samples in each
+ // channel.
+ const size_t encoded_len_adjusted =
+ PacketDuration(encoded, encoded_len) * 2 *
+ Channels(); // 2 bytes per sample per channel
+ size_t ret = WebRtcPcm16b_Decode(encoded, encoded_len_adjusted, decoded);
*speech_type = ConvertSpeechType(1);
return static_cast<int>(ret);
}
diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn
index 8300fca3a461385f7014c8690662494bb387079a..1cf262325162c6c6d28d6c5ca1a3cdbabade951b 100644
--- a/test/fuzzers/BUILD.gn
+++ b/test/fuzzers/BUILD.gn
@@ -306,6 +306,14 @@ webrtc_fuzzer_test("audio_decoder_multiopus_fuzzer") {
]
}
+webrtc_fuzzer_test("audio_decoder_pcm16b_fuzzer") {
+ sources = [ "audio_decoder_pcm16b_fuzzer.cc" ]
+ deps = [
+ ":audio_decoder_fuzzer",
+ "../../modules/audio_coding:pcm16b",
+ ]
+}
+
rtc_library("audio_encoder_fuzzer") {
testonly = true
sources = [
diff --git a/test/fuzzers/audio_decoder_pcm16b_fuzzer.cc b/test/fuzzers/audio_decoder_pcm16b_fuzzer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6e5d6e2190638185578ac71b400913f46f6b67cf
--- /dev/null
+++ b/test/fuzzers/audio_decoder_pcm16b_fuzzer.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <memory>
+
+#include "modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
+#include "test/fuzzers/audio_decoder_fuzzer.h"
+
+namespace webrtc {
+void FuzzOneInput(const uint8_t* data, size_t size) {
+ if (size > 10000 || size < 2) {
+ return;
+ }
+
+ int sample_rate_hz;
+ switch (data[0] % 4) {
+ case 0:
+ sample_rate_hz = 8000;
+ break;
+ case 1:
+ sample_rate_hz = 16000;
+ break;
+ case 2:
+ sample_rate_hz = 32000;
+ break;
+ case 3:
+ sample_rate_hz = 48000;
+ break;
+ default:
+ RTC_DCHECK_NOTREACHED();
+ return;
+ }
+ const size_t num_channels = data[1] % 16 + 1;
+
+ // Two first bytes of the data are used. Move forward.
+ data += 2;
+ size -= 2;
+
+ AudioDecoderPcm16B dec(sample_rate_hz, num_channels);
+ // Allocate a maximum output size of 100 ms.
+ const size_t allocated_ouput_size_samples =
+ sample_rate_hz * num_channels / 10;
+ std::unique_ptr<int16_t[]> output =
+ std::make_unique<int16_t[]>(allocated_ouput_size_samples);
+ FuzzAudioDecoder(
+ DecoderFunctionType::kNormalDecode, data, size, &dec, sample_rate_hz,
+ allocated_ouput_size_samples * sizeof(int16_t), output.get());
+}
+} // namespace webrtc

43
script/lib/azput.js Normal file
View File

@@ -0,0 +1,43 @@
/* eslint-disable camelcase */
const { BlobServiceClient } = require('@azure/storage-blob');
const fs = require('fs');
const path = require('path');
const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.ELECTRON_ARTIFACTS_BLOB_STORAGE);
const args = require('minimist')(process.argv.slice(2));
let { prefix = '/', key_prefix = '', _: files } = args;
if (prefix && !prefix.endsWith(path.sep)) prefix = path.resolve(prefix) + path.sep;
function filenameToKey (file) {
file = path.resolve(file);
if (file.startsWith(prefix)) file = file.substr(prefix.length - 1);
return key_prefix + (path.sep === '\\' ? file.replace(/\\/g, '/') : file);
}
let anErrorOccurred = false;
function next (done) {
const file = files.shift();
if (!file) return done();
const key = filenameToKey(file);
const [containerName, ...keyPath] = key.split('/');
const blobKey = keyPath.join('/');
console.log(`Uploading '${file}' to container '${containerName}' with key '${blobKey}'...`);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blockBlobClient = containerClient.getBlockBlobClient(blobKey);
blockBlobClient.uploadFile(file)
.then((uploadBlobResponse) => {
console.log(`Upload block blob ${blobKey} successfully: https://artifacts.electronjs.org/${key}`, uploadBlobResponse.requestId);
})
.catch((err) => {
console.error(err);
anErrorOccurred = true;
})
.then(() => next(done));
}
next(() => {
process.exit(anErrorOccurred ? 1 : 0);
});

View File

@@ -53,17 +53,6 @@ def get_env_var(name):
return value
def s3_config():
config = (get_env_var('S3_BUCKET'),
get_env_var('S3_ACCESS_KEY'),
get_env_var('S3_SECRET_KEY'))
message = ('Error: Please set the $ELECTRON_S3_BUCKET, '
'$ELECTRON_S3_ACCESS_KEY, and '
'$ELECTRON_S3_SECRET_KEY environment variables')
assert all(len(c) for c in config), message
return config
def enable_verbose_mode():
print('Running in verbose mode')
global verbose_mode

View File

@@ -1,40 +0,0 @@
/* eslint-disable camelcase */
const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');
AWS.config.update({ region: 'us-west-2' });
const s3 = new AWS.S3({ apiVersion: '2006-03-01' });
const args = require('minimist')(process.argv.slice(2));
let { bucket, prefix = '/', key_prefix = '', grant, _: files } = args;
if (prefix && !prefix.endsWith(path.sep)) prefix = path.resolve(prefix) + path.sep;
function filenameToKey (file) {
file = path.resolve(file);
if (file.startsWith(prefix)) file = file.substr(prefix.length - 1);
return key_prefix + (path.sep === '\\' ? file.replace(/\\/g, '/') : file);
}
let anErrorOccurred = false;
function next (done) {
const file = files.shift();
if (!file) return done();
const key = filenameToKey(file);
console.log(`Uploading '${file}' to bucket '${bucket}' with key '${key}'...`);
s3.upload({
Bucket: bucket,
Key: key,
Body: fs.createReadStream(file),
ACL: grant
}, (err, data) => {
if (err) {
console.error(err);
anErrorOccurred = true;
}
next(done);
});
}
next(() => {
process.exit(anErrorOccurred ? 1 : 0);
});

View File

@@ -160,17 +160,17 @@ def get_electron_version():
with open(version_file) as f:
return 'v' + f.read().strip()
def s3put(bucket, access_key, secret_key, prefix, key_prefix, files):
def store_artifact(prefix, key_prefix, files):
# Azure Storage
azput(prefix, key_prefix, files)
def azput(prefix, key_prefix, files):
env = os.environ.copy()
env['AWS_ACCESS_KEY_ID'] = access_key
env['AWS_SECRET_ACCESS_KEY'] = secret_key
output = execute([
'node',
os.path.join(os.path.dirname(__file__), 's3put.js'),
'--bucket', bucket,
os.path.join(os.path.dirname(__file__), 'azput.js'),
'--prefix', prefix,
'--key_prefix', key_prefix,
'--grant', 'public-read',
] + files, env)
print(output)

View File

@@ -42,6 +42,7 @@
"parallel/test-https-agent-session-reuse",
"parallel/test-https-options-boolean-check",
"parallel/test-inspector-inspect-brk-node",
"parallel/test-icu-minimum-version",
"parallel/test-inspector-multisession-ws",
"parallel/test-inspector-port-zero-cluster",
"parallel/test-inspector-tracing-domain",

View File

@@ -62,9 +62,9 @@ async function circleCIcall (targetBranch, workflowName, options) {
parameters: {}
};
if (options.ghRelease) {
buildRequest.parameters['upload-to-s3'] = '0';
buildRequest.parameters['upload-to-storage'] = '0';
} else {
buildRequest.parameters['upload-to-s3'] = '1';
buildRequest.parameters['upload-to-storage'] = '1';
}
buildRequest.parameters[`run-${workflowName}`] = true;
if (options.arch) {
@@ -110,12 +110,12 @@ async function getCircleCIWorkflowId (pipelineId) {
switch (pipelineInfo.state) {
case 'created': {
const workflows = await circleCIRequest(`${pipelineInfoUrl}/workflow`, 'GET');
// The logic below expects two workflow.items: publish [0] & setup [1]
if (workflows.items.length === 2) {
// The logic below expects three workflow.items: publish, lint, & setup
if (workflows.items.length === 3) {
workflowId = workflows.items.find(item => item.name.includes('publish')).id;
break;
}
console.log('Unxpected number of workflows, response was:', pipelineInfo);
console.log('Unxpected number of workflows, response was:', workflows);
workflowId = -1;
break;
}
@@ -205,7 +205,7 @@ async function callAppVeyor (targetBranch, job, options) {
};
if (!options.ghRelease) {
environmentVariables.UPLOAD_TO_S3 = 1;
environmentVariables.UPLOAD_TO_STORAGE = 1;
}
const requestOpts = {

View File

@@ -1,34 +1,25 @@
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda({
credentials: {
accessKeyId: process.env.AWS_LAMBDA_EXECUTE_KEY,
secretAccessKey: process.env.AWS_LAMBDA_EXECUTE_SECRET
},
region: 'us-east-1'
});
const got = require('got');
const url = require('url');
module.exports = async function getUrlHash (targetUrl, algorithm = 'sha256', attempts = 3) {
const options = {
code: process.env.ELECTRON_ARTIFACT_HASHER_FUNCTION_KEY,
targetUrl,
algorithm
};
const search = new url.URLSearchParams(options);
const functionUrl = url.format({
protocol: 'https:',
hostname: 'electron-artifact-hasher.azurewebsites.net',
pathname: '/api/HashArtifact',
search: search.toString()
});
try {
return new Promise((resolve, reject) => {
lambda.invoke({
FunctionName: 'hasher',
Payload: JSON.stringify({
targetUrl,
algorithm
})
}, (err, data) => {
if (err) return reject(err);
try {
const response = JSON.parse(data.Payload);
if (response.statusCode !== 200) return reject(new Error('non-200 status code received from hasher function'));
if (!response.hash) return reject(new Error('Successful lambda call but failed to get valid hash'));
resolve(response.hash);
} catch (err) {
return reject(err);
}
});
});
const resp = await got(functionUrl);
if (resp.statusCode !== 200) throw new Error('non-200 status code received from hasher function');
if (!resp.body) throw new Error('Successful lambda call but failed to get valid hash');
return resp.body.trim();
} catch (err) {
if (attempts > 1) {
console.error('Failed to get URL hash for', targetUrl, 'we will retry', err);

View File

@@ -17,8 +17,8 @@ const pkgVersion = `v${pkg.version}`;
const path = require('path');
const temp = require('temp').track();
const { URL } = require('url');
const { BlobServiceClient } = require('@azure/storage-blob');
const { Octokit } = require('@octokit/rest');
const AWS = require('aws-sdk');
require('colors');
const pass = '✓'.green;
@@ -78,8 +78,8 @@ async function validateReleaseAssets (release, validatingRelease) {
console.log(`${fail} error verifyingShasums`, err);
});
}
const s3RemoteFiles = s3RemoteFilesForVersion(release.tag_name);
await verifyShasumsForRemoteFiles(s3RemoteFiles, true);
const azRemoteFiles = azRemoteFilesForVersion(release.tag_name);
await verifyShasumsForRemoteFiles(azRemoteFiles, true);
}
}
@@ -177,26 +177,27 @@ function assetsForVersion (version, validatingRelease) {
return patterns;
}
function s3RemoteFilesForVersion (version) {
const bucket = 'https://gh-contractor-zcbenz.s3.amazonaws.com/';
const versionPrefix = `${bucket}atom-shell/dist/${version}/`;
const filePaths = [
`iojs-${version}-headers.tar.gz`,
`iojs-${version}.tar.gz`,
`node-${version}.tar.gz`,
'node.lib',
'x64/node.lib',
'win-x64/iojs.lib',
'win-x86/iojs.lib',
'win-arm64/iojs.lib',
'win-x64/node.lib',
'win-x86/node.lib',
'win-arm64/node.lib',
'arm64/node.lib',
'SHASUMS.txt',
'SHASUMS256.txt'
];
return filePaths.map((filePath) => ({
const cloudStoreFilePaths = (version) => [
`iojs-${version}-headers.tar.gz`,
`iojs-${version}.tar.gz`,
`node-${version}.tar.gz`,
'node.lib',
'x64/node.lib',
'win-x64/iojs.lib',
'win-x86/iojs.lib',
'win-arm64/iojs.lib',
'win-x64/node.lib',
'win-x86/node.lib',
'win-arm64/node.lib',
'arm64/node.lib',
'SHASUMS.txt',
'SHASUMS256.txt'
];
function azRemoteFilesForVersion (version) {
const azCDN = 'https://artifacts.electronjs.org/headers/';
const versionPrefix = `${azCDN}dist/${version}/`;
return cloudStoreFilePaths(version).map((filePath) => ({
file: filePath,
url: `${versionPrefix}${filePath}`
}));
@@ -217,49 +218,39 @@ function runScript (scriptName, scriptArgs, cwd) {
}
function uploadNodeShasums () {
console.log('Uploading Node SHASUMS file to S3.');
console.log('Uploading Node SHASUMS file to artifacts.electronjs.org.');
const scriptPath = path.join(ELECTRON_DIR, 'script', 'release', 'uploaders', 'upload-node-checksums.py');
runScript(scriptPath, ['-v', pkgVersion]);
console.log(`${pass} Done uploading Node SHASUMS file to S3.`);
console.log(`${pass} Done uploading Node SHASUMS file to artifacts.electronjs.org.`);
}
function uploadIndexJson () {
console.log('Uploading index.json to S3.');
console.log('Uploading index.json to artifacts.electronjs.org.');
const scriptPath = path.join(ELECTRON_DIR, 'script', 'release', 'uploaders', 'upload-index-json.py');
runScript(scriptPath, [pkgVersion]);
console.log(`${pass} Done uploading index.json to S3.`);
console.log(`${pass} Done uploading index.json to artifacts.electronjs.org.`);
}
async function mergeShasums (pkgVersion) {
// Download individual checksum files for Electron zip files from S3,
// Download individual checksum files for Electron zip files from artifact storage,
// concatenate them, and upload to GitHub.
const bucket = process.env.ELECTRON_S3_BUCKET;
const accessKeyId = process.env.ELECTRON_S3_ACCESS_KEY;
const secretAccessKey = process.env.ELECTRON_S3_SECRET_KEY;
if (!bucket || !accessKeyId || !secretAccessKey) {
throw new Error('Please set the $ELECTRON_S3_BUCKET, $ELECTRON_S3_ACCESS_KEY, and $ELECTRON_S3_SECRET_KEY environment variables');
const connectionString = process.env.ELECTRON_ARTIFACTS_BLOB_STORAGE;
if (!connectionString) {
throw new Error('Please set the $ELECTRON_ARTIFACTS_BLOB_STORAGE environment variable');
}
const s3 = new AWS.S3({
apiVersion: '2006-03-01',
accessKeyId,
secretAccessKey,
region: 'us-west-2'
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = blobServiceClient.getContainerClient('checksums-scratchpad');
const blobsIter = containerClient.listBlobsFlat({
prefix: `${pkgVersion}/`
});
const objects = await s3.listObjectsV2({
Bucket: bucket,
Prefix: `atom-shell/tmp/${pkgVersion}/`,
Delimiter: '/'
}).promise();
const shasums = [];
for (const obj of objects.Contents) {
if (obj.Key.endsWith('.sha256sum')) {
const data = await s3.getObject({
Bucket: bucket,
Key: obj.Key
}).promise();
shasums.push(data.Body.toString('ascii').trim());
for await (const blob of blobsIter) {
if (blob.name.endsWith('.sha256sum')) {
const blobClient = containerClient.getBlockBlobClient(blob.name);
const response = await blobClient.downloadToBuffer();
shasums.push(response.toString('ascii').trim());
}
}
return shasums.join('\n');

View File

@@ -4,13 +4,17 @@ from __future__ import print_function
import json
import os
import sys
import urllib2
# Python 3 / 2 compat import
try:
from urllib.request import Request, urlopen
except ImportError:
from urllib2 import Request, urlopen
sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
from lib.config import s3_config
from lib.util import s3put, scoped_cwd, safe_mkdir, get_out_dir, ELECTRON_DIR
from lib.util import store_artifact, scoped_cwd, safe_mkdir, get_out_dir, \
ELECTRON_DIR
OUT_DIR = get_out_dir()
@@ -28,12 +32,12 @@ def is_json(myjson):
def get_content(retry_count = 5):
try:
request = urllib2.Request(
request = Request(
BASE_URL + version,
headers={"Authorization" : authToken}
)
proposed_content = urllib2.urlopen(
proposed_content = urlopen(
request
).read()
@@ -56,12 +60,10 @@ def main():
new_content = get_content()
with open(index_json, "w") as f:
with open(index_json, "wb") as f:
f.write(new_content)
bucket, access_key, secret_key = s3_config()
s3put(bucket, access_key, secret_key, OUT_DIR, 'atom-shell/dist',
[index_json])
store_artifact(OUT_DIR, 'headers/dist', [index_json])
if __name__ == '__main__':

View File

@@ -10,8 +10,7 @@ import tempfile
sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
from lib.config import s3_config
from lib.util import download, rm_rf, s3put, safe_mkdir
from lib.util import download, rm_rf, store_artifact, safe_mkdir
DIST_URL = 'https://electronjs.org/headers/'
@@ -30,9 +29,8 @@ def main():
]
if args.target_dir is None:
bucket, access_key, secret_key = s3_config()
s3put(bucket, access_key, secret_key, directory,
'atom-shell/dist/{0}'.format(args.version), checksums)
store_artifact(directory, 'headers/dist/{0}'.format(args.version),
checksums)
else:
copy_files(checksums, args.target_dir)

View File

@@ -9,8 +9,9 @@ import sys
sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
from lib.config import PLATFORM, get_target_arch, s3_config
from lib.util import safe_mkdir, scoped_cwd, s3put, get_out_dir, get_dist_dir
from lib.config import PLATFORM, get_target_arch
from lib.util import safe_mkdir, scoped_cwd, store_artifact, get_out_dir, \
get_dist_dir
DIST_DIR = get_dist_dir()
OUT_DIR = get_out_dir()
@@ -26,9 +27,8 @@ HEADER_TAR_NAMES = [
def main():
args = parse_args()
# Upload node's headers to S3.
bucket, access_key, secret_key = s3_config()
upload_node(bucket, access_key, secret_key, args.version)
# Upload node's headers to artifact storage.
upload_node(args.version)
def parse_args():
@@ -38,17 +38,17 @@ def parse_args():
return parser.parse_args()
def upload_node(bucket, access_key, secret_key, version):
def upload_node(version):
with scoped_cwd(GEN_DIR):
generated_tar = os.path.join(GEN_DIR, 'node_headers.tar.gz')
for header_tar in HEADER_TAR_NAMES:
versioned_header_tar = header_tar.format(version)
shutil.copy2(generated_tar, os.path.join(GEN_DIR, versioned_header_tar))
s3put(bucket, access_key, secret_key, GEN_DIR,
'atom-shell/dist/{0}'.format(version), glob.glob('node-*.tar.gz'))
s3put(bucket, access_key, secret_key, GEN_DIR,
'atom-shell/dist/{0}'.format(version), glob.glob('iojs-*.tar.gz'))
store_artifact(GEN_DIR, 'headers/dist/{0}'.format(version),
glob.glob('node-*.tar.gz'))
store_artifact(GEN_DIR, 'headers/dist/{0}'.format(version),
glob.glob('iojs-*.tar.gz'))
if PLATFORM == 'win32':
if get_target_arch() == 'ia32':
@@ -73,16 +73,14 @@ def upload_node(bucket, access_key, secret_key, version):
shutil.copy2(electron_lib, v4_node_lib)
# Upload the node.lib.
s3put(bucket, access_key, secret_key, DIST_DIR,
'atom-shell/dist/{0}'.format(version), [node_lib])
store_artifact(DIST_DIR, 'headers/dist/{0}'.format(version), [node_lib])
# Upload the iojs.lib.
s3put(bucket, access_key, secret_key, DIST_DIR,
'atom-shell/dist/{0}'.format(version), [iojs_lib])
store_artifact(DIST_DIR, 'headers/dist/{0}'.format(version), [iojs_lib])
# Upload the v4 node.lib.
s3put(bucket, access_key, secret_key, DIST_DIR,
'atom-shell/dist/{0}'.format(version), [v4_node_lib])
store_artifact(DIST_DIR, 'headers/dist/{0}'.format(version),
[v4_node_lib])
if __name__ == '__main__':

View File

@@ -14,8 +14,8 @@ def is_fs_case_sensitive():
sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
from lib.config import PLATFORM, s3_config
from lib.util import get_electron_branding, execute, s3put, \
from lib.config import PLATFORM
from lib.util import get_electron_branding, execute, store_artifact, \
get_out_dir, ELECTRON_DIR
RELEASE_DIR = get_out_dir()
@@ -56,7 +56,7 @@ def main():
files += glob.glob(SYMBOLS_DIR + '/*/*/*.src.zip')
# The file upload needs to be atom-shell/symbols/:symbol_name/:hash/:symbol
# The file upload needs to be symbols/:symbol_name/:hash/:symbol
os.chdir(SYMBOLS_DIR)
files = [os.path.relpath(f, os.getcwd()) for f in files]
@@ -76,16 +76,15 @@ def main():
for f in files:
assert os.path.exists(f)
bucket, access_key, secret_key = s3_config()
upload_symbols(bucket, access_key, secret_key, files)
upload_symbols(files)
def run_symstore(pdb, dest, product):
execute(['symstore', 'add', '/r', '/f', pdb, '/s', dest, '/t', product])
def upload_symbols(bucket, access_key, secret_key, files):
s3put(bucket, access_key, secret_key, SYMBOLS_DIR, 'atom-shell/symbols',
def upload_symbols(files):
store_artifact(SYMBOLS_DIR, 'symbols',
files)

View File

@@ -16,10 +16,10 @@ sys.path.append(
os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
from zipfile import ZipFile
from lib.config import PLATFORM, get_target_arch, get_env_var, s3_config, \
from lib.config import PLATFORM, get_target_arch, \
get_zip_name, enable_verbose_mode, get_platform_key
from lib.util import get_electron_branding, execute, get_electron_version, \
s3put, get_electron_exec, get_out_dir, \
store_artifact, get_electron_exec, get_out_dir, \
SRC_DIR, ELECTRON_DIR, TS_NODE
@@ -45,7 +45,7 @@ def main():
args = parse_args()
if args.verbose:
enable_verbose_mode()
if args.upload_to_s3:
if args.upload_to_storage:
utcnow = datetime.datetime.utcnow()
args.upload_timestamp = utcnow.strftime('%Y%m%d')
@@ -62,7 +62,7 @@ def main():
if not release['draft']:
tag_exists = True
if not args.upload_to_s3:
if not args.upload_to_storage:
assert release['exists'], \
'Release does not exist; cannot upload to GitHub!'
assert tag_exists == args.overwrite, \
@@ -140,7 +140,7 @@ def main():
OUT_DIR, 'hunspell_dictionaries.zip')
upload_electron(release, hunspell_dictionaries_zip, args)
if not tag_exists and not args.upload_to_s3:
if not tag_exists and not args.upload_to_storage:
# Upload symbols to symbol server.
run_python_upload_script('upload-symbols.py')
if PLATFORM == 'win32':
@@ -165,9 +165,9 @@ def parse_args():
parser.add_argument('-p', '--publish-release',
help='Publish the release',
action='store_true')
parser.add_argument('-s', '--upload_to_s3',
help='Upload assets to s3 bucket',
dest='upload_to_s3',
parser.add_argument('-s', '--upload_to_storage',
help='Upload assets to azure bucket',
dest='upload_to_storage',
action='store_true',
default=False,
required=False)
@@ -332,16 +332,13 @@ def upload_electron(release, file_path, args):
except NonZipFileError:
pass
# if upload_to_s3 is set, skip github upload.
if args.upload_to_s3:
bucket, access_key, secret_key = s3_config()
key_prefix = 'electron-artifacts/{0}_{1}'.format(args.version,
# if upload_to_storage is set, skip github upload.
# todo (vertedinde): migrate this variable to upload_to_storage
if args.upload_to_storage:
key_prefix = 'release-builds/{0}_{1}'.format(args.version,
args.upload_timestamp)
s3put(bucket, access_key, secret_key, os.path.dirname(file_path),
key_prefix, [file_path])
store_artifact(os.path.dirname(file_path), key_prefix, [file_path])
upload_sha256_checksum(args.version, file_path, key_prefix)
s3url = 'https://gh-contractor-zcbenz.s3.amazonaws.com'
print('{0} uploaded to {1}/{2}/{0}'.format(filename, s3url, key_prefix))
return
# Upload the file.
@@ -361,10 +358,9 @@ def upload_io_to_github(release, filename, filepath, version):
def upload_sha256_checksum(version, file_path, key_prefix=None):
bucket, access_key, secret_key = s3_config()
checksum_path = '{}.sha256sum'.format(file_path)
if key_prefix is None:
key_prefix = 'atom-shell/tmp/{0}'.format(version)
key_prefix = 'checksums-scratchpad/{0}'.format(version)
sha256 = hashlib.sha256()
with open(file_path, 'rb') as f:
sha256.update(f.read())
@@ -372,8 +368,7 @@ def upload_sha256_checksum(version, file_path, key_prefix=None):
filename = os.path.basename(file_path)
with open(checksum_path, 'w') as checksum:
checksum.write('{} *{}'.format(sha256.hexdigest(), filename))
s3put(bucket, access_key, secret_key, os.path.dirname(checksum_path),
key_prefix, [checksum_path])
store_artifact(os.path.dirname(checksum_path), key_prefix, [checksum_path])
def get_release(version):

View File

@@ -41,8 +41,8 @@ const runners = new Map([
const specHashPath = path.resolve(__dirname, '../spec/.hash');
let runnersToRun = null;
if (args.runners) {
runnersToRun = args.runners.split(',');
if (args.runners !== undefined) {
runnersToRun = args.runners.split(',').filter(value => value);
if (!runnersToRun.every(r => [...runners.keys()].includes(r))) {
console.log(`${fail} ${runnersToRun} must be a subset of [${[...runners.keys()].join(' | ')}]`);
process.exit(1);

View File

@@ -31,12 +31,24 @@ void SetElectronCryptoReady(bool ready) {
#endif
bool IsEncryptionAvailable() {
#if defined(OS_LINUX)
// Calling IsEncryptionAvailable() before the app is ready results in a crash
// on Linux.
// Refs: https://github.com/electron/electron/issues/32206.
if (!Browser::Get()->is_ready())
return false;
#endif
return OSCrypt::IsEncryptionAvailable();
}
v8::Local<v8::Value> EncryptString(v8::Isolate* isolate,
const std::string& plaintext) {
if (!OSCrypt::IsEncryptionAvailable()) {
if (!IsEncryptionAvailable()) {
if (!Browser::Get()->is_ready()) {
gin_helper::ErrorThrower(isolate).ThrowError(
"safeStorage cannot be used before app is ready");
return v8::Local<v8::Value>();
}
gin_helper::ErrorThrower(isolate).ThrowError(
"Error while decrypting the ciphertext provided to "
"safeStorage.decryptString. "
@@ -59,7 +71,12 @@ v8::Local<v8::Value> EncryptString(v8::Isolate* isolate,
}
std::string DecryptString(v8::Isolate* isolate, v8::Local<v8::Value> buffer) {
if (!OSCrypt::IsEncryptionAvailable()) {
if (!IsEncryptionAvailable()) {
if (!Browser::Get()->is_ready()) {
gin_helper::ErrorThrower(isolate).ThrowError(
"safeStorage cannot be used before app is ready");
return "";
}
gin_helper::ErrorThrower(isolate).ThrowError(
"Error while decrypting the ciphertext provided to "
"safeStorage.decryptString. "

View File

@@ -166,7 +166,7 @@
#if BUILDFLAG(ENABLE_PRINTING)
#include "components/printing/browser/print_manager_utils.h"
#include "printing/backend/print_backend.h" // nogncheck
#include "printing/mojom/print.mojom.h"
#include "printing/mojom/print.mojom.h" // nogncheck
#include "shell/browser/printing/print_preview_message_handler.h"
#include "shell/browser/printing/print_view_manager_electron.h"
@@ -1661,7 +1661,7 @@ void WebContents::Message(bool internal,
// webContents.emit('-ipc-message', new Event(), internal, channel,
// arguments);
EmitWithSender("-ipc-message", render_frame_host,
electron::mojom::ElectronBrowser::InvokeCallback(), internal,
electron::mojom::ElectronApiIPC::InvokeCallback(), internal,
channel, std::move(arguments));
}
@@ -1669,7 +1669,7 @@ void WebContents::Invoke(
bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::InvokeCallback callback,
electron::mojom::ElectronApiIPC::InvokeCallback callback,
content::RenderFrameHost* render_frame_host) {
TRACE_EVENT1("electron", "WebContents::Invoke", "channel", channel);
// webContents.emit('-ipc-invoke', new Event(), internal, channel, arguments);
@@ -1695,7 +1695,7 @@ void WebContents::ReceivePostMessage(
v8::Local<v8::Value> message_value =
electron::DeserializeV8Value(isolate, message);
EmitWithSender("-ipc-ports", render_frame_host,
electron::mojom::ElectronBrowser::InvokeCallback(), false,
electron::mojom::ElectronApiIPC::InvokeCallback(), false,
channel, message_value, std::move(wrapped_ports));
}
@@ -1703,7 +1703,7 @@ void WebContents::MessageSync(
bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::MessageSyncCallback callback,
electron::mojom::ElectronApiIPC::MessageSyncCallback callback,
content::RenderFrameHost* render_frame_host) {
TRACE_EVENT1("electron", "WebContents::MessageSync", "channel", channel);
// webContents.emit('-ipc-message-sync', new Event(sender, message), internal,
@@ -1741,7 +1741,7 @@ void WebContents::MessageHost(const std::string& channel,
TRACE_EVENT1("electron", "WebContents::MessageHost", "channel", channel);
// webContents.emit('ipc-message-host', new Event(), channel, args);
EmitWithSender("ipc-message-host", render_frame_host,
electron::mojom::ElectronBrowser::InvokeCallback(), channel,
electron::mojom::ElectronApiIPC::InvokeCallback(), channel,
std::move(arguments));
}
@@ -3154,7 +3154,8 @@ void WebContents::SetTemporaryZoomLevel(double level) {
}
void WebContents::DoGetZoomLevel(
electron::mojom::ElectronBrowser::DoGetZoomLevelCallback callback) {
electron::mojom::ElectronWebContentsUtility::DoGetZoomLevelCallback
callback) {
std::move(callback).Run(GetZoomLevel());
}

View File

@@ -352,7 +352,7 @@ class WebContents : public gin::Wrappable<WebContents>,
template <typename... Args>
bool EmitWithSender(base::StringPiece name,
content::RenderFrameHost* sender,
electron::mojom::ElectronBrowser::InvokeCallback callback,
electron::mojom::ElectronApiIPC::InvokeCallback callback,
Args&&... args) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
@@ -396,7 +396,7 @@ class WebContents : public gin::Wrappable<WebContents>,
fullscreen_frame_ = rfh;
}
// mojom::ElectronBrowser
// mojom::ElectronApiIPC
void Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
@@ -404,9 +404,8 @@ class WebContents : public gin::Wrappable<WebContents>,
void Invoke(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::InvokeCallback callback,
electron::mojom::ElectronApiIPC::InvokeCallback callback,
content::RenderFrameHost* render_frame_host);
void OnFirstNonEmptyLayout(content::RenderFrameHost* render_frame_host);
void ReceivePostMessage(const std::string& channel,
blink::TransferableMessage message,
content::RenderFrameHost* render_frame_host);
@@ -414,7 +413,7 @@ class WebContents : public gin::Wrappable<WebContents>,
bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::MessageSyncCallback callback,
electron::mojom::ElectronApiIPC::MessageSyncCallback callback,
content::RenderFrameHost* render_frame_host);
void MessageTo(int32_t web_contents_id,
const std::string& channel,
@@ -422,10 +421,15 @@ class WebContents : public gin::Wrappable<WebContents>,
void MessageHost(const std::string& channel,
blink::CloneableMessage arguments,
content::RenderFrameHost* render_frame_host);
// mojom::ElectronWebContentsUtility
void OnFirstNonEmptyLayout(content::RenderFrameHost* render_frame_host);
void UpdateDraggableRegions(std::vector<mojom::DraggableRegionPtr> regions);
void SetTemporaryZoomLevel(double level);
void DoGetZoomLevel(
electron::mojom::ElectronBrowser::DoGetZoomLevelCallback callback);
electron::mojom::ElectronWebContentsUtility::DoGetZoomLevelCallback
callback);
void SetImageAnimationPolicy(const std::string& new_policy);
// Grants |origin| access to |device|.

View File

@@ -13,7 +13,7 @@ namespace gin_helper {
class Event : public gin::Wrappable<Event> {
public:
using InvokeCallback = electron::mojom::ElectronBrowser::InvokeCallback;
using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;
static gin::WrapperInfo kWrapperInfo;

View File

@@ -0,0 +1,108 @@
// Copyright (c) 2022 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/electron_api_ipc_handler_impl.h"
#include <utility>
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
namespace electron {
ElectronApiIPCHandlerImpl::ElectronApiIPCHandlerImpl(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver)
: render_process_id_(frame_host->GetProcess()->GetID()),
render_frame_id_(frame_host->GetRoutingID()) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(frame_host);
DCHECK(web_contents);
content::WebContentsObserver::Observe(web_contents);
receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(base::BindOnce(
&ElectronApiIPCHandlerImpl::OnConnectionError, GetWeakPtr()));
}
ElectronApiIPCHandlerImpl::~ElectronApiIPCHandlerImpl() = default;
void ElectronApiIPCHandlerImpl::WebContentsDestroyed() {
delete this;
}
void ElectronApiIPCHandlerImpl::OnConnectionError() {
delete this;
}
void ElectronApiIPCHandlerImpl::Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->Message(internal, channel, std::move(arguments),
GetRenderFrameHost());
}
}
void ElectronApiIPCHandlerImpl::Invoke(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
InvokeCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->Invoke(internal, channel, std::move(arguments),
std::move(callback), GetRenderFrameHost());
}
}
void ElectronApiIPCHandlerImpl::ReceivePostMessage(
const std::string& channel,
blink::TransferableMessage message) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->ReceivePostMessage(channel, std::move(message),
GetRenderFrameHost());
}
}
void ElectronApiIPCHandlerImpl::MessageSync(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
MessageSyncCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageSync(internal, channel, std::move(arguments),
std::move(callback), GetRenderFrameHost());
}
}
void ElectronApiIPCHandlerImpl::MessageTo(int32_t web_contents_id,
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageTo(web_contents_id, channel, std::move(arguments));
}
}
void ElectronApiIPCHandlerImpl::MessageHost(const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageHost(channel, std::move(arguments),
GetRenderFrameHost());
}
}
content::RenderFrameHost* ElectronApiIPCHandlerImpl::GetRenderFrameHost() {
return content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
}
// static
void ElectronApiIPCHandlerImpl::Create(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver) {
new ElectronApiIPCHandlerImpl(frame_host, std::move(receiver));
}
} // namespace electron

View File

@@ -1,9 +1,9 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Copyright (c) 2022 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_ELECTRON_BROWSER_HANDLER_IMPL_H_
#define SHELL_BROWSER_ELECTRON_BROWSER_HANDLER_IMPL_H_
#ifndef SHELL_BROWSER_ELECTRON_API_IPC_HANDLER_IMPL_H_
#define SHELL_BROWSER_ELECTRON_API_IPC_HANDLER_IMPL_H_
#include <string>
#include <vector>
@@ -12,6 +12,7 @@
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
#include "electron/shell/common/api/api.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "shell/browser/api/electron_api_web_contents.h"
namespace content {
@@ -19,17 +20,18 @@ class RenderFrameHost;
}
namespace electron {
class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
public content::WebContentsObserver {
class ElectronApiIPCHandlerImpl : public mojom::ElectronApiIPC,
public content::WebContentsObserver {
public:
explicit ElectronBrowserHandlerImpl(
explicit ElectronApiIPCHandlerImpl(
content::RenderFrameHost* render_frame_host,
mojo::PendingReceiver<mojom::ElectronBrowser> receiver);
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver);
static void Create(content::RenderFrameHost* frame_host,
mojo::PendingReceiver<mojom::ElectronBrowser> receiver);
static void Create(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver);
// mojom::ElectronBrowser:
// mojom::ElectronApiIPC:
void Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments) override;
@@ -37,7 +39,6 @@ class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
const std::string& channel,
blink::CloneableMessage arguments,
InvokeCallback callback) override;
void OnFirstNonEmptyLayout() override;
void ReceivePostMessage(const std::string& channel,
blink::TransferableMessage message) override;
void MessageSync(bool internal,
@@ -49,17 +50,13 @@ class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
blink::CloneableMessage arguments) override;
void MessageHost(const std::string& channel,
blink::CloneableMessage arguments) override;
void UpdateDraggableRegions(
std::vector<mojom::DraggableRegionPtr> regions) override;
void SetTemporaryZoomLevel(double level) override;
void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;
base::WeakPtr<ElectronBrowserHandlerImpl> GetWeakPtr() {
base::WeakPtr<ElectronApiIPCHandlerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
private:
~ElectronBrowserHandlerImpl() override;
~ElectronApiIPCHandlerImpl() override;
// content::WebContentsObserver:
void WebContentsDestroyed() override;
@@ -71,11 +68,11 @@ class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
const int render_process_id_;
const int render_frame_id_;
mojo::Receiver<mojom::ElectronBrowser> receiver_{this};
mojo::AssociatedReceiver<mojom::ElectronApiIPC> receiver_{this};
base::WeakPtrFactory<ElectronBrowserHandlerImpl> weak_factory_{this};
base::WeakPtrFactory<ElectronApiIPCHandlerImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ElectronBrowserHandlerImpl);
DISALLOW_COPY_AND_ASSIGN(ElectronApiIPCHandlerImpl);
};
} // namespace electron
#endif // SHELL_BROWSER_ELECTRON_BROWSER_HANDLER_IMPL_H_
#endif // SHELL_BROWSER_ELECTRON_API_IPC_HANDLER_IMPL_H_

View File

@@ -71,13 +71,14 @@
#include "shell/browser/api/electron_api_web_request.h"
#include "shell/browser/badging/badge_manager.h"
#include "shell/browser/child_web_contents_tracker.h"
#include "shell/browser/electron_api_ipc_handler_impl.h"
#include "shell/browser/electron_autofill_driver_factory.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/browser/electron_browser_handler_impl.h"
#include "shell/browser/electron_browser_main_parts.h"
#include "shell/browser/electron_navigation_throttle.h"
#include "shell/browser/electron_quota_permission_context.h"
#include "shell/browser/electron_speech_recognition_manager_delegate.h"
#include "shell/browser/electron_web_contents_utility_handler_impl.h"
#include "shell/browser/font_defaults.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/media/media_capture_devices_dispatcher.h"
@@ -1444,6 +1445,31 @@ bool ElectronBrowserClient::PreSpawnChild(
}
#endif // defined(OS_WIN)
bool BindElectronApiIPC(
mojo::PendingAssociatedReceiver<electron::mojom::ElectronApiIPC> receiver,
content::RenderFrameHost* frame_host) {
auto* contents = content::WebContents::FromRenderFrameHost(frame_host);
if (contents) {
auto* prefs = WebContentsPreferences::From(contents);
if (frame_host->GetFrameTreeNodeId() ==
contents->GetMainFrame()->GetFrameTreeNodeId() ||
(prefs && prefs->IsEnabled(options::kNodeIntegrationInSubFrames))) {
ElectronApiIPCHandlerImpl::Create(frame_host, std::move(receiver));
return true;
}
}
return false;
}
void BindElectronWebContentsUtility(
mojo::PendingAssociatedReceiver<electron::mojom::ElectronWebContentsUtility>
receiver,
content::RenderFrameHost* frame_host) {
ElectronWebContentsUtilityHandlerImpl::Create(frame_host,
std::move(receiver));
}
bool ElectronBrowserClient::BindAssociatedReceiverFromFrame(
content::RenderFrameHost* render_frame_host,
const std::string& interface_name,
@@ -1454,6 +1480,21 @@ bool ElectronBrowserClient::BindAssociatedReceiverFromFrame(
render_frame_host);
return true;
}
if (interface_name == electron::mojom::ElectronApiIPC::Name_) {
return BindElectronApiIPC(
mojo::PendingAssociatedReceiver<electron::mojom::ElectronApiIPC>(
std::move(*handle)),
render_frame_host);
}
if (interface_name == electron::mojom::ElectronWebContentsUtility::Name_) {
BindElectronWebContentsUtility(
mojo::PendingAssociatedReceiver<
electron::mojom::ElectronWebContentsUtility>(std::move(*handle)),
render_frame_host);
return true;
}
#if BUILDFLAG(ENABLE_PRINTING)
if (interface_name == printing::mojom::PrintManagerHost::Name_) {
mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost> receiver(
@@ -1506,12 +1547,6 @@ void ElectronBrowserClient::BindHostReceiverForRenderer(
#endif
}
void BindElectronBrowser(
content::RenderFrameHost* frame_host,
mojo::PendingReceiver<electron::mojom::ElectronBrowser> receiver) {
ElectronBrowserHandlerImpl::Create(frame_host, std::move(receiver));
}
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
void BindMimeHandlerService(
content::RenderFrameHost* frame_host,
@@ -1550,8 +1585,6 @@ void ElectronBrowserClient::RegisterBrowserInterfaceBindersForFrame(
base::BindRepeating(&BindNetworkHintsHandler));
map->Add<blink::mojom::BadgeService>(
base::BindRepeating(&badging::BadgeManager::BindFrameReceiver));
map->Add<electron::mojom::ElectronBrowser>(
base::BindRepeating(&BindElectronBrowser));
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
map->Add<extensions::mime_handler::MimeHandlerService>(
base::BindRepeating(&BindMimeHandlerService));

View File

@@ -1,141 +0,0 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/electron_browser_handler_impl.h"
#include <utility>
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
namespace electron {
ElectronBrowserHandlerImpl::ElectronBrowserHandlerImpl(
content::RenderFrameHost* frame_host,
mojo::PendingReceiver<mojom::ElectronBrowser> receiver)
: render_process_id_(frame_host->GetProcess()->GetID()),
render_frame_id_(frame_host->GetRoutingID()) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(frame_host);
DCHECK(web_contents);
content::WebContentsObserver::Observe(web_contents);
receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(base::BindOnce(
&ElectronBrowserHandlerImpl::OnConnectionError, GetWeakPtr()));
}
ElectronBrowserHandlerImpl::~ElectronBrowserHandlerImpl() = default;
void ElectronBrowserHandlerImpl::WebContentsDestroyed() {
delete this;
}
void ElectronBrowserHandlerImpl::OnConnectionError() {
delete this;
}
void ElectronBrowserHandlerImpl::Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->Message(internal, channel, std::move(arguments),
GetRenderFrameHost());
}
}
void ElectronBrowserHandlerImpl::Invoke(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
InvokeCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->Invoke(internal, channel, std::move(arguments),
std::move(callback), GetRenderFrameHost());
}
}
void ElectronBrowserHandlerImpl::OnFirstNonEmptyLayout() {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->OnFirstNonEmptyLayout(GetRenderFrameHost());
}
}
void ElectronBrowserHandlerImpl::ReceivePostMessage(
const std::string& channel,
blink::TransferableMessage message) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->ReceivePostMessage(channel, std::move(message),
GetRenderFrameHost());
}
}
void ElectronBrowserHandlerImpl::MessageSync(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
MessageSyncCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageSync(internal, channel, std::move(arguments),
std::move(callback), GetRenderFrameHost());
}
}
void ElectronBrowserHandlerImpl::MessageTo(int32_t web_contents_id,
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageTo(web_contents_id, channel, std::move(arguments));
}
}
void ElectronBrowserHandlerImpl::MessageHost(
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageHost(channel, std::move(arguments),
GetRenderFrameHost());
}
}
void ElectronBrowserHandlerImpl::UpdateDraggableRegions(
std::vector<mojom::DraggableRegionPtr> regions) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->UpdateDraggableRegions(std::move(regions));
}
}
void ElectronBrowserHandlerImpl::SetTemporaryZoomLevel(double level) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->SetTemporaryZoomLevel(level);
}
}
void ElectronBrowserHandlerImpl::DoGetZoomLevel(
DoGetZoomLevelCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->DoGetZoomLevel(std::move(callback));
}
}
content::RenderFrameHost* ElectronBrowserHandlerImpl::GetRenderFrameHost() {
return content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
}
// static
void ElectronBrowserHandlerImpl::Create(
content::RenderFrameHost* frame_host,
mojo::PendingReceiver<mojom::ElectronBrowser> receiver) {
new ElectronBrowserHandlerImpl(frame_host, std::move(receiver));
}
} // namespace electron

View File

@@ -17,6 +17,9 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "components/os_crypt/key_storage_config_linux.h"
#include "components/os_crypt/os_crypt.h"
#include "content/browser/browser_main_loop.h" // nogncheck
#include "content/public/browser/browser_thread.h"
@@ -483,6 +486,26 @@ void ElectronBrowserMainParts::PostCreateMainMessageLoop() {
#endif
#if defined(OS_LINUX)
bluez::DBusBluezManagerWrapperLinux::Initialize();
// Set up crypt config. This needs to be done before anything starts the
// network service, as the raw encryption key needs to be shared with the
// network service for encrypted cookie storage.
std::string app_name = electron::Browser::Get()->GetName();
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
std::unique_ptr<os_crypt::Config> config =
std::make_unique<os_crypt::Config>();
// Forward to os_crypt the flag to use a specific password store.
config->store = command_line.GetSwitchValueASCII(::switches::kPasswordStore);
config->product_name = app_name;
config->application_name = app_name;
config->main_thread_runner = base::ThreadTaskRunnerHandle::Get();
// c.f.
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/common/chrome_switches.cc;l=689;drc=9d82515060b9b75fa941986f5db7390299669ef1
config->should_use_preference =
command_line.HasSwitch(::switches::kEnableEncryptionSelection);
base::PathService::Get(chrome::DIR_USER_DATA, &config->user_data_path);
OSCrypt::SetConfig(std::move(config));
#endif
#if defined(OS_POSIX)
// Exit in response to SIGINT, SIGTERM, etc.

View File

@@ -333,22 +333,32 @@ bool ElectronPermissionManager::CheckDevicePermission(
static_cast<content::PermissionType>(
WebContentsPermissionHelper::PermissionType::SERIAL)) {
#if defined(OS_WIN)
if (device->FindStringKey(kDeviceInstanceIdKey) ==
granted_device.FindStringKey(kDeviceInstanceIdKey))
const auto* instance_id = device->FindStringKey(kDeviceInstanceIdKey);
const auto* port_instance_id =
granted_device.FindStringKey(kDeviceInstanceIdKey);
if (instance_id && port_instance_id &&
*instance_id == *port_instance_id)
return true;
#else
const auto* serial_number =
granted_device.FindStringKey(kSerialNumberKey);
const auto* port_serial_number =
device->FindStringKey(kSerialNumberKey);
if (device->FindIntKey(kVendorIdKey) !=
granted_device.FindIntKey(kVendorIdKey) ||
device->FindIntKey(kProductIdKey) !=
granted_device.FindIntKey(kProductIdKey) ||
*device->FindStringKey(kSerialNumberKey) !=
*granted_device.FindStringKey(kSerialNumberKey)) {
(serial_number && port_serial_number &&
*port_serial_number != *serial_number)) {
continue;
}
#if defined(OS_MAC)
if (*device->FindStringKey(kUsbDriverKey) !=
*granted_device.FindStringKey(kUsbDriverKey)) {
const auto* usb_driver_key = device->FindStringKey(kUsbDriverKey);
const auto* port_usb_driver_key =
granted_device.FindStringKey(kUsbDriverKey);
if (usb_driver_key && port_usb_driver_key &&
*usb_driver_key != *port_usb_driver_key) {
continue;
}
#endif // defined(OS_MAC)

View File

@@ -0,0 +1,83 @@
// Copyright (c) 2022 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/electron_web_contents_utility_handler_impl.h"
#include <utility>
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
namespace electron {
ElectronWebContentsUtilityHandlerImpl::ElectronWebContentsUtilityHandlerImpl(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronWebContentsUtility> receiver)
: render_process_id_(frame_host->GetProcess()->GetID()),
render_frame_id_(frame_host->GetRoutingID()) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(frame_host);
DCHECK(web_contents);
content::WebContentsObserver::Observe(web_contents);
receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(base::BindOnce(
&ElectronWebContentsUtilityHandlerImpl::OnConnectionError, GetWeakPtr()));
}
ElectronWebContentsUtilityHandlerImpl::
~ElectronWebContentsUtilityHandlerImpl() = default;
void ElectronWebContentsUtilityHandlerImpl::WebContentsDestroyed() {
delete this;
}
void ElectronWebContentsUtilityHandlerImpl::OnConnectionError() {
delete this;
}
void ElectronWebContentsUtilityHandlerImpl::OnFirstNonEmptyLayout() {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->OnFirstNonEmptyLayout(GetRenderFrameHost());
}
}
void ElectronWebContentsUtilityHandlerImpl::UpdateDraggableRegions(
std::vector<mojom::DraggableRegionPtr> regions) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->UpdateDraggableRegions(std::move(regions));
}
}
void ElectronWebContentsUtilityHandlerImpl::SetTemporaryZoomLevel(
double level) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->SetTemporaryZoomLevel(level);
}
}
void ElectronWebContentsUtilityHandlerImpl::DoGetZoomLevel(
DoGetZoomLevelCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->DoGetZoomLevel(std::move(callback));
}
}
content::RenderFrameHost*
ElectronWebContentsUtilityHandlerImpl::GetRenderFrameHost() {
return content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
}
// static
void ElectronWebContentsUtilityHandlerImpl::Create(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronWebContentsUtility>
receiver) {
new ElectronWebContentsUtilityHandlerImpl(frame_host, std::move(receiver));
}
} // namespace electron

View File

@@ -0,0 +1,68 @@
// Copyright (c) 2022 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_ELECTRON_WEB_CONTENTS_UTILITY_HANDLER_IMPL_H_
#define SHELL_BROWSER_ELECTRON_WEB_CONTENTS_UTILITY_HANDLER_IMPL_H_
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
#include "electron/shell/common/api/api.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "shell/browser/api/electron_api_web_contents.h"
namespace content {
class RenderFrameHost;
}
namespace electron {
class ElectronWebContentsUtilityHandlerImpl
: public mojom::ElectronWebContentsUtility,
public content::WebContentsObserver {
public:
explicit ElectronWebContentsUtilityHandlerImpl(
content::RenderFrameHost* render_frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronWebContentsUtility>
receiver);
static void Create(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronWebContentsUtility>
receiver);
// mojom::ElectronWebContentsUtility:
void OnFirstNonEmptyLayout() override;
void UpdateDraggableRegions(
std::vector<mojom::DraggableRegionPtr> regions) override;
void SetTemporaryZoomLevel(double level) override;
void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;
base::WeakPtr<ElectronWebContentsUtilityHandlerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
private:
~ElectronWebContentsUtilityHandlerImpl() override;
// content::WebContentsObserver:
void WebContentsDestroyed() override;
void OnConnectionError();
content::RenderFrameHost* GetRenderFrameHost();
const int render_process_id_;
const int render_frame_id_;
mojo::AssociatedReceiver<mojom::ElectronWebContentsUtility> receiver_{this};
base::WeakPtrFactory<ElectronWebContentsUtilityHandlerImpl> weak_factory_{
this};
DISALLOW_COPY_AND_ASSIGN(ElectronWebContentsUtilityHandlerImpl);
};
} // namespace electron
#endif // SHELL_BROWSER_ELECTRON_WEB_CONTENTS_UTILITY_HANDLER_IMPL_H_

View File

@@ -602,13 +602,23 @@ void NativeWindowMac::SetEnabled(bool enable) {
}
void NativeWindowMac::Maximize() {
if (IsMaximized())
const bool is_visible = [window_ isVisible];
if (IsMaximized()) {
if (!is_visible)
ShowInactive();
return;
}
// Take note of the current window size
if (IsNormal())
original_frame_ = [window_ frame];
[window_ zoom:nil];
if (!is_visible) {
ShowInactive();
NotifyWindowMaximize();
}
}
void NativeWindowMac::Unmaximize() {

View File

@@ -321,14 +321,15 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
// Set Window style so that we get a minimize and maximize animation when
// frameless.
DWORD frame_style = WS_CAPTION | WS_OVERLAPPED;
if (resizable_ && thick_frame_)
if (resizable_)
frame_style |= WS_THICKFRAME;
if (minimizable_)
frame_style |= WS_MINIMIZEBOX;
if (maximizable_)
frame_style |= WS_MAXIMIZEBOX;
if (!thick_frame_ || !has_frame())
frame_style &= ~WS_CAPTION;
// We should not show a frame for transparent window.
if (!thick_frame_)
frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
}

View File

@@ -293,46 +293,14 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(
KeychainPassword::GetServiceName() = app_name + " Safe Storage";
KeychainPassword::GetAccountName() = app_name;
#endif
#if defined(OS_LINUX)
// c.f.
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/net/system_network_context_manager.cc;l=515;drc=9d82515060b9b75fa941986f5db7390299669ef1;bpv=1;bpt=1
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
auto config = std::make_unique<os_crypt::Config>();
config->store = command_line.GetSwitchValueASCII(::switches::kPasswordStore);
config->product_name = app_name;
config->application_name = app_name;
config->main_thread_runner = base::ThreadTaskRunnerHandle::Get();
// c.f.
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/common/chrome_switches.cc;l=689;drc=9d82515060b9b75fa941986f5db7390299669ef1
config->should_use_preference =
command_line.HasSwitch(::switches::kEnableEncryptionSelection);
base::PathService::Get(chrome::DIR_USER_DATA, &config->user_data_path);
#endif
#if defined(OS_WIN) || defined(OS_MAC)
// The OSCrypt keys are process bound, so if network service is out of
// process, send it the required key.
if (content::IsOutOfProcessNetworkService() &&
electron::fuses::IsCookieEncryptionEnabled()) {
#if defined(OS_LINUX)
network::mojom::CryptConfigPtr network_crypt_config =
network::mojom::CryptConfig::New();
network_crypt_config->application_name = config->application_name;
network_crypt_config->product_name = config->product_name;
network_crypt_config->store = config->store;
network_crypt_config->should_use_preference = config->should_use_preference;
network_crypt_config->user_data_path = config->user_data_path;
network_service->SetCryptConfig(std::move(network_crypt_config));
#else
network_service->SetEncryptionKey(OSCrypt::GetRawEncryptionKey());
#endif
}
#if defined(OS_LINUX)
OSCrypt::SetConfig(std::move(config));
#endif
#if DCHECK_IS_ON()

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 15,5,1,0
PRODUCTVERSION 15,5,1,0
FILEVERSION 15,5,7,0
PRODUCTVERSION 15,5,7,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "15.5.1"
VALUE "FileVersion", "15.5.7"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "15.5.1"
VALUE "ProductVersion", "15.5.7"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -31,7 +31,21 @@ struct DraggableRegion {
gfx.mojom.Rect bounds;
};
interface ElectronBrowser {
interface ElectronWebContentsUtility {
// Informs underlying WebContents that first non-empty layout was performed
// by compositor.
OnFirstNonEmptyLayout();
UpdateDraggableRegions(
array<DraggableRegion> regions);
SetTemporaryZoomLevel(double zoom_level);
[Sync]
DoGetZoomLevel() => (double result);
};
interface ElectronApiIPC {
// Emits an event on |channel| from the ipcMain JavaScript object in the main
// process.
Message(
@@ -46,10 +60,6 @@ interface ElectronBrowser {
string channel,
blink.mojom.CloneableMessage arguments) => (blink.mojom.CloneableMessage result);
// Informs underlying WebContents that first non-empty layout was performed
// by compositor.
OnFirstNonEmptyLayout();
ReceivePostMessage(string channel, blink.mojom.TransferableMessage message);
// Emits an event on |channel| from the ipcMain JavaScript object in the main
@@ -70,12 +80,4 @@ interface ElectronBrowser {
MessageHost(
string channel,
blink.mojom.CloneableMessage arguments);
UpdateDraggableRegions(
array<DraggableRegion> regions);
SetTemporaryZoomLevel(double zoom_level);
[Sync]
DoGetZoomLevel() => (double result);
};

View File

@@ -54,7 +54,7 @@ v8::Local<v8::Object> CreateNativeEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> sender,
content::RenderFrameHost* frame,
electron::mojom::ElectronBrowser::MessageSyncCallback callback) {
electron::mojom::ElectronApiIPC::MessageSyncCallback callback) {
v8::Local<v8::Object> event;
if (frame && callback) {
gin::Handle<Event> native_event = Event::Create(isolate);

View File

@@ -29,7 +29,7 @@ v8::Local<v8::Object> CreateNativeEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> sender,
content::RenderFrameHost* frame,
electron::mojom::ElectronBrowser::MessageSyncCallback callback);
electron::mojom::ElectronApiIPC::MessageSyncCallback callback);
} // namespace internal

View File

@@ -251,7 +251,8 @@ std::string OpenExternalOnWorkerThread(
ShellExecuteW(nullptr, L"open", escaped_url.c_str(), nullptr,
working_dir.empty() ? nullptr : working_dir.c_str(),
SW_SHOWNORMAL)) <= 32) {
return "Failed to open";
return "Failed to open: " +
logging::SystemErrorCodeToString(logging::GetLastSystemErrorCode());
}
return "";
}

View File

@@ -22,7 +22,7 @@
#include "shell/common/node_bindings.h"
#include "shell/common/node_includes.h"
#include "shell/common/v8_value_serializer.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_message_port_converter.h"
@@ -59,17 +59,17 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
v8::Global<v8::Context>(isolate, isolate->GetCurrentContext());
weak_context_.SetWeak();
render_frame->GetBrowserInterfaceBroker()->GetInterface(
electron_browser_remote_.BindNewPipeAndPassReceiver());
render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
&electron_ipc_remote_);
}
void OnDestruct() override { electron_browser_remote_.reset(); }
void OnDestruct() override { electron_ipc_remote_.reset(); }
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int32_t world_id) override {
if (weak_context_.IsEmpty() ||
weak_context_.Get(context->GetIsolate()) == context)
electron_browser_remote_.reset();
electron_ipc_remote_.reset();
}
// gin::Wrappable:
@@ -92,7 +92,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
bool internal,
const std::string& channel,
v8::Local<v8::Value> arguments) {
if (!electron_browser_remote_) {
if (!electron_ipc_remote_) {
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
return;
}
@@ -100,7 +100,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
return;
}
electron_browser_remote_->Message(internal, channel, std::move(message));
electron_ipc_remote_->Message(internal, channel, std::move(message));
}
v8::Local<v8::Promise> Invoke(v8::Isolate* isolate,
@@ -108,7 +108,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
bool internal,
const std::string& channel,
v8::Local<v8::Value> arguments) {
if (!electron_browser_remote_) {
if (!electron_ipc_remote_) {
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
return v8::Local<v8::Promise>();
}
@@ -119,7 +119,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
gin_helper::Promise<blink::CloneableMessage> p(isolate);
auto handle = p.GetHandle();
electron_browser_remote_->Invoke(
electron_ipc_remote_->Invoke(
internal, channel, std::move(message),
base::BindOnce(
[](gin_helper::Promise<blink::CloneableMessage> p,
@@ -134,7 +134,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
const std::string& channel,
v8::Local<v8::Value> message_value,
absl::optional<v8::Local<v8::Value>> transfer) {
if (!electron_browser_remote_) {
if (!electron_ipc_remote_) {
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
return;
}
@@ -166,8 +166,8 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
}
transferable_message.ports = std::move(ports);
electron_browser_remote_->ReceivePostMessage(
channel, std::move(transferable_message));
electron_ipc_remote_->ReceivePostMessage(channel,
std::move(transferable_message));
}
void SendTo(v8::Isolate* isolate,
@@ -175,7 +175,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
int32_t web_contents_id,
const std::string& channel,
v8::Local<v8::Value> arguments) {
if (!electron_browser_remote_) {
if (!electron_ipc_remote_) {
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
return;
}
@@ -183,15 +183,15 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
return;
}
electron_browser_remote_->MessageTo(web_contents_id, channel,
std::move(message));
electron_ipc_remote_->MessageTo(web_contents_id, channel,
std::move(message));
}
void SendToHost(v8::Isolate* isolate,
gin_helper::ErrorThrower thrower,
const std::string& channel,
v8::Local<v8::Value> arguments) {
if (!electron_browser_remote_) {
if (!electron_ipc_remote_) {
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
return;
}
@@ -199,7 +199,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
return;
}
electron_browser_remote_->MessageHost(channel, std::move(message));
electron_ipc_remote_->MessageHost(channel, std::move(message));
}
v8::Local<v8::Value> SendSync(v8::Isolate* isolate,
@@ -207,7 +207,7 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
bool internal,
const std::string& channel,
v8::Local<v8::Value> arguments) {
if (!electron_browser_remote_) {
if (!electron_ipc_remote_) {
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
return v8::Local<v8::Value>();
}
@@ -217,13 +217,13 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
}
blink::CloneableMessage result;
electron_browser_remote_->MessageSync(internal, channel, std::move(message),
&result);
electron_ipc_remote_->MessageSync(internal, channel, std::move(message),
&result);
return electron::DeserializeV8Value(isolate, result);
}
v8::Global<v8::Context> weak_context_;
mojo::Remote<electron::mojom::ElectronBrowser> electron_browser_remote_;
mojo::AssociatedRemote<electron::mojom::ElectronApiIPC> electron_ipc_remote_;
};
gin::WrapperInfo IPCRenderer::kWrapperInfo = {gin::kEmbedderNativeGin};

View File

@@ -34,7 +34,7 @@
#include "shell/renderer/api/electron_api_context_bridge.h"
#include "shell/renderer/api/electron_api_spell_check_client.h"
#include "shell/renderer/renderer_client_base.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/common/web_cache/web_cache_resource_type_stats.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
@@ -445,10 +445,11 @@ class WebFrameRenderer : public gin::Wrappable<WebFrameRenderer>,
if (!MaybeGetRenderFrame(isolate, "setZoomLevel", &render_frame))
return;
mojo::Remote<mojom::ElectronBrowser> browser_remote;
render_frame->GetBrowserInterfaceBroker()->GetInterface(
browser_remote.BindNewPipeAndPassReceiver());
browser_remote->SetTemporaryZoomLevel(level);
mojo::AssociatedRemote<mojom::ElectronWebContentsUtility>
web_contents_utility_remote;
render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
&web_contents_utility_remote);
web_contents_utility_remote->SetTemporaryZoomLevel(level);
}
double GetZoomLevel(v8::Isolate* isolate) {
@@ -457,10 +458,11 @@ class WebFrameRenderer : public gin::Wrappable<WebFrameRenderer>,
if (!MaybeGetRenderFrame(isolate, "getZoomLevel", &render_frame))
return result;
mojo::Remote<mojom::ElectronBrowser> browser_remote;
render_frame->GetBrowserInterfaceBroker()->GetInterface(
browser_remote.BindNewPipeAndPassReceiver());
browser_remote->DoGetZoomLevel(&result);
mojo::AssociatedRemote<mojom::ElectronWebContentsUtility>
web_contents_utility_remote;
render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
&web_contents_utility_remote);
web_contents_utility_remote->DoGetZoomLevel(&result);
return result;
}

View File

@@ -22,7 +22,7 @@
#include "shell/common/options_switches.h"
#include "shell/common/world_ids.h"
#include "shell/renderer/renderer_client_base.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/platform/web_isolated_world_info.h"
#include "third_party/blink/public/web/blink.h"
@@ -149,10 +149,11 @@ void ElectronRenderFrameObserver::DraggableRegionsChanged() {
regions.push_back(std::move(region));
}
mojo::Remote<mojom::ElectronBrowser> browser_remote;
render_frame_->GetBrowserInterfaceBroker()->GetInterface(
browser_remote.BindNewPipeAndPassReceiver());
browser_remote->UpdateDraggableRegions(std::move(regions));
mojo::AssociatedRemote<mojom::ElectronWebContentsUtility>
web_contents_utility_remote;
render_frame_->GetRemoteAssociatedInterfaces()->GetInterface(
&web_contents_utility_remote);
web_contents_utility_remote->UpdateDraggableRegions(std::move(regions));
}
void ElectronRenderFrameObserver::WillReleaseScriptContext(
@@ -169,10 +170,11 @@ void ElectronRenderFrameObserver::OnDestruct() {
void ElectronRenderFrameObserver::DidMeaningfulLayout(
blink::WebMeaningfulLayout layout_type) {
if (layout_type == blink::WebMeaningfulLayout::kVisuallyNonEmpty) {
mojo::Remote<mojom::ElectronBrowser> browser_remote;
render_frame_->GetBrowserInterfaceBroker()->GetInterface(
browser_remote.BindNewPipeAndPassReceiver());
browser_remote->OnFirstNonEmptyLayout();
mojo::AssociatedRemote<mojom::ElectronWebContentsUtility>
web_contents_utility_remote;
render_frame_->GetRemoteAssociatedInterfaces()->GetInterface(
&web_contents_utility_remote);
web_contents_utility_remote->OnFirstNonEmptyLayout();
}
}

View File

@@ -3517,6 +3517,32 @@ describe('BrowserWindow module', () => {
});
});
// TODO(dsanders11): Enable once maximize event works on Linux again on CI
// TODO(jkleinsc): fix this test on Windows
ifdescribe(process.platform !== 'linux' && process.platform !== 'win32')('BrowserWindow.maximize()', () => {
afterEach(closeAllWindows);
it('should show the window if it is not currently shown', async () => {
const w = new BrowserWindow({ show: false });
const hidden = emittedOnce(w, 'hide');
let shown = emittedOnce(w, 'show');
const maximize = emittedOnce(w, 'maximize');
expect(w.isVisible()).to.be.false('visible');
w.maximize();
await maximize;
await shown;
expect(w.isMaximized()).to.be.true('maximized');
expect(w.isVisible()).to.be.true('visible');
// Even if the window is already maximized
w.hide();
await hidden;
expect(w.isVisible()).to.be.false('visible');
shown = emittedOnce(w, 'show');
w.maximize();
await shown;
expect(w.isVisible()).to.be.true('visible');
});
});
describe('BrowserWindow.unmaximize()', () => {
afterEach(closeAllWindows);
it('should restore the previous window position', () => {

View File

@@ -12,8 +12,27 @@ import * as fs from 'fs';
*
* Because all encryption methods are gated by isEncryptionAvailable, the methods will never return the correct values
* when run on CI and linux.
* Refs: https://github.com/electron/electron/issues/30424.
*/
describe('safeStorage module', () => {
it('safeStorage before and after app is ready', async () => {
const appPath = path.join(__dirname, 'fixtures', 'crash-cases', 'safe-storage');
const appProcess = cp.spawn(process.execPath, [appPath]);
let output = '';
appProcess.stdout.on('data', data => { output += data; });
appProcess.stderr.on('data', data => { output += data; });
const code = (await emittedOnce(appProcess, 'exit'))[0] ?? 1;
if (code !== 0 && output) {
console.log(output);
}
expect(code).to.equal(0);
});
});
ifdescribe(process.platform !== 'linux')('safeStorage module', () => {
after(async () => {
const pathToEncryptedString = path.resolve(__dirname, 'fixtures', 'api', 'safe-storage', 'encrypted.txt');

View File

@@ -1722,11 +1722,39 @@ describe('navigator.serial', () => {
});
it('returns a port when select-serial-port event is defined', async () => {
let havePorts = false;
w.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
callback(portList[0].portId);
if (portList.length > 0) {
havePorts = true;
callback(portList[0].portId);
} else {
callback('');
}
});
const port = await getPorts();
expect(port).to.equal('[object SerialPort]');
if (havePorts) {
expect(port).to.equal('[object SerialPort]');
} else {
expect(port).to.equal('NotFoundError: No port selected by the user.');
}
});
it('navigator.serial.getPorts() returns values', async () => {
let havePorts = false;
w.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
if (portList.length > 0) {
havePorts = true;
callback(portList[0].portId);
} else {
callback('');
}
});
await getPorts();
if (havePorts) {
const grantedPorts = await w.webContents.executeJavaScript('navigator.serial.getPorts()');
expect(grantedPorts).to.not.be.empty();
}
});
});

View File

@@ -0,0 +1,39 @@
const { app, safeStorage } = require('electron');
const { expect } = require('chai');
(async () => {
if (!app.isReady()) {
// isEncryptionAvailable() returns false before the app is ready on
// Linux: https://github.com/electron/electron/issues/32206
// and
// Windows: https://github.com/electron/electron/issues/33640.
expect(safeStorage.isEncryptionAvailable()).to.equal(process.platform === 'darwin');
if (safeStorage.isEncryptionAvailable()) {
const plaintext = 'plaintext';
const ciphertext = safeStorage.encryptString(plaintext);
expect(Buffer.isBuffer(ciphertext)).to.equal(true);
expect(safeStorage.decryptString(ciphertext)).to.equal(plaintext);
} else {
expect(() => safeStorage.encryptString('plaintext')).to.throw(/safeStorage cannot be used before app is ready/);
expect(() => safeStorage.decryptString(Buffer.from(''))).to.throw(/safeStorage cannot be used before app is ready/);
}
}
await app.whenReady();
// isEncryptionAvailable() will always return false on CI due to a mocked
// dbus as mentioned above.
expect(safeStorage.isEncryptionAvailable()).to.equal(process.platform !== 'linux');
if (safeStorage.isEncryptionAvailable()) {
const plaintext = 'plaintext';
const ciphertext = safeStorage.encryptString(plaintext);
expect(Buffer.isBuffer(ciphertext)).to.equal(true);
expect(safeStorage.decryptString(ciphertext)).to.equal(plaintext);
} else {
expect(() => safeStorage.encryptString('plaintext')).to.throw(/Encryption is not available/);
expect(() => safeStorage.decryptString(Buffer.from(''))).to.throw(/Decryption is not available/);
}
})()
.then(app.quit)
.catch((err) => {
console.error(err);
app.exit(1);
});

View File

@@ -28,6 +28,13 @@ v8.setFlagsFromString('--expose_gc');
app.commandLine.appendSwitch('js-flags', '--expose_gc');
app.commandLine.appendSwitch('ignore-certificate-errors');
app.commandLine.appendSwitch('disable-renderer-backgrounding');
// Some ports are considered to be "unsafe" by Chromium
// but Windows on Microsoft-hosted agents sometimes assigns one of them
// to a Node.js server. Chromium refuses to establish a connection
// and the whole app crashes with the "Error: net::ERR_UNSAFE_PORT" error.
// Let's allow connections to those ports to avoid test failures.
// Use a comma-separated list of ports as a flag value, e.g. "666,667,668".
app.commandLine.appendSwitch('explicitly-allowed-ports', '2049');
// Disable security warnings (the security warnings test will enable them)
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = true;

View File

@@ -7,7 +7,7 @@ const { emittedOnce, waitForEvent } = require('./events-helpers');
const { ifdescribe, ifit, delay } = require('./spec-helpers');
const features = process._linkedBinding('electron_common_features');
const nativeModulesEnabled = process.env.ELECTRON_SKIP_NATIVE_MODULE_TESTS;
const nativeModulesEnabled = !process.env.ELECTRON_SKIP_NATIVE_MODULE_TESTS;
/* Most of the APIs here don't use standard callbacks */
/* eslint-disable standard/no-callback-literal */

229
yarn.lock
View File

@@ -2,6 +2,94 @@
# yarn lockfile v1
"@azure/abort-controller@^1.0.0":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.4.tgz#fd3c4d46c8ed67aace42498c8e2270960250eafd"
integrity sha512-lNUmDRVGpanCsiUN3NWxFTdwmdFI53xwhkTFfHDGTYk46ca7Ind3nanJc+U6Zj9Tv+9nTCWRBscWEW1DyKOpTw==
dependencies:
tslib "^2.0.0"
"@azure/core-asynciterator-polyfill@^1.0.0":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz#0dd3849fb8d97f062a39db0e5cadc9ffaf861fec"
integrity sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw==
"@azure/core-auth@^1.3.0":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.3.2.tgz#6a2c248576c26df365f6c7881ca04b7f6d08e3d0"
integrity sha512-7CU6DmCHIZp5ZPiZ9r3J17lTKMmYsm/zGvNkjArQwPkrLlZ1TZ+EUYfGgh2X31OLMVAQCTJZW4cXHJi02EbJnA==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-http@^2.0.0":
version "2.2.4"
resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-2.2.4.tgz#df5a5b4138dbbc4299879f2fc6f257d0a5f0401e"
integrity sha512-QmmJmexXKtPyc3/rsZR/YTLDvMatzbzAypJmLzvlfxgz/SkgnqV/D4f6F2LsK6tBj1qhyp8BoXiOebiej0zz3A==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-asynciterator-polyfill" "^1.0.0"
"@azure/core-auth" "^1.3.0"
"@azure/core-tracing" "1.0.0-preview.13"
"@azure/logger" "^1.0.0"
"@types/node-fetch" "^2.5.0"
"@types/tunnel" "^0.0.3"
form-data "^4.0.0"
node-fetch "^2.6.7"
process "^0.11.10"
tough-cookie "^4.0.0"
tslib "^2.2.0"
tunnel "^0.0.6"
uuid "^8.3.0"
xml2js "^0.4.19"
"@azure/core-lro@^2.2.0":
version "2.2.4"
resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-2.2.4.tgz#42fbf4ae98093c59005206a4437ddcd057c57ca1"
integrity sha512-e1I2v2CZM0mQo8+RSix0x091Av493e4bnT22ds2fcQGslTHzM2oTbswkB65nP4iEpCxBrFxOSDPKExmTmjCVtQ==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-tracing" "1.0.0-preview.13"
"@azure/logger" "^1.0.0"
tslib "^2.2.0"
"@azure/core-paging@^1.1.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.2.1.tgz#1b884f563b6e49971e9a922da3c7a20931867b54"
integrity sha512-UtH5iMlYsvg+nQYIl4UHlvvSrsBjOlRF4fs0j7mxd3rWdAStrKYrh2durOpHs5C9yZbVhsVDaisoyaf/lL1EVA==
dependencies:
"@azure/core-asynciterator-polyfill" "^1.0.0"
tslib "^2.2.0"
"@azure/core-tracing@1.0.0-preview.13":
version "1.0.0-preview.13"
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644"
integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==
dependencies:
"@opentelemetry/api" "^1.0.1"
tslib "^2.2.0"
"@azure/logger@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96"
integrity sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g==
dependencies:
tslib "^2.2.0"
"@azure/storage-blob@^12.9.0":
version "12.9.0"
resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.9.0.tgz#4cbd8b4c7a47dd064867430db892f4ef2d8f17ab"
integrity sha512-ank38FdCLfJ+EoeMzCz3hkYJuZAd63ARvDKkxZYRDb+beBYf+/+gx8jNTqkq/hfyUl4dJQ/a7tECU0Y0F98CHg==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-http" "^2.0.0"
"@azure/core-lro" "^2.2.0"
"@azure/core-paging" "^1.1.1"
"@azure/core-tracing" "1.0.0-preview.13"
"@azure/logger" "^1.0.0"
events "^3.0.0"
tslib "^2.2.0"
"@babel/code-frame@^7.0.0":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
@@ -181,6 +269,11 @@
dependencies:
"@types/node" ">= 8"
"@opentelemetry/api@^1.0.1":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.4.tgz#a167e46c10d05a07ab299fc518793b0cff8f6924"
integrity sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog==
"@primer/octicons@^10.0.0":
version "10.0.0"
resolved "https://registry.yarnpkg.com/@primer/octicons/-/octicons-10.0.0.tgz#81e94ed32545dfd3472c8625a5b345f3ea4c153d"
@@ -390,6 +483,14 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce"
integrity sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==
"@types/node-fetch@^2.5.0":
version "2.6.1"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975"
integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==
dependencies:
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*":
version "12.6.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.1.tgz#d5544f6de0aae03eefbb63d5120f6c8be0691946"
@@ -493,6 +594,13 @@
dependencies:
"@types/node" "*"
"@types/tunnel@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9"
integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==
dependencies:
"@types/node" "*"
"@types/uglify-js@*":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082"
@@ -1074,6 +1182,11 @@ async-each@^1.0.0, async-each@^1.0.1:
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
at-least-node@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
@@ -1678,6 +1791,13 @@ colors@^1.1.2:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@^2.20.0, commander@^2.9.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
@@ -2003,6 +2123,11 @@ deglob@^4.0.1:
run-parallel "^1.1.2"
uniq "^1.0.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@@ -3005,6 +3130,24 @@ for-own@^0.1.4:
dependencies:
for-in "^1.0.1"
form-data@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
format@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
@@ -4680,6 +4823,18 @@ mime-db@1.40.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mime-types@~2.1.24:
version "2.1.24"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
@@ -4883,10 +5038,12 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-fetch@^2.3.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-fetch@^2.3.0, node-fetch@^2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
dependencies:
whatwg-url "^5.0.0"
node-libs-browser@^2.2.1:
version "2.2.1"
@@ -5599,6 +5756,11 @@ prr@~1.0.1:
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
psl@^1.1.33:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
public-encrypt@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
@@ -5646,7 +5808,7 @@ punycode@^1.2.4:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
punycode@^2.1.0:
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
@@ -7334,6 +7496,20 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
tough-cookie@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==
dependencies:
psl "^1.1.33"
punycode "^2.1.1"
universalify "^0.1.2"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
trim-trailing-lines@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz#d2f1e153161152e9f02fabc670fb40bec2ea2e3a"
@@ -7389,6 +7565,11 @@ tslib@^1.8.1, tslib@^1.9.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
tslib@^2.0.0, tslib@^2.2.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
tsutils@^3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
@@ -7401,6 +7582,11 @@ tty-browserify@0.0.0:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@@ -7621,7 +7807,7 @@ universal-user-agent@^6.0.0:
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
universalify@^0.1.0:
universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
@@ -7737,6 +7923,11 @@ uuid@3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
uuid@^8.3.0:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
@@ -7831,6 +8022,11 @@ wcwidth@^1.0.1:
dependencies:
defaults "^1.0.3"
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
webpack-cli@^3.3.12:
version "3.3.12"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a"
@@ -7885,6 +8081,14 @@ webpack@^4.43.0:
watchpack "^1.6.1"
webpack-sources "^1.4.1"
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
@@ -7991,6 +8195,19 @@ xml2js@0.4.19:
sax ">=0.6.0"
xmlbuilder "~9.0.1"
xml2js@^0.4.19:
version "0.4.23"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
dependencies:
sax ">=0.6.0"
xmlbuilder "~11.0.0"
xmlbuilder@~11.0.0:
version "11.0.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
xmlbuilder@~4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5"