mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b804177fa | ||
|
|
77478353c6 | ||
|
|
30e8011b9f | ||
|
|
54432ab8b2 | ||
|
|
37558a6215 | ||
|
|
d5ba5c8e0a | ||
|
|
b1b83f79b7 | ||
|
|
a85b38847e | ||
|
|
ade9151181 | ||
|
|
9d2961868c | ||
|
|
cdd6fc93b2 | ||
|
|
1e21b7c910 | ||
|
|
c224431ae8 | ||
|
|
9e0fda8393 | ||
|
|
36b72ba5ee | ||
|
|
dd8c63e15a | ||
|
|
6bfa54fcf2 | ||
|
|
6d9f3a4945 | ||
|
|
a20396588a | ||
|
|
f988853128 | ||
|
|
8bc25e8a9d | ||
|
|
a8f8b507aa | ||
|
|
eb320cbbf9 | ||
|
|
37eab5c66e | ||
|
|
fc912026e2 | ||
|
|
6aa0609a97 | ||
|
|
620d615fe0 | ||
|
|
ec7baba401 | ||
|
|
f8ba4d6012 | ||
|
|
79af6f3493 | ||
|
|
6a952c4ff1 | ||
|
|
ce7c83e8d6 | ||
|
|
a686f7e102 | ||
|
|
fa07b74836 | ||
|
|
587353dbc9 | ||
|
|
21b8b3064d | ||
|
|
0f05991c3e | ||
|
|
6bdab4a353 | ||
|
|
6e5f02426a | ||
|
|
30da5dee2a | ||
|
|
bd9c7c41ba | ||
|
|
76f4ced8d4 | ||
|
|
cac38cb6ea | ||
|
|
e8f89da1c4 | ||
|
|
a0f73938cd | ||
|
|
1bf71fa81f | ||
|
|
0de8079b33 | ||
|
|
52fd3da443 | ||
|
|
742aab764e | ||
|
|
1f669c3cc5 | ||
|
|
d26d064082 | ||
|
|
a31e722d43 | ||
|
|
81b923c8f5 | ||
|
|
b745364907 | ||
|
|
91cf2e2163 | ||
|
|
53af38ad54 | ||
|
|
2fef020e06 | ||
|
|
b60dfe4117 | ||
|
|
7e123ac6e5 | ||
|
|
a29136950e | ||
|
|
458a843174 | ||
|
|
e11e12d5b3 | ||
|
|
25ed65150d | ||
|
|
8737aa046d | ||
|
|
0d94bdda50 | ||
|
|
2c3081afb8 | ||
|
|
f583acff46 | ||
|
|
271e98c059 | ||
|
|
8279c02e9a | ||
|
|
ef4cbe86af | ||
|
|
300a40f939 |
1
.circleci/.gitignore
vendored
Normal file
1
.circleci/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
config-staging
|
||||
@@ -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
|
||||
|
||||
@@ -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
34
.circleci/config/build.js
Normal 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());
|
||||
51
.circleci/config/jobs/lint.yml
Normal file
51
.circleci/config/jobs/lint.yml
Normal 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
|
||||
10
.circleci/config/package.json
Normal file
10
.circleci/config/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
43
.circleci/config/yarn.lock
Normal file
43
.circleci/config/yarn.lock
Normal 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
20
.github/workflows/semantic.yml
vendored
Normal 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
|
||||
4
BUILD.gn
4
BUILD.gn
@@ -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" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
15.5.1
|
||||
15.5.7
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)`
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
31
patches/angle/cherry-pick-a602a068e022.patch
Normal file
31
patches/angle/cherry-pick-a602a068e022.patch
Normal 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))
|
||||
100
patches/angle/cherry-pick-d27d9d059b51.patch
Normal file
100
patches/angle/cherry-pick-d27d9d059b51.patch
Normal 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,
|
||||
33
patches/angle/cherry-pick-d49484c21e3c.patch
Normal file
33
patches/angle/cherry-pick-d49484c21e3c.patch
Normal 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;
|
||||
}
|
||||
|
||||
58
patches/angle/fix_checkednumeric_using_the_wrong_type.patch
Normal file
58
patches/angle/fix_checkednumeric_using_the_wrong_type.patch
Normal 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)
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
89
patches/chromium/cherry-pick-12ba78f3fa7a.patch
Normal file
89
patches/chromium/cherry-pick-12ba78f3fa7a.patch
Normal 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,<svg id='x' xmlns='http://www.w3.org/2000/svg'><image href='fake' onerror='executed=true' /></svg>#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>
|
||||
118
patches/chromium/cherry-pick-1665a1d16d46.patch
Normal file
118
patches/chromium/cherry-pick-1665a1d16d46.patch
Normal 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));
|
||||
}
|
||||
|
||||
62
patches/chromium/cherry-pick-1a31e2110440.patch
Normal file
62
patches/chromium/cherry-pick-1a31e2110440.patch
Normal 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>
|
||||
154
patches/chromium/cherry-pick-4d26949260aa.patch
Normal file
154
patches/chromium/cherry-pick-4d26949260aa.patch
Normal 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.
|
||||
+
|
||||
36
patches/chromium/cherry-pick-5be8e065f43e.patch
Normal file
36
patches/chromium/cherry-pick-5be8e065f43e.patch
Normal 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;
|
||||
40
patches/chromium/cherry-pick-5ff02e4d7368.patch
Normal file
40
patches/chromium/cherry-pick-5ff02e4d7368.patch
Normal 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));
|
||||
64
patches/chromium/cherry-pick-99c3f3bfd507.patch
Normal file
64
patches/chromium/cherry-pick-99c3f3bfd507.patch
Normal 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;
|
||||
}
|
||||
160
patches/chromium/cherry-pick-ec0cce63f47d.patch
Normal file
160
patches/chromium/cherry-pick-ec0cce63f47d.patch
Normal 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
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
83
patches/chromium/fix_--without-valid_build.patch
Normal file
83
patches/chromium/fix_--without-valid_build.patch
Normal 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;
|
||||
@@ -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_);
|
||||
@@ -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");
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
@@ -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,
|
||||
- ¶ms.aa_flags, ¶ms.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,
|
||||
@@ -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 ]
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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()
|
||||
190
patches/chromium/use-after-free_of_id_and_idref_attributes.patch
Normal file
190
patches/chromium/use-after-free_of_id_and_idref_attributes.patch
Normal 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);
|
||||
}
|
||||
|
||||
@@ -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
1
patches/icu/.patches
Normal file
@@ -0,0 +1 @@
|
||||
m100_cp_pr_2070_fix_int32_overflow.patch
|
||||
349
patches/icu/m100_cp_pr_2070_fix_int32_overflow.patch
Normal file
349
patches/icu/m100_cp_pr_2070_fix_int32_overflow.patch
Normal 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
1
patches/pdfium/.patches
Normal file
@@ -0,0 +1 @@
|
||||
cherry-pick-a48de319c521.patch
|
||||
93
patches/pdfium/cherry-pick-a48de319c521.patch
Normal file
93
patches/pdfium/cherry-pick-a48de319c521.patch
Normal 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();
|
||||
@@ -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
|
||||
|
||||
62
patches/v8/cherry-pick-2004594a46c8.patch
Normal file
62
patches/v8/cherry-pick-2004594a46c8.patch
Normal 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)) {
|
||||
29
patches/v8/cherry-pick-a1427aad7cef.patch
Normal file
29
patches/v8/cherry-pick-a1427aad7cef.patch
Normal 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);
|
||||
|
||||
79
patches/v8/cherry-pick-b2d3ef69ef99.patch
Normal file
79
patches/v8/cherry-pick-b2d3ef69ef99.patch
Normal 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();
|
||||
37
patches/v8/cherry-pick-e42dbcdedb7a.patch
Normal file
37
patches/v8/cherry-pick-e42dbcdedb7a.patch
Normal 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(
|
||||
92
patches/v8/cherry-pick-f546ac11eec7.patch
Normal file
92
patches/v8/cherry-pick-f546ac11eec7.patch
Normal 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: [
|
||||
153
patches/v8/cherry-pick-f599381978f2.patch
Normal file
153
patches/v8/cherry-pick-f599381978f2.patch
Normal 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) {
|
||||
@@ -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
|
||||
|
||||
@@ -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
43
script/lib/azput.js
Normal 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);
|
||||
});
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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__':
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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__':
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. "
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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|.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
108
shell/browser/electron_api_ipc_handler_impl.cc
Normal file
108
shell/browser/electron_api_ipc_handler_impl.cc
Normal 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
|
||||
@@ -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_
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
83
shell/browser/electron_web_contents_utility_handler_impl.cc
Normal file
83
shell/browser/electron_web_contents_utility_handler_impl.cc
Normal 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
|
||||
68
shell/browser/electron_web_contents_utility_handler_impl.h
Normal file
68
shell/browser/electron_web_contents_utility_handler_impl.h
Normal 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_
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 "";
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
39
spec-main/fixtures/crash-cases/safe-storage/index.js
Normal file
39
spec-main/fixtures/crash-cases/safe-storage/index.js
Normal 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);
|
||||
});
|
||||
@@ -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;
|
||||
|
||||
@@ -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
229
yarn.lock
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user