mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f1f744e88 | ||
|
|
2d7e11a76c | ||
|
|
3fc23369b6 | ||
|
|
965ac948e0 | ||
|
|
e58fcdece3 | ||
|
|
73552d2720 | ||
|
|
da458ffd10 | ||
|
|
0cbdf2f037 | ||
|
|
5442f1d7fb | ||
|
|
be77994af2 | ||
|
|
2046ae8773 | ||
|
|
92892ca481 | ||
|
|
0ba01d5cc6 | ||
|
|
a32b124d64 | ||
|
|
8f26c7a1b8 | ||
|
|
45d03a5392 | ||
|
|
c8be8adebf | ||
|
|
f10a9b784c | ||
|
|
9d2f8cb4da | ||
|
|
1173004739 | ||
|
|
be37adefd0 | ||
|
|
7007907df0 | ||
|
|
2c8b6ee0c0 | ||
|
|
4c64377ead | ||
|
|
0ef056130c | ||
|
|
64373df3ca | ||
|
|
13e44072be | ||
|
|
16a038502a | ||
|
|
00a492d282 | ||
|
|
290a77b843 | ||
|
|
87baa17e65 | ||
|
|
e6928c1319 | ||
|
|
976a7bece5 | ||
|
|
03244a56f1 | ||
|
|
8e0f534873 | ||
|
|
1573d6b28c | ||
|
|
1b3e1433dd | ||
|
|
e551cf8c00 | ||
|
|
bd3abf3a2c | ||
|
|
da140aea7c | ||
|
|
8699ce4f98 | ||
|
|
5fded6ae88 | ||
|
|
0e6e480a8b | ||
|
|
44b21205c7 | ||
|
|
db8e94113b | ||
|
|
db7ed2bfc9 | ||
|
|
315496c148 | ||
|
|
842290c50f | ||
|
|
9bf952f1c5 | ||
|
|
7594783ff8 | ||
|
|
f929de8896 | ||
|
|
37bb19a3e3 | ||
|
|
f5016aaec0 | ||
|
|
17697b193d | ||
|
|
3679fd56e7 | ||
|
|
09a028cf8b | ||
|
|
d0978d2812 | ||
|
|
143faed926 | ||
|
|
3e6086d930 | ||
|
|
7549704f1a | ||
|
|
48c473fa06 | ||
|
|
69c8cbf259 | ||
|
|
c7f44f4101 | ||
|
|
a369ec963b | ||
|
|
4544b97e28 | ||
|
|
277164fc20 | ||
|
|
41377f9467 | ||
|
|
08e0583889 | ||
|
|
6af676f473 | ||
|
|
2973952857 | ||
|
|
a5f098d2b7 | ||
|
|
74856fdd47 | ||
|
|
d733f01f3b |
16
.github/actions/build-electron/action.yml
vendored
16
.github/actions/build-electron/action.yml
vendored
@@ -174,7 +174,17 @@ runs:
|
|||||||
if: ${{ inputs.is-release == 'true' }}
|
if: ${{ inputs.is-release == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
cd src
|
cd src
|
||||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true use_siso=true $GN_EXTRA_ARGS"
|
# Reuse the hermetic mac_sdk_path that `e build` wrote for out/Default so
|
||||||
|
# out/ffmpeg builds against the same SDK instead of the runner's system Xcode.
|
||||||
|
# The path has to live under root_build_dir, so copy the symlink tree and
|
||||||
|
# rewrite Default -> ffmpeg.
|
||||||
|
MAC_SDK_ARG=""
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
mkdir -p out/ffmpeg
|
||||||
|
cp -a out/Default/xcode_links out/ffmpeg/
|
||||||
|
MAC_SDK_ARG=$(sed -n 's|^\(mac_sdk_path = "//out/\)Default/|\1ffmpeg/|p' out/Default/args.gn)
|
||||||
|
fi
|
||||||
|
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true use_siso=true $MAC_SDK_ARG $GN_EXTRA_ARGS"
|
||||||
e build --target electron:electron_ffmpeg_zip -C ../../out/ffmpeg
|
e build --target electron:electron_ffmpeg_zip -C ../../out/ffmpeg
|
||||||
- name: Remove Clang problem matcher
|
- name: Remove Clang problem matcher
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -243,12 +253,12 @@ runs:
|
|||||||
run: ./src/electron/script/actions/move-artifacts.sh
|
run: ./src/electron/script/actions/move-artifacts.sh
|
||||||
- name: Upload Generated Artifacts ${{ inputs.step-suffix }}
|
- name: Upload Generated Artifacts ${{ inputs.step-suffix }}
|
||||||
if: always() && !cancelled()
|
if: always() && !cancelled()
|
||||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
|
||||||
with:
|
with:
|
||||||
name: generated_artifacts_${{ env.ARTIFACT_KEY }}
|
name: generated_artifacts_${{ env.ARTIFACT_KEY }}
|
||||||
path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
|
path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
|
||||||
- name: Upload Src Artifacts ${{ inputs.step-suffix }}
|
- name: Upload Src Artifacts ${{ inputs.step-suffix }}
|
||||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
|
||||||
with:
|
with:
|
||||||
name: src_artifacts_${{ env.ARTIFACT_KEY }}
|
name: src_artifacts_${{ env.ARTIFACT_KEY }}
|
||||||
path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
|
path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
|
||||||
|
|||||||
30
.github/actions/checkout/action.yml
vendored
30
.github/actions/checkout/action.yml
vendored
@@ -28,7 +28,7 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
node src/electron/script/generate-deps-hash.js
|
node src/electron/script/generate-deps-hash.js
|
||||||
DEPSHASH="v1-src-cache-$(cat src/electron/.depshash)"
|
DEPSHASH="v2-src-cache-$(cat src/electron/.depshash)"
|
||||||
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
||||||
echo "CACHE_FILE=$DEPSHASH.tar" >> $GITHUB_ENV
|
echo "CACHE_FILE=$DEPSHASH.tar" >> $GITHUB_ENV
|
||||||
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||||
@@ -43,7 +43,7 @@ runs:
|
|||||||
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$CACHE_FILE?platform=${{ inputs.target-platform }}&getAccountName=true" > sas-token
|
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$CACHE_FILE?platform=${{ inputs.target-platform }}&getAccountName=true" > sas-token
|
||||||
- name: Save SAS Key
|
- name: Save SAS Key
|
||||||
if: ${{ inputs.generate-sas-token == 'true' }}
|
if: ${{ inputs.generate-sas-token == 'true' }}
|
||||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||||
with:
|
with:
|
||||||
path: sas-token
|
path: sas-token
|
||||||
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
|
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
|
||||||
@@ -109,7 +109,7 @@ runs:
|
|||||||
echo "target_os=['$TARGET_OS']" >> ./.gclient
|
echo "target_os=['$TARGET_OS']" >> ./.gclient
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 e d gclient sync --with_branch_heads --with_tags -vv
|
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN=0 DEPOT_TOOLS_WIN_TOOLCHAIN=0 ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 e d gclient sync --with_branch_heads --with_tags
|
||||||
if [[ "${{ inputs.is-release }}" != "true" ]]; then
|
if [[ "${{ inputs.is-release }}" != "true" ]]; then
|
||||||
# Re-export all the patches to check if there were changes.
|
# Re-export all the patches to check if there were changes.
|
||||||
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
|
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||||
@@ -187,21 +187,35 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
|
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
|
||||||
tar -cf $CACHE_FILE src
|
# Named .tar but zstd-compressed; the sas-sidecar's filename allowlist
|
||||||
|
# only permits .tar/.tgz so we keep the extension and decode on restore.
|
||||||
|
tar -cf - src | zstd -T0 --long=30 -f -o $CACHE_FILE
|
||||||
echo "Compressed src to $(du -sh $CACHE_FILE | cut -f1 -d' ')"
|
echo "Compressed src to $(du -sh $CACHE_FILE | cut -f1 -d' ')"
|
||||||
cp ./$CACHE_FILE $CACHE_DRIVE/
|
|
||||||
- name: Persist Src Cache
|
- name: Persist Src Cache
|
||||||
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
|
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
final_cache_path=$CACHE_DRIVE/$CACHE_FILE
|
final_cache_path=$CACHE_DRIVE/$CACHE_FILE
|
||||||
|
# Upload to a run-unique temp name first so concurrent readers never
|
||||||
|
# observe a partially-written file, and an interrupted copy can't leave
|
||||||
|
# a truncated file at the final path. Orphaned temp files get swept by
|
||||||
|
# the clean-orphaned-cache-uploads workflow.
|
||||||
|
tmp_cache_path=$final_cache_path.upload-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}
|
||||||
|
echo "Uploading to temp path: $tmp_cache_path"
|
||||||
|
cp ./$CACHE_FILE $tmp_cache_path
|
||||||
|
|
||||||
echo "Using cache key: $DEPSHASH"
|
echo "Using cache key: $DEPSHASH"
|
||||||
echo "Checking path: $final_cache_path"
|
if [ -f "$final_cache_path" ]; then
|
||||||
|
echo "Cache already persisted at $final_cache_path by a concurrent run; discarding ours"
|
||||||
|
rm -f $tmp_cache_path
|
||||||
|
else
|
||||||
|
mv -f $tmp_cache_path $final_cache_path
|
||||||
|
echo "Cache key persisted in $final_cache_path"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "$final_cache_path" ]; then
|
if [ ! -f "$final_cache_path" ]; then
|
||||||
echo "Cache key not found"
|
echo "Cache key not found"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
|
||||||
echo "Cache key persisted in $final_cache_path"
|
|
||||||
fi
|
fi
|
||||||
- name: Wait for active SSH sessions
|
- name: Wait for active SSH sessions
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
1
.github/actions/fix-sync/action.yml
vendored
1
.github/actions/fix-sync/action.yml
vendored
@@ -27,6 +27,7 @@ runs:
|
|||||||
python3 src/tools/clang/scripts/update.py
|
python3 src/tools/clang/scripts/update.py
|
||||||
# Refs https://chromium-review.googlesource.com/c/chromium/src/+/6667681
|
# Refs https://chromium-review.googlesource.com/c/chromium/src/+/6667681
|
||||||
python3 src/tools/clang/scripts/update.py --package objdump
|
python3 src/tools/clang/scripts/update.py --package objdump
|
||||||
|
python3 src/tools/clang/scripts/update.py --package clang-tidy
|
||||||
- name: Fix esbuild
|
- name: Fix esbuild
|
||||||
if: ${{ inputs.target-platform != 'linux' }}
|
if: ${{ inputs.target-platform != 'linux' }}
|
||||||
uses: ./src/electron/.github/actions/cipd-install
|
uses: ./src/electron/.github/actions/cipd-install
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
id: yarn-cache-dir-path
|
id: yarn-cache-dir-path
|
||||||
run: echo "dir=$(node src/electron/script/yarn.js config get cacheFolder)" >> $GITHUB_OUTPUT
|
run: echo "dir=$(node src/electron/script/yarn.js config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||||
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||||
id: yarn-cache
|
id: yarn-cache
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
|
|||||||
2
.github/actions/restore-cache-aks/action.yml
vendored
2
.github/actions/restore-cache-aks/action.yml
vendored
@@ -31,7 +31,7 @@ runs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir temp-cache
|
mkdir temp-cache
|
||||||
tar -xf $cache_path -C temp-cache
|
zstd -d --long=30 -c $cache_path | tar -xf - -C temp-cache
|
||||||
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
||||||
|
|
||||||
if [ -d "temp-cache/src" ]; then
|
if [ -d "temp-cache/src" ]; then
|
||||||
|
|||||||
33
.github/actions/restore-cache-azcopy/action.yml
vendored
33
.github/actions/restore-cache-azcopy/action.yml
vendored
@@ -8,14 +8,14 @@ runs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Obtain SAS Key
|
- name: Obtain SAS Key
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||||
with:
|
with:
|
||||||
path: sas-token
|
path: sas-token
|
||||||
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-1
|
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-1
|
||||||
enableCrossOsArchive: true
|
enableCrossOsArchive: true
|
||||||
- name: Obtain SAS Key
|
- name: Obtain SAS Key
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||||
with:
|
with:
|
||||||
path: sas-token
|
path: sas-token
|
||||||
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
|
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
|
||||||
@@ -24,7 +24,7 @@ runs:
|
|||||||
# The cache will always exist here as a result of the checkout job
|
# The cache will always exist here as a result of the checkout job
|
||||||
# Either it was uploaded to Azure in the checkout job for this commit
|
# Either it was uploaded to Azure in the checkout job for this commit
|
||||||
# or it was uploaded in the checkout job for a previous commit.
|
# or it was uploaded in the checkout job for a previous commit.
|
||||||
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
with:
|
with:
|
||||||
timeout_minutes: 30
|
timeout_minutes: 30
|
||||||
max_attempts: 3
|
max_attempts: 3
|
||||||
@@ -61,9 +61,9 @@ runs:
|
|||||||
echo "Cache is empty - exiting"
|
echo "Cache is empty - exiting"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir temp-cache
|
mkdir temp-cache
|
||||||
tar -xf $DEPSHASH.tar -C temp-cache
|
zstd -d --long=30 -c $DEPSHASH.tar | tar -xf - -C temp-cache
|
||||||
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
||||||
|
|
||||||
if [ -d "temp-cache/src" ]; then
|
if [ -d "temp-cache/src" ]; then
|
||||||
@@ -85,23 +85,21 @@ runs:
|
|||||||
|
|
||||||
- name: Unzip and Ensure Src Cache (Windows)
|
- name: Unzip and Ensure Src Cache (Windows)
|
||||||
if: ${{ inputs.target-platform == 'win' }}
|
if: ${{ inputs.target-platform == 'win' }}
|
||||||
shell: powershell
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
$src_cache = "$env:DEPSHASH.tar"
|
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
|
||||||
$cache_size = $(Get-Item $src_cache).length
|
if [ `du $DEPSHASH.tar | cut -f1` = "0" ]; then
|
||||||
Write-Host "Downloaded cache is $cache_size"
|
echo "Cache is empty - exiting"
|
||||||
if ($cache_size -eq 0) {
|
|
||||||
Write-Host "Cache is empty - exiting"
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
fi
|
||||||
|
|
||||||
$TEMP_DIR=New-Item -ItemType Directory -Path temp-cache
|
mkdir temp-cache
|
||||||
$TEMP_DIR_PATH = $TEMP_DIR.FullName
|
zstd -d --long=30 -c $DEPSHASH.tar | tar -xf - -C temp-cache
|
||||||
C:\ProgramData\Chocolatey\bin\7z.exe -y -snld20 x $src_cache -o"$TEMP_DIR_PATH"
|
rm -f $DEPSHASH.tar
|
||||||
|
|
||||||
- name: Move Src Cache (Windows)
|
- name: Move Src Cache (Windows)
|
||||||
if: ${{ inputs.target-platform == 'win' }}
|
if: ${{ inputs.target-platform == 'win' }}
|
||||||
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
with:
|
with:
|
||||||
timeout_minutes: 30
|
timeout_minutes: 30
|
||||||
max_attempts: 3
|
max_attempts: 3
|
||||||
@@ -112,9 +110,6 @@ runs:
|
|||||||
Write-Host "Relocating Cache"
|
Write-Host "Relocating Cache"
|
||||||
Remove-Item -Recurse -Force src
|
Remove-Item -Recurse -Force src
|
||||||
Move-Item temp-cache\src src
|
Move-Item temp-cache\src src
|
||||||
|
|
||||||
Write-Host "Deleting zip file"
|
|
||||||
Remove-Item -Force $src_cache
|
|
||||||
}
|
}
|
||||||
if (-Not (Test-Path "src\third_party\blink")) {
|
if (-Not (Test-Path "src\third_party\blink")) {
|
||||||
Write-Host "Cache was not correctly restored - exiting"
|
Write-Host "Cache was not correctly restored - exiting"
|
||||||
|
|||||||
8
.github/workflows/apply-patches.yml
vendored
8
.github/workflows/apply-patches.yml
vendored
@@ -71,3 +71,11 @@ jobs:
|
|||||||
uses: ./src/electron/.github/actions/checkout
|
uses: ./src/electron/.github/actions/checkout
|
||||||
with:
|
with:
|
||||||
target-platform: linux
|
target-platform: linux
|
||||||
|
- name: Upload Patch Conflict Fix
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||||
|
with:
|
||||||
|
name: update-patches
|
||||||
|
path: patches/update-patches.patch
|
||||||
|
if-no-files-found: ignore
|
||||||
|
archive: false
|
||||||
|
|||||||
2
.github/workflows/archaeologist-dig.yml
vendored
2
.github/workflows/archaeologist-dig.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.0.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup Node.js/npm
|
- name: Setup Node.js/npm
|
||||||
|
|||||||
6
.github/workflows/build-git-cache.yml
vendored
6
.github/workflows/build-git-cache.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -47,7 +47,7 @@ jobs:
|
|||||||
TARGET_OS: 'win'
|
TARGET_OS: 'win'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -72,7 +72,7 @@ jobs:
|
|||||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
35
.github/workflows/build.yml
vendored
35
.github/workflows/build.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
|||||||
build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
|
build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
|
||||||
docs-only: ${{ steps.set-output.outputs.docs-only }}
|
docs-only: ${{ steps.set-output.outputs.docs-only }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||||
@@ -124,7 +124,7 @@ jobs:
|
|||||||
build-image-sha: ${{ needs.setup.outputs.build-image-sha }}
|
build-image-sha: ${{ needs.setup.outputs.build-image-sha }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -156,7 +156,7 @@ jobs:
|
|||||||
build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
|
build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -188,7 +188,7 @@ jobs:
|
|||||||
build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
|
build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -431,3 +431,30 @@ jobs:
|
|||||||
- name: GitHub Actions Jobs Done
|
- name: GitHub Actions Jobs Done
|
||||||
run: |
|
run: |
|
||||||
echo "All GitHub Actions Jobs are done"
|
echo "All GitHub Actions Jobs are done"
|
||||||
|
|
||||||
|
check-signed-commits:
|
||||||
|
name: Check signed commits in green PR
|
||||||
|
needs: gha-done
|
||||||
|
if: ${{ contains(github.event.pull_request.labels.*.name, 'needs-signed-commits')}}
|
||||||
|
runs-on: ubuntu-slim
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Check signed commits in PR
|
||||||
|
uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1
|
||||||
|
with:
|
||||||
|
comment: |
|
||||||
|
⚠️ This PR contains unsigned commits. This repository enforces [commit signatures](https://docs.github.com/en/authentication/managing-commit-signature-verification)
|
||||||
|
for all incoming PRs. To get your PR merged, please sign those commits
|
||||||
|
(`git rebase --exec 'git commit -S --amend --no-edit -n' @{upstream}`) and force push them to this branch
|
||||||
|
(`git push --force-with-lease`)
|
||||||
|
|
||||||
|
For more information on signing commits, see GitHub's documentation on [Telling Git about your signing key](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key).
|
||||||
|
|
||||||
|
- name: Remove needs-signed-commits label
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||||
|
run: |
|
||||||
|
gh pr edit $PR_URL --remove-label needs-signed-commits
|
||||||
|
|||||||
32
.github/workflows/clean-orphaned-cache-uploads.yml
vendored
Normal file
32
.github/workflows/clean-orphaned-cache-uploads.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: Clean Orphaned Cache Uploads
|
||||||
|
|
||||||
|
# Description:
|
||||||
|
# Sweeps orphaned in-flight upload temp files left on the src-cache volumes
|
||||||
|
# by checkout/action.yml when its cp-to-share step dies before the rename.
|
||||||
|
# A successful upload finishes in minutes, so anything older than 4h is dead.
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 */4 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
clean-orphaned-uploads:
|
||||||
|
if: github.repository == 'electron/electron'
|
||||||
|
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
container:
|
||||||
|
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
|
||||||
|
options: --user root
|
||||||
|
volumes:
|
||||||
|
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||||
|
- /mnt/win-cache:/mnt/win-cache
|
||||||
|
steps:
|
||||||
|
- name: Remove Orphaned Upload Temp Files
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
find /mnt/cross-instance-cache -maxdepth 1 -type f -name '*.tar.upload-*' -mmin +240 -print -delete
|
||||||
|
find /mnt/win-cache -maxdepth 1 -type f -name '*.tar.upload-*' -mmin +240 -print -delete
|
||||||
2
.github/workflows/linux-publish.yml
vendored
2
.github/workflows/linux-publish.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
2
.github/workflows/macos-publish.yml
vendored
2
.github/workflows/macos-publish.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
|||||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
container: ${{ fromJSON(inputs.container) }}
|
container: ${{ fromJSON(inputs.container) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -35,7 +35,7 @@ jobs:
|
|||||||
- name: Generate DEPS Hash
|
- name: Generate DEPS Hash
|
||||||
run: |
|
run: |
|
||||||
node src/electron/script/generate-deps-hash.js
|
node src/electron/script/generate-deps-hash.js
|
||||||
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
|
DEPSHASH=v2-src-cache-$(cat src/electron/.depshash)
|
||||||
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
||||||
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
||||||
- name: Restore src cache via AKS
|
- name: Restore src cache via AKS
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
target-platform: linux
|
target-platform: linux
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
6
.github/workflows/pipeline-electron-lint.yml
vendored
6
.github/workflows/pipeline-electron-lint.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
container: ${{ fromJSON(inputs.container) }}
|
container: ${{ fromJSON(inputs.container) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
|
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)"
|
gn_version="$(curl -sL "https://raw.githubusercontent.com/chromium/chromium/refs/tags/${chromium_revision}/DEPS" | grep gn_version | head -n1 | cut -d\' -f4)"
|
||||||
|
|
||||||
cipd ensure -ensure-file - -root . <<-CIPD
|
cipd ensure -ensure-file - -root . <<-CIPD
|
||||||
\$ServiceURL https://chrome-infra-packages.appspot.com/
|
\$ServiceURL https://chrome-infra-packages.appspot.com/
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
|
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||||
|
|
||||||
mkdir -p src/buildtools
|
mkdir -p src/buildtools
|
||||||
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS
|
curl -sL "https://raw.githubusercontent.com/chromium/chromium/refs/tags/${chromium_revision}/buildtools/DEPS" > src/buildtools/DEPS
|
||||||
|
|
||||||
gclient sync --spec="solutions=[{'name':'src/buildtools','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':True},'managed':False}]"
|
gclient sync --spec="solutions=[{'name':'src/buildtools','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':True},'managed':False}]"
|
||||||
- name: Add problem matchers
|
- name: Add problem matchers
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir src
|
mkdir src
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -151,7 +151,7 @@ jobs:
|
|||||||
- name: Generate DEPS Hash
|
- name: Generate DEPS Hash
|
||||||
run: |
|
run: |
|
||||||
node src/electron/script/generate-deps-hash.js
|
node src/electron/script/generate-deps-hash.js
|
||||||
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
|
DEPSHASH=v2-src-cache-$(cat src/electron/.depshash)
|
||||||
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
||||||
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
||||||
- name: Restore src cache via AZCopy
|
- name: Restore src cache via AZCopy
|
||||||
@@ -163,7 +163,7 @@ jobs:
|
|||||||
if: ${{ inputs.target-platform == 'linux' }}
|
if: ${{ inputs.target-platform == 'linux' }}
|
||||||
uses: ./src/electron/.github/actions/restore-cache-aks
|
uses: ./src/electron/.github/actions/restore-cache-aks
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
container: ${{ fromJSON(inputs.check-container) }}
|
container: ${{ fromJSON(inputs.check-container) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -81,7 +81,7 @@ jobs:
|
|||||||
- name: Generate DEPS Hash
|
- name: Generate DEPS Hash
|
||||||
run: |
|
run: |
|
||||||
node src/electron/script/generate-deps-hash.js
|
node src/electron/script/generate-deps-hash.js
|
||||||
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
|
DEPSHASH=v2-src-cache-$(cat src/electron/.depshash)
|
||||||
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
||||||
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
||||||
- name: Restore src cache via AZCopy
|
- name: Restore src cache via AZCopy
|
||||||
@@ -115,7 +115,7 @@ jobs:
|
|||||||
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
|
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
|
||||||
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
|
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir src
|
mkdir src
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -160,7 +160,7 @@ jobs:
|
|||||||
- name: Generate DEPS Hash
|
- name: Generate DEPS Hash
|
||||||
run: |
|
run: |
|
||||||
node src/electron/script/generate-deps-hash.js
|
node src/electron/script/generate-deps-hash.js
|
||||||
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
|
DEPSHASH=v2-src-cache-$(cat src/electron/.depshash)
|
||||||
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
||||||
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
||||||
- name: Restore src cache via AZCopy
|
- name: Restore src cache via AZCopy
|
||||||
@@ -172,7 +172,7 @@ jobs:
|
|||||||
if: ${{ inputs.target-platform == 'linux' }}
|
if: ${{ inputs.target-platform == 'linux' }}
|
||||||
uses: ./src/electron/.github/actions/restore-cache-aks
|
uses: ./src/electron/.github/actions/restore-cache-aks
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ env:
|
|||||||
ELECTRON_OUT_DIR: Default
|
ELECTRON_OUT_DIR: Default
|
||||||
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
||||||
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
|
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
|
||||||
|
# @sentry/cli is only needed by release upload-symbols.py; skip the ~17MB CDN download on test jobs
|
||||||
|
SENTRYCLI_SKIP_DOWNLOAD: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
@@ -69,6 +71,7 @@ jobs:
|
|||||||
if: ${{ inputs.target-arch == 'arm' && inputs.target-platform == 'linux' }}
|
if: ${{ inputs.target-arch == 'arm' && inputs.target-platform == 'linux' }}
|
||||||
run: |
|
run: |
|
||||||
cp $(which node) /mnt/runner-externals/node20/bin/
|
cp $(which node) /mnt/runner-externals/node20/bin/
|
||||||
|
cp $(which node) /mnt/runner-externals/node24/bin/
|
||||||
- name: Setup Node.js/npm
|
- name: Setup Node.js/npm
|
||||||
if: ${{ inputs.target-platform == 'win' }}
|
if: ${{ inputs.target-platform == 'win' }}
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
|
||||||
@@ -118,7 +121,7 @@ jobs:
|
|||||||
if: ${{ inputs.target-platform == 'macos' }}
|
if: ${{ inputs.target-platform == 'macos' }}
|
||||||
run: sudo xcode-select --switch /Applications/Xcode_16.4.app
|
run: sudo xcode-select --switch /Applications/Xcode_16.4.app
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -190,15 +193,25 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd src/out/Default
|
cd src/out/Default
|
||||||
unzip -:o dist.zip
|
unzip -:o dist.zip
|
||||||
#- name: Import & Trust Self-Signed Codesigning Cert on MacOS
|
- name: Import & Trust Self-Signed Codesigning Cert on MacOS
|
||||||
# if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
|
if: ${{ inputs.target-platform == 'macos' }}
|
||||||
# run: |
|
run: |
|
||||||
# sudo security authorizationdb write com.apple.trust-settings.admin allow
|
cd src/electron
|
||||||
# cd src/electron
|
./script/codesign/generate-identity.sh
|
||||||
# ./script/codesign/generate-identity.sh
|
# Only sign on x64 — arm64 builds are already ad-hoc signed, and re-signing
|
||||||
|
# with an untrusted cert breaks macOS system integrations (e.g. dock bounce).
|
||||||
|
# Autoupdater tests sign their own fixture copies via signApp().
|
||||||
|
- name: Sign Electron.app for macOS tests
|
||||||
|
if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
|
||||||
|
run: |
|
||||||
|
identity=$(src/electron/script/codesign/get-trusted-identity.sh)
|
||||||
|
if [ -n "$identity" ]; then
|
||||||
|
codesign -s "$identity" --deep --force src/out/Default/Electron.app
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Run Electron Tests
|
- name: Run Electron Tests
|
||||||
shell: bash
|
shell: bash
|
||||||
|
timeout-minutes: 40
|
||||||
env:
|
env:
|
||||||
MOCHA_REPORTER: mocha-multi-reporters
|
MOCHA_REPORTER: mocha-multi-reporters
|
||||||
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
|
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
|
||||||
@@ -249,6 +262,19 @@ jobs:
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
- name: Take screenshot on timeout or cancellation
|
||||||
|
if: ${{ inputs.target-platform != 'linux' && (cancelled() || failure()) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
screenshot_dir="src/electron/spec/artifacts"
|
||||||
|
mkdir -p "$screenshot_dir"
|
||||||
|
screenshot_file="$screenshot_dir/screenshot-timeout-$(date +%Y%m%d%H%M%S).png"
|
||||||
|
if [ "${{ inputs.target-platform }}" = "macos" ]; then
|
||||||
|
screencapture -x "$screenshot_file" || true
|
||||||
|
elif [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||||
|
powershell -command "Add-Type -AssemblyName System.Windows.Forms; \$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds; \$bitmap = New-Object System.Drawing.Bitmap(\$screen.Width, \$screen.Height); \$graphics = [System.Drawing.Graphics]::FromImage(\$bitmap); \$graphics.CopyFromScreen(\$screen.Location, [System.Drawing.Point]::Empty, \$screen.Size); \$bitmap.Save('$screenshot_file')" || true
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Upload Test results to Datadog
|
- name: Upload Test results to Datadog
|
||||||
env:
|
env:
|
||||||
DD_ENV: ci
|
DD_ENV: ci
|
||||||
@@ -264,8 +290,8 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
if: always() && !cancelled()
|
if: always() && !cancelled()
|
||||||
- name: Upload Test Artifacts
|
- name: Upload Test Artifacts
|
||||||
if: always() && !cancelled()
|
if: always()
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
|
||||||
with:
|
with:
|
||||||
name: test_artifacts_${{ env.ARTIFACT_KEY }}_${{ matrix.shard }}
|
name: test_artifacts_${{ env.ARTIFACT_KEY }}_${{ matrix.shard }}
|
||||||
path: src/electron/spec/artifacts
|
path: src/electron/spec/artifacts
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ env:
|
|||||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||||
ELECTRON_OUT_DIR: Default
|
ELECTRON_OUT_DIR: Default
|
||||||
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
||||||
|
# @sentry/cli is only needed by release upload-symbols.py; skip the ~17MB CDN download on test jobs
|
||||||
|
SENTRYCLI_SKIP_DOWNLOAD: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
node-tests:
|
node-tests:
|
||||||
@@ -50,7 +52,7 @@ jobs:
|
|||||||
container: ${{ fromJSON(inputs.test-container) }}
|
container: ${{ fromJSON(inputs.test-container) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -106,7 +108,7 @@ jobs:
|
|||||||
container: ${{ fromJSON(inputs.test-container) }}
|
container: ${{ fromJSON(inputs.test-container) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
35
.github/workflows/pull-request-opened-synchronized.yml
vendored
Normal file
35
.github/workflows/pull-request-opened-synchronized.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: Pull Request Opened/Synchronized
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, synchronize]
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-signed-commits:
|
||||||
|
name: Check signed commits in PR
|
||||||
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'needs-signed-commits')}}
|
||||||
|
runs-on: ubuntu-slim
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Check signed commits in PR
|
||||||
|
uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1
|
||||||
|
with:
|
||||||
|
comment: |
|
||||||
|
⚠️ This PR contains unsigned commits. This repository enforces [commit signatures](https://docs.github.com/en/authentication/managing-commit-signature-verification)
|
||||||
|
for all incoming PRs. To get your PR merged, please sign those commits
|
||||||
|
(`git rebase --exec 'git commit -S --amend --no-edit -n' @{upstream}`) and force push them to this branch
|
||||||
|
(`git push --force-with-lease`)
|
||||||
|
|
||||||
|
For more information on signing commits, see GitHub's documentation on [Telling Git about your signing key](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key).
|
||||||
|
|
||||||
|
- name: Add needs-signed-commits label
|
||||||
|
if: ${{ failure() }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||||
|
run: |
|
||||||
|
gh pr edit $PR_URL --add-label needs-signed-commits
|
||||||
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/windows-publish.yml
vendored
2
.github/workflows/windows-publish.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
|||||||
build-image-sha: ${{ inputs.build-image-sha }}
|
build-image-sha: ${{ inputs.build-image-sha }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Electron
|
- name: Checkout Electron
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
path: src/electron
|
path: src/electron
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
@@ -9,4 +9,8 @@ npmMinimalAgeGate: 10080
|
|||||||
npmPreapprovedPackages:
|
npmPreapprovedPackages:
|
||||||
- "@electron/*"
|
- "@electron/*"
|
||||||
|
|
||||||
|
httpProxy: "${HTTP_PROXY:-}"
|
||||||
|
|
||||||
|
httpsProxy: "${HTTPS_PROXY:-}"
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-4.12.0.cjs
|
yarnPath: .yarn/releases/yarn-4.12.0.cjs
|
||||||
|
|||||||
2
DEPS
2
DEPS
@@ -4,7 +4,7 @@ vars = {
|
|||||||
'chromium_version':
|
'chromium_version':
|
||||||
'142.0.7444.265',
|
'142.0.7444.265',
|
||||||
'node_version':
|
'node_version':
|
||||||
'v22.22.0',
|
'v22.22.1',
|
||||||
'nan_version':
|
'nan_version':
|
||||||
'e14bdcd1f72d62bca1d541b66da43130384ec213',
|
'e14bdcd1f72d62bca1d541b66da43130384ec213',
|
||||||
'squirrel.mac_version':
|
'squirrel.mac_version':
|
||||||
|
|||||||
@@ -345,6 +345,11 @@ Affects the default output directory of [v8.setHeapSnapshotNearHeapLimit](https:
|
|||||||
|
|
||||||
Disable exposition of [Navigator API][] on the global scope from Node.js.
|
Disable exposition of [Navigator API][] on the global scope from Node.js.
|
||||||
|
|
||||||
|
### `--experimental-transform-types`
|
||||||
|
|
||||||
|
Enables the [transformation](https://nodejs.org/api/typescript.html#type-stripping)
|
||||||
|
of TypeScript-only syntax into JavaScript code.
|
||||||
|
|
||||||
## Chromium Flags
|
## Chromium Flags
|
||||||
|
|
||||||
There isn't a documented list of all Chromium switches, but there are a few ways to find them.
|
There isn't a documented list of all Chromium switches, but there are a few ways to find them.
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ The `desktopCapturer` module has the following methods:
|
|||||||
Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured.
|
Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
<!-- markdownlint-disable-next-line MD032 -->
|
||||||
> * Capturing audio requires `NSAudioCaptureUsageDescription` Info.plist key on macOS 14.2 Sonoma and higher - [read more](#macos-versions-142-or-higher).
|
> * Capturing audio requires `NSAudioCaptureUsageDescription` Info.plist key on macOS 14.2 Sonoma and higher - [read more](#macos-versions-142-or-higher).
|
||||||
> * Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, which can detected by [`systemPreferences.getMediaAccessStatus`][].
|
> * Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, which can detected by [`systemPreferences.getMediaAccessStatus`][].
|
||||||
|
|
||||||
@@ -109,30 +109,41 @@ Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`Desktop
|
|||||||
|
|
||||||
PipeWire supports a single capture for both screens and windows. If you request the window and screen type, the selected source will be returned as a window capture.
|
PipeWire supports a single capture for both screens and windows. If you request the window and screen type, the selected source will be returned as a window capture.
|
||||||
|
|
||||||
---
|
### macOS versions 14.2 or higher
|
||||||
|
|
||||||
### MacOS versions 14.2 or higher
|
`NSAudioCaptureUsageDescription` Info.plist key must be added in order for audio to be captured by
|
||||||
|
`desktopCapturer`. If instead you are running Electron from another program like a terminal or IDE
|
||||||
`NSAudioCaptureUsageDescription` Info.plist key must be added in-order for audio to be captured by `desktopCapturer`. If instead you are running electron from another program like a terminal or IDE then that parent program must contain the Info.plist key.
|
then that parent program must contain the Info.plist key.
|
||||||
|
|
||||||
This is in order to facillitate use of Apple's new [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps#Configure-the-sample-code-project) by Chromium.
|
This is in order to facillitate use of Apple's new [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps#Configure-the-sample-code-project) by Chromium.
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Failure of `desktopCapturer` to start an audio stream due to `NSAudioCaptureUsageDescription` permission not present will still create a dead audio stream however no warnings or errors are displayed.
|
> Failure of `desktopCapturer` to start an audio stream due to `NSAudioCaptureUsageDescription`
|
||||||
|
> permission not present will still create a dead audio stream however no warnings or errors are
|
||||||
|
> displayed.
|
||||||
|
|
||||||
As of electron `v39.0.0-beta.4` Chromium [made Apple's new `CoreAudio Tap API` the default](https://source.chromium.org/chromium/chromium/src/+/ad17e8f8b93d5f34891b06085d373a668918255e) for desktop audio capture. There is no fallback to the older `Screen & System Audio Recording` permissions system even if [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps) stream creation fails.
|
As of Electron `v39.0.0-beta.4`, Chromium [made Apple's new `CoreAudio Tap API` the default](https://source.chromium.org/chromium/chromium/src/+/ad17e8f8b93d5f34891b06085d373a668918255e)
|
||||||
|
for desktop audio capture. There is no fallback to the older `Screen & System Audio Recording`
|
||||||
|
permissions system even if [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps) stream creation fails.
|
||||||
|
|
||||||
If you need to continue using `Screen & System Audio Recording` permissions for `desktopCapturer` on macOS versions 14.2 and later, you can apply a chromium feature flag to force use of that older permissions system:
|
If you need to continue using `Screen & System Audio Recording` permissions for `desktopCapturer`
|
||||||
|
on macOS versions 14.2 and later, you can apply a Chromium feature flag to force use of that older
|
||||||
|
permissions system:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// main.js (right beneath your require/import statments)
|
// main.js (right beneath your require/import statments)
|
||||||
app.commandLine.appendSwitch('disable-features', 'MacCatapLoopbackAudioForScreenShare')
|
app.commandLine.appendSwitch('disable-features', 'MacCatapLoopbackAudioForScreenShare')
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
### macOS versions 12.7.6 or lower
|
||||||
|
|
||||||
### MacOS versions 12.7.6 or lower
|
`navigator.mediaDevices.getUserMedia` does not work on macOS versions 12.7.6 and prior for audio
|
||||||
|
capture due to a fundamental limitation whereby apps that want to access the system's audio require
|
||||||
|
a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html).
|
||||||
|
Chromium, and by extension Electron, does not provide this. Only in macOS 13 and onwards does Apple
|
||||||
|
provide APIs to capture desktop audio without the need for a signed kernel extension.
|
||||||
|
|
||||||
`navigator.mediaDevices.getUserMedia` does not work on macOS versions 12.7.6 and prior for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html). Chromium, and by extension Electron, does not provide this. Only in macOS 13 and onwards does Apple provide APIs to capture desktop audio without the need for a signed kernel extension.
|
It is possible to circumvent this limitation by capturing system audio with another macOS app like
|
||||||
|
[BlackHole](https://existential.audio/blackhole/) or [Soundflower](https://rogueamoeba.com/freebies/soundflower/)
|
||||||
It is possible to circumvent this limitation by capturing system audio with another macOS app like [BlackHole](https://existential.audio/blackhole/) or [Soundflower](https://rogueamoeba.com/freebies/soundflower/) and passing it through a virtual audio input device. This virtual device can then be queried with `navigator.mediaDevices.getUserMedia`.
|
and passing it through a virtual audio input device. This virtual device can then be queried
|
||||||
|
with `navigator.mediaDevices.getUserMedia`.
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ Returns [`Point`](structures/point.md)
|
|||||||
|
|
||||||
The current absolute position of the mouse pointer.
|
The current absolute position of the mouse pointer.
|
||||||
|
|
||||||
|
Not supported on Wayland (Linux).
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> The return value is a DIP point, not a screen physical point.
|
> The return value is a DIP point, not a screen physical point.
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ $ ../../electron/script/git-import-patches ../../electron/patches/node
|
|||||||
$ ../../electron/script/git-export-patches -o ../../electron/patches/node
|
$ ../../electron/script/git-export-patches -o ../../electron/patches/node
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that `git-import-patches` will mark the commit that was `HEAD` when it was run as `refs/patches/upstream-head`. This lets you keep track of which commits are from Electron patches (those that come after `refs/patches/upstream-head`) and which commits are in upstream (those before `refs/patches/upstream-head`).
|
Note that `git-import-patches` will mark the commit that was `HEAD` when it was run as `refs/patches/upstream-head` (and a checkout-specific `refs/patches/upstream-head-<hash>` so that gclient worktrees sharing a `.git/refs` directory don't clobber each other). This lets you keep track of which commits are from Electron patches (those that come after `refs/patches/upstream-head`) and which commits are in upstream (those before `refs/patches/upstream-head`).
|
||||||
|
|
||||||
#### Resolving conflicts
|
#### Resolving conflicts
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ filenames = {
|
|||||||
"shell/browser/win/scoped_hstring.h",
|
"shell/browser/win/scoped_hstring.h",
|
||||||
"shell/common/api/electron_api_native_image_win.cc",
|
"shell/common/api/electron_api_native_image_win.cc",
|
||||||
"shell/common/application_info_win.cc",
|
"shell/common/application_info_win.cc",
|
||||||
|
"shell/common/command_line_util_win.cc",
|
||||||
|
"shell/common/command_line_util_win.h",
|
||||||
"shell/common/language_util_win.cc",
|
"shell/common/language_util_win.cc",
|
||||||
"shell/common/node_bindings_win.cc",
|
"shell/common/node_bindings_win.cc",
|
||||||
"shell/common/node_bindings_win.h",
|
"shell/common/node_bindings_win.h",
|
||||||
|
|||||||
@@ -8,13 +8,19 @@ const {
|
|||||||
isOnBatteryPower
|
isOnBatteryPower
|
||||||
} = process._linkedBinding('electron_browser_power_monitor');
|
} = process._linkedBinding('electron_browser_power_monitor');
|
||||||
|
|
||||||
|
// Hold the native PowerMonitor at module level so it is never garbage-collected
|
||||||
|
// while this module is alive. The C++ side registers OS-level callbacks (HWND
|
||||||
|
// user-data on Windows, shutdown handler on macOS, notification observers) that
|
||||||
|
// prevent safe collection of the C++ wrapper while those registrations exist.
|
||||||
|
let pm: any;
|
||||||
|
|
||||||
class PowerMonitor extends EventEmitter implements Electron.PowerMonitor {
|
class PowerMonitor extends EventEmitter implements Electron.PowerMonitor {
|
||||||
constructor () {
|
constructor () {
|
||||||
super();
|
super();
|
||||||
// Don't start the event source until both a) the app is ready and b)
|
// Don't start the event source until both a) the app is ready and b)
|
||||||
// there's a listener registered for a powerMonitor event.
|
// there's a listener registered for a powerMonitor event.
|
||||||
this.once('newListener', () => {
|
this.once('newListener', () => {
|
||||||
const pm = createPowerMonitor();
|
pm = createPowerMonitor();
|
||||||
pm.emit = this.emit.bind(this);
|
pm.emit = this.emit.bind(this);
|
||||||
|
|
||||||
if (process.platform === 'linux') {
|
if (process.platform === 'linux') {
|
||||||
|
|||||||
@@ -777,8 +777,7 @@ WebContents.prototype._init = function () {
|
|||||||
const originCounts = new Map<string, number>();
|
const originCounts = new Map<string, number>();
|
||||||
const openDialogs = new Set<AbortController>();
|
const openDialogs = new Set<AbortController>();
|
||||||
this.on('-run-dialog', async (info, callback) => {
|
this.on('-run-dialog', async (info, callback) => {
|
||||||
const originUrl = new URL(info.frame.url);
|
const origin = info.frame.origin === 'file://' ? info.frame.url : info.frame.origin;
|
||||||
const origin = originUrl.protocol === 'file:' ? originUrl.href : originUrl.origin;
|
|
||||||
if ((originCounts.get(origin) ?? 0) < 0) return callback(false, '');
|
if ((originCounts.get(origin) ?? 0) < 0) return callback(false, '');
|
||||||
|
|
||||||
const prefs = this.getLastWebPreferences();
|
const prefs = this.getLastWebPreferences();
|
||||||
|
|||||||
@@ -17,11 +17,6 @@ export type WindowOpenArgs = {
|
|||||||
features: string,
|
features: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const frameNamesToWindow = new Map<string, WebContents>();
|
|
||||||
const registerFrameNameToGuestWindow = (name: string, webContents: WebContents) => frameNamesToWindow.set(name, webContents);
|
|
||||||
const unregisterFrameName = (name: string) => frameNamesToWindow.delete(name);
|
|
||||||
const getGuestWebContentsByFrameName = (name: string) => frameNamesToWindow.get(name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `openGuestWindow` is called to create and setup event handling for the new
|
* `openGuestWindow` is called to create and setup event handling for the new
|
||||||
* window.
|
* window.
|
||||||
@@ -47,20 +42,6 @@ export function openGuestWindow ({ embedder, guest, referrer, disposition, postD
|
|||||||
...overrideBrowserWindowOptions
|
...overrideBrowserWindowOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
// To spec, subsequent window.open calls with the same frame name (`target` in
|
|
||||||
// spec parlance) will reuse the previous window.
|
|
||||||
// https://html.spec.whatwg.org/multipage/window-object.html#apis-for-creating-and-navigating-browsing-contexts-by-name
|
|
||||||
const existingWebContents = getGuestWebContentsByFrameName(frameName);
|
|
||||||
if (existingWebContents) {
|
|
||||||
if (existingWebContents.isDestroyed()) {
|
|
||||||
// FIXME(t57ser): The webContents is destroyed for some reason, unregister the frame name
|
|
||||||
unregisterFrameName(frameName);
|
|
||||||
} else {
|
|
||||||
existingWebContents.loadURL(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (createWindow) {
|
if (createWindow) {
|
||||||
const webContents = createWindow({
|
const webContents = createWindow({
|
||||||
webContents: guest,
|
webContents: guest,
|
||||||
@@ -72,7 +53,7 @@ export function openGuestWindow ({ embedder, guest, referrer, disposition, postD
|
|||||||
throw new Error('Invalid webContents. Created window should be connected to webContents passed with options object.');
|
throw new Error('Invalid webContents. Created window should be connected to webContents passed with options object.');
|
||||||
}
|
}
|
||||||
|
|
||||||
handleWindowLifecycleEvents({ embedder, frameName, guest, outlivesOpener });
|
handleWindowLifecycleEvents({ embedder, guest, outlivesOpener });
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -96,7 +77,7 @@ export function openGuestWindow ({ embedder, guest, referrer, disposition, postD
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleWindowLifecycleEvents({ embedder, frameName, guest: window.webContents, outlivesOpener });
|
handleWindowLifecycleEvents({ embedder, guest: window.webContents, outlivesOpener });
|
||||||
|
|
||||||
embedder.emit('did-create-window', window, { url, frameName, options: browserWindowOptions, disposition, referrer, postData });
|
embedder.emit('did-create-window', window, { url, frameName, options: browserWindowOptions, disposition, referrer, postData });
|
||||||
}
|
}
|
||||||
@@ -107,10 +88,9 @@ export function openGuestWindow ({ embedder, guest, referrer, disposition, postD
|
|||||||
* too is the guest destroyed; this is Electron convention and isn't based in
|
* too is the guest destroyed; this is Electron convention and isn't based in
|
||||||
* browser behavior.
|
* browser behavior.
|
||||||
*/
|
*/
|
||||||
const handleWindowLifecycleEvents = function ({ embedder, guest, frameName, outlivesOpener }: {
|
const handleWindowLifecycleEvents = function ({ embedder, guest, outlivesOpener }: {
|
||||||
embedder: WebContents,
|
embedder: WebContents,
|
||||||
guest: WebContents,
|
guest: WebContents,
|
||||||
frameName: string,
|
|
||||||
outlivesOpener: boolean
|
outlivesOpener: boolean
|
||||||
}) {
|
}) {
|
||||||
const closedByEmbedder = function () {
|
const closedByEmbedder = function () {
|
||||||
@@ -128,13 +108,6 @@ const handleWindowLifecycleEvents = function ({ embedder, guest, frameName, outl
|
|||||||
embedder.once('current-render-view-deleted' as any, closedByEmbedder);
|
embedder.once('current-render-view-deleted' as any, closedByEmbedder);
|
||||||
}
|
}
|
||||||
guest.once('destroyed', closedByUser);
|
guest.once('destroyed', closedByUser);
|
||||||
|
|
||||||
if (frameName) {
|
|
||||||
registerFrameNameToGuestWindow(frameName, guest);
|
|
||||||
guest.once('destroyed', function () {
|
|
||||||
unregisterFrameName(frameName);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Security options that child windows will always inherit from parent windows
|
// Security options that child windows will always inherit from parent windows
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ export function invokeInWebContents<T> (sender: Electron.WebContents, command: s
|
|||||||
const requestId = ++nextId;
|
const requestId = ++nextId;
|
||||||
const channel = `${command}_RESPONSE_${requestId}`;
|
const channel = `${command}_RESPONSE_${requestId}`;
|
||||||
ipcMainInternal.on(channel, function handler (event, error: Error, result: any) {
|
ipcMainInternal.on(channel, function handler (event, error: Error, result: any) {
|
||||||
if (event.type === 'frame' && event.sender !== sender) {
|
if (event.type !== 'frame' || event.sender !== sender) {
|
||||||
console.error(`Reply to ${command} sent by unexpected WebContents (${event.sender.id})`);
|
console.error(`Reply to ${command} sent by unexpected sender`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1232,6 +1232,8 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
|||||||
// has filesystem caching.
|
// has filesystem caching.
|
||||||
overrideAPI(fs, 'copyFile');
|
overrideAPI(fs, 'copyFile');
|
||||||
overrideAPISync(fs, 'copyFileSync');
|
overrideAPISync(fs, 'copyFileSync');
|
||||||
|
overrideAPI(fs, 'cp');
|
||||||
|
overrideAPISync(fs, 'cpSync');
|
||||||
|
|
||||||
overrideAPI(fs, 'open');
|
overrideAPI(fs, 'open');
|
||||||
overrideAPISync(process, 'dlopen', 1);
|
overrideAPISync(process, 'dlopen', 1);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ if ((globalThis as any).blinkfetch) {
|
|||||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
|
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
||||||
|
delete (globalThis as any)[`blink${key}`];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,14 @@ export default contextBridge;
|
|||||||
|
|
||||||
export const internalContextBridge = {
|
export const internalContextBridge = {
|
||||||
contextIsolationEnabled: process.contextIsolated,
|
contextIsolationEnabled: process.contextIsolated,
|
||||||
|
tryOverrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
|
||||||
|
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true, true);
|
||||||
|
},
|
||||||
overrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
|
overrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
|
||||||
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false);
|
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false, false);
|
||||||
},
|
},
|
||||||
overrideGlobalValueWithDynamicPropsFromIsolatedWorld: (keys: string[], value: any) => {
|
overrideGlobalValueWithDynamicPropsFromIsolatedWorld: (keys: string[], value: any) => {
|
||||||
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true);
|
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true, false);
|
||||||
},
|
},
|
||||||
overrideGlobalPropertyFromIsolatedWorld: (keys: string[], getter: Function, setter?: Function) => {
|
overrideGlobalPropertyFromIsolatedWorld: (keys: string[], getter: Function, setter?: Function) => {
|
||||||
return binding._overrideGlobalPropertyFromIsolatedWorld(keys, getter, setter || null);
|
return binding._overrideGlobalPropertyFromIsolatedWorld(keys, getter, setter || null);
|
||||||
|
|||||||
@@ -11,14 +11,12 @@ const { contextIsolationEnabled } = internalContextBridge;
|
|||||||
* 1) Use menu API to show context menu.
|
* 1) Use menu API to show context menu.
|
||||||
*/
|
*/
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
if (window.InspectorFrontendHost) {
|
if (contextIsolationEnabled) {
|
||||||
if (contextIsolationEnabled) {
|
internalContextBridge.tryOverrideGlobalValueFromIsolatedWorld([
|
||||||
internalContextBridge.overrideGlobalValueFromIsolatedWorld([
|
'InspectorFrontendHost', 'showContextMenuAtPoint'
|
||||||
'InspectorFrontendHost', 'showContextMenuAtPoint'
|
], createMenu);
|
||||||
], createMenu);
|
} else {
|
||||||
} else {
|
window.InspectorFrontendHost!.showContextMenuAtPoint = createMenu;
|
||||||
window.InspectorFrontendHost.showContextMenuAtPoint = createMenu;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ if ((globalThis as any).blinkfetch) {
|
|||||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
|
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
||||||
|
delete (globalThis as any)[`blink${key}`];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"@electron/typescript-definitions": "^9.1.2",
|
"@electron/typescript-definitions": "^9.1.2",
|
||||||
"@octokit/rest": "^20.1.2",
|
"@octokit/rest": "^20.1.2",
|
||||||
"@primer/octicons": "^10.0.0",
|
"@primer/octicons": "^10.0.0",
|
||||||
|
"@sentry/cli": "1.72.0",
|
||||||
"@types/minimist": "^1.2.5",
|
"@types/minimist": "^1.2.5",
|
||||||
"@types/node": "^22.7.7",
|
"@types/node": "^22.7.7",
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.8",
|
||||||
@@ -150,6 +151,9 @@
|
|||||||
"spec/fixtures/native-addon/*"
|
"spec/fixtures/native-addon/*"
|
||||||
],
|
],
|
||||||
"dependenciesMeta": {
|
"dependenciesMeta": {
|
||||||
|
"@sentry/cli": {
|
||||||
|
"built": true
|
||||||
|
},
|
||||||
"abstract-socket": {
|
"abstract-socket": {
|
||||||
"built": true
|
"built": true
|
||||||
}
|
}
|
||||||
|
|||||||
2
patches/angle/.patches
Normal file
2
patches/angle/.patches
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
cherry-pick-a08731cf6d70.patch
|
||||||
|
cherry-pick-bf6dd974238b.patch
|
||||||
239
patches/angle/cherry-pick-a08731cf6d70.patch
Normal file
239
patches/angle/cherry-pick-a08731cf6d70.patch
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||||
|
Date: Thu, 19 Feb 2026 14:42:08 -0500
|
||||||
|
Subject: Vulkan: Avoid overflow in texture size calculation
|
||||||
|
|
||||||
|
Bug: chromium:485622239
|
||||||
|
Change-Id: Idf9847afa0aa2e72b6433ac8348ae2820c1ad8c5
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7595734
|
||||||
|
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
|
||||||
|
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||||
|
index 0459bb7fc8a415e21563de813a306d1801f1a39e..8b152a581d4ebae1cc4c0cb0a95d02434a43f24d 100644
|
||||||
|
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||||
|
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||||
|
@@ -3069,8 +3069,17 @@ angle::Result TextureVk::reinitImageAsRenderable(ContextVk *contextVk, const vk:
|
||||||
|
// invalidate must be called after wait for finish.
|
||||||
|
ANGLE_TRY(srcBuffer->invalidate(renderer));
|
||||||
|
|
||||||
|
- size_t dstBufferSize = sourceBox.width * sourceBox.height * sourceBox.depth *
|
||||||
|
- dstFormat.pixelBytes * layerCount;
|
||||||
|
+ // Use size_t calculations to avoid 32-bit overflows. Note that the dimensions are bound by
|
||||||
|
+ // the maximums specified in Constants.h, and that gl::Box members are signed 32-bit
|
||||||
|
+ // integers.
|
||||||
|
+ static_assert(gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE *
|
||||||
|
+ gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE <
|
||||||
|
+ std::numeric_limits<int32_t>::max());
|
||||||
|
+ size_t dstBufferSize = sourceBox.width * sourceBox.height;
|
||||||
|
+ static_assert(gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE *
|
||||||
|
+ gl::IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS * 16 <
|
||||||
|
+ std::numeric_limits<int32_t>::max());
|
||||||
|
+ dstBufferSize *= sourceBox.depth * dstFormat.pixelBytes * layerCount;
|
||||||
|
|
||||||
|
// Allocate memory in the destination texture for the copy/conversion.
|
||||||
|
uint8_t *dstData = nullptr;
|
||||||
|
diff --git a/src/tests/gl_tests/FramebufferTest.cpp b/src/tests/gl_tests/FramebufferTest.cpp
|
||||||
|
index 020a0416881e85ebff9a6fa2f902e61f899477b9..f72f1a7674eab758487be0bf30bee5150a0e7508 100644
|
||||||
|
--- a/src/tests/gl_tests/FramebufferTest.cpp
|
||||||
|
+++ b/src/tests/gl_tests/FramebufferTest.cpp
|
||||||
|
@@ -8894,6 +8894,62 @@ TEST_P(FramebufferTest_ES31, MixesMultisampleTextureRenderbuffer)
|
||||||
|
ASSERT_GL_NO_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Test that 2D array texture size calculation doesn't overflow internally when rendering to it. An
|
||||||
|
+// RGB format is used which is often emualted with RGBA.
|
||||||
|
+//
|
||||||
|
+// Practically we cannot run this test. On most configurations, allocating a 4GB texture fails due
|
||||||
|
+// to internal driver limitations. On the few configs that the test actually runs, allocating such
|
||||||
|
+// large memory leads to instability.
|
||||||
|
+TEST_P(FramebufferTest_ES3, DISABLED_MaxSize2DArrayNoOverflow)
|
||||||
|
+{
|
||||||
|
+ GLint maxTexture2DSize;
|
||||||
|
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexture2DSize);
|
||||||
|
+
|
||||||
|
+ maxTexture2DSize = std::min(maxTexture2DSize, 16384);
|
||||||
|
+
|
||||||
|
+ // Create a 2D array texture with RGB format. Every layer is going to take 1GB of memory (if
|
||||||
|
+ // emulated with RGBA), so only create 4 layers of it (for a total of 4GB of memory). If 32-bit
|
||||||
|
+ // math is involved when calculating sizes related to this texture, they will overflow.
|
||||||
|
+ constexpr uint32_t kLayers = 4;
|
||||||
|
+ GLTexture tex;
|
||||||
|
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
|
||||||
|
+ glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, maxTexture2DSize, maxTexture2DSize, kLayers);
|
||||||
|
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
+
|
||||||
|
+ // Initialize the texture so its content is considered valid and worth preserving.
|
||||||
|
+ constexpr int kValidSubsectionWidth = 16;
|
||||||
|
+ constexpr int kValidSubsectionHeight = 20;
|
||||||
|
+ std::vector<GLColorRGB> data(kValidSubsectionWidth * kValidSubsectionHeight,
|
||||||
|
+ GLColorRGB(0, 255, 0));
|
||||||
|
+ for (uint32_t layer = 0; layer < kLayers; ++layer)
|
||||||
|
+ {
|
||||||
|
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, kValidSubsectionWidth,
|
||||||
|
+ kValidSubsectionHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, data.data());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Draw with the texture, making sure it's initialized and data is flushed.
|
||||||
|
+ ANGLE_GL_PROGRAM(drawTex2DArray, essl3_shaders::vs::Texture2DArray(),
|
||||||
|
+ essl3_shaders::fs::Texture2DArray());
|
||||||
|
+ drawQuad(drawTex2DArray, essl3_shaders::PositionAttrib(), 0.5f);
|
||||||
|
+
|
||||||
|
+ // Bind a framebuffer to the texture and render into it. In some backends, the texture is
|
||||||
|
+ // recreated to RGBA to be renderable.
|
||||||
|
+ GLFramebuffer fbo;
|
||||||
|
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
+ glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
|
||||||
|
+
|
||||||
|
+ ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
|
||||||
|
+ glViewport(0, 0, kValidSubsectionWidth / 2, kValidSubsectionHeight);
|
||||||
|
+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
|
||||||
|
+
|
||||||
|
+ EXPECT_PIXEL_RECT_EQ(0, 0, kValidSubsectionWidth / 2, kValidSubsectionHeight, GLColor::red);
|
||||||
|
+ EXPECT_PIXEL_RECT_EQ(kValidSubsectionWidth / 2, 0,
|
||||||
|
+ kValidSubsectionWidth - kValidSubsectionWidth / 2, kValidSubsectionHeight,
|
||||||
|
+ GLColor::green);
|
||||||
|
+ ASSERT_GL_NO_ERROR();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
ANGLE_INSTANTIATE_TEST_ES2_AND(AddMockTextureNoRenderTargetTest,
|
||||||
|
ES2_D3D9().enable(Feature::AddMockTextureNoRenderTarget),
|
||||||
|
ES2_D3D11().enable(Feature::AddMockTextureNoRenderTarget));
|
||||||
|
diff --git a/src/tests/gl_tests/VulkanImageTest.cpp b/src/tests/gl_tests/VulkanImageTest.cpp
|
||||||
|
index 2f06e2d5d9240371865f0adccc80f0d622c2199a..87e7482d971851c3bfd78818ce8b9ffc5e4bfa4d 100644
|
||||||
|
--- a/src/tests/gl_tests/VulkanImageTest.cpp
|
||||||
|
+++ b/src/tests/gl_tests/VulkanImageTest.cpp
|
||||||
|
@@ -677,8 +677,8 @@ TEST_P(VulkanMemoryTest, AllocateVMAImageAfterFreeing2DArrayGarbageWhenDeviceOOM
|
||||||
|
kTextureHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, textureColor.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
- ANGLE_GL_PROGRAM(drawTex2DArray, essl1_shaders::vs::Texture2DArray(),
|
||||||
|
- essl1_shaders::fs::Texture2DArray());
|
||||||
|
+ ANGLE_GL_PROGRAM(drawTex2DArray, essl3_shaders::vs::Texture2DArray(),
|
||||||
|
+ essl3_shaders::fs::Texture2DArray());
|
||||||
|
drawQuad(drawTex2DArray, essl1_shaders::PositionAttrib(), 0.5f);
|
||||||
|
|
||||||
|
// Fill up the device memory until we start allocating on the system memory.
|
||||||
|
diff --git a/util/shader_utils.cpp b/util/shader_utils.cpp
|
||||||
|
index 45f5461c36820c26ea1718e575bde65f1e181548..84ba2674884787edb43972f1bda970b474c58fd9 100644
|
||||||
|
--- a/util/shader_utils.cpp
|
||||||
|
+++ b/util/shader_utils.cpp
|
||||||
|
@@ -582,18 +582,6 @@ void main()
|
||||||
|
})";
|
||||||
|
}
|
||||||
|
|
||||||
|
-const char *Texture2DArray()
|
||||||
|
-{
|
||||||
|
- return R"(#version 300 es
|
||||||
|
-out vec2 v_texCoord;
|
||||||
|
-in vec4 a_position;
|
||||||
|
-void main()
|
||||||
|
-{
|
||||||
|
- gl_Position = vec4(a_position.xy, 0.0, 1.0);
|
||||||
|
- v_texCoord = (a_position.xy * 0.5) + 0.5;
|
||||||
|
-})";
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
} // namespace vs
|
||||||
|
|
||||||
|
namespace fs
|
||||||
|
@@ -691,20 +679,6 @@ void main()
|
||||||
|
})";
|
||||||
|
}
|
||||||
|
|
||||||
|
-const char *Texture2DArray()
|
||||||
|
-{
|
||||||
|
- return R"(#version 300 es
|
||||||
|
-precision highp float;
|
||||||
|
-uniform highp sampler2DArray tex2DArray;
|
||||||
|
-uniform int slice;
|
||||||
|
-in vec2 v_texCoord;
|
||||||
|
-out vec4 fragColor;
|
||||||
|
-void main()
|
||||||
|
-{
|
||||||
|
- fragColor = texture(tex2DArray, vec3(v_texCoord, float(slice)));
|
||||||
|
-})";
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
} // namespace fs
|
||||||
|
} // namespace essl1_shaders
|
||||||
|
|
||||||
|
@@ -789,6 +763,18 @@ void main()
|
||||||
|
})";
|
||||||
|
}
|
||||||
|
|
||||||
|
+const char *Texture2DArray()
|
||||||
|
+{
|
||||||
|
+ return R"(#version 300 es
|
||||||
|
+out vec2 v_texCoord;
|
||||||
|
+in vec4 a_position;
|
||||||
|
+void main()
|
||||||
|
+{
|
||||||
|
+ gl_Position = vec4(a_position.xy, 0.0, 1.0);
|
||||||
|
+ v_texCoord = (a_position.xy * 0.5) + 0.5;
|
||||||
|
+})";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
} // namespace vs
|
||||||
|
|
||||||
|
namespace fs
|
||||||
|
@@ -846,6 +832,20 @@ void main()
|
||||||
|
})";
|
||||||
|
}
|
||||||
|
|
||||||
|
+const char *Texture2DArray()
|
||||||
|
+{
|
||||||
|
+ return R"(#version 300 es
|
||||||
|
+precision highp float;
|
||||||
|
+uniform highp sampler2DArray tex2DArray;
|
||||||
|
+uniform int slice;
|
||||||
|
+in vec2 v_texCoord;
|
||||||
|
+out vec4 fragColor;
|
||||||
|
+void main()
|
||||||
|
+{
|
||||||
|
+ fragColor = texture(tex2DArray, vec3(v_texCoord, float(slice)));
|
||||||
|
+})";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
} // namespace fs
|
||||||
|
} // namespace essl3_shaders
|
||||||
|
|
||||||
|
diff --git a/util/shader_utils.h b/util/shader_utils.h
|
||||||
|
index 676341ebc55ea4984df68ab755444b49a5199f6f..cf211cfc9b1b48ae1de7368f8260e006f73e4219 100644
|
||||||
|
--- a/util/shader_utils.h
|
||||||
|
+++ b/util/shader_utils.h
|
||||||
|
@@ -90,7 +90,6 @@ ANGLE_UTIL_EXPORT const char *Passthrough();
|
||||||
|
// A shader that simply passes through attribute a_position, setting it to gl_Position and varying
|
||||||
|
// texcoord.
|
||||||
|
ANGLE_UTIL_EXPORT const char *Texture2D();
|
||||||
|
-ANGLE_UTIL_EXPORT const char *Texture2DArray();
|
||||||
|
|
||||||
|
} // namespace vs
|
||||||
|
|
||||||
|
@@ -120,7 +119,6 @@ ANGLE_UTIL_EXPORT const char *Blue();
|
||||||
|
|
||||||
|
// A shader that samples the texture
|
||||||
|
ANGLE_UTIL_EXPORT const char *Texture2D();
|
||||||
|
-ANGLE_UTIL_EXPORT const char *Texture2DArray();
|
||||||
|
|
||||||
|
} // namespace fs
|
||||||
|
} // namespace essl1_shaders
|
||||||
|
@@ -151,6 +149,7 @@ ANGLE_UTIL_EXPORT const char *Passthrough();
|
||||||
|
// A shader that simply passes through attribute a_position, setting it to gl_Position and varying
|
||||||
|
// texcoord.
|
||||||
|
ANGLE_UTIL_EXPORT const char *Texture2DLod();
|
||||||
|
+ANGLE_UTIL_EXPORT const char *Texture2DArray();
|
||||||
|
|
||||||
|
} // namespace vs
|
||||||
|
|
||||||
|
@@ -169,6 +168,9 @@ ANGLE_UTIL_EXPORT const char *Blue();
|
||||||
|
// A shader that samples the texture at a given lod.
|
||||||
|
ANGLE_UTIL_EXPORT const char *Texture2DLod();
|
||||||
|
|
||||||
|
+// A shader that samples the texture at a given slice.
|
||||||
|
+ANGLE_UTIL_EXPORT const char *Texture2DArray();
|
||||||
|
+
|
||||||
|
} // namespace fs
|
||||||
|
} // namespace essl3_shaders
|
||||||
|
|
||||||
376
patches/angle/cherry-pick-bf6dd974238b.patch
Normal file
376
patches/angle/cherry-pick-bf6dd974238b.patch
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Geoff Lang <geofflang@chromium.org>
|
||||||
|
Date: Wed, 11 Feb 2026 15:51:46 -0500
|
||||||
|
Subject: Optionally validate GL_MAX_*_UNIFORM_BLOCKS at compile time.
|
||||||
|
|
||||||
|
These were validated at link time but some drivers have compiler crashes
|
||||||
|
when compiling shaders with too many uniform blocks.
|
||||||
|
|
||||||
|
Bug: chromium:475877320
|
||||||
|
Change-Id: I4413ce06307b4fe9e27105d85f66f610c235a301
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7568089
|
||||||
|
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||||
|
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
|
||||||
|
index a4d90d43b6e300d6a1158e1b5a9b623e0123f7ce..c87dfa42d6f71fa5d8e92a7e9b31c566e87ee16a 100644
|
||||||
|
--- a/include/GLSLANG/ShaderLang.h
|
||||||
|
+++ b/include/GLSLANG/ShaderLang.h
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
|
||||||
|
// Version number for shader translation API.
|
||||||
|
// It is incremented every time the API changes.
|
||||||
|
-#define ANGLE_SH_VERSION 382
|
||||||
|
+#define ANGLE_SH_VERSION 383
|
||||||
|
|
||||||
|
enum ShShaderSpec
|
||||||
|
{
|
||||||
|
@@ -388,6 +388,10 @@ struct ShCompileOptions
|
||||||
|
|
||||||
|
uint64_t forceShaderPrecisionHighpToMediump : 1;
|
||||||
|
|
||||||
|
+ // Validate that the count of uniform blocks is within the GL_MAX_*_UNIFORM_BLOCKS limits. These
|
||||||
|
+ // limits must be supplied in the BuiltinResources.
|
||||||
|
+ uint64_t validatePerStageMaxUniformBlocks : 1;
|
||||||
|
+
|
||||||
|
// Ask compiler to generate Vulkan transform feedback emulation support code.
|
||||||
|
uint64_t addVulkanXfbEmulationSupportCode : 1;
|
||||||
|
|
||||||
|
@@ -587,6 +591,12 @@ struct ShBuiltInResources
|
||||||
|
int MinProgramTexelOffset;
|
||||||
|
int MaxProgramTexelOffset;
|
||||||
|
|
||||||
|
+ // GL_MAX_FRAGMENT_UNIFORM_BLOCKS
|
||||||
|
+ int MaxFragmentUniformBlocks;
|
||||||
|
+
|
||||||
|
+ // GL_MAX_VERTEX_UNIFORM_BLOCKS
|
||||||
|
+ int MaxVertexUniformBlocks;
|
||||||
|
+
|
||||||
|
// Extension constants.
|
||||||
|
|
||||||
|
// Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT for OpenGL ES output context.
|
||||||
|
@@ -704,6 +714,9 @@ struct ShBuiltInResources
|
||||||
|
// maximum point size (higher limit from ALIASED_POINT_SIZE_RANGE)
|
||||||
|
float MaxPointSize;
|
||||||
|
|
||||||
|
+ // GL_MAX_COMPUTE_UNIFORM_BLOCKS
|
||||||
|
+ int MaxComputeUniformBlocks;
|
||||||
|
+
|
||||||
|
// EXT_geometry_shader constants
|
||||||
|
int MaxGeometryUniformComponents;
|
||||||
|
int MaxGeometryUniformBlocks;
|
||||||
|
@@ -727,6 +740,7 @@ struct ShBuiltInResources
|
||||||
|
int MaxTessControlImageUniforms;
|
||||||
|
int MaxTessControlAtomicCounters;
|
||||||
|
int MaxTessControlAtomicCounterBuffers;
|
||||||
|
+ int MaxTessControlUniformBlocks;
|
||||||
|
|
||||||
|
int MaxTessPatchComponents;
|
||||||
|
int MaxPatchVertices;
|
||||||
|
@@ -739,6 +753,7 @@ struct ShBuiltInResources
|
||||||
|
int MaxTessEvaluationImageUniforms;
|
||||||
|
int MaxTessEvaluationAtomicCounters;
|
||||||
|
int MaxTessEvaluationAtomicCounterBuffers;
|
||||||
|
+ int MaxTessEvaluationUniformBlocks;
|
||||||
|
|
||||||
|
// Subpixel bits used in rasterization.
|
||||||
|
int SubPixelBits;
|
||||||
|
diff --git a/include/platform/autogen/FeaturesGL_autogen.h b/include/platform/autogen/FeaturesGL_autogen.h
|
||||||
|
index c5fb020f74f23cb072732459f520823bfb97b82c..c492b8287a03b5cd3966caae4fc96ecf71317918 100644
|
||||||
|
--- a/include/platform/autogen/FeaturesGL_autogen.h
|
||||||
|
+++ b/include/platform/autogen/FeaturesGL_autogen.h
|
||||||
|
@@ -632,6 +632,12 @@ struct FeaturesGL : FeatureSetBase
|
||||||
|
&members,
|
||||||
|
};
|
||||||
|
|
||||||
|
+ FeatureInfo validateMaxPerStageUniformBlocksAtCompileTime = {
|
||||||
|
+ "validateMaxPerStageUniformBlocksAtCompileTime",
|
||||||
|
+ FeatureCategory::OpenGLWorkarounds,
|
||||||
|
+ &members,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
};
|
||||||
|
|
||||||
|
inline FeaturesGL::FeaturesGL() = default;
|
||||||
|
diff --git a/include/platform/gl_features.json b/include/platform/gl_features.json
|
||||||
|
index f69426154880aacbdeb1be35749ee765b8790a6f..656133772e36d4a9be0d006e3298437216ae0044 100644
|
||||||
|
--- a/include/platform/gl_features.json
|
||||||
|
+++ b/include/platform/gl_features.json
|
||||||
|
@@ -820,6 +820,14 @@
|
||||||
|
"Some Adreno drivers assume incorrect glSampleCoverage if new FBO is bound with different sample count"
|
||||||
|
],
|
||||||
|
"issue": "https://crbug.com/408364831"
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "name": "validate_max_per_stage_uniform_blocks_at_compile_time",
|
||||||
|
+ "category": "Workarounds",
|
||||||
|
+ "description": [
|
||||||
|
+ "Validate GL_MAX_*_UNIFORM_BLOCKS at compile time instead of link time to work around compiler bugs."
|
||||||
|
+ ],
|
||||||
|
+ "issue": "http://crbug.com/475877320"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
|
||||||
|
index bd5e6990fbde80f02faf42c2b914580737caa4b2..f966774d4e521527721b54fbe170595bf209600e 100644
|
||||||
|
--- a/src/compiler/translator/Compiler.cpp
|
||||||
|
+++ b/src/compiler/translator/Compiler.cpp
|
||||||
|
@@ -1633,6 +1633,8 @@ void TCompiler::setResourceString()
|
||||||
|
<< ":MaxFragmentInputVectors:" << mResources.MaxFragmentInputVectors
|
||||||
|
<< ":MinProgramTexelOffset:" << mResources.MinProgramTexelOffset
|
||||||
|
<< ":MaxProgramTexelOffset:" << mResources.MaxProgramTexelOffset
|
||||||
|
+ << ":MaxFragmentUniformBlocks:" << mResources.MaxFragmentUniformBlocks
|
||||||
|
+ << ":MaxVertexUniformBlocks:" << mResources.MaxVertexUniformBlocks
|
||||||
|
<< ":MaxDualSourceDrawBuffers:" << mResources.MaxDualSourceDrawBuffers
|
||||||
|
<< ":MaxViewsOVR:" << mResources.MaxViewsOVR
|
||||||
|
<< ":NV_draw_buffers:" << mResources.NV_draw_buffers
|
||||||
|
@@ -1682,6 +1684,7 @@ void TCompiler::setResourceString()
|
||||||
|
<< ":MaxFragmentAtomicCounterBuffers:" << mResources.MaxFragmentAtomicCounterBuffers
|
||||||
|
<< ":MaxCombinedAtomicCounterBuffers:" << mResources.MaxCombinedAtomicCounterBuffers
|
||||||
|
<< ":MaxAtomicCounterBufferSize:" << mResources.MaxAtomicCounterBufferSize
|
||||||
|
+ << ":MaxComputeUnformBlocks:" << mResources.MaxComputeUniformBlocks
|
||||||
|
<< ":MaxGeometryUniformComponents:" << mResources.MaxGeometryUniformComponents
|
||||||
|
<< ":MaxGeometryUniformBlocks:" << mResources.MaxGeometryUniformBlocks
|
||||||
|
<< ":MaxGeometryInputComponents:" << mResources.MaxGeometryInputComponents
|
||||||
|
@@ -1705,6 +1708,7 @@ void TCompiler::setResourceString()
|
||||||
|
<< ":MaxTessControlImageUniforms:" << mResources.MaxTessControlImageUniforms
|
||||||
|
<< ":MaxTessControlAtomicCounters:" << mResources.MaxTessControlAtomicCounters
|
||||||
|
<< ":MaxTessControlAtomicCounterBuffers:" << mResources.MaxTessControlAtomicCounterBuffers
|
||||||
|
+ << ":MaxTessControlUniformBlocks:" << mResources.MaxTessControlUniformBlocks
|
||||||
|
<< ":MaxTessPatchComponents:" << mResources.MaxTessPatchComponents
|
||||||
|
<< ":MaxPatchVertices:" << mResources.MaxPatchVertices
|
||||||
|
<< ":MaxTessGenLevel:" << mResources.MaxTessGenLevel
|
||||||
|
@@ -1714,7 +1718,9 @@ void TCompiler::setResourceString()
|
||||||
|
<< ":MaxTessEvaluationUniformComponents:" << mResources.MaxTessEvaluationUniformComponents
|
||||||
|
<< ":MaxTessEvaluationImageUniforms:" << mResources.MaxTessEvaluationImageUniforms
|
||||||
|
<< ":MaxTessEvaluationAtomicCounters:" << mResources.MaxTessEvaluationAtomicCounters
|
||||||
|
- << ":MaxTessEvaluationAtomicCounterBuffers:" << mResources.MaxTessEvaluationAtomicCounterBuffers;
|
||||||
|
+ << ":MaxTessEvaluationAtomicCounterBuffers:" << mResources.MaxTessEvaluationAtomicCounterBuffers
|
||||||
|
+ << ":MaxTessControlUniformBlocks:" << mResources.MaxTessControlUniformBlocks
|
||||||
|
+ ;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
mBuiltInResourcesString = strstream.str();
|
||||||
|
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
|
||||||
|
index de788456a27399e0a25a57f737c2a7b5e73b848c..53a3f79a9302cbacd16e4080527ceb7f21feabdb 100644
|
||||||
|
--- a/src/compiler/translator/ParseContext.cpp
|
||||||
|
+++ b/src/compiler/translator/ParseContext.cpp
|
||||||
|
@@ -250,6 +250,37 @@ bool IsSamplerOrStructWithOnlySamplers(const TType *type)
|
||||||
|
{
|
||||||
|
return IsSampler(type->getBasicType()) || type->isStructureContainingOnlySamplers();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+unsigned int GetMaxUniformBlocksForShaderType(sh::GLenum shaderType,
|
||||||
|
+ const ShCompileOptions &options,
|
||||||
|
+ const ShBuiltInResources &resources)
|
||||||
|
+{
|
||||||
|
+ // If the validatePerStageMaxUniformBlocks workaround is disabled. Set a limit that will not be
|
||||||
|
+ // hit.
|
||||||
|
+ if (!options.validatePerStageMaxUniformBlocks)
|
||||||
|
+ {
|
||||||
|
+ return std::numeric_limits<unsigned int>::max();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (shaderType)
|
||||||
|
+ {
|
||||||
|
+ case GL_FRAGMENT_SHADER:
|
||||||
|
+ return resources.MaxFragmentUniformBlocks;
|
||||||
|
+ case GL_VERTEX_SHADER:
|
||||||
|
+ return resources.MaxVertexUniformBlocks;
|
||||||
|
+ case GL_COMPUTE_SHADER:
|
||||||
|
+ return resources.MaxComputeUniformBlocks;
|
||||||
|
+ case GL_GEOMETRY_SHADER:
|
||||||
|
+ return resources.MaxGeometryUniformBlocks;
|
||||||
|
+ case GL_TESS_CONTROL_SHADER:
|
||||||
|
+ return resources.MaxTessControlUniformBlocks;
|
||||||
|
+ case GL_TESS_EVALUATION_SHADER:
|
||||||
|
+ return resources.MaxTessEvaluationUniformBlocks;
|
||||||
|
+ default:
|
||||||
|
+ UNREACHABLE();
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// This tracks each binding point's current default offset for inheritance of subsequent
|
||||||
|
@@ -341,6 +372,8 @@ TParseContext::TParseContext(TSymbolTable &symt,
|
||||||
|
mMaxAtomicCounterBufferSize(resources.MaxAtomicCounterBufferSize),
|
||||||
|
mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
|
||||||
|
mMaxPixelLocalStoragePlanes(resources.MaxPixelLocalStoragePlanes),
|
||||||
|
+ mMaxUniformBlocks(GetMaxUniformBlocksForShaderType(mShaderType, options, resources)),
|
||||||
|
+ mNumUniformBlocks(0),
|
||||||
|
mDeclaringFunction(false),
|
||||||
|
mDeclaringMain(false),
|
||||||
|
mIsMainDeclared(false),
|
||||||
|
@@ -5080,6 +5113,22 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
|
||||||
|
error(arraySizesLine, "geometry shader input blocks must be an array", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Validate max uniform block limits
|
||||||
|
+ if (typeQualifier.qualifier == EvqUniform)
|
||||||
|
+ {
|
||||||
|
+ unsigned int blockCount =
|
||||||
|
+ arraySizes == nullptr || arraySizes->empty() ? 1 : (*arraySizes)[0];
|
||||||
|
+ if (mNumUniformBlocks + blockCount > mMaxUniformBlocks)
|
||||||
|
+ {
|
||||||
|
+ error(arraySizesLine,
|
||||||
|
+ "uniform block count greater than per stage maximum uniform blocks", "");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ mNumUniformBlocks += blockCount;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
checkIndexIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.index);
|
||||||
|
|
||||||
|
if (mShaderVersion < 310)
|
||||||
|
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
|
||||||
|
index 5f6800df8c003aa8f930915222a0c04ff838cdad..fb13198d49df37be82cf4199cc05a0cb1337d00c 100644
|
||||||
|
--- a/src/compiler/translator/ParseContext.h
|
||||||
|
+++ b/src/compiler/translator/ParseContext.h
|
||||||
|
@@ -798,6 +798,12 @@ class TParseContext : angle::NonCopyable
|
||||||
|
int mMaxShaderStorageBufferBindings;
|
||||||
|
int mMaxPixelLocalStoragePlanes;
|
||||||
|
|
||||||
|
+ // Maximum number of uniform blocks allowed to be declared in this shader. Taken from the
|
||||||
|
+ // built-in resources and resolved to this shader type.
|
||||||
|
+ unsigned int mMaxUniformBlocks;
|
||||||
|
+ // Current count of declared uniform blocks.
|
||||||
|
+ unsigned int mNumUniformBlocks;
|
||||||
|
+
|
||||||
|
// keeps track whether we are declaring / defining a function
|
||||||
|
bool mDeclaringFunction;
|
||||||
|
|
||||||
|
diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
|
||||||
|
index fa67c01cc5bc4f0d3027aa06f4133fd3521b61ce..56bd95a7241f479bb63e2ec13838a6de184b24ab 100644
|
||||||
|
--- a/src/compiler/translator/ShaderLang.cpp
|
||||||
|
+++ b/src/compiler/translator/ShaderLang.cpp
|
||||||
|
@@ -254,6 +254,8 @@ void InitBuiltInResources(ShBuiltInResources *resources)
|
||||||
|
resources->MaxFragmentInputVectors = 15;
|
||||||
|
resources->MinProgramTexelOffset = -8;
|
||||||
|
resources->MaxProgramTexelOffset = 7;
|
||||||
|
+ resources->MaxFragmentUniformBlocks = 12;
|
||||||
|
+ resources->MaxVertexUniformBlocks = 12;
|
||||||
|
|
||||||
|
// Extensions constants.
|
||||||
|
resources->MaxDualSourceDrawBuffers = 0;
|
||||||
|
@@ -314,6 +316,8 @@ void InitBuiltInResources(ShBuiltInResources *resources)
|
||||||
|
resources->MaxUniformBufferBindings = 32;
|
||||||
|
resources->MaxShaderStorageBufferBindings = 4;
|
||||||
|
|
||||||
|
+ resources->MaxComputeUniformBlocks = 12;
|
||||||
|
+
|
||||||
|
resources->MaxGeometryUniformComponents = 1024;
|
||||||
|
resources->MaxGeometryUniformBlocks = 12;
|
||||||
|
resources->MaxGeometryInputComponents = 64;
|
||||||
|
@@ -335,6 +339,7 @@ void InitBuiltInResources(ShBuiltInResources *resources)
|
||||||
|
resources->MaxTessControlImageUniforms = 0;
|
||||||
|
resources->MaxTessControlAtomicCounters = 0;
|
||||||
|
resources->MaxTessControlAtomicCounterBuffers = 0;
|
||||||
|
+ resources->MaxTessControlUniformBlocks = 12;
|
||||||
|
|
||||||
|
resources->MaxTessPatchComponents = 120;
|
||||||
|
resources->MaxPatchVertices = 32;
|
||||||
|
@@ -347,6 +352,7 @@ void InitBuiltInResources(ShBuiltInResources *resources)
|
||||||
|
resources->MaxTessEvaluationImageUniforms = 0;
|
||||||
|
resources->MaxTessEvaluationAtomicCounters = 0;
|
||||||
|
resources->MaxTessEvaluationAtomicCounterBuffers = 0;
|
||||||
|
+ resources->MaxTessEvaluationUniformBlocks = 12;
|
||||||
|
|
||||||
|
resources->SubPixelBits = 8;
|
||||||
|
|
||||||
|
diff --git a/src/libANGLE/Compiler.cpp b/src/libANGLE/Compiler.cpp
|
||||||
|
index 00684c8ed08609a3a4d6ef6f36107756207ed72b..1893b6bddb33fde567162e2e9dbb12785dad538d 100644
|
||||||
|
--- a/src/libANGLE/Compiler.cpp
|
||||||
|
+++ b/src/libANGLE/Compiler.cpp
|
||||||
|
@@ -169,6 +169,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp
|
||||||
|
mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
|
||||||
|
mResources.MinProgramTexelOffset = caps.minProgramTexelOffset;
|
||||||
|
mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
|
||||||
|
+ mResources.MaxFragmentUniformBlocks = caps.maxShaderUniformBlocks[gl::ShaderType::Fragment];
|
||||||
|
+ mResources.MaxVertexUniformBlocks = caps.maxShaderUniformBlocks[gl::ShaderType::Vertex];
|
||||||
|
|
||||||
|
// EXT_blend_func_extended
|
||||||
|
mResources.EXT_blend_func_extended = extensions.blendFuncExtendedEXT;
|
||||||
|
@@ -211,6 +213,7 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp
|
||||||
|
mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms;
|
||||||
|
mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
|
||||||
|
mResources.MaxUniformLocations = caps.maxUniformLocations;
|
||||||
|
+ mResources.MaxComputeUniformBlocks = caps.maxShaderUniformBlocks[gl::ShaderType::Compute];
|
||||||
|
|
||||||
|
for (size_t index = 0u; index < 3u; ++index)
|
||||||
|
{
|
||||||
|
@@ -280,6 +283,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp
|
||||||
|
mResources.MaxTessControlAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::TessControl];
|
||||||
|
mResources.MaxTessControlAtomicCounterBuffers =
|
||||||
|
caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
|
||||||
|
+ mResources.MaxTessControlUniformBlocks =
|
||||||
|
+ caps.maxShaderUniformBlocks[gl::ShaderType::TessControl];
|
||||||
|
|
||||||
|
mResources.MaxTessPatchComponents = caps.maxTessPatchComponents;
|
||||||
|
mResources.MaxPatchVertices = caps.maxPatchVertices;
|
||||||
|
@@ -297,6 +302,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp
|
||||||
|
caps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
|
||||||
|
mResources.MaxTessEvaluationAtomicCounterBuffers =
|
||||||
|
caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
|
||||||
|
+ mResources.MaxTessEvaluationUniformBlocks =
|
||||||
|
+ caps.maxShaderUniformBlocks[gl::ShaderType::TessEvaluation];
|
||||||
|
|
||||||
|
// Subpixel bits.
|
||||||
|
mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
|
||||||
|
diff --git a/src/libANGLE/renderer/gl/ShaderGL.cpp b/src/libANGLE/renderer/gl/ShaderGL.cpp
|
||||||
|
index bef2feaee055bae36c24bd4edfc98c86ada25cc3..6b66d4e529933d90984ea972ed9375964e6a2ff5 100644
|
||||||
|
--- a/src/libANGLE/renderer/gl/ShaderGL.cpp
|
||||||
|
+++ b/src/libANGLE/renderer/gl/ShaderGL.cpp
|
||||||
|
@@ -272,6 +272,11 @@ std::shared_ptr<ShaderTranslateTask> ShaderGL::compile(const gl::Context *contex
|
||||||
|
options->pls = contextGL->getNativePixelLocalStorageOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (features.validateMaxPerStageUniformBlocksAtCompileTime.enabled)
|
||||||
|
+ {
|
||||||
|
+ options->validatePerStageMaxUniformBlocks = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return std::shared_ptr<ShaderTranslateTask>(
|
||||||
|
new ShaderTranslateTaskGL(functions, mShaderID, contextGL->hasNativeParallelCompile()));
|
||||||
|
}
|
||||||
|
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
|
||||||
|
index b8b328b050ba1af54dbb02143d26456d827260dc..aaa928d6e595dbea220e95129be92461cd1eb280 100644
|
||||||
|
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
|
||||||
|
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
|
||||||
|
@@ -2707,6 +2707,10 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
|
||||||
|
// number of samples in currently bound FBO and require to reset sample
|
||||||
|
// coverage each time FBO changes.
|
||||||
|
ANGLE_FEATURE_CONDITION(features, resetSampleCoverageOnFBOChange, isQualcomm);
|
||||||
|
+
|
||||||
|
+ // IMG GL drivers crash while compiling shaders with more than the limit of uniform blocks.
|
||||||
|
+ ANGLE_FEATURE_CONDITION(features, validateMaxPerStageUniformBlocksAtCompileTime,
|
||||||
|
+ IsPowerVR(vendor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
|
||||||
|
diff --git a/util/autogen/angle_features_autogen.cpp b/util/autogen/angle_features_autogen.cpp
|
||||||
|
index 7ff616edd4b5a61e544254e6bf1a0bc6c49293a4..f56164ad977ad19b7d58ccbf628f28c8fb24f0a2 100644
|
||||||
|
--- a/util/autogen/angle_features_autogen.cpp
|
||||||
|
+++ b/util/autogen/angle_features_autogen.cpp
|
||||||
|
@@ -473,6 +473,7 @@ constexpr PackedEnumMap<Feature, const char *> kFeatureNames = {{
|
||||||
|
{Feature::UseVkEventForBufferBarrier, "useVkEventForBufferBarrier"},
|
||||||
|
{Feature::UseVkEventForImageBarrier, "useVkEventForImageBarrier"},
|
||||||
|
{Feature::UseVmaForImageSuballocation, "useVmaForImageSuballocation"},
|
||||||
|
+ {Feature::ValidateMaxPerStageUniformBlocksAtCompileTime, "validateMaxPerStageUniformBlocksAtCompileTime"},
|
||||||
|
{Feature::VaryingsRequireMatchingPrecisionInSpirv, "varyingsRequireMatchingPrecisionInSpirv"},
|
||||||
|
{Feature::VerifyPipelineCacheInBlobCache, "verifyPipelineCacheInBlobCache"},
|
||||||
|
{Feature::VertexIDDoesNotIncludeBaseVertex, "vertexIDDoesNotIncludeBaseVertex"},
|
||||||
|
diff --git a/util/autogen/angle_features_autogen.h b/util/autogen/angle_features_autogen.h
|
||||||
|
index fd19b2b8f4eb7a0bf9973bf2baeaf68c106e11a8..55bf1b418c4f2f185e833c4c385094792f1bbf05 100644
|
||||||
|
--- a/util/autogen/angle_features_autogen.h
|
||||||
|
+++ b/util/autogen/angle_features_autogen.h
|
||||||
|
@@ -473,6 +473,7 @@ enum class Feature
|
||||||
|
UseVkEventForBufferBarrier,
|
||||||
|
UseVkEventForImageBarrier,
|
||||||
|
UseVmaForImageSuballocation,
|
||||||
|
+ ValidateMaxPerStageUniformBlocksAtCompileTime,
|
||||||
|
VaryingsRequireMatchingPrecisionInSpirv,
|
||||||
|
VerifyPipelineCacheInBlobCache,
|
||||||
|
VertexIDDoesNotIncludeBaseVertex,
|
||||||
@@ -151,3 +151,12 @@ graphite_handle_out_of_order_recording_errors.patch
|
|||||||
ozone_wayland_treat_dnd_drop_performed_with_none_action_as_a.patch
|
ozone_wayland_treat_dnd_drop_performed_with_none_action_as_a.patch
|
||||||
cherry-pick-e045399a1ecb.patch
|
cherry-pick-e045399a1ecb.patch
|
||||||
loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch
|
loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch
|
||||||
|
cherry-pick-50b057660b4d.patch
|
||||||
|
cherry-pick-074d472db745.patch
|
||||||
|
validate_uniform_block_count_limits_at_compile_time_on_img.patch
|
||||||
|
feat_plumb_node_integration_in_worker_through_workersettings.patch
|
||||||
|
cherry-pick-45c5a70d984d.patch
|
||||||
|
cherry-pick-05e4b544803c.patch
|
||||||
|
cherry-pick-5efc7a0127a6.patch
|
||||||
|
cherry-pick-d8b01057f740.patch
|
||||||
|
cherry-pick-89b42d2d3326.patch
|
||||||
|
|||||||
204
patches/chromium/cherry-pick-05e4b544803c.patch
Normal file
204
patches/chromium/cherry-pick-05e4b544803c.patch
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Date: Wed, 25 Feb 2026 03:25:14 -0800
|
||||||
|
Subject: Stringify CSSUnparsedValues via toString, as normal
|
||||||
|
|
||||||
|
CSSUnparsedValue exposes a special stringification function
|
||||||
|
ToUnparsedString() in addition to the regular toString().
|
||||||
|
The documentation says it returns "tokens without substituting
|
||||||
|
variables", but it's not clear what this means; we don't substitute
|
||||||
|
any variables in CSSStyleValue::toString() either.
|
||||||
|
|
||||||
|
This CL makes ToUnparsedString() private (and renames it).
|
||||||
|
Clients needing to serialize a CSSUnparsedValue can do so via
|
||||||
|
the normal toString() function. (If ToUnparsedString() existed
|
||||||
|
for performance reasons, that should have been documented.)
|
||||||
|
|
||||||
|
Also, the /**/-"fixup" pass over the value has been folded into
|
||||||
|
ToStringInternal(). This is to make it easy to find the canonical string
|
||||||
|
representation of this value within CSSUnparsedValue (without going
|
||||||
|
through a CSSValue).
|
||||||
|
|
||||||
|
The main point of this CL is to prepare for validating
|
||||||
|
the "argument grammar" of the value during the StyleValue-to-CSSValue
|
||||||
|
conversion in StylePropertyMap (which requires item (2) above).
|
||||||
|
|
||||||
|
We now jump through additional hoops to ultimately get a string
|
||||||
|
from the outside of CSSUnparsedValue, but there should otherwise
|
||||||
|
be no behavior change.
|
||||||
|
|
||||||
|
Bug: 484751092
|
||||||
|
Change-Id: I5db45ad85f780c67a2ea3ba8482c390ebab10068
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7600415
|
||||||
|
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1590041}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc b/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc
|
||||||
|
index dcc2eccbc84e6cd5710ab51cee2dab49661467c1..86d42c87a6bd10838a3e059c9227868e5bfc0798 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/cross_thread_style_value_test.cc
|
||||||
|
@@ -19,12 +19,12 @@
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
|
||||||
|
-#include "third_party/blink/renderer/core/css/cssom/css_unparsed_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_unsupported_color.h"
|
||||||
|
#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread.h"
|
||||||
|
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
|
||||||
|
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
|
||||||
|
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
|
||||||
|
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
|
||||||
|
|
||||||
|
namespace blink {
|
||||||
|
|
||||||
|
@@ -152,8 +152,7 @@ TEST_F(CrossThreadStyleValueTest, CrossThreadUnparsedValueToCSSStyleValue) {
|
||||||
|
CSSStyleValue* style_value = value->ToCSSStyleValue();
|
||||||
|
EXPECT_EQ(style_value->GetType(),
|
||||||
|
CSSStyleValue::StyleValueType::kUnparsedType);
|
||||||
|
- EXPECT_EQ(static_cast<CSSUnparsedValue*>(style_value)->ToUnparsedString(),
|
||||||
|
- "Unparsed");
|
||||||
|
+ EXPECT_EQ(style_value->toString(), "Unparsed");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CrossThreadStyleValueTest, PassKeywordValueCrossThread) {
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
index 67a4afde452f94ffb9ecbaeea104a3997c65b7b3..9c6bb62d044f804b0ce7bc8df398d77695cf950c 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
@@ -124,16 +124,26 @@ IndexedPropertySetterResult CSSUnparsedValue::AnonymousIndexedSetter(
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSSValue* CSSUnparsedValue::ToCSSValue() const {
|
||||||
|
- String unparsed_string = ToUnparsedString();
|
||||||
|
- CSSParserTokenStream stream(unparsed_string);
|
||||||
|
+ String unparsed_string = ToStringInternal();
|
||||||
|
|
||||||
|
- if (stream.AtEnd()) {
|
||||||
|
+ if (unparsed_string.IsNull()) {
|
||||||
|
return MakeGarbageCollected<CSSUnparsedDeclarationValue>(
|
||||||
|
MakeGarbageCollected<CSSVariableData>());
|
||||||
|
}
|
||||||
|
|
||||||
|
- // The string we just parsed has /**/ inserted between every token
|
||||||
|
- // to make sure we get back the correct sequence of tokens.
|
||||||
|
+ // TODO(crbug.com/985028): We should probably propagate the CSSParserContext
|
||||||
|
+ // to here.
|
||||||
|
+ return MakeGarbageCollected<CSSUnparsedDeclarationValue>(
|
||||||
|
+ CSSVariableData::Create(unparsed_string, false /* is_animation_tainted */,
|
||||||
|
+ false /* is_attr_tainted */,
|
||||||
|
+ false /* needs_variable_resolution */));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+String CSSUnparsedValue::ToStringInternal() const {
|
||||||
|
+ String serialized = SerializeSegments();
|
||||||
|
+
|
||||||
|
+ // The serialization above defensively inserted /**/ between segments
|
||||||
|
+ // to make sure that e.g. ['foo', 'bar'] does not collapse into 'foobar'.
|
||||||
|
// The spec mentions nothing of the sort:
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#unparsedvalue-serialization
|
||||||
|
//
|
||||||
|
@@ -147,6 +157,10 @@ const CSSValue* CSSUnparsedValue::ToCSSValue() const {
|
||||||
|
// the original contents of any comments will be lost, but Typed OM does
|
||||||
|
// not have anywhere to store that kind of data, so it is expected.
|
||||||
|
StringBuilder builder;
|
||||||
|
+ CSSParserTokenStream stream(serialized);
|
||||||
|
+ if (stream.AtEnd()) {
|
||||||
|
+ return g_null_atom;
|
||||||
|
+ }
|
||||||
|
CSSParserToken token = stream.ConsumeRaw();
|
||||||
|
token.Serialize(builder);
|
||||||
|
while (!stream.Peek().IsEOF()) {
|
||||||
|
@@ -156,17 +170,10 @@ const CSSValue* CSSUnparsedValue::ToCSSValue() const {
|
||||||
|
token = stream.ConsumeRaw();
|
||||||
|
token.Serialize(builder);
|
||||||
|
}
|
||||||
|
- String original_text = builder.ReleaseString();
|
||||||
|
-
|
||||||
|
- // TODO(crbug.com/985028): We should probably propagate the CSSParserContext
|
||||||
|
- // to here.
|
||||||
|
- return MakeGarbageCollected<CSSUnparsedDeclarationValue>(
|
||||||
|
- CSSVariableData::Create(original_text, false /* is_animation_tainted */,
|
||||||
|
- false /* is_attr_tainted */,
|
||||||
|
- false /* needs_variable_resolution */));
|
||||||
|
+ return builder.ReleaseString();
|
||||||
|
}
|
||||||
|
|
||||||
|
-String CSSUnparsedValue::ToUnparsedString() const {
|
||||||
|
+String CSSUnparsedValue::SerializeSegments() const {
|
||||||
|
StringBuilder builder;
|
||||||
|
HeapHashSet<Member<const CSSUnparsedValue>> values_on_stack;
|
||||||
|
if (AppendUnparsedString(builder, values_on_stack)) {
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
index 5d1961b170f14ae21ca8f69b3c3cd8af28f4478a..ec7e3ed708f406d7a61fdb370b2eed8a8297cffb 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
@@ -67,15 +67,9 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
CSSStyleValue::Trace(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Unlike CSSStyleValue::toString(), this returns tokens without
|
||||||
|
- // substituting variables. There are extra /**/ inserted between
|
||||||
|
- // every token to ensure there are no ambiguities, which is fine
|
||||||
|
- // because this value is never presented directly to the user
|
||||||
|
- // (ToCSSValue() will parse to a token range and then re-serialize
|
||||||
|
- // using extra /**/ only where needed).
|
||||||
|
- String ToUnparsedString() const;
|
||||||
|
-
|
||||||
|
private:
|
||||||
|
+ String ToStringInternal() const;
|
||||||
|
+ String SerializeSegments() const;
|
||||||
|
// Return 'false' if there is a cycle in the serialization.
|
||||||
|
bool AppendUnparsedString(
|
||||||
|
StringBuilder&,
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
|
||||||
|
index f81fa39423a9235bc58e1600ca7a250affd3d9bb..2ee4dd7e591095b8460ca559b29b78e37ab71729 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
+
|
||||||
|
#include "base/synchronization/waitable_event.h"
|
||||||
|
#include "base/task/single_thread_task_runner.h"
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
@@ -13,7 +14,6 @@
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_paint_worklet_input.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
|
||||||
|
-#include "third_party/blink/renderer/core/css/cssom/css_unparsed_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_unsupported_color.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
|
||||||
|
#include "third_party/blink/renderer/core/dom/element.h"
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
|
||||||
|
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
|
||||||
|
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
|
||||||
|
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
|
||||||
|
|
||||||
|
namespace blink {
|
||||||
|
|
||||||
|
@@ -66,8 +67,7 @@ class PaintWorkletStylePropertyMapTest : public PageTestBase {
|
||||||
|
CSSStyleValue* style_value = data.at("--x")->ToCSSStyleValue();
|
||||||
|
EXPECT_EQ(style_value->GetType(),
|
||||||
|
CSSStyleValue::StyleValueType::kUnparsedType);
|
||||||
|
- EXPECT_EQ(static_cast<CSSUnparsedValue*>(style_value)->ToUnparsedString(),
|
||||||
|
- "50");
|
||||||
|
+ EXPECT_EQ(style_value->toString(), "50");
|
||||||
|
waitable_event->Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
|
||||||
|
index 1db0fd72478d708008f1b95a6aff206b28f60a6a..b52d8065c770aba822e9977c251c540643972629 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
|
||||||
|
@@ -4872,7 +4872,7 @@ ComputedStyleUtils::CrossThreadStyleValueFromCSSStyleValue(
|
||||||
|
To<CSSUnsupportedColor>(style_value)->Value());
|
||||||
|
case CSSStyleValue::StyleValueType::kUnparsedType:
|
||||||
|
return std::make_unique<CrossThreadUnparsedValue>(
|
||||||
|
- To<CSSUnparsedValue>(style_value)->ToUnparsedString());
|
||||||
|
+ To<CSSUnparsedValue>(style_value)->toString());
|
||||||
|
default:
|
||||||
|
return std::make_unique<CrossThreadUnsupportedValue>(
|
||||||
|
style_value->toString());
|
||||||
296
patches/chromium/cherry-pick-074d472db745.patch
Normal file
296
patches/chromium/cherry-pick-074d472db745.patch
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mikel Astiz <mastiz@chromium.org>
|
||||||
|
Date: Tue, 10 Mar 2026 13:22:17 -0700
|
||||||
|
Subject: [M146][base] Fix UAF in base::OnceCallbackList on re-entrant Notify()
|
||||||
|
|
||||||
|
Before this patch, `base::OnceCallbackList` was susceptible to a
|
||||||
|
heap-use-after-free when `Notify()` was called re-entrantly.
|
||||||
|
|
||||||
|
The UAF occurred because `OnceCallbackList::RunCallback()` immediately
|
||||||
|
spliced executed nodes out of `callbacks_` and into `null_callbacks_`.
|
||||||
|
If a nested `Notify()` executed a node that an outer `Notify()` loop was
|
||||||
|
already holding an iterator to, and that node's subscription was
|
||||||
|
subsequently destroyed during the re-entrant cycle, the node would be
|
||||||
|
physically erased from `null_callbacks_`. When control returned to the
|
||||||
|
outer loop, it would attempt to evaluate the now-dangling iterator.
|
||||||
|
|
||||||
|
This CL fixes the bug by deferring list mutations until the outermost
|
||||||
|
iteration completes:
|
||||||
|
1. `RunCallback()` no longer splices nodes during iteration.
|
||||||
|
2. Cancellation logic is pushed down to the subclasses via a new
|
||||||
|
`CancelCallback()` hook, which is an extension to the pre-existing
|
||||||
|
`CancelNullCallback()` with increased responsibilities and clearer
|
||||||
|
semantics.
|
||||||
|
3. If a subscription is destroyed while `is_iterating` is true,
|
||||||
|
`OnceCallbackList` resets the node and stashes its iterator in
|
||||||
|
`pending_erasures_`.
|
||||||
|
4. A new `CleanUpNullCallbacksPostIteration()` phase runs at the end
|
||||||
|
of the outermost `Notify()`, which safely splices executed nodes
|
||||||
|
into `null_callbacks_` and physically erases the pending dead nodes.
|
||||||
|
|
||||||
|
As a side effect, the type-trait hack in `Notify()` based on
|
||||||
|
`is_instantiation<CallbackType, OnceCallback>` can be removed, because
|
||||||
|
this information is exposed directly by
|
||||||
|
`OnceCallbackList::CleanUpNullCallbacksPostIteration()`.
|
||||||
|
|
||||||
|
The newly-added unit-test
|
||||||
|
CallbackListTest.OnceCallbackListCancelDuringReentrantNotify reproduces
|
||||||
|
the scenario and crashed before this patch.
|
||||||
|
|
||||||
|
(cherry picked from commit 36acd49636845be2419269acbe9a5137da3d5d96)
|
||||||
|
|
||||||
|
Change-Id: I6b1e2bcb97be1bc8d6a15e5ca7511992e00e1772
|
||||||
|
Fixed: 489381399
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7627506
|
||||||
|
Commit-Queue: Mikel Astiz <mastiz@chromium.org>
|
||||||
|
Reviewed-by: Gabriel Charette <gab@chromium.org>
|
||||||
|
Cr-Original-Commit-Position: refs/heads/main@{#1594520}
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7653916
|
||||||
|
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||||
|
Cr-Commit-Position: refs/branch-heads/7680@{#2287}
|
||||||
|
Cr-Branched-From: 76b7d80e5cda23fe6537eed26d68c92e995c7f39-refs/heads/main@{#1582197}
|
||||||
|
|
||||||
|
diff --git a/base/callback_list.h b/base/callback_list.h
|
||||||
|
index 82cb11dc0ee02906b009cc383c41a056861199d0..d5f99cf685486f1ea74718b4e6b228a5d83f0c29 100644
|
||||||
|
--- a/base/callback_list.h
|
||||||
|
+++ b/base/callback_list.h
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
+#include <vector>
|
||||||
|
|
||||||
|
#include "base/auto_reset.h"
|
||||||
|
#include "base/base_export.h"
|
||||||
|
@@ -16,7 +17,6 @@
|
||||||
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback.h"
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
|
-#include "base/types/is_instantiation.h"
|
||||||
|
|
||||||
|
// OVERVIEW:
|
||||||
|
//
|
||||||
|
@@ -240,17 +240,14 @@ class CallbackListBase {
|
||||||
|
|
||||||
|
// Any null callbacks remaining in the list were canceled due to
|
||||||
|
// Subscription destruction during iteration, and can safely be erased now.
|
||||||
|
- const size_t erased_callbacks =
|
||||||
|
- std::erase_if(callbacks_, [](const auto& cb) { return cb.is_null(); });
|
||||||
|
-
|
||||||
|
- // Run |removal_callback_| if any callbacks were canceled. Note that we
|
||||||
|
- // cannot simply compare list sizes before and after iterating, since
|
||||||
|
- // notification may result in Add()ing new callbacks as well as canceling
|
||||||
|
- // them. Also note that if this is a OnceCallbackList, the OnceCallbacks
|
||||||
|
- // that were executed above have all been removed regardless of whether
|
||||||
|
- // they're counted in |erased_callbacks_|.
|
||||||
|
- if (removal_callback_ &&
|
||||||
|
- (erased_callbacks || is_instantiation<CallbackType, OnceCallback>)) {
|
||||||
|
+ const bool any_callbacks_erased = static_cast<CallbackListImpl*>(this)
|
||||||
|
+ ->CleanUpNullCallbacksPostIteration();
|
||||||
|
+
|
||||||
|
+ // Run |removal_callback_| if any callbacks were canceled or executed. Note
|
||||||
|
+ // that simply comparing list sizes before and after iterating cannot be
|
||||||
|
+ // done, since notification may result in Add()ing new callbacks as well as
|
||||||
|
+ // canceling them.
|
||||||
|
+ if (removal_callback_ && any_callbacks_erased) {
|
||||||
|
removal_callback_.Run(); // May delete |this|!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -264,21 +261,9 @@ class CallbackListBase {
|
||||||
|
private:
|
||||||
|
// Cancels the callback pointed to by |it|, which is guaranteed to be valid.
|
||||||
|
void CancelCallback(const typename Callbacks::iterator& it) {
|
||||||
|
- if (static_cast<CallbackListImpl*>(this)->CancelNullCallback(it)) {
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (iterating_) {
|
||||||
|
- // Calling erase() here is unsafe, since the loop in Notify() may be
|
||||||
|
- // referencing this same iterator, e.g. if adjacent callbacks'
|
||||||
|
- // Subscriptions are both destroyed when the first one is Run(). Just
|
||||||
|
- // reset the callback and let Notify() clean it up at the end.
|
||||||
|
- it->Reset();
|
||||||
|
- } else {
|
||||||
|
- callbacks_.erase(it);
|
||||||
|
- if (removal_callback_) {
|
||||||
|
- removal_callback_.Run(); // May delete |this|!
|
||||||
|
- }
|
||||||
|
+ if (static_cast<CallbackListImpl*>(this)->CancelCallback(it, iterating_) &&
|
||||||
|
+ removal_callback_) {
|
||||||
|
+ removal_callback_.Run(); // May delete |this|!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -304,23 +289,71 @@ class OnceCallbackList
|
||||||
|
// Runs the current callback, which may cancel it or any other callbacks.
|
||||||
|
template <typename... RunArgs>
|
||||||
|
void RunCallback(typename Traits::Callbacks::iterator it, RunArgs&&... args) {
|
||||||
|
- // OnceCallbacks still have Subscriptions with outstanding iterators;
|
||||||
|
- // splice() removes them from |callbacks_| without invalidating those.
|
||||||
|
- null_callbacks_.splice(null_callbacks_.end(), this->callbacks_, it);
|
||||||
|
+ // Do not splice here. Splicing during iteration breaks re-entrant Notify()
|
||||||
|
+ // by invalidating the outer loop's iterator. Splicing is deferred to
|
||||||
|
+ // CleanUpNullCallbacksPostIteration(), which is called when the outermost
|
||||||
|
+ // Notify() finishes.
|
||||||
|
|
||||||
|
// NOTE: Intentionally does not call std::forward<RunArgs>(args)...; see
|
||||||
|
// comments in Notify().
|
||||||
|
std::move(*it).Run(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
- // If |it| refers to an already-canceled callback, does any necessary cleanup
|
||||||
|
- // and returns true. Otherwise returns false.
|
||||||
|
- bool CancelNullCallback(const typename Traits::Callbacks::iterator& it) {
|
||||||
|
+ // Called during subscription destruction to cancel the callback. Returns true
|
||||||
|
+ // if the callback was removed from the active list and the generic removal
|
||||||
|
+ // callback should be executed. Returns false if the callback was already
|
||||||
|
+ // executed, or if the erasure is deferred due to active iteration.
|
||||||
|
+ bool CancelCallback(const typename Traits::Callbacks::iterator& it,
|
||||||
|
+ bool is_iterating) {
|
||||||
|
+ if (is_iterating) {
|
||||||
|
+ // During iteration, nodes cannot be safely erased from |callbacks_|
|
||||||
|
+ // without invalidating iterators. They also cannot be spliced into
|
||||||
|
+ // |null_callbacks_| right now. Thus, the node is reset and tracked for
|
||||||
|
+ // erasure in CleanUpNullCallbacksPostIteration().
|
||||||
|
+ it->Reset();
|
||||||
|
+ pending_erasures_.push_back(it);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (it->is_null()) {
|
||||||
|
+ // The callback already ran, so it's safely sitting in |null_callbacks_|.
|
||||||
|
null_callbacks_.erase(it);
|
||||||
|
- return true;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
- return false;
|
||||||
|
+
|
||||||
|
+ // The callback hasn't run yet, so it's still in |callbacks_|.
|
||||||
|
+ this->callbacks_.erase(it);
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Performs post-iteration cleanup. Successfully executed callbacks (which
|
||||||
|
+ // become null) are spliced into |null_callbacks_| to keep their
|
||||||
|
+ // Subscriptions' iterators valid. Callbacks explicitly canceled during
|
||||||
|
+ // iteration (tracked in |pending_erasures_|) are erased. Returns true if any
|
||||||
|
+ // callbacks were erased or spliced out.
|
||||||
|
+ bool CleanUpNullCallbacksPostIteration() {
|
||||||
|
+ bool any_spliced = false;
|
||||||
|
+ for (auto it = this->callbacks_.begin(); it != this->callbacks_.end();) {
|
||||||
|
+ if (it->is_null()) {
|
||||||
|
+ any_spliced = true;
|
||||||
|
+ auto next = std::next(it);
|
||||||
|
+ null_callbacks_.splice(null_callbacks_.end(), this->callbacks_, it);
|
||||||
|
+ it = next;
|
||||||
|
+ } else {
|
||||||
|
+ ++it;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bool any_erased = !pending_erasures_.empty();
|
||||||
|
+ for (auto pending_it : pending_erasures_) {
|
||||||
|
+ // Note: `pending_it` was originally an iterator into `callbacks_`, but
|
||||||
|
+ // the node it points to has just been spliced into `null_callbacks_`. The
|
||||||
|
+ // iterator itself remains valid and can now be used for erasure from
|
||||||
|
+ // `null_callbacks_`.
|
||||||
|
+ null_callbacks_.erase(pending_it);
|
||||||
|
+ }
|
||||||
|
+ pending_erasures_.clear();
|
||||||
|
+ return any_spliced || any_erased;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Holds null callbacks whose Subscriptions are still alive, so the
|
||||||
|
@@ -328,6 +361,11 @@ class OnceCallbackList
|
||||||
|
// OnceCallbacks, since RepeatingCallbacks are not canceled except by
|
||||||
|
// Subscription destruction.
|
||||||
|
typename Traits::Callbacks null_callbacks_;
|
||||||
|
+
|
||||||
|
+ // Holds iterators for callbacks canceled during iteration.
|
||||||
|
+ // Erasure is deferred to CleanUpNullCallbacksPostIteration() when iteration
|
||||||
|
+ // completes to prevent invalidating iterators that an outer loop might hold.
|
||||||
|
+ std::vector<typename Traits::Callbacks::iterator> pending_erasures_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Signature>
|
||||||
|
@@ -344,14 +382,29 @@ class RepeatingCallbackList
|
||||||
|
it->Run(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
- // If |it| refers to an already-canceled callback, does any necessary cleanup
|
||||||
|
- // and returns true. Otherwise returns false.
|
||||||
|
- bool CancelNullCallback(const typename Traits::Callbacks::iterator& it) {
|
||||||
|
- // Because at most one Subscription can point to a given callback, and
|
||||||
|
- // RepeatingCallbacks are only reset by CancelCallback(), no one should be
|
||||||
|
- // able to request cancellation of a canceled RepeatingCallback.
|
||||||
|
- DCHECK(!it->is_null());
|
||||||
|
- return false;
|
||||||
|
+ // Called during subscription destruction to cancel the callback. Returns true
|
||||||
|
+ // if the callback was removed from the active list and the generic removal
|
||||||
|
+ // callback should be executed. Returns false if the callback was already
|
||||||
|
+ // executed, or if the erasure is deferred due to active iteration.
|
||||||
|
+ bool CancelCallback(const typename Traits::Callbacks::iterator& it,
|
||||||
|
+ bool is_iterating) {
|
||||||
|
+ if (is_iterating) {
|
||||||
|
+ // During iteration, nodes cannot be safely erased from |callbacks_|
|
||||||
|
+ // without invalidating iterators. The node is reset and will be swept up
|
||||||
|
+ // by CleanUpNullCallbacksPostIteration().
|
||||||
|
+ it->Reset();
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this->callbacks_.erase(it);
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Performs post-iteration cleanup by erasing all canceled callbacks. Returns
|
||||||
|
+ // true if any callbacks were erased.
|
||||||
|
+ bool CleanUpNullCallbacksPostIteration() {
|
||||||
|
+ return std::erase_if(this->callbacks_,
|
||||||
|
+ [](const auto& cb) { return cb.is_null(); }) > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/base/callback_list_unittest.cc b/base/callback_list_unittest.cc
|
||||||
|
index 7474278525e5efecc0de903809a54d366896d524..a855443fbae862befbc3a2a484ea335632136e94 100644
|
||||||
|
--- a/base/callback_list_unittest.cc
|
||||||
|
+++ b/base/callback_list_unittest.cc
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
|
#include "base/memory/raw_ptr.h"
|
||||||
|
+#include "base/test/bind.h"
|
||||||
|
#include "base/test/test_future.h"
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
@@ -577,6 +578,30 @@ TEST(CallbackListTest, ReentrantNotify) {
|
||||||
|
EXPECT_EQ(1, d.total());
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Regression test for crbug.com/489381399: Verifies Notify() can be called
|
||||||
|
+// reentrantly for OnceCallbackList even if a callback is canceled during the
|
||||||
|
+// reentrant notification.
|
||||||
|
+TEST(CallbackListTest, OnceCallbackListCancelDuringReentrantNotify) {
|
||||||
|
+ OnceClosureList cb_reg;
|
||||||
|
+ CallbackListSubscription sub_a, sub_b;
|
||||||
|
+
|
||||||
|
+ auto cb_a = base::BindLambdaForTesting([&]() {
|
||||||
|
+ // Re-entrant notification.
|
||||||
|
+ cb_reg.Notify();
|
||||||
|
+ // After re-entrant notification returns, sub_b has been run. Destroying it
|
||||||
|
+ // now should be a no-op.
|
||||||
|
+ sub_b = {};
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ auto cb_b = base::DoNothing();
|
||||||
|
+
|
||||||
|
+ sub_a = cb_reg.Add(std::move(cb_a));
|
||||||
|
+ sub_b = cb_reg.Add(std::move(cb_b));
|
||||||
|
+
|
||||||
|
+ // This should not crash.
|
||||||
|
+ cb_reg.Notify();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST(CallbackListTest, ClearPreventsInvocation) {
|
||||||
|
Listener listener;
|
||||||
|
RepeatingClosureList cb_reg;
|
||||||
199
patches/chromium/cherry-pick-45c5a70d984d.patch
Normal file
199
patches/chromium/cherry-pick-45c5a70d984d.patch
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Date: Wed, 25 Feb 2026 03:24:19 -0800
|
||||||
|
Subject: Describe a vector of segments as "segments", not "tokens"
|
||||||
|
|
||||||
|
The specification uses the term "tokens" to refer to a sequence
|
||||||
|
of V8CSSUnparsedSegment objects, and CSSUnparsedValue has adopted
|
||||||
|
this terminology. While it is usually a good idea for Blink
|
||||||
|
to mirror the language used in specifications, "tokens" is very
|
||||||
|
confusing here, since it always means CSSParserTokens in every other
|
||||||
|
place in the style code.
|
||||||
|
|
||||||
|
Bug: 487117772
|
||||||
|
Change-Id: I2dc132c4e618e398e1f8bdabc03a8d2ab6c118e7
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7606599
|
||||||
|
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1590040}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
index 3d43306dd902b3071637e5d5d0af26e5ee47f141..67a4afde452f94ffb9ecbaeea104a3997c65b7b3 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
@@ -24,12 +24,12 @@ String FindVariableName(CSSParserTokenStream& stream) {
|
||||||
|
|
||||||
|
V8CSSUnparsedSegment* VariableReferenceValue(
|
||||||
|
const StringView& variable_name,
|
||||||
|
- const HeapVector<Member<V8CSSUnparsedSegment>>& tokens) {
|
||||||
|
+ const HeapVector<Member<V8CSSUnparsedSegment>>& segments) {
|
||||||
|
CSSUnparsedValue* unparsed_value;
|
||||||
|
- if (tokens.size() == 0) {
|
||||||
|
+ if (segments.size() == 0) {
|
||||||
|
unparsed_value = nullptr;
|
||||||
|
} else {
|
||||||
|
- unparsed_value = CSSUnparsedValue::Create(tokens);
|
||||||
|
+ unparsed_value = CSSUnparsedValue::Create(segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSSStyleVariableReferenceValue* variable_reference =
|
||||||
|
@@ -41,13 +41,13 @@ V8CSSUnparsedSegment* VariableReferenceValue(
|
||||||
|
HeapVector<Member<V8CSSUnparsedSegment>> ParserTokenStreamToTokens(
|
||||||
|
CSSParserTokenStream& stream) {
|
||||||
|
int nesting_level = 0;
|
||||||
|
- HeapVector<Member<V8CSSUnparsedSegment>> tokens;
|
||||||
|
+ HeapVector<Member<V8CSSUnparsedSegment>> segments;
|
||||||
|
StringBuilder builder;
|
||||||
|
while (stream.Peek().GetType() != kEOFToken) {
|
||||||
|
if (stream.Peek().FunctionId() == CSSValueID::kVar ||
|
||||||
|
stream.Peek().FunctionId() == CSSValueID::kEnv) {
|
||||||
|
if (!builder.empty()) {
|
||||||
|
- tokens.push_back(MakeGarbageCollected<V8CSSUnparsedSegment>(
|
||||||
|
+ segments.push_back(MakeGarbageCollected<V8CSSUnparsedSegment>(
|
||||||
|
builder.ReleaseString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ HeapVector<Member<V8CSSUnparsedSegment>> ParserTokenStreamToTokens(
|
||||||
|
if (stream.Peek().GetType() == CSSParserTokenType::kCommaToken) {
|
||||||
|
stream.Consume();
|
||||||
|
}
|
||||||
|
- tokens.push_back(VariableReferenceValue(
|
||||||
|
+ segments.push_back(VariableReferenceValue(
|
||||||
|
variable_name, ParserTokenStreamToTokens(stream)));
|
||||||
|
} else {
|
||||||
|
if (stream.Peek().GetBlockType() == CSSParserToken::kBlockStart) {
|
||||||
|
@@ -73,10 +73,10 @@ HeapVector<Member<V8CSSUnparsedSegment>> ParserTokenStreamToTokens(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!builder.empty()) {
|
||||||
|
- tokens.push_back(
|
||||||
|
+ segments.push_back(
|
||||||
|
MakeGarbageCollected<V8CSSUnparsedSegment>(builder.ReleaseString()));
|
||||||
|
}
|
||||||
|
- return tokens;
|
||||||
|
+ return segments;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
@@ -96,8 +96,8 @@ CSSUnparsedValue* CSSUnparsedValue::FromCSSVariableData(
|
||||||
|
V8CSSUnparsedSegment* CSSUnparsedValue::AnonymousIndexedGetter(
|
||||||
|
uint32_t index,
|
||||||
|
ExceptionState& exception_state) const {
|
||||||
|
- if (index < tokens_.size()) {
|
||||||
|
- return tokens_[index].Get();
|
||||||
|
+ if (index < segments_.size()) {
|
||||||
|
+ return segments_[index].Get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
@@ -106,20 +106,20 @@ IndexedPropertySetterResult CSSUnparsedValue::AnonymousIndexedSetter(
|
||||||
|
uint32_t index,
|
||||||
|
V8CSSUnparsedSegment* segment,
|
||||||
|
ExceptionState& exception_state) {
|
||||||
|
- if (index < tokens_.size()) {
|
||||||
|
- tokens_[index] = segment;
|
||||||
|
+ if (index < segments_.size()) {
|
||||||
|
+ segments_[index] = segment;
|
||||||
|
return IndexedPropertySetterResult::kIntercepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (index == tokens_.size()) {
|
||||||
|
- tokens_.push_back(segment);
|
||||||
|
+ if (index == segments_.size()) {
|
||||||
|
+ segments_.push_back(segment);
|
||||||
|
return IndexedPropertySetterResult::kIntercepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
exception_state.ThrowRangeError(
|
||||||
|
ExceptionMessages::IndexOutsideRange<unsigned>(
|
||||||
|
- "index", index, 0, ExceptionMessages::kInclusiveBound, tokens_.size(),
|
||||||
|
- ExceptionMessages::kInclusiveBound));
|
||||||
|
+ "index", index, 0, ExceptionMessages::kInclusiveBound,
|
||||||
|
+ segments_.size(), ExceptionMessages::kInclusiveBound));
|
||||||
|
return IndexedPropertySetterResult::kIntercepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -182,14 +182,14 @@ bool CSSUnparsedValue::AppendUnparsedString(
|
||||||
|
return false; // Cycle.
|
||||||
|
}
|
||||||
|
values_on_stack.insert(this);
|
||||||
|
- for (unsigned i = 0; i < tokens_.size(); i++) {
|
||||||
|
+ for (unsigned i = 0; i < segments_.size(); i++) {
|
||||||
|
if (i) {
|
||||||
|
builder.Append("/**/");
|
||||||
|
}
|
||||||
|
- switch (tokens_[i]->GetContentType()) {
|
||||||
|
+ switch (segments_[i]->GetContentType()) {
|
||||||
|
case V8CSSUnparsedSegment::ContentType::kCSSVariableReferenceValue: {
|
||||||
|
const auto* reference_value =
|
||||||
|
- tokens_[i]->GetAsCSSVariableReferenceValue();
|
||||||
|
+ segments_[i]->GetAsCSSVariableReferenceValue();
|
||||||
|
builder.Append("var(");
|
||||||
|
builder.Append(reference_value->variable());
|
||||||
|
if (reference_value->fallback()) {
|
||||||
|
@@ -203,7 +203,7 @@ bool CSSUnparsedValue::AppendUnparsedString(
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case V8CSSUnparsedSegment::ContentType::kString:
|
||||||
|
- builder.Append(tokens_[i]->GetAsString());
|
||||||
|
+ builder.Append(segments_[i]->GetAsString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
index c9dab7a0b3ffeaeb6b5d2ab50d876d40c38a760e..5d1961b170f14ae21ca8f69b3c3cd8af28f4478a 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
@@ -26,8 +26,8 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CSSUnparsedValue* Create(
|
||||||
|
- const HeapVector<Member<V8CSSUnparsedSegment>>& tokens) {
|
||||||
|
- return MakeGarbageCollected<CSSUnparsedValue>(tokens);
|
||||||
|
+ const HeapVector<Member<V8CSSUnparsedSegment>>& segments) {
|
||||||
|
+ return MakeGarbageCollected<CSSUnparsedValue>(segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blink-internal constructor
|
||||||
|
@@ -37,14 +37,14 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
static CSSUnparsedValue* FromCSSValue(const CSSUnparsedDeclarationValue&);
|
||||||
|
static CSSUnparsedValue* FromCSSVariableData(const CSSVariableData&);
|
||||||
|
static CSSUnparsedValue* FromString(const String& string) {
|
||||||
|
- HeapVector<Member<V8CSSUnparsedSegment>> tokens;
|
||||||
|
- tokens.push_back(MakeGarbageCollected<V8CSSUnparsedSegment>(string));
|
||||||
|
- return Create(tokens);
|
||||||
|
+ HeapVector<Member<V8CSSUnparsedSegment>> segments;
|
||||||
|
+ segments.push_back(MakeGarbageCollected<V8CSSUnparsedSegment>(string));
|
||||||
|
+ return Create(segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit CSSUnparsedValue(
|
||||||
|
- const HeapVector<Member<V8CSSUnparsedSegment>>& tokens)
|
||||||
|
- : tokens_(tokens) {}
|
||||||
|
+ const HeapVector<Member<V8CSSUnparsedSegment>>& segments)
|
||||||
|
+ : segments_(segments) {}
|
||||||
|
CSSUnparsedValue(const CSSUnparsedValue&) = delete;
|
||||||
|
CSSUnparsedValue& operator=(const CSSUnparsedValue&) = delete;
|
||||||
|
|
||||||
|
@@ -60,10 +60,10 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
V8CSSUnparsedSegment* segment,
|
||||||
|
ExceptionState& exception_state);
|
||||||
|
|
||||||
|
- wtf_size_t length() const { return tokens_.size(); }
|
||||||
|
+ wtf_size_t length() const { return segments_.size(); }
|
||||||
|
|
||||||
|
void Trace(Visitor* visitor) const override {
|
||||||
|
- visitor->Trace(tokens_);
|
||||||
|
+ visitor->Trace(segments_);
|
||||||
|
CSSStyleValue::Trace(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -81,7 +81,7 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
StringBuilder&,
|
||||||
|
HeapHashSet<Member<const CSSUnparsedValue>>& values_on_stack) const;
|
||||||
|
|
||||||
|
- HeapVector<Member<V8CSSUnparsedSegment>> tokens_;
|
||||||
|
+ HeapVector<Member<V8CSSUnparsedSegment>> segments_;
|
||||||
|
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(CSSUnparsedDeclarationValueTest, MixedList);
|
||||||
|
};
|
||||||
149
patches/chromium/cherry-pick-50b057660b4d.patch
Normal file
149
patches/chromium/cherry-pick-50b057660b4d.patch
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kai Ninomiya <kainino@chromium.org>
|
||||||
|
Date: Wed, 11 Mar 2026 14:52:44 -0700
|
||||||
|
Subject: [M146] Increment WebGL context generation number on context restore
|
||||||
|
|
||||||
|
Objects created while the context is lost should not be valid to use
|
||||||
|
after the context is restored.
|
||||||
|
- Replace number_of_context_losses_ with a "context generation number"
|
||||||
|
which increments on both context loss and context restore.
|
||||||
|
- Technically, it would make sense to increment it only on context
|
||||||
|
restore, but just in case any logic is relying on the current
|
||||||
|
behavior, increment it in both places.
|
||||||
|
- It's uint64_t just in case someone figures out how to increment it 4
|
||||||
|
billion times.
|
||||||
|
- Remove unused WebGLRenderingContextBase::number_of_context_losses_,
|
||||||
|
left over from before it was moved into WebGLContextObjectSupport.
|
||||||
|
|
||||||
|
(cherry picked from commit c1433740f3ea902fd6b15d63c4865ad60a3761f9)
|
||||||
|
|
||||||
|
Bug: 485935305
|
||||||
|
Change-Id: I1007217c8e69cfb8de4f117e0b7845ca574579c4
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7630664
|
||||||
|
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||||
|
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
|
||||||
|
Cr-Original-Commit-Position: refs/heads/main@{#1593726}
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7658823
|
||||||
|
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
|
||||||
|
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||||
|
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||||
|
Cr-Commit-Position: refs/branch-heads/7680@{#2370}
|
||||||
|
Cr-Branched-From: 76b7d80e5cda23fe6537eed26d68c92e995c7f39-refs/heads/main@{#1582197}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/modules/webgl/webgl_context_object_support.cc b/third_party/blink/renderer/modules/webgl/webgl_context_object_support.cc
|
||||||
|
index 6a3b1416354e7993e7a9ebd25c4ca08593105d9a..83941f8163a5e9425f2df8fd3bb98e1fd37537ad 100644
|
||||||
|
--- a/third_party/blink/renderer/modules/webgl/webgl_context_object_support.cc
|
||||||
|
+++ b/third_party/blink/renderer/modules/webgl/webgl_context_object_support.cc
|
||||||
|
@@ -22,7 +22,10 @@ WebGLContextObjectSupport::WebGLContextObjectSupport(
|
||||||
|
|
||||||
|
void WebGLContextObjectSupport::OnContextLost() {
|
||||||
|
DCHECK(!is_lost_);
|
||||||
|
- number_of_context_losses_++;
|
||||||
|
+ // Invalidate all past objects.
|
||||||
|
+ // (It may not be strictly necessary to do this here, since it's also done in
|
||||||
|
+ // OnContextRestored, but we did it historically, and there's no harm in it.)
|
||||||
|
+ context_generation_++;
|
||||||
|
is_lost_ = true;
|
||||||
|
gles2_interface_ = nullptr;
|
||||||
|
extensions_enabled_.reset();
|
||||||
|
@@ -31,6 +34,8 @@ void WebGLContextObjectSupport::OnContextLost() {
|
||||||
|
void WebGLContextObjectSupport::OnContextRestored(
|
||||||
|
gpu::gles2::GLES2Interface* gl) {
|
||||||
|
DCHECK(is_lost_);
|
||||||
|
+ // Invalidate all past objects.
|
||||||
|
+ context_generation_++;
|
||||||
|
is_lost_ = false;
|
||||||
|
gles2_interface_ = gl;
|
||||||
|
}
|
||||||
|
diff --git a/third_party/blink/renderer/modules/webgl/webgl_context_object_support.h b/third_party/blink/renderer/modules/webgl/webgl_context_object_support.h
|
||||||
|
index 907866bb21acf9647d1c0ecd791e642e96b734fc..ba8b79f8bb9db12058614982a625baaff5546af7 100644
|
||||||
|
--- a/third_party/blink/renderer/modules/webgl/webgl_context_object_support.h
|
||||||
|
+++ b/third_party/blink/renderer/modules/webgl/webgl_context_object_support.h
|
||||||
|
@@ -33,10 +33,10 @@ class MODULES_EXPORT WebGLContextObjectSupport : public ScriptWrappable {
|
||||||
|
bool IsWebGL2() const { return is_webgl2_; }
|
||||||
|
bool IsLost() const { return is_lost_; }
|
||||||
|
|
||||||
|
- // How many context losses there were, to check whether a WebGLObject was
|
||||||
|
- // created since the last context resoration or before that (and hence invalid
|
||||||
|
- // to use).
|
||||||
|
- uint32_t NumberOfContextLosses() const { return number_of_context_losses_; }
|
||||||
|
+ // Which "generation" the context is on (essentially, how many times it has
|
||||||
|
+ // been restored), to check whether a WebGLObject was created since the last
|
||||||
|
+ // context restoration, or before that (and hence invalid to use).
|
||||||
|
+ uint64_t GetContextGeneration() const { return context_generation_; }
|
||||||
|
|
||||||
|
bool ExtensionEnabled(WebGLExtensionName name) const {
|
||||||
|
return extensions_enabled_.test(name);
|
||||||
|
@@ -65,7 +65,7 @@ class MODULES_EXPORT WebGLContextObjectSupport : public ScriptWrappable {
|
||||||
|
std::bitset<kWebGLExtensionNameCount> extensions_enabled_ = {};
|
||||||
|
raw_ptr<gpu::gles2::GLES2Interface> gles2_interface_ = nullptr;
|
||||||
|
|
||||||
|
- uint32_t number_of_context_losses_ = 0;
|
||||||
|
+ uint64_t context_generation_ = 0;
|
||||||
|
bool is_lost_ = true;
|
||||||
|
bool is_webgl2_;
|
||||||
|
};
|
||||||
|
diff --git a/third_party/blink/renderer/modules/webgl/webgl_object.cc b/third_party/blink/renderer/modules/webgl/webgl_object.cc
|
||||||
|
index 9d984de0073796f23a5038bfc0a51ec676179765..07e0a9a4aa3406a1298a677a3159edadc5f2cbb5 100644
|
||||||
|
--- a/third_party/blink/renderer/modules/webgl/webgl_object.cc
|
||||||
|
+++ b/third_party/blink/renderer/modules/webgl/webgl_object.cc
|
||||||
|
@@ -33,9 +33,9 @@ namespace blink {
|
||||||
|
|
||||||
|
WebGLObject::WebGLObject(WebGLContextObjectSupport* context)
|
||||||
|
: context_(context),
|
||||||
|
- cached_number_of_context_losses_(std::numeric_limits<uint32_t>::max()) {
|
||||||
|
+ context_generation_at_creation_(std::numeric_limits<uint64_t>::max()) {
|
||||||
|
if (context_) {
|
||||||
|
- cached_number_of_context_losses_ = context->NumberOfContextLosses();
|
||||||
|
+ context_generation_at_creation_ = context->GetContextGeneration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ bool WebGLObject::Validate(const WebGLContextObjectSupport* context) const {
|
||||||
|
// the objects they ever created, so there's no way to invalidate them
|
||||||
|
// eagerly during context loss. The invalidation is discovered lazily.
|
||||||
|
return (context == context_ && context_ != nullptr &&
|
||||||
|
- cached_number_of_context_losses_ == context->NumberOfContextLosses());
|
||||||
|
+ context_generation_at_creation_ == context->GetContextGeneration());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebGLObject::SetObject(GLuint object) {
|
||||||
|
@@ -71,7 +71,7 @@ void WebGLObject::DeleteObject(gpu::gles2::GLES2Interface* gl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (context_->NumberOfContextLosses() != cached_number_of_context_losses_) {
|
||||||
|
+ if (context_->GetContextGeneration() != context_generation_at_creation_) {
|
||||||
|
// This object has been invalidated.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
diff --git a/third_party/blink/renderer/modules/webgl/webgl_object.h b/third_party/blink/renderer/modules/webgl/webgl_object.h
|
||||||
|
index bb56df0f99e8e8432e03442feb9302b8dde27d01..97caa90e34288911b1a827e60c2569544d2b8f69 100644
|
||||||
|
--- a/third_party/blink/renderer/modules/webgl/webgl_object.h
|
||||||
|
+++ b/third_party/blink/renderer/modules/webgl/webgl_object.h
|
||||||
|
@@ -123,9 +123,9 @@ class WebGLObject : public ScriptWrappable {
|
||||||
|
|
||||||
|
GLuint object_ = 0;
|
||||||
|
|
||||||
|
- // This was the number of context losses of the object's associated
|
||||||
|
- // WebGLContext at the time this object was created.
|
||||||
|
- uint32_t cached_number_of_context_losses_;
|
||||||
|
+ // The context generation number of the associated WebGLContext when the
|
||||||
|
+ // object was created, to prevent reuse in later generations.
|
||||||
|
+ uint64_t context_generation_at_creation_;
|
||||||
|
|
||||||
|
unsigned attachment_count_ = 0;
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
|
||||||
|
index 48b5dd8f3baffed5ae898e029f7dd187ddf20ce3..33554fe5b9cdbbd703b6e02d6131104a4e591f4e 100644
|
||||||
|
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
|
||||||
|
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
|
||||||
|
@@ -2064,8 +2064,6 @@ class MODULES_EXPORT WebGLRenderingContextBase
|
||||||
|
|
||||||
|
bool has_been_drawn_to_ = false;
|
||||||
|
|
||||||
|
- uint32_t number_of_context_losses_ = 0;
|
||||||
|
-
|
||||||
|
// Tracks if the context has ever called glBeginPixelLocalStorageANGLE. If it
|
||||||
|
// has, we need to start using the pixel local storage interrupt mechanism
|
||||||
|
// when we take over the client's context.
|
||||||
201
patches/chromium/cherry-pick-5efc7a0127a6.patch
Normal file
201
patches/chromium/cherry-pick-5efc7a0127a6.patch
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Date: Wed, 25 Feb 2026 12:17:00 -0800
|
||||||
|
Subject: Validate CSSUnparsedValues upon assignment
|
||||||
|
|
||||||
|
CSS Typed OM has a concept of a value "matching a grammar" (or not)
|
||||||
|
upon assignment to a property [1]. For CSSUnparsedValues, we currently
|
||||||
|
don't perform any significant validation, and as a consequence
|
||||||
|
we allow "invalid" CSSUnparsedDeclarationValues to be created
|
||||||
|
(causing DCHECKs later in the pipeline).
|
||||||
|
|
||||||
|
This CL makes sure values can be parsed using CSSVariableParser::
|
||||||
|
ConsumeUnparsedDeclaration before assignment.
|
||||||
|
|
||||||
|
We're still not handling the value in the context of the destination
|
||||||
|
property, which we probably should. This is also a problem with
|
||||||
|
current state of things, however, so for now the goal is primarily
|
||||||
|
to avoid the DCHECKs in Issue 484751092.
|
||||||
|
|
||||||
|
Finally, I opened an issue against the specification [2], which
|
||||||
|
currently doesn't define any of this.
|
||||||
|
|
||||||
|
[1] https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation
|
||||||
|
[2] https://github.com/w3c/csswg-drafts/issues/13547
|
||||||
|
|
||||||
|
Fixed: 484751092
|
||||||
|
Change-Id: Id7f888a6df8c02ade24910900f5d01909cb2dfad
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7595347
|
||||||
|
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
|
||||||
|
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1590110}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl
|
||||||
|
index edfa73a57d30ebd4f9a7147702df42b836f7d82b..4442ba0872ca4c739596b546e6d3b600c5a31598 100644
|
||||||
|
--- a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl
|
||||||
|
+++ b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
|
||||||
|
+#include "third_party/blink/renderer/core/css/cssom/css_unparsed_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/cssom_keywords.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/properties/css_property.h"
|
||||||
|
@@ -105,8 +106,8 @@ bool CSSOMTypes::PropertyCanTake(CSSPropertyID id,
|
||||||
|
: CSSPropertyName(id);
|
||||||
|
return unsupported_style_value->IsValidFor(name);
|
||||||
|
}
|
||||||
|
- if (value.GetType() == CSSStyleValue::kUnparsedType) {
|
||||||
|
- return true;
|
||||||
|
+ if (auto* unparsed_value = DynamicTo<CSSUnparsedValue>(value)) {
|
||||||
|
+ return unparsed_value->IsValidDeclarationValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
index 9c6bb62d044f804b0ce7bc8df398d77695cf950c..17a86e1292d76ff0b0c74b701750c0e972b4d885 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
|
||||||
|
@@ -4,11 +4,13 @@
|
||||||
|
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_unparsed_value.h"
|
||||||
|
|
||||||
|
+#include "css_style_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/css_unparsed_declaration_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/css_variable_data.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/cssom/css_style_variable_reference_value.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/parser/css_parser_token_stream.h"
|
||||||
|
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
|
||||||
|
+#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
|
||||||
|
#include "third_party/blink/renderer/core/css_value_keywords.h"
|
||||||
|
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
|
||||||
|
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
|
||||||
|
@@ -123,6 +125,10 @@ IndexedPropertySetterResult CSSUnparsedValue::AnonymousIndexedSetter(
|
||||||
|
return IndexedPropertySetterResult::kIntercepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool CSSUnparsedValue::IsValidDeclarationValue() const {
|
||||||
|
+ return IsValidDeclarationValue(ToStringInternal());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const CSSValue* CSSUnparsedValue::ToCSSValue() const {
|
||||||
|
String unparsed_string = ToStringInternal();
|
||||||
|
|
||||||
|
@@ -131,12 +137,40 @@ const CSSValue* CSSUnparsedValue::ToCSSValue() const {
|
||||||
|
MakeGarbageCollected<CSSVariableData>());
|
||||||
|
}
|
||||||
|
|
||||||
|
+ CHECK(IsValidDeclarationValue(unparsed_string));
|
||||||
|
+ // The call to IsValidDeclarationValue() above also creates a CSSVariableData
|
||||||
|
+ // to carry out its check. It would be nice to use that here, but WPTs
|
||||||
|
+ // expect leading whitespace to be preserved, even though it's not possible
|
||||||
|
+ // to create such declaration values normally.
|
||||||
|
+ CSSVariableData* variable_data =
|
||||||
|
+ CSSVariableData::Create(unparsed_string,
|
||||||
|
+ /*is_animation_tainted=*/false,
|
||||||
|
+ /*is_attr_tainted=*/false,
|
||||||
|
+ /*needs_variable_resolution=*/false);
|
||||||
|
+
|
||||||
|
// TODO(crbug.com/985028): We should probably propagate the CSSParserContext
|
||||||
|
// to here.
|
||||||
|
- return MakeGarbageCollected<CSSUnparsedDeclarationValue>(
|
||||||
|
- CSSVariableData::Create(unparsed_string, false /* is_animation_tainted */,
|
||||||
|
- false /* is_attr_tainted */,
|
||||||
|
- false /* needs_variable_resolution */));
|
||||||
|
+ return MakeGarbageCollected<CSSUnparsedDeclarationValue>(variable_data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool CSSUnparsedValue::IsValidDeclarationValue(const String& string) {
|
||||||
|
+ CSSParserTokenStream stream(string);
|
||||||
|
+ bool important_unused;
|
||||||
|
+ // This checks that the value does not violate the "argument grammar" [1]
|
||||||
|
+ // of any substitution functions, and that it is a valid <declaration-value>
|
||||||
|
+ // otherwise.
|
||||||
|
+ //
|
||||||
|
+ // [1] https://drafts.csswg.org/css-values-5/#argument-grammar
|
||||||
|
+ //
|
||||||
|
+ // TODO(andruud): 'restricted_value' depends on the destination property.
|
||||||
|
+ return CSSVariableParser::ConsumeUnparsedDeclaration(
|
||||||
|
+ stream,
|
||||||
|
+ /*allow_important_annotation=*/false,
|
||||||
|
+ /*is_animation_tainted=*/false,
|
||||||
|
+ /*must_contain_variable_reference=*/false,
|
||||||
|
+ /*restricted_value=*/false,
|
||||||
|
+ /*comma_ends_declaration=*/false, important_unused,
|
||||||
|
+ *StrictCSSParserContext(SecureContextMode::kInsecureContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
String CSSUnparsedValue::ToStringInternal() const {
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
index ec7e3ed708f406d7a61fdb370b2eed8a8297cffb..7fd66aed677e31046a1bd206854b2cbeac07c25b 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
|
||||||
|
@@ -48,6 +48,14 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
CSSUnparsedValue(const CSSUnparsedValue&) = delete;
|
||||||
|
CSSUnparsedValue& operator=(const CSSUnparsedValue&) = delete;
|
||||||
|
|
||||||
|
+ // True if this CSSUnparsedValue can be converted into
|
||||||
|
+ // a CSSUnparsedDeclarationValue.
|
||||||
|
+ //
|
||||||
|
+ // We may want to ban some invalid values earlier, see:
|
||||||
|
+ // https://github.com/w3c/csswg-drafts/issues/13547
|
||||||
|
+ bool IsValidDeclarationValue() const;
|
||||||
|
+
|
||||||
|
+ // Requires IsValidDeclarationValue()==true.
|
||||||
|
const CSSValue* ToCSSValue() const override;
|
||||||
|
|
||||||
|
StyleValueType GetType() const override { return kUnparsedType; }
|
||||||
|
@@ -68,6 +76,7 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
+ static bool IsValidDeclarationValue(const String&);
|
||||||
|
String ToStringInternal() const;
|
||||||
|
String SerializeSegments() const;
|
||||||
|
// Return 'false' if there is a cycle in the serialization.
|
||||||
|
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-invalid-untyped-value-crash.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-invalid-untyped-value-crash.html
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..ce618bf38fe651297b969ffdc16e212dee6a3688
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/set-invalid-untyped-value-crash.html
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+<!DOCTYPE html>
|
||||||
|
+<title>Crash when setting invalid CSSUnparsedValue</title>
|
||||||
|
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/13547">
|
||||||
|
+<div id=target></div>
|
||||||
|
+<script>
|
||||||
|
+ let examples = [
|
||||||
|
+ 'var()',
|
||||||
|
+ 'var(,)',
|
||||||
|
+ 'var(0)',
|
||||||
|
+ 'env()',
|
||||||
|
+ 'env(,)',
|
||||||
|
+ 'env(0)',
|
||||||
|
+ 'attr()',
|
||||||
|
+ 'attr(,)',
|
||||||
|
+ 'attr(0)',
|
||||||
|
+ 'if()',
|
||||||
|
+ 'if(,)',
|
||||||
|
+ 'if(0)',
|
||||||
|
+ '--f()',
|
||||||
|
+ '--f(,)',
|
||||||
|
+ '--f(0)',
|
||||||
|
+ 'thing!!!',
|
||||||
|
+ 'var(--x) !important',
|
||||||
|
+ ];
|
||||||
|
+ // Some of the above cases may be valid. That's fine; just don't crash.
|
||||||
|
+
|
||||||
|
+ for (let e of examples) {
|
||||||
|
+ try {
|
||||||
|
+ let value = new CSSUnparsedValue([e]);
|
||||||
|
+ target.attributeStyleMap.set('width', value);
|
||||||
|
+ // One of the two above statements should likely throw an exception.
|
||||||
|
+ // If they don't, then we should at least not crash on get():
|
||||||
|
+ target.attributeStyleMap.get('width');
|
||||||
|
+ } catch (e) {
|
||||||
|
+ // Intentionally empty.
|
||||||
|
+ }
|
||||||
|
+ target.offsetTop;
|
||||||
|
+ }
|
||||||
|
+</script>
|
||||||
401
patches/chromium/cherry-pick-89b42d2d3326.patch
Normal file
401
patches/chromium/cherry-pick-89b42d2d3326.patch
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alvin Ji <alvinji@chromium.org>
|
||||||
|
Date: Wed, 18 Mar 2026 21:55:14 -0700
|
||||||
|
Subject: WebUSB: Strengthen control transfer protection for protected classes
|
||||||
|
|
||||||
|
Strengthens control transfer permissions to block requests targeting
|
||||||
|
protected interface classes like HID or Mass Storage. Requests are now
|
||||||
|
scrutinized for protected interfaces via the wIndex field regardless of
|
||||||
|
recipient. Standard requests for device-level management remain allowed.
|
||||||
|
This behavior is gated by the kWebUsbProtectedClassControlTransferBlock
|
||||||
|
feature flag.
|
||||||
|
|
||||||
|
Bug: 489711638
|
||||||
|
Change-Id: Ic69c88f81e2a10abcaa80832b330d3789493f3b2
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7677820
|
||||||
|
Reviewed-by: Reilly Grant <reillyg@chromium.org>
|
||||||
|
Commit-Queue: Alvin Ji <alvinji@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1601756}
|
||||||
|
|
||||||
|
diff --git a/services/device/public/cpp/device_features.cc b/services/device/public/cpp/device_features.cc
|
||||||
|
index 1345a85271139e702dd371f72f35f5e466630169..c290276590ec50535533d3569cd38c5710b42252 100644
|
||||||
|
--- a/services/device/public/cpp/device_features.cc
|
||||||
|
+++ b/services/device/public/cpp/device_features.cc
|
||||||
|
@@ -34,6 +34,12 @@ BASE_FEATURE(kWebUsbBlocklist,
|
||||||
|
"WebUSBBlocklist",
|
||||||
|
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||||
|
|
||||||
|
+// When enabled, WebUSB control transfers are blocked if they target a
|
||||||
|
+// protected interface class, even if the recipient is not set to interface
|
||||||
|
+// or endpoint. This protects devices which ignore this field.
|
||||||
|
+BASE_FEATURE(kWebUsbProtectedClassControlTransferBlock,
|
||||||
|
+ base::FEATURE_ENABLED_BY_DEFAULT);
|
||||||
|
+
|
||||||
|
// When enabled, accessing the navigator.hid attribute does not prevent the
|
||||||
|
// frame from entering the back forward cache.
|
||||||
|
BASE_FEATURE(kWebHidAttributeAllowsBackForwardCache,
|
||||||
|
diff --git a/services/device/public/cpp/device_features.h b/services/device/public/cpp/device_features.h
|
||||||
|
index af05fafcbfdfb00e5a150e6c813e42f5903c270d..e69af38b0913b07cd23ed401183a3569164c852d 100644
|
||||||
|
--- a/services/device/public/cpp/device_features.h
|
||||||
|
+++ b/services/device/public/cpp/device_features.h
|
||||||
|
@@ -23,6 +23,8 @@ DEVICE_FEATURES_EXPORT BASE_DECLARE_FEATURE(
|
||||||
|
DEVICE_FEATURES_EXPORT BASE_DECLARE_FEATURE(kGenericSensorExtraClasses);
|
||||||
|
DEVICE_FEATURES_EXPORT BASE_DECLARE_FEATURE(kSerialPortConnected);
|
||||||
|
DEVICE_FEATURES_EXPORT BASE_DECLARE_FEATURE(kWebUsbBlocklist);
|
||||||
|
+DEVICE_FEATURES_EXPORT BASE_DECLARE_FEATURE(
|
||||||
|
+ kWebUsbProtectedClassControlTransferBlock);
|
||||||
|
DEVICE_FEATURES_EXPORT BASE_DECLARE_FEATURE(
|
||||||
|
kWebHidAttributeAllowsBackForwardCache);
|
||||||
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
diff --git a/services/device/usb/mojo/BUILD.gn b/services/device/usb/mojo/BUILD.gn
|
||||||
|
index d2398c6ea481ca072af68a562c1be616d97c2427..5c2f1aba2f640f0af6ac037a3922123514f6e03b 100644
|
||||||
|
--- a/services/device/usb/mojo/BUILD.gn
|
||||||
|
+++ b/services/device/usb/mojo/BUILD.gn
|
||||||
|
@@ -17,6 +17,7 @@ source_set("mojo") {
|
||||||
|
deps = [
|
||||||
|
"//mojo/public/cpp/bindings",
|
||||||
|
"//net",
|
||||||
|
+ "//services/device/public/cpp:device_features",
|
||||||
|
"//services/device/public/cpp/usb",
|
||||||
|
"//services/device/public/mojom:usb",
|
||||||
|
"//services/device/public/mojom:usb_test",
|
||||||
|
diff --git a/services/device/usb/mojo/device_impl.cc b/services/device/usb/mojo/device_impl.cc
|
||||||
|
index fb11f7ff5eae436acf45001e656374f882c22708..bf18dbc6ca0f456046b2f2ea6636587bfceb3071 100644
|
||||||
|
--- a/services/device/usb/mojo/device_impl.cc
|
||||||
|
+++ b/services/device/usb/mojo/device_impl.cc
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#include "base/memory/ptr_util.h"
|
||||||
|
#include "base/memory/ref_counted_memory.h"
|
||||||
|
#include "base/strings/stringprintf.h"
|
||||||
|
+#include "services/device/public/cpp/device_features.h"
|
||||||
|
#include "services/device/public/cpp/usb/usb_utils.h"
|
||||||
|
#include "services/device/usb/usb_device.h"
|
||||||
|
#include "third_party/blink/public/common/features.h"
|
||||||
|
@@ -156,31 +157,75 @@ void DeviceImpl::CloseHandle() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceImpl::HasControlTransferPermission(
|
||||||
|
+ mojom::UsbControlTransferType type,
|
||||||
|
UsbControlTransferRecipient recipient,
|
||||||
|
uint16_t index) {
|
||||||
|
DCHECK(device_handle_);
|
||||||
|
|
||||||
|
- if (recipient != UsbControlTransferRecipient::INTERFACE &&
|
||||||
|
- recipient != UsbControlTransferRecipient::ENDPOINT) {
|
||||||
|
+ // STANDARD requests to the DEVICE or OTHER recipients (e.g. GET_DESCRIPTOR)
|
||||||
|
+ // are fundamental for device discovery and management. These requests are
|
||||||
|
+ // always permitted because the USB 2.0 spec (Section 9.3) defines the usage
|
||||||
|
+ // of the `index` field (wIndex in the spec) for these types as either 0 or a
|
||||||
|
+ // Language ID. Since they are not used for interface-based routing, they
|
||||||
|
+ // are always allowed.
|
||||||
|
+ if (type == mojom::UsbControlTransferType::STANDARD &&
|
||||||
|
+ (recipient == UsbControlTransferRecipient::DEVICE ||
|
||||||
|
+ recipient == UsbControlTransferRecipient::OTHER)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mojom::UsbConfigurationInfo* config = device_->GetActiveConfiguration();
|
||||||
|
- if (!config)
|
||||||
|
+ if (!config) {
|
||||||
|
return false;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ // Identify the interface targeted by this request.
|
||||||
|
const mojom::UsbInterfaceInfo* interface = nullptr;
|
||||||
|
if (recipient == UsbControlTransferRecipient::ENDPOINT) {
|
||||||
|
+ // For the ENDPOINT recipient, the low byte of `index` is the endpoint
|
||||||
|
+ // address. We look up the interface that owns this endpoint.
|
||||||
|
interface = device_handle_->FindInterfaceByEndpoint(index & 0xff);
|
||||||
|
} else {
|
||||||
|
+ // For the INTERFACE recipient, the low byte of `index` is the interface
|
||||||
|
+ // number.
|
||||||
|
+ // For DEVICE and OTHER recipients, the USB spec allows `index` to be used
|
||||||
|
+ // arbitrarily by the vendor/class. We treat the low byte of `index` as a
|
||||||
|
+ // candidate interface ID to prevent routing bypasses.
|
||||||
|
auto interface_it =
|
||||||
|
std::ranges::find(config->interfaces, index & 0xff,
|
||||||
|
&mojom::UsbInterfaceInfo::interface_number);
|
||||||
|
- if (interface_it != config->interfaces.end())
|
||||||
|
+ if (interface_it != config->interfaces.end()) {
|
||||||
|
interface = interface_it->get();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- return interface != nullptr;
|
||||||
|
+ // If the request targets a protected interface class (e.g. HID, Mass
|
||||||
|
+ // Storage), it must be blocked. This prevents a site from communicating
|
||||||
|
+ // with a protected interface,
|
||||||
|
+ // 1. by explicitly targeting an INTERFACE or ENDPOINT recipient, or
|
||||||
|
+ // 2. VENDOR or CLASS requests to the DEVICE or OTHER recipient where
|
||||||
|
+ // index looks like an interface number in case the device will
|
||||||
|
+ // respond to these requests despite an incorrectly set recipient.
|
||||||
|
+ if (interface && base::FeatureList::IsEnabled(
|
||||||
|
+ features::kWebUsbProtectedClassControlTransferBlock)) {
|
||||||
|
+ for (const auto& alternate : interface->alternates) {
|
||||||
|
+ if (blocked_interface_classes_.contains(alternate->class_code)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // For requests explicitly targeting an INTERFACE or ENDPOINT, the interface
|
||||||
|
+ // must actually exist in the current configuration.
|
||||||
|
+ if (recipient == UsbControlTransferRecipient::INTERFACE ||
|
||||||
|
+ recipient == UsbControlTransferRecipient::ENDPOINT) {
|
||||||
|
+ return interface != nullptr;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // For DEVICE and OTHER recipients, if we reached here, it means either no
|
||||||
|
+ // interface was identified by wIndex, or the interface it identified is
|
||||||
|
+ // not protected. These requests are allowed for device-level management.
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
@@ -343,7 +388,8 @@ void DeviceImpl::ControlTransferIn(UsbControlTransferParamsPtr params,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (HasControlTransferPermission(params->recipient, params->index)) {
|
||||||
|
+ if (HasControlTransferPermission(params->type, params->recipient,
|
||||||
|
+ params->index)) {
|
||||||
|
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(length);
|
||||||
|
device_handle_->ControlTransfer(
|
||||||
|
UsbTransferDirection::INBOUND, params->type, params->recipient,
|
||||||
|
@@ -366,7 +412,8 @@ void DeviceImpl::ControlTransferOut(UsbControlTransferParamsPtr params,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (HasControlTransferPermission(params->recipient, params->index) &&
|
||||||
|
+ if (HasControlTransferPermission(params->type, params->recipient,
|
||||||
|
+ params->index) &&
|
||||||
|
(allow_security_key_requests_ ||
|
||||||
|
!IsAndroidSecurityKeyRequest(params, data))) {
|
||||||
|
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(data);
|
||||||
|
diff --git a/services/device/usb/mojo/device_impl.h b/services/device/usb/mojo/device_impl.h
|
||||||
|
index ddcd3b49e6ae2ec8e08dbbd41c193db4d8a21434..8651ece839b6da653bcb7a7aba238ff37d15095e 100644
|
||||||
|
--- a/services/device/usb/mojo/device_impl.h
|
||||||
|
+++ b/services/device/usb/mojo/device_impl.h
|
||||||
|
@@ -51,6 +51,7 @@ class DeviceImpl : public mojom::UsbDevice, public device::UsbDevice::Observer {
|
||||||
|
|
||||||
|
// Checks interface permissions for control transfers.
|
||||||
|
bool HasControlTransferPermission(
|
||||||
|
+ mojom::UsbControlTransferType type,
|
||||||
|
mojom::UsbControlTransferRecipient recipient,
|
||||||
|
uint16_t index);
|
||||||
|
|
||||||
|
diff --git a/services/device/usb/mojo/device_impl_unittest.cc b/services/device/usb/mojo/device_impl_unittest.cc
|
||||||
|
index 403de59eb1d8bf2fe19a21e3b0c7ee9c172bd323..984a64f9242e0bca91efb5549f6c02e7206b0d89 100644
|
||||||
|
--- a/services/device/usb/mojo/device_impl_unittest.cc
|
||||||
|
+++ b/services/device/usb/mojo/device_impl_unittest.cc
|
||||||
|
@@ -27,11 +27,13 @@
|
||||||
|
#include "base/strings/stringprintf.h"
|
||||||
|
#include "base/task/sequenced_task_runner.h"
|
||||||
|
#include "base/test/bind.h"
|
||||||
|
+#include "base/test/scoped_feature_list.h"
|
||||||
|
#include "base/test/task_environment.h"
|
||||||
|
#include "base/test/test_future.h"
|
||||||
|
#include "mojo/public/cpp/bindings/receiver.h"
|
||||||
|
#include "mojo/public/cpp/bindings/remote.h"
|
||||||
|
#include "mojo/public/cpp/test_support/test_utils.h"
|
||||||
|
+#include "services/device/public/cpp/device_features.h"
|
||||||
|
#include "services/device/usb/mock_usb_device.h"
|
||||||
|
#include "services/device/usb/mock_usb_device_handle.h"
|
||||||
|
#include "services/device/usb/usb_descriptors.h"
|
||||||
|
@@ -814,7 +816,7 @@ TEST_F(USBDeviceImplTest, ClaimProtectedInterface) {
|
||||||
|
|
||||||
|
// The second interface implements a class which has been blocked above.
|
||||||
|
AddMockConfig(
|
||||||
|
- ConfigBuilder(/*value=*/1)
|
||||||
|
+ ConfigBuilder(/*configuration_value=*/1)
|
||||||
|
.AddInterface(/*interface_number=*/0, /*alternate_setting=*/0,
|
||||||
|
/*class_code=*/1, /*subclass_code=*/0,
|
||||||
|
/*protocol_code=*/0)
|
||||||
|
@@ -976,6 +978,187 @@ TEST_F(USBDeviceImplTest, ControlTransfer) {
|
||||||
|
EXPECT_CALL(mock_handle(), Close());
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Test control transfers to an interface with a protected class only work for
|
||||||
|
+// STANDARD type, not VENDOR or CLASS.
|
||||||
|
+TEST_F(USBDeviceImplTest, ControlTransferProtectedClassBlock) {
|
||||||
|
+ // Block interface class 2.
|
||||||
|
+ mojo::Remote<mojom::UsbDevice> device =
|
||||||
|
+ GetMockDeviceProxyWithBlockedInterfaces(base::span_from_ref(uint8_t{2}));
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_device(), OpenInternal(_));
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ base::test::TestFuture<mojom::UsbOpenDeviceResultPtr> future;
|
||||||
|
+ device->Open(future.GetCallback());
|
||||||
|
+ EXPECT_TRUE(future.Get()->is_success());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Interface 7 has class 2 (blocked).
|
||||||
|
+ AddMockConfig(ConfigBuilder(/*configuration_value=*/1)
|
||||||
|
+ .AddInterface(/*interface_number=*/7,
|
||||||
|
+ /*alternate_setting=*/0,
|
||||||
|
+ /*class_code=*/2, /*subclass_code=*/0,
|
||||||
|
+ /*protocol_code=*/0)
|
||||||
|
+ .Build());
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_handle(), SetConfigurationInternal(1, _));
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->SetConfiguration(
|
||||||
|
+ 1, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ // A VENDOR request to the DEVICE with index 7 (targeting the blocked
|
||||||
|
+ // interface) should be blocked.
|
||||||
|
+ auto params = mojom::UsbControlTransferParams::New();
|
||||||
|
+ params->type = UsbControlTransferType::VENDOR;
|
||||||
|
+ params->recipient = UsbControlTransferRecipient::DEVICE;
|
||||||
|
+ params->request = 5;
|
||||||
|
+ params->value = 6;
|
||||||
|
+ params->index = 7;
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->ControlTransferIn(
|
||||||
|
+ std::move(params), 8, 0,
|
||||||
|
+ base::BindOnce(&ExpectTransferInAndThen,
|
||||||
|
+ mojom::UsbTransferStatus::PERMISSION_DENIED,
|
||||||
|
+ std::vector<uint8_t>(), loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ // A CLASS request to the DEVICE with index 7 (targeting the blocked
|
||||||
|
+ // interface) should be blocked.
|
||||||
|
+ auto params = mojom::UsbControlTransferParams::New();
|
||||||
|
+ params->type = UsbControlTransferType::CLASS;
|
||||||
|
+ params->recipient = UsbControlTransferRecipient::DEVICE;
|
||||||
|
+ params->request = 5;
|
||||||
|
+ params->value = 6;
|
||||||
|
+ params->index = 7;
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->ControlTransferIn(
|
||||||
|
+ std::move(params), 8, 0,
|
||||||
|
+ base::BindOnce(&ExpectTransferInAndThen,
|
||||||
|
+ mojom::UsbTransferStatus::PERMISSION_DENIED,
|
||||||
|
+ std::vector<uint8_t>(), loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ // A STANDARD request to the DEVICE with index 7 should still be allowed
|
||||||
|
+ // even if index 7 matches a blocked interface.
|
||||||
|
+ std::vector<uint8_t> fake_data = {1, 2, 3};
|
||||||
|
+ AddMockInboundData(fake_data);
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_handle(),
|
||||||
|
+ ControlTransferInternal(UsbTransferDirection::INBOUND,
|
||||||
|
+ UsbControlTransferType::STANDARD,
|
||||||
|
+ UsbControlTransferRecipient::DEVICE, 5,
|
||||||
|
+ 6, 7, _, 0, _));
|
||||||
|
+
|
||||||
|
+ auto params = mojom::UsbControlTransferParams::New();
|
||||||
|
+ params->type = UsbControlTransferType::STANDARD;
|
||||||
|
+ params->recipient = UsbControlTransferRecipient::DEVICE;
|
||||||
|
+ params->request = 5;
|
||||||
|
+ params->value = 6;
|
||||||
|
+ params->index = 7;
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->ControlTransferIn(
|
||||||
|
+ std::move(params), static_cast<uint32_t>(fake_data.size()), 0,
|
||||||
|
+ base::BindOnce(&ExpectTransferInAndThen,
|
||||||
|
+ mojom::UsbTransferStatus::COMPLETED, fake_data,
|
||||||
|
+ loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ // A STANDARD request to the INTERFACE with index 7 (targeting the blocked
|
||||||
|
+ // interface) should be blocked.
|
||||||
|
+ auto params = mojom::UsbControlTransferParams::New();
|
||||||
|
+ params->type = UsbControlTransferType::STANDARD;
|
||||||
|
+ params->recipient = UsbControlTransferRecipient::INTERFACE;
|
||||||
|
+ params->request = 5;
|
||||||
|
+ params->value = 6;
|
||||||
|
+ params->index = 7;
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->ControlTransferIn(
|
||||||
|
+ std::move(params), 8, 0,
|
||||||
|
+ base::BindOnce(&ExpectTransferInAndThen,
|
||||||
|
+ mojom::UsbTransferStatus::PERMISSION_DENIED,
|
||||||
|
+ std::vector<uint8_t>(), loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_handle(), Close());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+TEST_F(USBDeviceImplTest, ControlTransferProtectedClassBlockDisabled) {
|
||||||
|
+ base::test::ScopedFeatureList feature_list;
|
||||||
|
+ feature_list.InitAndDisableFeature(
|
||||||
|
+ features::kWebUsbProtectedClassControlTransferBlock);
|
||||||
|
+
|
||||||
|
+ // Block interface class 2.
|
||||||
|
+ mojo::Remote<mojom::UsbDevice> device =
|
||||||
|
+ GetMockDeviceProxyWithBlockedInterfaces(base::span_from_ref(uint8_t{2}));
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_device(), OpenInternal(_));
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ base::test::TestFuture<mojom::UsbOpenDeviceResultPtr> future;
|
||||||
|
+ device->Open(future.GetCallback());
|
||||||
|
+ EXPECT_TRUE(future.Get()->is_success());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Interface 7 has class 2 (blocked).
|
||||||
|
+ AddMockConfig(ConfigBuilder(/*configuration_value=*/1)
|
||||||
|
+ .AddInterface(/*interface_number=*/7,
|
||||||
|
+ /*alternate_setting=*/0,
|
||||||
|
+ /*class_code=*/2, /*subclass_code=*/0,
|
||||||
|
+ /*protocol_code=*/0)
|
||||||
|
+ .Build());
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_handle(), SetConfigurationInternal(1, _));
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->SetConfiguration(
|
||||||
|
+ 1, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ // A VENDOR request to the DEVICE with index 7 targeting the blocked
|
||||||
|
+ // interface should be ALLOWED because
|
||||||
|
+ // `kWebUsbProtectedClassControlTransferBlock` is disabled.
|
||||||
|
+ std::vector<uint8_t> fake_data = {1, 2, 3};
|
||||||
|
+ AddMockInboundData(fake_data);
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_handle(),
|
||||||
|
+ ControlTransferInternal(UsbTransferDirection::INBOUND,
|
||||||
|
+ UsbControlTransferType::VENDOR,
|
||||||
|
+ UsbControlTransferRecipient::DEVICE, 5,
|
||||||
|
+ 6, 7, _, 0, _));
|
||||||
|
+
|
||||||
|
+ auto params = mojom::UsbControlTransferParams::New();
|
||||||
|
+ params->type = UsbControlTransferType::VENDOR;
|
||||||
|
+ params->recipient = UsbControlTransferRecipient::DEVICE;
|
||||||
|
+ params->request = 5;
|
||||||
|
+ params->value = 6;
|
||||||
|
+ params->index = 7;
|
||||||
|
+ base::RunLoop loop;
|
||||||
|
+ device->ControlTransferIn(
|
||||||
|
+ std::move(params), static_cast<uint32_t>(fake_data.size()), 0,
|
||||||
|
+ base::BindOnce(&ExpectTransferInAndThen,
|
||||||
|
+ mojom::UsbTransferStatus::COMPLETED, fake_data,
|
||||||
|
+ loop.QuitClosure()));
|
||||||
|
+ loop.Run();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ EXPECT_CALL(mock_handle(), Close());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
TEST_F(USBDeviceImplTest, GenericTransfer) {
|
||||||
|
mojo::Remote<mojom::UsbDevice> device = GetMockDeviceProxy();
|
||||||
|
|
||||||
39
patches/chromium/cherry-pick-d8b01057f740.patch
Normal file
39
patches/chromium/cherry-pick-d8b01057f740.patch
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Steinar H. Gunderson" <sesse@chromium.org>
|
||||||
|
Date: Fri, 20 Mar 2026 07:22:02 -0700
|
||||||
|
Subject: Fix another use-after-free with lazy style attributes.
|
||||||
|
|
||||||
|
This is a similar problem as regular attribute checks, just for
|
||||||
|
the special case of input type="" (which is a similar but separate
|
||||||
|
path).
|
||||||
|
|
||||||
|
Style perftest and Speedometer3 are neutral.
|
||||||
|
|
||||||
|
Fixed: 493952652
|
||||||
|
Change-Id: I264503545c345325e6d21afa0726f524bb9394b8
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7686835
|
||||||
|
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||||
|
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1602570}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.cc b/third_party/blink/renderer/core/css/element_rule_collector.cc
|
||||||
|
index 9c472ed289a51b828bc7718ffada1df1a68aec30..ebefc123c4fc0d511126b8bf223b34b7e15d6a3e 100644
|
||||||
|
--- a/third_party/blink/renderer/core/css/element_rule_collector.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/css/element_rule_collector.cc
|
||||||
|
@@ -941,10 +941,14 @@ DISABLE_CFI_PERF bool ElementRuleCollector::CollectMatchingRulesInternal(
|
||||||
|
if (const AtomicString& input_type =
|
||||||
|
element.getAttribute(html_names::kTypeAttr);
|
||||||
|
!input_type.IsNull()) {
|
||||||
|
+ // Do not use input_type in the loop; the reference
|
||||||
|
+ // may be dangling if CollectMatchingRulesForList()
|
||||||
|
+ // adds lazy attributes.
|
||||||
|
+ AtomicString input_type_lower = input_type.LowerASCII();
|
||||||
|
for (const auto bundle : match_request.RuleSetsWithInputRules()) {
|
||||||
|
if (CollectMatchingRulesForList<stop_at_first_match>(
|
||||||
|
- bundle.rule_set->InputRules(input_type.LowerASCII()),
|
||||||
|
- match_request, bundle.rule_set, bundle.style_sheet_index,
|
||||||
|
+ bundle.rule_set->InputRules(input_type_lower), match_request,
|
||||||
|
+ bundle.rule_set, bundle.style_sheet_index,
|
||||||
|
checker, context.context) &&
|
||||||
|
stop_at_first_match) {
|
||||||
|
return true;
|
||||||
@@ -65,7 +65,7 @@ index 2748dd196fe1f56357348a204e24f0b8a28b97dd..5800dd00b47c657d9e6766f3fc5a3065
|
|||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
bool EscapeVirtualization(const base::FilePath& user_data_dir);
|
bool EscapeVirtualization(const base::FilePath& user_data_dir);
|
||||||
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
|
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
|
||||||
index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..b9f2a43cb90fac4b031a4b4da38d6435a50990d2 100644
|
index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..c683575aab2154b46b1fa9cc9e5e30aa8ed4f0ee 100644
|
||||||
--- a/chrome/browser/process_singleton_posix.cc
|
--- a/chrome/browser/process_singleton_posix.cc
|
||||||
+++ b/chrome/browser/process_singleton_posix.cc
|
+++ b/chrome/browser/process_singleton_posix.cc
|
||||||
@@ -614,6 +614,7 @@ class ProcessSingleton::LinuxWatcher
|
@@ -614,6 +614,7 @@ class ProcessSingleton::LinuxWatcher
|
||||||
@@ -106,21 +106,39 @@ index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..b9f2a43cb90fac4b031a4b4da38d6435
|
|||||||
const size_t kMinMessageLength = std::size(kStartToken) + 4;
|
const size_t kMinMessageLength = std::size(kStartToken) + 4;
|
||||||
if (bytes_read_ < kMinMessageLength) {
|
if (bytes_read_ < kMinMessageLength) {
|
||||||
buf_[bytes_read_] = 0;
|
buf_[bytes_read_] = 0;
|
||||||
@@ -757,10 +763,28 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
|
@@ -757,10 +763,46 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
|
||||||
tokens.erase(tokens.begin());
|
tokens.erase(tokens.begin());
|
||||||
tokens.erase(tokens.begin());
|
tokens.erase(tokens.begin());
|
||||||
|
|
||||||
+ size_t num_args;
|
+ size_t num_args;
|
||||||
+ base::StringToSizeT(tokens[0], &num_args);
|
+ if (!base::StringToSizeT(tokens[0], &num_args) ||
|
||||||
+ std::vector<std::string> command_line(tokens.begin() + 1, tokens.begin() + 1 + num_args);
|
+ num_args > tokens.size() - 1) {
|
||||||
|
+ LOG(ERROR) << "Invalid num_args in socket message";
|
||||||
|
+ CleanupAndDeleteSelf();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ std::vector<std::string> command_line(tokens.begin() + 1,
|
||||||
|
+ tokens.begin() + 1 + num_args);
|
||||||
+
|
+
|
||||||
+ std::vector<uint8_t> additional_data;
|
+ std::vector<uint8_t> additional_data;
|
||||||
+ if (tokens.size() >= 3 + num_args) {
|
+ // After consuming [num_args, argv...], two more tokens are needed for
|
||||||
|
+ // additional data: [size, payload]. Subtract to avoid overflow when
|
||||||
|
+ // num_args is large.
|
||||||
|
+ if (tokens.size() - 1 - num_args >= 2) {
|
||||||
+ size_t additional_data_size;
|
+ size_t additional_data_size;
|
||||||
+ base::StringToSizeT(tokens[1 + num_args], &additional_data_size);
|
+ if (!base::StringToSizeT(tokens[1 + num_args], &additional_data_size)) {
|
||||||
|
+ LOG(ERROR) << "Invalid additional_data_size in socket message";
|
||||||
|
+ CleanupAndDeleteSelf();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
+ std::string remaining_args = base::JoinString(
|
+ std::string remaining_args = base::JoinString(
|
||||||
+ base::span(tokens.begin() + 2 + num_args, tokens.end()),
|
+ base::span(tokens.begin() + 2 + num_args, tokens.end()),
|
||||||
+ std::string(1, kTokenDelimiter));
|
+ std::string(1, kTokenDelimiter));
|
||||||
|
+ if (additional_data_size > remaining_args.size()) {
|
||||||
|
+ LOG(ERROR) << "additional_data_size exceeds payload length";
|
||||||
|
+ CleanupAndDeleteSelf();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
+ const uint8_t* additional_data_bits =
|
+ const uint8_t* additional_data_bits =
|
||||||
+ reinterpret_cast<const uint8_t*>(remaining_args.c_str());
|
+ reinterpret_cast<const uint8_t*>(remaining_args.c_str());
|
||||||
+ additional_data = std::vector<uint8_t>(
|
+ additional_data = std::vector<uint8_t>(
|
||||||
@@ -136,7 +154,7 @@ index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..b9f2a43cb90fac4b031a4b4da38d6435
|
|||||||
fd_watch_controller_.reset();
|
fd_watch_controller_.reset();
|
||||||
|
|
||||||
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
|
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
|
||||||
@@ -789,8 +813,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
|
@@ -789,8 +831,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
|
||||||
//
|
//
|
||||||
ProcessSingleton::ProcessSingleton(
|
ProcessSingleton::ProcessSingleton(
|
||||||
const base::FilePath& user_data_dir,
|
const base::FilePath& user_data_dir,
|
||||||
@@ -147,7 +165,7 @@ index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..b9f2a43cb90fac4b031a4b4da38d6435
|
|||||||
current_pid_(base::GetCurrentProcId()) {
|
current_pid_(base::GetCurrentProcId()) {
|
||||||
socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
|
socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
|
||||||
lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
|
lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
|
||||||
@@ -911,7 +937,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
@@ -911,7 +955,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
||||||
sizeof(socket_timeout));
|
sizeof(socket_timeout));
|
||||||
|
|
||||||
// Found another process, prepare our command line
|
// Found another process, prepare our command line
|
||||||
@@ -157,7 +175,7 @@ index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..b9f2a43cb90fac4b031a4b4da38d6435
|
|||||||
std::string to_send(kStartToken);
|
std::string to_send(kStartToken);
|
||||||
to_send.push_back(kTokenDelimiter);
|
to_send.push_back(kTokenDelimiter);
|
||||||
|
|
||||||
@@ -921,11 +948,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
@@ -921,11 +966,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
||||||
to_send.append(current_dir.value());
|
to_send.append(current_dir.value());
|
||||||
|
|
||||||
const std::vector<std::string>& argv = cmd_line.argv();
|
const std::vector<std::string>& argv = cmd_line.argv();
|
||||||
@@ -180,10 +198,18 @@ index 08cbe32a258bf478f1da0a07064d3e9ef14c44a5..b9f2a43cb90fac4b031a4b4da38d6435
|
|||||||
if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
|
if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
|
||||||
// Try to kill the other process, because it might have been dead.
|
// Try to kill the other process, because it might have been dead.
|
||||||
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
|
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
|
||||||
index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..bec94d4039379400ae8b00f1adbbb16a02ccbac0 100644
|
index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..3458909dd20e2b7fdf624a0e0eaeed6e8271475b 100644
|
||||||
--- a/chrome/browser/process_singleton_win.cc
|
--- a/chrome/browser/process_singleton_win.cc
|
||||||
+++ b/chrome/browser/process_singleton_win.cc
|
+++ b/chrome/browser/process_singleton_win.cc
|
||||||
@@ -81,10 +81,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
|
@@ -9,6 +9,7 @@
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
+#include "base/base64.h"
|
||||||
|
#include "base/base_paths.h"
|
||||||
|
#include "base/command_line.h"
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
@@ -81,10 +82,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
|
||||||
|
|
||||||
bool ParseCommandLine(const COPYDATASTRUCT* cds,
|
bool ParseCommandLine(const COPYDATASTRUCT* cds,
|
||||||
base::CommandLine* parsed_command_line,
|
base::CommandLine* parsed_command_line,
|
||||||
@@ -198,7 +224,7 @@ index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..bec94d4039379400ae8b00f1adbbb16a
|
|||||||
static const int min_message_size = 7;
|
static const int min_message_size = 7;
|
||||||
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
|
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
|
||||||
cds->cbData % sizeof(wchar_t) != 0) {
|
cds->cbData % sizeof(wchar_t) != 0) {
|
||||||
@@ -134,6 +136,23 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
|
@@ -134,6 +137,25 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
|
||||||
const std::wstring cmd_line =
|
const std::wstring cmd_line =
|
||||||
msg.substr(second_null + 1, third_null - second_null);
|
msg.substr(second_null + 1, third_null - second_null);
|
||||||
*parsed_command_line = base::CommandLine::FromString(cmd_line);
|
*parsed_command_line = base::CommandLine::FromString(cmd_line);
|
||||||
@@ -211,18 +237,20 @@ index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..bec94d4039379400ae8b00f1adbbb16a
|
|||||||
+ return true;
|
+ return true;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // Get the actual additional data.
|
+ // Get the actual additional data. It is base64-encoded so it can
|
||||||
+ const std::wstring additional_data =
|
+ // safely traverse the null-delimited wchar_t buffer.
|
||||||
+ msg.substr(third_null + 1, fourth_null - third_null);
|
+ const std::wstring encoded_w =
|
||||||
+ base::span<const uint8_t> additional_data_bytes =
|
+ msg.substr(third_null + 1, fourth_null - third_null - 1);
|
||||||
+ base::as_byte_span(additional_data);
|
+ std::string encoded = base::WideToASCII(encoded_w);
|
||||||
+ *parsed_additional_data = std::vector<uint8_t>(
|
+ std::optional<std::vector<uint8_t>> decoded = base::Base64Decode(encoded);
|
||||||
+ additional_data_bytes.begin(), additional_data_bytes.end());
|
+ if (decoded) {
|
||||||
|
+ *parsed_additional_data = std::move(*decoded);
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -155,13 +174,14 @@ bool ProcessLaunchNotification(
|
@@ -155,13 +177,14 @@ bool ProcessLaunchNotification(
|
||||||
|
|
||||||
base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
|
base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
|
||||||
base::FilePath current_directory;
|
base::FilePath current_directory;
|
||||||
@@ -240,7 +268,7 @@ index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..bec94d4039379400ae8b00f1adbbb16a
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,9 +285,11 @@ bool ProcessSingleton::EscapeVirtualization(
|
@@ -265,9 +288,11 @@ bool ProcessSingleton::EscapeVirtualization(
|
||||||
ProcessSingleton::ProcessSingleton(
|
ProcessSingleton::ProcessSingleton(
|
||||||
const std::string& program_name,
|
const std::string& program_name,
|
||||||
const base::FilePath& user_data_dir,
|
const base::FilePath& user_data_dir,
|
||||||
@@ -252,7 +280,7 @@ index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..bec94d4039379400ae8b00f1adbbb16a
|
|||||||
program_name_(program_name),
|
program_name_(program_name),
|
||||||
is_app_sandboxed_(is_app_sandboxed),
|
is_app_sandboxed_(is_app_sandboxed),
|
||||||
is_virtualized_(false),
|
is_virtualized_(false),
|
||||||
@@ -294,7 +316,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
@@ -294,7 +319,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
||||||
return PROCESS_NONE;
|
return PROCESS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,10 +290,18 @@ index 64ebf49c0d1b6396d1cfbe3bf91480f61b47688d..bec94d4039379400ae8b00f1adbbb16a
|
|||||||
return PROCESS_NOTIFIED;
|
return PROCESS_NOTIFIED;
|
||||||
case NotifyChromeResult::NOTIFY_FAILED:
|
case NotifyChromeResult::NOTIFY_FAILED:
|
||||||
diff --git a/chrome/browser/win/chrome_process_finder.cc b/chrome/browser/win/chrome_process_finder.cc
|
diff --git a/chrome/browser/win/chrome_process_finder.cc b/chrome/browser/win/chrome_process_finder.cc
|
||||||
index 58a4c5adfda49fb4bd1b5351bd02d358946043bd..adaa070eb0f3cf8f771b57743a7436fd48a1e576 100644
|
index 58a4c5adfda49fb4bd1b5351bd02d358946043bd..6f21585faca6e98d2ed08be6a91df88947da6b3a 100644
|
||||||
--- a/chrome/browser/win/chrome_process_finder.cc
|
--- a/chrome/browser/win/chrome_process_finder.cc
|
||||||
+++ b/chrome/browser/win/chrome_process_finder.cc
|
+++ b/chrome/browser/win/chrome_process_finder.cc
|
||||||
@@ -39,7 +39,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
|
@@ -11,6 +11,7 @@
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
+#include "base/base64.h"
|
||||||
|
#include "base/check.h"
|
||||||
|
#include "base/command_line.h"
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
@@ -39,7 +40,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
|
||||||
return base::win::MessageWindow::FindWindow(user_data_dir.value());
|
return base::win::MessageWindow::FindWindow(user_data_dir.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +312,7 @@ index 58a4c5adfda49fb4bd1b5351bd02d358946043bd..adaa070eb0f3cf8f771b57743a7436fd
|
|||||||
TRACE_EVENT0("startup", "AttemptToNotifyRunningChrome");
|
TRACE_EVENT0("startup", "AttemptToNotifyRunningChrome");
|
||||||
|
|
||||||
DCHECK(remote_window);
|
DCHECK(remote_window);
|
||||||
@@ -70,12 +72,24 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
|
@@ -70,12 +73,22 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
|
||||||
new_command_line.AppendSwitch(switches::kSourceAppId);
|
new_command_line.AppendSwitch(switches::kSourceAppId);
|
||||||
}
|
}
|
||||||
// Send the command line to the remote chrome window.
|
// Send the command line to the remote chrome window.
|
||||||
@@ -288,14 +324,12 @@ index 58a4c5adfda49fb4bd1b5351bd02d358946043bd..adaa070eb0f3cf8f771b57743a7436fd
|
|||||||
std::wstring_view{L"\0", 1}, new_command_line.GetCommandLineString(),
|
std::wstring_view{L"\0", 1}, new_command_line.GetCommandLineString(),
|
||||||
std::wstring_view{L"\0", 1}});
|
std::wstring_view{L"\0", 1}});
|
||||||
|
|
||||||
+ size_t additional_data_size = additional_data.size_bytes();
|
+ if (!additional_data.empty()) {
|
||||||
+ if (additional_data_size) {
|
+ // Base64-encode so the payload survives the null-delimited wchar_t
|
||||||
+ size_t padded_size = additional_data_size / sizeof(wchar_t);
|
+ // framing; raw serialized bytes can contain 0x0000 sequences which
|
||||||
+ if (additional_data_size % sizeof(wchar_t) != 0) {
|
+ // would otherwise terminate the field early.
|
||||||
+ padded_size++;
|
+ std::string encoded = base::Base64Encode(additional_data);
|
||||||
+ }
|
+ to_send.append(base::ASCIIToWide(encoded));
|
||||||
+ to_send.append(reinterpret_cast<const wchar_t*>(additional_data.data()),
|
|
||||||
+ padded_size);
|
|
||||||
+ to_send.append(L"\0", 1); // Null separator.
|
+ to_send.append(L"\0", 1); // Null separator.
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Samuel Attard <sattard@anthropic.com>
|
||||||
|
Date: Sat, 7 Mar 2026 23:07:30 -0800
|
||||||
|
Subject: feat: plumb node_integration_in_worker through WorkerSettings
|
||||||
|
|
||||||
|
Copy the node_integration_in_worker flag from the initiating frame's
|
||||||
|
WebPreferences into WorkerSettings at dedicated worker creation time,
|
||||||
|
so the value is readable per-worker on the worker thread rather than
|
||||||
|
relying on a process-wide command line switch. The value is also
|
||||||
|
propagated to nested workers via WorkerSettings::Copy.
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc
|
||||||
|
index b6cd50a0005a69edcd2b5c059ffa35f82faac792..b74fd8f7e290075d37f10a2c216bef6de60f1052 100644
|
||||||
|
--- a/third_party/blink/renderer/core/workers/dedicated_worker.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
|
||||||
|
#include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h"
|
||||||
|
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
|
||||||
|
+#include "third_party/blink/renderer/core/exported/web_view_impl.h"
|
||||||
|
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
|
||||||
|
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
|
||||||
|
#include "third_party/blink/renderer/core/loader/document_loader.h"
|
||||||
|
@@ -555,6 +556,12 @@ DedicatedWorker::CreateGlobalScopeCreationParams(
|
||||||
|
auto* frame = window->GetFrame();
|
||||||
|
parent_devtools_token = frame->GetDevToolsFrameToken();
|
||||||
|
settings = std::make_unique<WorkerSettings>(frame->GetSettings());
|
||||||
|
+ if (auto* web_local_frame = WebLocalFrameImpl::FromFrame(frame)) {
|
||||||
|
+ if (auto* web_view = web_local_frame->ViewImpl()) {
|
||||||
|
+ settings->SetNodeIntegrationInWorker(
|
||||||
|
+ web_view->GetWebPreferences().node_integration_in_worker);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
agent_group_scheduler_compositor_task_runner =
|
||||||
|
execution_context->GetScheduler()
|
||||||
|
->ToFrameScheduler()
|
||||||
|
diff --git a/third_party/blink/renderer/core/workers/worker_settings.cc b/third_party/blink/renderer/core/workers/worker_settings.cc
|
||||||
|
index 45680c5f6ea0c7e89ccf43eb88f8a11e3318c02e..3fa3af62f4e7ba8186441c5e3184b1c04fe32d12 100644
|
||||||
|
--- a/third_party/blink/renderer/core/workers/worker_settings.cc
|
||||||
|
+++ b/third_party/blink/renderer/core/workers/worker_settings.cc
|
||||||
|
@@ -40,6 +40,8 @@ std::unique_ptr<WorkerSettings> WorkerSettings::Copy(
|
||||||
|
old_settings->strictly_block_blockable_mixed_content_;
|
||||||
|
new_settings->generic_font_family_settings_ =
|
||||||
|
old_settings->generic_font_family_settings_;
|
||||||
|
+ new_settings->node_integration_in_worker_ =
|
||||||
|
+ old_settings->node_integration_in_worker_;
|
||||||
|
return new_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/third_party/blink/renderer/core/workers/worker_settings.h b/third_party/blink/renderer/core/workers/worker_settings.h
|
||||||
|
index 45c60dd2c44b05fdd279f759069383479823c7f2..33a2a0337efb9a46293e11d0d09b3fc182ab9618 100644
|
||||||
|
--- a/third_party/blink/renderer/core/workers/worker_settings.h
|
||||||
|
+++ b/third_party/blink/renderer/core/workers/worker_settings.h
|
||||||
|
@@ -43,6 +43,11 @@ class CORE_EXPORT WorkerSettings {
|
||||||
|
return generic_font_family_settings_;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ bool NodeIntegrationInWorker() const { return node_integration_in_worker_; }
|
||||||
|
+ void SetNodeIntegrationInWorker(bool value) {
|
||||||
|
+ node_integration_in_worker_ = value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private:
|
||||||
|
void CopyFlagValuesFromSettings(Settings*);
|
||||||
|
|
||||||
|
@@ -54,6 +59,7 @@ class CORE_EXPORT WorkerSettings {
|
||||||
|
bool strict_mixed_content_checking_ = false;
|
||||||
|
bool allow_running_of_insecure_content_ = false;
|
||||||
|
bool strictly_block_blockable_mixed_content_ = false;
|
||||||
|
+ bool node_integration_in_worker_ = false;
|
||||||
|
|
||||||
|
GenericFontFamilySettings generic_font_family_settings_;
|
||||||
|
};
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Keeley Hammond <vertedinde@electronjs.org>
|
||||||
|
Date: Mon, 23 Mar 2026 18:27:45 -0700
|
||||||
|
Subject: Validate uniform block count limits at compile time on IMG.
|
||||||
|
|
||||||
|
Normally these limits are validated at link time but the IMG compiler
|
||||||
|
has issues when these limits are exceeded. Validate at compile time
|
||||||
|
instead.
|
||||||
|
|
||||||
|
Bug: chromium:475877320
|
||||||
|
Change-Id: Ieeed6914b8cdd2b5e50242d06facae62badddefd
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7568129
|
||||||
|
Auto-Submit: Geoff Lang <geofflang@chromium.org>
|
||||||
|
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
|
||||||
|
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/heads/main@{#1586673}
|
||||||
|
|
||||||
|
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||||
|
index 02078983a7b10588c7d68f5a3affa5536edb29d5..a7131ef3a34e86d44ce5af5bb8bfab8853c32a50 100644
|
||||||
|
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||||
|
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||||
|
@@ -3664,6 +3664,9 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
|
||||||
|
driver_bug_workarounds.dontUseLoopsToInitializeVariables = true;
|
||||||
|
if (workarounds().remove_dynamic_indexing_of_swizzled_vector)
|
||||||
|
driver_bug_workarounds.removeDynamicIndexingOfSwizzledVector = true;
|
||||||
|
+ if (workarounds().validate_max_per_stage_uniform_blocks_at_compile_time) {
|
||||||
|
+ driver_bug_workarounds.validatePerStageMaxUniformBlocks = true;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
// Initialize uninitialized locals by default
|
||||||
|
driver_bug_workarounds.initializeUninitializedLocals = true;
|
||||||
|
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
|
||||||
|
index deeb8fb1ea810a87bb19bcb85cc352fe802361ac..900b5fa1decf4c1895f32eb5ab05fd54a806669c 100644
|
||||||
|
--- a/gpu/config/gpu_driver_bug_list.json
|
||||||
|
+++ b/gpu/config/gpu_driver_bug_list.json
|
||||||
|
@@ -3772,6 +3772,17 @@
|
||||||
|
"features": [
|
||||||
|
"disable_d3d12_av1_multi_ref_encoding"
|
||||||
|
]
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "id": 472,
|
||||||
|
+ "description": "Validate GL_MAX_*_UNIFORM_BLOCKS at compile time instead of link time to work around compiler bugs.",
|
||||||
|
+ "os": {
|
||||||
|
+ "type": "android"
|
||||||
|
+ },
|
||||||
|
+ "gl_vendor": "Imagination.*",
|
||||||
|
+ "features": [
|
||||||
|
+ "validate_max_per_stage_uniform_blocks_at_compile_time"
|
||||||
|
+ ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt
|
||||||
|
index 32b7797c2f19b3e597963d1d2c78da6066ff3bd3..300586499f496d25c571adcb90cb066b4e778899 100644
|
||||||
|
--- a/gpu/config/gpu_workaround_list.txt
|
||||||
|
+++ b/gpu/config/gpu_workaround_list.txt
|
||||||
|
@@ -127,6 +127,7 @@ use_first_valid_ref_for_av1_invalid_ref
|
||||||
|
use_gpu_driver_workaround_for_testing
|
||||||
|
use_non_zero_size_for_client_side_stream_buffers
|
||||||
|
use_virtualized_gl_contexts
|
||||||
|
+validate_max_per_stage_uniform_blocks_at_compile_time
|
||||||
|
wake_up_gpu_before_drawing
|
||||||
|
webgl_or_caps_max_texture_size_limit_4096
|
||||||
|
webgl_or_caps_max_texture_size_limit_8192
|
||||||
@@ -13,5 +13,6 @@
|
|||||||
{ "patch_dir": "src/electron/patches/webrtc", "repo": "src/third_party/webrtc" },
|
{ "patch_dir": "src/electron/patches/webrtc", "repo": "src/third_party/webrtc" },
|
||||||
{ "patch_dir": "src/electron/patches/reclient-configs", "repo": "src/third_party/engflow-reclient-configs" },
|
{ "patch_dir": "src/electron/patches/reclient-configs", "repo": "src/third_party/engflow-reclient-configs" },
|
||||||
{ "patch_dir": "src/electron/patches/sqlite", "repo": "src/third_party/sqlite/src" },
|
{ "patch_dir": "src/electron/patches/sqlite", "repo": "src/third_party/sqlite/src" },
|
||||||
{ "patch_dir": "src/electron/patches/skia", "repo": "src/third_party/skia" }
|
{ "patch_dir": "src/electron/patches/skia", "repo": "src/third_party/skia" },
|
||||||
|
{ "patch_dir": "src/electron/patches/angle", "repo": "src/third_party/angle/src" }
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ cli_move_--trace-atomics-wait_to_eol.patch
|
|||||||
fix_cppgc_initializing_twice.patch
|
fix_cppgc_initializing_twice.patch
|
||||||
fix_task_starvation_in_inspector_context_test.patch
|
fix_task_starvation_in_inspector_context_test.patch
|
||||||
fix_expose_readfilesync_override_for_modules.patch
|
fix_expose_readfilesync_override_for_modules.patch
|
||||||
fix_array_out-of-bounds_read_in_boyer-moore_search.patch
|
|
||||||
chore_add_missing_include_of_iterator.patch
|
chore_add_missing_include_of_iterator.patch
|
||||||
test_accomodate_v8_thenable_stack_trace_change_in_snapshot.patch
|
test_accomodate_v8_thenable_stack_trace_change_in_snapshot.patch
|
||||||
chore_exclude_electron_node_folder_from_exit-time-destructors.patch
|
chore_exclude_electron_node_folder_from_exit-time-destructors.patch
|
||||||
@@ -53,7 +52,6 @@ fix_replace_deprecated_setprototype.patch
|
|||||||
fix_redefined_macos_sdk_header_symbols.patch
|
fix_redefined_macos_sdk_header_symbols.patch
|
||||||
src_use_cp_utf8_for_wide_file_names_on_win32.patch
|
src_use_cp_utf8_for_wide_file_names_on_win32.patch
|
||||||
fix_ensure_traverseparent_bails_on_resource_path_exit.patch
|
fix_ensure_traverseparent_bails_on_resource_path_exit.patch
|
||||||
src_handle_der_decoding_errors_from_system_certificates.patch
|
|
||||||
remove_obsolete_noarraybufferzerofillscope.patch
|
remove_obsolete_noarraybufferzerofillscope.patch
|
||||||
src_prepare_for_v8_sandboxing.patch
|
src_prepare_for_v8_sandboxing.patch
|
||||||
test_correct_conditional_secure_heap_flags_test.patch
|
fix_generate_config_gypi_needs_to_generate_valid_json.patch
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ Subject: Remove deprecated `GetIsolate`
|
|||||||
https://chromium-review.googlesource.com/c/v8/v8/+/6905244
|
https://chromium-review.googlesource.com/c/v8/v8/+/6905244
|
||||||
|
|
||||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||||
index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a83853443 100644
|
index d2614bba9463056e931b6d5c1f3153e2f576b779..f3a992b634e9532cba34ec4d54b3a1d0f68a8545 100644
|
||||||
--- a/src/api/environment.cc
|
--- a/src/api/environment.cc
|
||||||
+++ b/src/api/environment.cc
|
+++ b/src/api/environment.cc
|
||||||
@@ -646,7 +646,7 @@ std::unique_ptr<MultiIsolatePlatform> MultiIsolatePlatform::Create(
|
@@ -651,7 +651,7 @@ std::unique_ptr<MultiIsolatePlatform> MultiIsolatePlatform::Create(
|
||||||
|
|
||||||
MaybeLocal<Object> GetPerContextExports(Local<Context> context,
|
MaybeLocal<Object> GetPerContextExports(Local<Context> context,
|
||||||
IsolateData* isolate_data) {
|
IsolateData* isolate_data) {
|
||||||
@@ -18,7 +18,7 @@ index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a
|
|||||||
EscapableHandleScope handle_scope(isolate);
|
EscapableHandleScope handle_scope(isolate);
|
||||||
|
|
||||||
Local<Object> global = context->Global();
|
Local<Object> global = context->Global();
|
||||||
@@ -692,7 +692,7 @@ void ProtoThrower(const FunctionCallbackInfo<Value>& info) {
|
@@ -697,7 +697,7 @@ void ProtoThrower(const FunctionCallbackInfo<Value>& info) {
|
||||||
// This runs at runtime, regardless of whether the context
|
// This runs at runtime, regardless of whether the context
|
||||||
// is created from a snapshot.
|
// is created from a snapshot.
|
||||||
Maybe<void> InitializeContextRuntime(Local<Context> context) {
|
Maybe<void> InitializeContextRuntime(Local<Context> context) {
|
||||||
@@ -27,7 +27,7 @@ index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a
|
|||||||
HandleScope handle_scope(isolate);
|
HandleScope handle_scope(isolate);
|
||||||
|
|
||||||
// When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path
|
// When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path
|
||||||
@@ -771,7 +771,7 @@ Maybe<void> InitializeContextRuntime(Local<Context> context) {
|
@@ -776,7 +776,7 @@ Maybe<void> InitializeContextRuntime(Local<Context> context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
||||||
@@ -36,7 +36,7 @@ index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a
|
|||||||
HandleScope handle_scope(isolate);
|
HandleScope handle_scope(isolate);
|
||||||
|
|
||||||
// Delete `Intl.v8BreakIterator`
|
// Delete `Intl.v8BreakIterator`
|
||||||
@@ -796,7 +796,7 @@ Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
@@ -801,7 +801,7 @@ Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
||||||
@@ -45,7 +45,7 @@ index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a
|
|||||||
HandleScope handle_scope(isolate);
|
HandleScope handle_scope(isolate);
|
||||||
|
|
||||||
// Initialize the default values.
|
// Initialize the default values.
|
||||||
@@ -814,7 +814,7 @@ Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
@@ -819,7 +819,7 @@ Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
||||||
MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||||
IsolateData* isolate_data) {
|
IsolateData* isolate_data) {
|
||||||
CHECK(isolate_data);
|
CHECK(isolate_data);
|
||||||
@@ -54,7 +54,7 @@ index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a
|
|||||||
EscapableHandleScope scope(isolate);
|
EscapableHandleScope scope(isolate);
|
||||||
Context::Scope context_scope(context);
|
Context::Scope context_scope(context);
|
||||||
|
|
||||||
@@ -838,7 +838,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
@@ -843,7 +843,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||||
MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||||
IsolateData* isolate_data) {
|
IsolateData* isolate_data) {
|
||||||
CHECK(isolate_data);
|
CHECK(isolate_data);
|
||||||
@@ -63,7 +63,7 @@ index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a
|
|||||||
EscapableHandleScope scope(isolate);
|
EscapableHandleScope scope(isolate);
|
||||||
Context::Scope context_scope(context);
|
Context::Scope context_scope(context);
|
||||||
|
|
||||||
@@ -864,7 +864,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
@@ -869,7 +869,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||||
Maybe<void> InitializePrimordials(Local<Context> context,
|
Maybe<void> InitializePrimordials(Local<Context> context,
|
||||||
IsolateData* isolate_data) {
|
IsolateData* isolate_data) {
|
||||||
// Run per-context JS files.
|
// Run per-context JS files.
|
||||||
@@ -85,10 +85,10 @@ index 6f731b17fe0b84dd3d2c9bc9cfef1f8062a2c5f7..71a1072ed2decbee08d40eda7c47456b
|
|||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
||||||
index 8f50d0cc132ac65fa74cf1fc2172247b5ad42962..0c6b12f8e17b4a7e86ebc836a4e1cc77333f211a 100644
|
index 2cd7cd67c1c480eb9ec549a12bc2b9584d5a53b3..081a4ccdee718afc63b55da90a60ef9758dcc96a 100644
|
||||||
--- a/src/crypto/crypto_context.cc
|
--- a/src/crypto/crypto_context.cc
|
||||||
+++ b/src/crypto/crypto_context.cc
|
+++ b/src/crypto/crypto_context.cc
|
||||||
@@ -1020,7 +1020,7 @@ bool ArrayOfStringsToX509s(Local<Context> context,
|
@@ -1043,7 +1043,7 @@ bool ArrayOfStringsToX509s(Local<Context> context,
|
||||||
Local<Array> cert_array,
|
Local<Array> cert_array,
|
||||||
std::vector<X509*>* certs) {
|
std::vector<X509*>* certs) {
|
||||||
ClearErrorOnReturn clear_error_on_return;
|
ClearErrorOnReturn clear_error_on_return;
|
||||||
@@ -144,7 +144,7 @@ index eb6dad44a49d997097c8fb5009eeb60a7305da27..fd29d17de195017970856ce30d7a9c57
|
|||||||
NewStringType::kNormal,
|
NewStringType::kNormal,
|
||||||
mem->length)
|
mem->length)
|
||||||
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
|
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
|
||||||
index 31ed995714bb99ab534f26ba9ebc6051c258a1c9..5ace688bb7ffc86eedf5aff11ab0ab487ad9440e 100644
|
index cddc88f1e0309072d22aa76d4a17115e4d9159e2..22eecffa437a9e0f4a0e170953aa35fa527511b5 100644
|
||||||
--- a/src/encoding_binding.cc
|
--- a/src/encoding_binding.cc
|
||||||
+++ b/src/encoding_binding.cc
|
+++ b/src/encoding_binding.cc
|
||||||
@@ -73,7 +73,7 @@ void BindingData::Deserialize(Local<Context> context,
|
@@ -73,7 +73,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||||
@@ -183,10 +183,10 @@ index c6209cc7cf317de1bb9217e39dd760e5a83303e2..161d577e0ea6a251c83ba1903b1ec9a5
|
|||||||
} else {
|
} else {
|
||||||
info.js_execution_async_resources = 0;
|
info.js_execution_async_resources = 0;
|
||||||
diff --git a/src/inspector/network_agent.cc b/src/inspector/network_agent.cc
|
diff --git a/src/inspector/network_agent.cc b/src/inspector/network_agent.cc
|
||||||
index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af20f4e2e89 100644
|
index 57ea5afd56a4e3c4c5826a263ce498448effbb84..c2c17760022ab669188a774e91ca96c9a5d7f57e 100644
|
||||||
--- a/src/inspector/network_agent.cc
|
--- a/src/inspector/network_agent.cc
|
||||||
+++ b/src/inspector/network_agent.cc
|
+++ b/src/inspector/network_agent.cc
|
||||||
@@ -29,31 +29,31 @@ using v8::Value;
|
@@ -31,31 +31,31 @@ constexpr size_t kDefaultMaxTotalBufferSize = 100 * 1024 * 1024; // 100MB
|
||||||
Maybe<protocol::String> ObjectGetProtocolString(v8::Local<v8::Context> context,
|
Maybe<protocol::String> ObjectGetProtocolString(v8::Local<v8::Context> context,
|
||||||
Local<Object> object,
|
Local<Object> object,
|
||||||
Local<v8::String> property) {
|
Local<v8::String> property) {
|
||||||
@@ -224,7 +224,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
.ToLocal(&value) ||
|
.ToLocal(&value) ||
|
||||||
!value->IsNumber()) {
|
!value->IsNumber()) {
|
||||||
return Nothing<double>();
|
return Nothing<double>();
|
||||||
@@ -65,9 +65,9 @@ Maybe<double> ObjectGetDouble(v8::Local<v8::Context> context,
|
@@ -67,9 +67,9 @@ Maybe<double> ObjectGetDouble(v8::Local<v8::Context> context,
|
||||||
Maybe<int> ObjectGetInt(v8::Local<v8::Context> context,
|
Maybe<int> ObjectGetInt(v8::Local<v8::Context> context,
|
||||||
Local<Object> object,
|
Local<Object> object,
|
||||||
const char* property) {
|
const char* property) {
|
||||||
@@ -236,7 +236,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
.ToLocal(&value) ||
|
.ToLocal(&value) ||
|
||||||
!value->IsInt32()) {
|
!value->IsInt32()) {
|
||||||
return Nothing<int>();
|
return Nothing<int>();
|
||||||
@@ -79,9 +79,9 @@ Maybe<int> ObjectGetInt(v8::Local<v8::Context> context,
|
@@ -81,9 +81,9 @@ Maybe<int> ObjectGetInt(v8::Local<v8::Context> context,
|
||||||
Maybe<bool> ObjectGetBool(v8::Local<v8::Context> context,
|
Maybe<bool> ObjectGetBool(v8::Local<v8::Context> context,
|
||||||
Local<Object> object,
|
Local<Object> object,
|
||||||
const char* property) {
|
const char* property) {
|
||||||
@@ -248,7 +248,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
.ToLocal(&value) ||
|
.ToLocal(&value) ||
|
||||||
!value->IsBoolean()) {
|
!value->IsBoolean()) {
|
||||||
return Nothing<bool>();
|
return Nothing<bool>();
|
||||||
@@ -93,9 +93,9 @@ Maybe<bool> ObjectGetBool(v8::Local<v8::Context> context,
|
@@ -95,9 +95,9 @@ Maybe<bool> ObjectGetBool(v8::Local<v8::Context> context,
|
||||||
MaybeLocal<v8::Object> ObjectGetObject(v8::Local<v8::Context> context,
|
MaybeLocal<v8::Object> ObjectGetObject(v8::Local<v8::Context> context,
|
||||||
Local<Object> object,
|
Local<Object> object,
|
||||||
const char* property) {
|
const char* property) {
|
||||||
@@ -260,7 +260,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
.ToLocal(&value) ||
|
.ToLocal(&value) ||
|
||||||
!value->IsObject()) {
|
!value->IsObject()) {
|
||||||
return {};
|
return {};
|
||||||
@@ -106,7 +106,7 @@ MaybeLocal<v8::Object> ObjectGetObject(v8::Local<v8::Context> context,
|
@@ -108,7 +108,7 @@ MaybeLocal<v8::Object> ObjectGetObject(v8::Local<v8::Context> context,
|
||||||
// Create a protocol::Network::Headers from the v8 object.
|
// Create a protocol::Network::Headers from the v8 object.
|
||||||
std::unique_ptr<protocol::Network::Headers> createHeadersFromObject(
|
std::unique_ptr<protocol::Network::Headers> createHeadersFromObject(
|
||||||
v8::Local<v8::Context> context, Local<Object> headers_obj) {
|
v8::Local<v8::Context> context, Local<Object> headers_obj) {
|
||||||
@@ -269,7 +269,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
|
|
||||||
std::unique_ptr<protocol::DictionaryValue> dict =
|
std::unique_ptr<protocol::DictionaryValue> dict =
|
||||||
protocol::DictionaryValue::create();
|
protocol::DictionaryValue::create();
|
||||||
@@ -127,7 +127,7 @@ std::unique_ptr<protocol::Network::Headers> createHeadersFromObject(
|
@@ -129,7 +129,7 @@ std::unique_ptr<protocol::Network::Headers> createHeadersFromObject(
|
||||||
.To(&property_value)) {
|
.To(&property_value)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
property_value);
|
property_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ std::unique_ptr<protocol::Network::Headers> createHeadersFromObject(
|
@@ -139,7 +139,7 @@ std::unique_ptr<protocol::Network::Headers> createHeadersFromObject(
|
||||||
// Create a protocol::Network::Request from the v8 object.
|
// Create a protocol::Network::Request from the v8 object.
|
||||||
std::unique_ptr<protocol::Network::Request> createRequestFromObject(
|
std::unique_ptr<protocol::Network::Request> createRequestFromObject(
|
||||||
v8::Local<v8::Context> context, Local<Object> request) {
|
v8::Local<v8::Context> context, Local<Object> request) {
|
||||||
@@ -287,7 +287,7 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
|
|||||||
protocol::String url;
|
protocol::String url;
|
||||||
if (!ObjectGetProtocolString(context, request, "url").To(&url)) {
|
if (!ObjectGetProtocolString(context, request, "url").To(&url)) {
|
||||||
return {};
|
return {};
|
||||||
@@ -169,7 +169,7 @@ std::unique_ptr<protocol::Network::Request> createRequestFromObject(
|
@@ -171,7 +171,7 @@ std::unique_ptr<protocol::Network::Request> createRequestFromObject(
|
||||||
// Create a protocol::Network::Response from the v8 object.
|
// Create a protocol::Network::Response from the v8 object.
|
||||||
std::unique_ptr<protocol::Network::Response> createResponseFromObject(
|
std::unique_ptr<protocol::Network::Response> createResponseFromObject(
|
||||||
v8::Local<v8::Context> context, Local<Object> response) {
|
v8::Local<v8::Context> context, Local<Object> response) {
|
||||||
@@ -359,10 +359,10 @@ index 4a35e41e78a22993f87ab9d5919f401a7b742438..327d7b77bc306db8193fa68bc7129c33
|
|||||||
CHECK(!env->temporary_required_module_facade_original.IsEmpty());
|
CHECK(!env->temporary_required_module_facade_original.IsEmpty());
|
||||||
return env->temporary_required_module_facade_original.Get(isolate);
|
return env->temporary_required_module_facade_original.Get(isolate);
|
||||||
diff --git a/src/node.h b/src/node.h
|
diff --git a/src/node.h b/src/node.h
|
||||||
index 16a0c71aef949b0ddd27def9dc843298f9a6b75f..28fa4cb3e7a621480a5ff11c48666c0de1363375 100644
|
index fe44369dff7519ea0d960ae478d5caf524e17366..bba7393e7378fa7468837319af7b7f643b68167e 100644
|
||||||
--- a/src/node.h
|
--- a/src/node.h
|
||||||
+++ b/src/node.h
|
+++ b/src/node.h
|
||||||
@@ -1050,7 +1050,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
@@ -1049,7 +1049,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
||||||
|
|
||||||
#define NODE_DEFINE_CONSTANT(target, constant) \
|
#define NODE_DEFINE_CONSTANT(target, constant) \
|
||||||
do { \
|
do { \
|
||||||
@@ -371,7 +371,7 @@ index 16a0c71aef949b0ddd27def9dc843298f9a6b75f..28fa4cb3e7a621480a5ff11c48666c0d
|
|||||||
v8::Local<v8::Context> context = isolate->GetCurrentContext(); \
|
v8::Local<v8::Context> context = isolate->GetCurrentContext(); \
|
||||||
v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \
|
v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \
|
||||||
isolate, #constant, v8::NewStringType::kInternalized); \
|
isolate, #constant, v8::NewStringType::kInternalized); \
|
||||||
@@ -1066,7 +1066,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
@@ -1065,7 +1065,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
||||||
|
|
||||||
#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \
|
#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \
|
||||||
do { \
|
do { \
|
||||||
@@ -539,10 +539,10 @@ index 36a21b9523351fe2f225ffe7fca184d737640b62..c6e9e2c00064348c435ae10871a4013c
|
|||||||
READONLY_PROPERTY(target, "exitCodes", exit_codes);
|
READONLY_PROPERTY(target, "exitCodes", exit_codes);
|
||||||
|
|
||||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||||
index 5de3ebb04b12286a07e3041d0a6dd1cc9072e76a..75be21c9e8b413f522240a906da06d26c44d5b71 100644
|
index 9f888b28ecb05f3496c0b18fdd6a2c1cc9b068fd..57c8dc35dc86efed6e8736e4649b90905a8da54b 100644
|
||||||
--- a/src/node_file.cc
|
--- a/src/node_file.cc
|
||||||
+++ b/src/node_file.cc
|
+++ b/src/node_file.cc
|
||||||
@@ -3755,7 +3755,7 @@ void BindingData::Deserialize(Local<Context> context,
|
@@ -3761,7 +3761,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||||
int index,
|
int index,
|
||||||
InternalFieldInfoBase* info) {
|
InternalFieldInfoBase* info) {
|
||||||
DCHECK_IS_SNAPSHOT_SLOT(index);
|
DCHECK_IS_SNAPSHOT_SLOT(index);
|
||||||
@@ -627,7 +627,7 @@ index 9dcca7509f37f239b8442201b086df428415dcd1..b0cf8c3a8e1c3e89d621a865390b1bdb
|
|||||||
// Recreate the buffer in the constructor.
|
// Recreate the buffer in the constructor.
|
||||||
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
|
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
|
||||||
diff --git a/src/node_realm.cc b/src/node_realm.cc
|
diff --git a/src/node_realm.cc b/src/node_realm.cc
|
||||||
index 66a8ee48fc68b22eaf6c9d9209cc5cb2439e55ff..b31e244f8af7d37c35319853a478776c609b9bca 100644
|
index b6461c7bb009fa3f44cb0225eec49dbb161d81fd..5ffe23beb7b33f8becf5ba997fea2119e9aa23cf 100644
|
||||||
--- a/src/node_realm.cc
|
--- a/src/node_realm.cc
|
||||||
+++ b/src/node_realm.cc
|
+++ b/src/node_realm.cc
|
||||||
@@ -19,7 +19,7 @@ using v8::String;
|
@@ -19,7 +19,7 @@ using v8::String;
|
||||||
@@ -740,7 +740,7 @@ index 9b5ada71c174567498c4902259d97f9d11fefb91..1134856a202bac0a4ff1957d5ecc5600
|
|||||||
if (wasi->memory_.IsEmpty()) {
|
if (wasi->memory_.IsEmpty()) {
|
||||||
THROW_ERR_WASI_NOT_STARTED(isolate);
|
THROW_ERR_WASI_NOT_STARTED(isolate);
|
||||||
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
|
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
|
||||||
index e3c3223789032badbab56a558148da67e99ca9b2..9a7b7db881a564a68683c55cb10919454e80edbf 100644
|
index a442a479b8732ef793aaf3bf57decc4f324eb816..d6dee522023a4e65d948b1554e9ae472f1e96e40 100644
|
||||||
--- a/src/node_webstorage.cc
|
--- a/src/node_webstorage.cc
|
||||||
+++ b/src/node_webstorage.cc
|
+++ b/src/node_webstorage.cc
|
||||||
@@ -58,7 +58,7 @@ using v8::Value;
|
@@ -58,7 +58,7 @@ using v8::Value;
|
||||||
@@ -752,7 +752,7 @@ index e3c3223789032badbab56a558148da67e99ca9b2..9a7b7db881a564a68683c55cb1091945
|
|||||||
auto dom_exception_str = FIXED_ONE_BYTE_STRING(isolate, "DOMException");
|
auto dom_exception_str = FIXED_ONE_BYTE_STRING(isolate, "DOMException");
|
||||||
auto err_name = FIXED_ONE_BYTE_STRING(isolate, "QuotaExceededError");
|
auto err_name = FIXED_ONE_BYTE_STRING(isolate, "QuotaExceededError");
|
||||||
auto err_message =
|
auto err_message =
|
||||||
@@ -434,7 +434,7 @@ Maybe<void> Storage::Store(Local<Name> key, Local<Value> value) {
|
@@ -438,7 +438,7 @@ Maybe<void> Storage::Store(Local<Name> key, Local<Value> value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static MaybeLocal<String> Uint32ToName(Local<Context> context, uint32_t index) {
|
static MaybeLocal<String> Uint32ToName(Local<Context> context, uint32_t index) {
|
||||||
@@ -762,10 +762,10 @@ index e3c3223789032badbab56a558148da67e99ca9b2..9a7b7db881a564a68683c55cb1091945
|
|||||||
|
|
||||||
static void Clear(const FunctionCallbackInfo<Value>& info) {
|
static void Clear(const FunctionCallbackInfo<Value>& info) {
|
||||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
||||||
index 8555ab556b5b74a1cf9cf30747f1f417bfe4e4d9..1a2532337504444d59098304b87e0d65f16e838c 100644
|
index ddfea91272d03d4ef1d4ac1b982ada5dcd24b601..7b4335475cc70369a1e868de70c749465a5bdfbd 100644
|
||||||
--- a/src/node_worker.cc
|
--- a/src/node_worker.cc
|
||||||
+++ b/src/node_worker.cc
|
+++ b/src/node_worker.cc
|
||||||
@@ -1289,8 +1289,6 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
|
@@ -1288,8 +1288,6 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
|
||||||
Local<Object> port = env->message_port();
|
Local<Object> port = env->message_port();
|
||||||
CHECK_IMPLIES(!env->is_main_thread(), !port.IsEmpty());
|
CHECK_IMPLIES(!env->is_main_thread(), !port.IsEmpty());
|
||||||
if (!port.IsEmpty()) {
|
if (!port.IsEmpty()) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ really in 20/21. We have to wait until 22 is released to be able to
|
|||||||
build with upstream GN files.
|
build with upstream GN files.
|
||||||
|
|
||||||
diff --git a/configure.py b/configure.py
|
diff --git a/configure.py b/configure.py
|
||||||
index 91283ca577f580dbf1e0c4e2dbf851a9ceaa38ed..e8eaff30ec947677db2d45425f9180759d0c55de 100755
|
index 77c87f5a9539714f68278d95ec79878cc52dc18b..ff93eebd4714ac8d9c9abe9c53e3636f02e0baac 100755
|
||||||
--- a/configure.py
|
--- a/configure.py
|
||||||
+++ b/configure.py
|
+++ b/configure.py
|
||||||
@@ -1728,7 +1728,7 @@ def configure_v8(o, configs):
|
@@ -1728,7 +1728,7 @@ def configure_v8(o, configs):
|
||||||
@@ -93,7 +93,7 @@ index f9426599f2d5dc6ad061407f0c4eb2c9203a4433..302030f610965f07dd6998d282275c1b
|
|||||||
// Handles compilation and caching of built-in JavaScript modules and
|
// Handles compilation and caching of built-in JavaScript modules and
|
||||||
// bootstrap scripts, whose source are bundled into the binary as static data.
|
// bootstrap scripts, whose source are bundled into the binary as static data.
|
||||||
diff --git a/tools/install.py b/tools/install.py
|
diff --git a/tools/install.py b/tools/install.py
|
||||||
index 8797b59e59c85a8877b977fa3281e50165e6f6b2..0af01e075616195f38fb242626dcab770ec1eb57 100755
|
index a619fd17b16e404cf8deb5b91f7dbd980895f760..2b981b23e724120f69a5f7ef655e5f648aa310e9 100755
|
||||||
--- a/tools/install.py
|
--- a/tools/install.py
|
||||||
+++ b/tools/install.py
|
+++ b/tools/install.py
|
||||||
@@ -222,6 +222,7 @@ def headers(options, action):
|
@@ -222,6 +222,7 @@ def headers(options, action):
|
||||||
@@ -115,7 +115,7 @@ index 8797b59e59c85a8877b977fa3281e50165e6f6b2..0af01e075616195f38fb242626dcab77
|
|||||||
diff --git a/tools/js2c.cc b/tools/js2c.cc
|
diff --git a/tools/js2c.cc b/tools/js2c.cc
|
||||||
old mode 100644
|
old mode 100644
|
||||||
new mode 100755
|
new mode 100755
|
||||||
index 21992cbe894a880e3223c379326b62db22f2f12d..1296a5457422099035ba34f2b02624f2e9dfb0f0
|
index 9c2f70de4e00834ff448e573743898072dc14c5d..71a12c606f4da7165cc41a295a278b2e504af1b6
|
||||||
--- a/tools/js2c.cc
|
--- a/tools/js2c.cc
|
||||||
+++ b/tools/js2c.cc
|
+++ b/tools/js2c.cc
|
||||||
@@ -28,6 +28,7 @@ namespace js2c {
|
@@ -28,6 +28,7 @@ namespace js2c {
|
||||||
@@ -210,7 +210,7 @@ index 21992cbe894a880e3223c379326b62db22f2f12d..1296a5457422099035ba34f2b02624f2
|
|||||||
static_cast<int>(def_buf.size()),
|
static_cast<int>(def_buf.size()),
|
||||||
def_buf.data(),
|
def_buf.data(),
|
||||||
static_cast<int>(init_buf.size()),
|
static_cast<int>(init_buf.size()),
|
||||||
@@ -846,12 +890,15 @@ int JS2C(const FileList& js_files,
|
@@ -836,12 +880,15 @@ int JS2C(const FileList& js_files,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ index 21992cbe894a880e3223c379326b62db22f2f12d..1296a5457422099035ba34f2b02624f2
|
|||||||
Fragment out = Format(definitions, initializers, registrations);
|
Fragment out = Format(definitions, initializers, registrations);
|
||||||
return WriteIfChanged(out, dest);
|
return WriteIfChanged(out, dest);
|
||||||
}
|
}
|
||||||
@@ -877,6 +924,8 @@ int Main(int argc, char* argv[]) {
|
@@ -867,6 +914,8 @@ int Main(int argc, char* argv[]) {
|
||||||
std::string arg(argv[i]);
|
std::string arg(argv[i]);
|
||||||
if (arg == "--verbose") {
|
if (arg == "--verbose") {
|
||||||
is_verbose = true;
|
is_verbose = true;
|
||||||
@@ -235,7 +235,7 @@ index 21992cbe894a880e3223c379326b62db22f2f12d..1296a5457422099035ba34f2b02624f2
|
|||||||
} else if (arg == "--root") {
|
} else if (arg == "--root") {
|
||||||
if (i == argc - 1) {
|
if (i == argc - 1) {
|
||||||
fprintf(stderr, "--root must be followed by a path\n");
|
fprintf(stderr, "--root must be followed by a path\n");
|
||||||
@@ -925,6 +974,14 @@ int Main(int argc, char* argv[]) {
|
@@ -915,6 +964,14 @@ int Main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ index 21992cbe894a880e3223c379326b62db22f2f12d..1296a5457422099035ba34f2b02624f2
|
|||||||
// Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
|
// Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
|
||||||
assert(file_map.size() == 3);
|
assert(file_map.size() == 3);
|
||||||
auto gypi_it = file_map.find(".gypi");
|
auto gypi_it = file_map.find(".gypi");
|
||||||
@@ -951,6 +1008,7 @@ int Main(int argc, char* argv[]) {
|
@@ -941,6 +998,7 @@ int Main(int argc, char* argv[]) {
|
||||||
std::sort(mjs_it->second.begin(), mjs_it->second.end());
|
std::sort(mjs_it->second.begin(), mjs_it->second.end());
|
||||||
|
|
||||||
return JS2C(js_it->second, mjs_it->second, gypi_it->second[0], output);
|
return JS2C(js_it->second, mjs_it->second, gypi_it->second[0], output);
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ V8 requires C++20 support as of https://chromium-review.googlesource.com/c/v8/v8
|
|||||||
This can be removed when Electron upgrades to a version of Node.js containing the required V8 version.
|
This can be removed when Electron upgrades to a version of Node.js containing the required V8 version.
|
||||||
|
|
||||||
diff --git a/common.gypi b/common.gypi
|
diff --git a/common.gypi b/common.gypi
|
||||||
index c28d6f5fe2c922f0b1e3f7e56289c78e7b91c294..95c56305926fc3e0e46e4cf99ec86d3d1b5576a7 100644
|
index 4cb925480961ae88eb423559ab34ac0ee91239e4..bbfc0f4ec293df19662e57fa4890c4c53cd79d75 100644
|
||||||
--- a/common.gypi
|
--- a/common.gypi
|
||||||
+++ b/common.gypi
|
+++ b/common.gypi
|
||||||
@@ -539,7 +539,7 @@
|
@@ -536,7 +536,7 @@
|
||||||
'-fno-rtti',
|
'-fno-rtti',
|
||||||
'-fno-exceptions',
|
'-fno-exceptions',
|
||||||
'-fno-strict-aliasing',
|
'-fno-strict-aliasing',
|
||||||
@@ -22,7 +22,7 @@ index c28d6f5fe2c922f0b1e3f7e56289c78e7b91c294..95c56305926fc3e0e46e4cf99ec86d3d
|
|||||||
],
|
],
|
||||||
'defines': [ '__STDC_FORMAT_MACROS' ],
|
'defines': [ '__STDC_FORMAT_MACROS' ],
|
||||||
'ldflags': [ '-rdynamic' ],
|
'ldflags': [ '-rdynamic' ],
|
||||||
@@ -719,7 +719,7 @@
|
@@ -716,7 +716,7 @@
|
||||||
['clang==1', {
|
['clang==1', {
|
||||||
'xcode_settings': {
|
'xcode_settings': {
|
||||||
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
|
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ index 8d7204f6cb48f783adc4d1c1eb2de0c83b7fffe2..a154559a56bf383d3c26af523c9bb07b
|
|||||||
|
|
||||||
// Non-alphabetic chars.
|
// Non-alphabetic chars.
|
||||||
diff --git a/lib/internal/http.js b/lib/internal/http.js
|
diff --git a/lib/internal/http.js b/lib/internal/http.js
|
||||||
index 4f250a2e70a20fddeeb7886e0c269822883f7ccf..4e5c2dd1f13e6818576c3c4c88200b5cf5fb1257 100644
|
index 78010bd8f23512073430008742479b655e936314..12b6430cadc31dbfa6907ed0b904ce81bd333a05 100644
|
||||||
--- a/lib/internal/http.js
|
--- a/lib/internal/http.js
|
||||||
+++ b/lib/internal/http.js
|
+++ b/lib/internal/http.js
|
||||||
@@ -10,8 +10,8 @@ const {
|
@@ -10,8 +10,8 @@ const {
|
||||||
@@ -64,7 +64,7 @@ index 4f250a2e70a20fddeeb7886e0c269822883f7ccf..4e5c2dd1f13e6818576c3c4c88200b5c
|
|||||||
|
|
||||||
function ipToInt(ip) {
|
function ipToInt(ip) {
|
||||||
diff --git a/node.gyp b/node.gyp
|
diff --git a/node.gyp b/node.gyp
|
||||||
index 0e0071b508f605bb9b7722f8304814dc176d907e..bcb9f371c4e4d8c665058115dc39eaa65125d679 100644
|
index f9ee71dd9a395fa1de99a6f62ba60acdf8be12a1..e3b308ca079aab6e672a1cfa9b12d49ef64b3816 100644
|
||||||
--- a/node.gyp
|
--- a/node.gyp
|
||||||
+++ b/node.gyp
|
+++ b/node.gyp
|
||||||
@@ -174,7 +174,6 @@
|
@@ -174,7 +174,6 @@
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Subject: build: ensure native module compilation fails if not using a new
|
|||||||
This should not be upstreamed, it is a quality-of-life patch for downstream module builders.
|
This should not be upstreamed, it is a quality-of-life patch for downstream module builders.
|
||||||
|
|
||||||
diff --git a/common.gypi b/common.gypi
|
diff --git a/common.gypi b/common.gypi
|
||||||
index 6b79de07be3f839af5b0644f19bfef9c33de590e..c28d6f5fe2c922f0b1e3f7e56289c78e7b91c294 100644
|
index 79bd0879cd5d9408d45aae150d9ace4e1bf43d36..4cb925480961ae88eb423559ab34ac0ee91239e4 100644
|
||||||
--- a/common.gypi
|
--- a/common.gypi
|
||||||
+++ b/common.gypi
|
+++ b/common.gypi
|
||||||
@@ -89,6 +89,8 @@
|
@@ -89,6 +89,8 @@
|
||||||
@@ -42,7 +42,7 @@ index 6b79de07be3f839af5b0644f19bfef9c33de590e..c28d6f5fe2c922f0b1e3f7e56289c78e
|
|||||||
# list in v8/BUILD.gn.
|
# list in v8/BUILD.gn.
|
||||||
['v8_enable_v8_checks == 1', {
|
['v8_enable_v8_checks == 1', {
|
||||||
diff --git a/configure.py b/configure.py
|
diff --git a/configure.py b/configure.py
|
||||||
index e8eaff30ec947677db2d45425f9180759d0c55de..dc2d9d80059e845b33444f8bdc29e82d0fe0e26b 100755
|
index ff93eebd4714ac8d9c9abe9c53e3636f02e0baac..04d484071821af1afc07d5a0081c6ad7f2e59ab5 100755
|
||||||
--- a/configure.py
|
--- a/configure.py
|
||||||
+++ b/configure.py
|
+++ b/configure.py
|
||||||
@@ -1710,6 +1710,7 @@ def configure_library(lib, output, pkgname=None):
|
@@ -1710,6 +1710,7 @@ def configure_library(lib, output, pkgname=None):
|
||||||
@@ -54,7 +54,7 @@ index e8eaff30ec947677db2d45425f9180759d0c55de..dc2d9d80059e845b33444f8bdc29e82d
|
|||||||
o['variables']['v8_enable_javascript_promise_hooks'] = 1
|
o['variables']['v8_enable_javascript_promise_hooks'] = 1
|
||||||
o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
|
o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
|
||||||
diff --git a/src/node.h b/src/node.h
|
diff --git a/src/node.h b/src/node.h
|
||||||
index a336f44dc1e785ea237865077216d41ab032c0af..96c599aa6448e2aa8e57e84f811564a5281c139a 100644
|
index 67bef5f7d8a08c4dd37ad72073537f1d2b4cb2ee..4e66924e4ca5b5d787fc6259de940a3fb40bff38 100644
|
||||||
--- a/src/node.h
|
--- a/src/node.h
|
||||||
+++ b/src/node.h
|
+++ b/src/node.h
|
||||||
@@ -22,6 +22,12 @@
|
@@ -22,6 +22,12 @@
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ node-gyp will use the result of `process.config` that reflects the environment
|
|||||||
in which the binary got built.
|
in which the binary got built.
|
||||||
|
|
||||||
diff --git a/common.gypi b/common.gypi
|
diff --git a/common.gypi b/common.gypi
|
||||||
index 95c56305926fc3e0e46e4cf99ec86d3d1b5576a7..45bb2c4ff94ceac377c9117da4497cdc5ac41171 100644
|
index bbfc0f4ec293df19662e57fa4890c4c53cd79d75..23ac608d9fc3cd4b8b8381492d609051127cd755 100644
|
||||||
--- a/common.gypi
|
--- a/common.gypi
|
||||||
+++ b/common.gypi
|
+++ b/common.gypi
|
||||||
@@ -128,6 +128,7 @@
|
@@ -128,6 +128,7 @@
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ they use themselves as the entry point. We should try to upstream some form
|
|||||||
of this.
|
of this.
|
||||||
|
|
||||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||||
index 15443a710ccf53fae333da3b1fbb52a970c658d5..464b34829c1a566836bfca6bbc2b87fcf5e50016 100644
|
index 3546544ad0d4542917d0dfe7634bd6ec1e25476b..3eabcb05f1d370693ade51ac794852725767ad85 100644
|
||||||
--- a/lib/internal/process/pre_execution.js
|
--- a/lib/internal/process/pre_execution.js
|
||||||
+++ b/lib/internal/process/pre_execution.js
|
+++ b/lib/internal/process/pre_execution.js
|
||||||
@@ -265,12 +265,14 @@ function patchProcessObject(expandArgv1) {
|
@@ -268,12 +268,14 @@ function patchProcessObject(expandArgv1) {
|
||||||
// the entry point.
|
// the entry point.
|
||||||
if (expandArgv1 && process.argv[1] && process.argv[1][0] !== '-') {
|
if (expandArgv1 && process.argv[1] && process.argv[1][0] !== '-') {
|
||||||
// Expand process.argv[1] into a full path.
|
// Expand process.argv[1] into a full path.
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ Without this patch, building with simdjson fails with
|
|||||||
> error: identifier '_padded' preceded by whitespace in a literal operator
|
> error: identifier '_padded' preceded by whitespace in a literal operator
|
||||||
> declaration is deprecated [-Werror,-Wdeprecated-literal-operator]
|
> declaration is deprecated [-Werror,-Wdeprecated-literal-operator]
|
||||||
|
|
||||||
|
and
|
||||||
|
> error: declaration requires an exit-time destructor [-Werror,-Wexit-time-destructors]
|
||||||
|
|
||||||
This patch can be removed once this is fixed upstream in simdjson.
|
This patch can be removed once this is fixed upstream in simdjson.
|
||||||
|
|
||||||
diff --git a/deps/simdjson/simdjson.h b/deps/simdjson/simdjson.h
|
diff --git a/deps/simdjson/simdjson.h b/deps/simdjson/simdjson.h
|
||||||
index 8f52a4331d59996786450eec982659da9244cac1..74729673d87b068dff5f24166bbb77d844f15f42 100644
|
index 1d6560e80fab0458b22f0ac2437056bce4873e8f..c3dbe2b6fc08c36a07ced5e29a814f7bcd85b748 100644
|
||||||
--- a/deps/simdjson/simdjson.h
|
--- a/deps/simdjson/simdjson.h
|
||||||
+++ b/deps/simdjson/simdjson.h
|
+++ b/deps/simdjson/simdjson.h
|
||||||
@@ -3899,12 +3899,17 @@ inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string
|
@@ -4215,12 +4215,17 @@ inline std::ostream& operator<<(std::ostream& out, simdjson_result<padded_string
|
||||||
|
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
@@ -32,7 +35,7 @@ index 8f52a4331d59996786450eec982659da9244cac1..74729673d87b068dff5f24166bbb77d8
|
|||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@@ -4304,6 +4309,9 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
|
@@ -4729,6 +4734,9 @@ inline simdjson_result<padded_string> padded_string::load(std::wstring_view file
|
||||||
|
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
@@ -42,8 +45,8 @@ index 8f52a4331d59996786450eec982659da9244cac1..74729673d87b068dff5f24166bbb77d8
|
|||||||
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
||||||
return simdjson::padded_string(str, len);
|
return simdjson::padded_string(str, len);
|
||||||
}
|
}
|
||||||
@@ -4312,6 +4320,8 @@ inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len
|
@@ -4737,6 +4745,8 @@ inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len
|
||||||
return simdjson::padded_string(reinterpret_cast<const char8_t *>(str), len);
|
return simdjson::padded_string(reinterpret_cast<const char *>(str), len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
+#pragma clang diagnostic pop
|
+#pragma clang diagnostic pop
|
||||||
@@ -51,3 +54,37 @@ index 8f52a4331d59996786450eec982659da9244cac1..74729673d87b068dff5f24166bbb77d8
|
|||||||
#endif // SIMDJSON_PADDED_STRING_INL_H
|
#endif // SIMDJSON_PADDED_STRING_INL_H
|
||||||
/* end file simdjson/padded_string-inl.h */
|
/* end file simdjson/padded_string-inl.h */
|
||||||
/* skipped duplicate #include "simdjson/padded_string_view.h" */
|
/* skipped duplicate #include "simdjson/padded_string_view.h" */
|
||||||
|
@@ -44745,12 +44755,16 @@ simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::
|
||||||
|
return parser_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#pragma clang diagnostic push
|
||||||
|
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
||||||
|
+
|
||||||
|
simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::get_threadlocal_parser_if_exists() {
|
||||||
|
// @the-moisrex points out that this could be implemented with std::optional (C++17).
|
||||||
|
thread_local std::unique_ptr<ondemand::parser> parser_instance = nullptr;
|
||||||
|
return parser_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
} // namespace ondemand
|
||||||
|
} // namespace arm64
|
||||||
|
@@ -59221,12 +59235,16 @@ simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::
|
||||||
|
return parser_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#pragma clang diagnostic push
|
||||||
|
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
||||||
|
+
|
||||||
|
simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::get_threadlocal_parser_if_exists() {
|
||||||
|
// @the-moisrex points out that this could be implemented with std::optional (C++17).
|
||||||
|
thread_local std::unique_ptr<ondemand::parser> parser_instance = nullptr;
|
||||||
|
return parser_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
} // namespace ondemand
|
||||||
|
} // namespace fallback
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
|
|||||||
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
|
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
|
||||||
|
|
||||||
diff --git a/doc/api/cli.md b/doc/api/cli.md
|
diff --git a/doc/api/cli.md b/doc/api/cli.md
|
||||||
index a97053929c81ac18bcb3beda7cecb69621b6e70c..a54d0e46c8e4e3aa6be433fba73ef9a3228fa175 100644
|
index 2133555fd05f0c4f4b03c1d76ae8e33c14b621fa..1f93fa0fa56b27cb176d06231b9f2c8854c3c009 100644
|
||||||
--- a/doc/api/cli.md
|
--- a/doc/api/cli.md
|
||||||
+++ b/doc/api/cli.md
|
+++ b/doc/api/cli.md
|
||||||
@@ -2749,39 +2749,6 @@ added: v12.0.0
|
@@ -2755,39 +2755,6 @@ added: v12.0.0
|
||||||
Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.3'. Use to disable support
|
Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.3'. Use to disable support
|
||||||
for TLSv1.2, which is not as secure as TLSv1.3.
|
for TLSv1.2, which is not as secure as TLSv1.3.
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ index a97053929c81ac18bcb3beda7cecb69621b6e70c..a54d0e46c8e4e3aa6be433fba73ef9a3
|
|||||||
### `--trace-deprecation`
|
### `--trace-deprecation`
|
||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
@@ -3483,7 +3450,6 @@ one is included in the list below.
|
@@ -3489,7 +3456,6 @@ one is included in the list below.
|
||||||
* `--tls-min-v1.1`
|
* `--tls-min-v1.1`
|
||||||
* `--tls-min-v1.2`
|
* `--tls-min-v1.2`
|
||||||
* `--tls-min-v1.3`
|
* `--tls-min-v1.3`
|
||||||
@@ -83,7 +83,7 @@ index fed2c77c2afed665be7aa17c2d53824f049a909e..7a3c09a40fca9458f83be1e7d8eec930
|
|||||||
Print stack traces for deprecations.
|
Print stack traces for deprecations.
|
||||||
.
|
.
|
||||||
diff --git a/src/node.cc b/src/node.cc
|
diff --git a/src/node.cc b/src/node.cc
|
||||||
index f012b365455bb111cddea44fcff020804086ab72..b99b5170553af51466fd1ee69af3be5026f3fada 100644
|
index f85b5ed687180d7a12648b87398a734fb321f346..0bc4aff4573ccd0e53de5f288b5bccdb6063652a 100644
|
||||||
--- a/src/node.cc
|
--- a/src/node.cc
|
||||||
+++ b/src/node.cc
|
+++ b/src/node.cc
|
||||||
@@ -232,44 +232,6 @@ void Environment::WaitForInspectorFrontendByOptions() {
|
@@ -232,44 +232,6 @@ void Environment::WaitForInspectorFrontendByOptions() {
|
||||||
@@ -150,7 +150,7 @@ index f012b365455bb111cddea44fcff020804086ab72..b99b5170553af51466fd1ee69af3be50
|
|||||||
isolate_->SetPromiseHook(TracePromises);
|
isolate_->SetPromiseHook(TracePromises);
|
||||||
}
|
}
|
||||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||||
index 4bbace2f702777fa12ba9246984894721df99b50..b067685822dc056e446e1a9402a5a6cba86cc722 100644
|
index acd747ff5d853a920a66c27d421ae9ddfc7bcd82..5a1675f2b4448e5da71f0badee8ac5f2d2a9c6ee 100644
|
||||||
--- a/src/node_options.cc
|
--- a/src/node_options.cc
|
||||||
+++ b/src/node_options.cc
|
+++ b/src/node_options.cc
|
||||||
@@ -827,10 +827,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
|
@@ -827,10 +827,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
|
||||||
@@ -165,7 +165,7 @@ index 4bbace2f702777fa12ba9246984894721df99b50..b067685822dc056e446e1a9402a5a6cb
|
|||||||
"show stack traces on deprecations",
|
"show stack traces on deprecations",
|
||||||
&EnvironmentOptions::trace_deprecation,
|
&EnvironmentOptions::trace_deprecation,
|
||||||
diff --git a/src/node_options.h b/src/node_options.h
|
diff --git a/src/node_options.h b/src/node_options.h
|
||||||
index d8751a6ee734233e2fc24866ed87d9cd516072ae..e12abb55e43068e8446eaabc65deb63cc469f554 100644
|
index b7d9b429f0b498dfd70301074948a13a2d35532e..31b5e51ec8ac3061778b723f59cef606fac7c924 100644
|
||||||
--- a/src/node_options.h
|
--- a/src/node_options.h
|
||||||
+++ b/src/node_options.h
|
+++ b/src/node_options.h
|
||||||
@@ -205,7 +205,6 @@ class EnvironmentOptions : public Options {
|
@@ -205,7 +205,6 @@ class EnvironmentOptions : public Options {
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ Reviewed-By: Michaël Zasso <targos@protonmail.com>
|
|||||||
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
|
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
|
||||||
|
|
||||||
diff --git a/doc/api/cli.md b/doc/api/cli.md
|
diff --git a/doc/api/cli.md b/doc/api/cli.md
|
||||||
index 7ff68d28f1c80d8a852f649e2c39216a2f4bdb16..a97053929c81ac18bcb3beda7cecb69621b6e70c 100644
|
index 0dfbe4b4fe0e4113e5e6c0cbe8a5d3ec4ff97e5a..2133555fd05f0c4f4b03c1d76ae8e33c14b621fa 100644
|
||||||
--- a/doc/api/cli.md
|
--- a/doc/api/cli.md
|
||||||
+++ b/doc/api/cli.md
|
+++ b/doc/api/cli.md
|
||||||
@@ -3522,7 +3522,6 @@ V8 options that are allowed are:
|
@@ -3528,7 +3528,6 @@ V8 options that are allowed are:
|
||||||
* `--disallow-code-generation-from-strings`
|
* `--disallow-code-generation-from-strings`
|
||||||
* `--enable-etw-stack-walking`
|
* `--enable-etw-stack-walking`
|
||||||
* `--expose-gc`
|
* `--expose-gc`
|
||||||
@@ -30,7 +30,7 @@ index 7ff68d28f1c80d8a852f649e2c39216a2f4bdb16..a97053929c81ac18bcb3beda7cecb696
|
|||||||
* `--jitless`
|
* `--jitless`
|
||||||
* `--max-old-space-size`
|
* `--max-old-space-size`
|
||||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||||
index 3026b3d814ae652a9996c1dcba62b4fa678ac871..4bbace2f702777fa12ba9246984894721df99b50 100644
|
index 41de3936265f0544831521fe753d2050e91b58e1..acd747ff5d853a920a66c27d421ae9ddfc7bcd82 100644
|
||||||
--- a/src/node_options.cc
|
--- a/src/node_options.cc
|
||||||
+++ b/src/node_options.cc
|
+++ b/src/node_options.cc
|
||||||
@@ -1060,11 +1060,6 @@ PerIsolateOptionsParser::PerIsolateOptionsParser(
|
@@ -1060,11 +1060,6 @@ PerIsolateOptionsParser::PerIsolateOptionsParser(
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ modules to sandboxed renderers.
|
|||||||
TODO(codebytere): remove and replace with a public facing API.
|
TODO(codebytere): remove and replace with a public facing API.
|
||||||
|
|
||||||
diff --git a/src/node_binding.cc b/src/node_binding.cc
|
diff --git a/src/node_binding.cc b/src/node_binding.cc
|
||||||
index aa4213c3622eab077fa8d764775c1f95c6313e34..11f722d2d7c21079cbc65033429086231a786ca7 100644
|
index 75d2f649a76583b7c965871131147b9f451234c4..b7fa9b8e48ffcd1e80d890b127b5ffb52152838b 100644
|
||||||
--- a/src/node_binding.cc
|
--- a/src/node_binding.cc
|
||||||
+++ b/src/node_binding.cc
|
+++ b/src/node_binding.cc
|
||||||
@@ -652,6 +652,10 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
|
@@ -652,6 +652,10 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
|
||||||
@@ -24,10 +24,10 @@ index aa4213c3622eab077fa8d764775c1f95c6313e34..11f722d2d7c21079cbc6503342908623
|
|||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
|
||||||
diff --git a/src/node_binding.h b/src/node_binding.h
|
diff --git a/src/node_binding.h b/src/node_binding.h
|
||||||
index 611f38ef5e21cc303127326d50c648fbb557b4da..3d95ad2733dc83d0b7d37d57c337732c8a0e83d7 100644
|
index bf931994d31ab6f6c400eecd36ff09cb655a67f2..7e839bafd2b2b0b07aa216d317f0ab0d89108979 100644
|
||||||
--- a/src/node_binding.h
|
--- a/src/node_binding.h
|
||||||
+++ b/src/node_binding.h
|
+++ b/src/node_binding.h
|
||||||
@@ -154,6 +154,8 @@ void GetInternalBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
@@ -153,6 +153,8 @@ void GetInternalBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
void GetLinkedBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
void GetLinkedBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
void DLOpen(const v8::FunctionCallbackInfo<v8::Value>& args);
|
void DLOpen(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ common.gypi is a file that's included in the node header bundle, despite
|
|||||||
the fact that we do not build node with gyp.
|
the fact that we do not build node with gyp.
|
||||||
|
|
||||||
diff --git a/common.gypi b/common.gypi
|
diff --git a/common.gypi b/common.gypi
|
||||||
index ae31b372b96358a156761ec7e9c39c9530d1abd1..6b79de07be3f839af5b0644f19bfef9c33de590e 100644
|
index d71df903c125e4b5daf1184604c627b82272d3cc..79bd0879cd5d9408d45aae150d9ace4e1bf43d36 100644
|
||||||
--- a/common.gypi
|
--- a/common.gypi
|
||||||
+++ b/common.gypi
|
+++ b/common.gypi
|
||||||
@@ -91,6 +91,23 @@
|
@@ -91,6 +91,23 @@
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ We can fix this by allowing the C++ implementation of legacyMainResolve to use
|
|||||||
a fileExists function that does take Asar into account.
|
a fileExists function that does take Asar into account.
|
||||||
|
|
||||||
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
||||||
index e3afd30ba1f591d0298793bc42fd7166a4219bce..408dc96307d7f52f92db41004b358051a81c627c 100644
|
index 4216e136d01a119264de1523ed466efb783311c3..a7e9c8eb1084c9d5a0c27f0fca840fc47ce12dd1 100644
|
||||||
--- a/lib/internal/modules/esm/resolve.js
|
--- a/lib/internal/modules/esm/resolve.js
|
||||||
+++ b/lib/internal/modules/esm/resolve.js
|
+++ b/lib/internal/modules/esm/resolve.js
|
||||||
@@ -28,14 +28,13 @@ const { BuiltinModule } = require('internal/bootstrap/realm');
|
@@ -28,14 +28,13 @@ const { BuiltinModule } = require('internal/bootstrap/realm');
|
||||||
@@ -31,7 +31,7 @@ index e3afd30ba1f591d0298793bc42fd7166a4219bce..408dc96307d7f52f92db41004b358051
|
|||||||
const {
|
const {
|
||||||
ERR_INPUT_TYPE_NOT_ALLOWED,
|
ERR_INPUT_TYPE_NOT_ALLOWED,
|
||||||
ERR_INVALID_ARG_TYPE,
|
ERR_INVALID_ARG_TYPE,
|
||||||
@@ -183,6 +182,11 @@ const legacyMainResolveExtensionsIndexes = {
|
@@ -184,6 +183,11 @@ const legacyMainResolveExtensionsIndexes = {
|
||||||
kResolvedByPackageAndNode: 9,
|
kResolvedByPackageAndNode: 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ index e3afd30ba1f591d0298793bc42fd7166a4219bce..408dc96307d7f52f92db41004b358051
|
|||||||
/**
|
/**
|
||||||
* Legacy CommonJS main resolution:
|
* Legacy CommonJS main resolution:
|
||||||
* 1. let M = pkg_url + (json main field)
|
* 1. let M = pkg_url + (json main field)
|
||||||
@@ -201,7 +205,7 @@ function legacyMainResolve(packageJSONUrl, packageConfig, base) {
|
@@ -202,7 +206,7 @@ function legacyMainResolve(packageJSONUrl, packageConfig, base) {
|
||||||
|
|
||||||
const baseStringified = isURL(base) ? base.href : base;
|
const baseStringified = isURL(base) ? base.href : base;
|
||||||
|
|
||||||
@@ -53,10 +53,10 @@ index e3afd30ba1f591d0298793bc42fd7166a4219bce..408dc96307d7f52f92db41004b358051
|
|||||||
const maybeMain = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ?
|
const maybeMain = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ?
|
||||||
packageConfig.main || './' : '';
|
packageConfig.main || './' : '';
|
||||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||||
index 77f8f1bd4e8294f2ebc7e0724aea5902eb0f95ab..5de3ebb04b12286a07e3041d0a6dd1cc9072e76a 100644
|
index 6ed00e0c173ecc37d09e5d1420fbf5451b6fd906..9f888b28ecb05f3496c0b18fdd6a2c1cc9b068fd 100644
|
||||||
--- a/src/node_file.cc
|
--- a/src/node_file.cc
|
||||||
+++ b/src/node_file.cc
|
+++ b/src/node_file.cc
|
||||||
@@ -3504,13 +3504,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
@@ -3510,13 +3510,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile(
|
BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile(
|
||||||
@@ -83,7 +83,7 @@ index 77f8f1bd4e8294f2ebc7e0724aea5902eb0f95ab..5de3ebb04b12286a07e3041d0a6dd1cc
|
|||||||
uv_fs_t req;
|
uv_fs_t req;
|
||||||
|
|
||||||
int rc = uv_fs_stat(env->event_loop(), &req, file_path.c_str(), nullptr);
|
int rc = uv_fs_stat(env->event_loop(), &req, file_path.c_str(), nullptr);
|
||||||
@@ -3568,6 +3580,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
@@ -3574,6 +3586,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||||
std::optional<std::string> initial_file_path;
|
std::optional<std::string> initial_file_path;
|
||||||
std::string file_path;
|
std::string file_path;
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ index 77f8f1bd4e8294f2ebc7e0724aea5902eb0f95ab..5de3ebb04b12286a07e3041d0a6dd1cc
|
|||||||
if (args.Length() >= 2 && args[1]->IsString()) {
|
if (args.Length() >= 2 && args[1]->IsString()) {
|
||||||
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
|
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
|
||||||
|
|
||||||
@@ -3588,7 +3605,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
@@ -3594,7 +3611,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||||
BufferValue buff_file_path(isolate, local_file_path);
|
BufferValue buff_file_path(isolate, local_file_path);
|
||||||
ToNamespacedPath(env, &buff_file_path);
|
ToNamespacedPath(env, &buff_file_path);
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ index 77f8f1bd4e8294f2ebc7e0724aea5902eb0f95ab..5de3ebb04b12286a07e3041d0a6dd1cc
|
|||||||
case BindingData::FilePathIsFileReturnType::kIsFile:
|
case BindingData::FilePathIsFileReturnType::kIsFile:
|
||||||
return args.GetReturnValue().Set(i);
|
return args.GetReturnValue().Set(i);
|
||||||
case BindingData::FilePathIsFileReturnType::kIsNotFile:
|
case BindingData::FilePathIsFileReturnType::kIsNotFile:
|
||||||
@@ -3625,7 +3642,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
@@ -3631,7 +3648,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||||
BufferValue buff_file_path(isolate, local_file_path);
|
BufferValue buff_file_path(isolate, local_file_path);
|
||||||
ToNamespacedPath(env, &buff_file_path);
|
ToNamespacedPath(env, &buff_file_path);
|
||||||
|
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
|
||||||
Date: Thu, 10 Jul 2025 08:36:12 +0000
|
|
||||||
Subject: fix: array out-of-bounds read in Boyer-Moore search
|
|
||||||
|
|
||||||
Refs https://chromium-review.googlesource.com/c/chromium/src/+/6703757
|
|
||||||
|
|
||||||
The above CL enabled array bounds sanitization, which triggered a crash in a Node.js
|
|
||||||
test which exposed an issue in Node.js implementation of Boyer-Moore string search.
|
|
||||||
|
|
||||||
Some Boyer-Moore search impl functions were using "biased pointer" arithmetic to
|
|
||||||
create array pointers that point outside the actual array bounds.
|
|
||||||
|
|
||||||
When start_ is large this creates pointers far outside the valid memory range.
|
|
||||||
While this worked by accident in practice, it's undefined behavior that the CL
|
|
||||||
correctly prohibits.
|
|
||||||
|
|
||||||
diff --git a/deps/nbytes/include/nbytes.h b/deps/nbytes/include/nbytes.h
|
|
||||||
index b012729c6cca8e42c94fd9b6a9c72301b4370de4..bb2e2e5fd2781f9e3db7f0b0699e1b0513e6782d 100644
|
|
||||||
--- a/deps/nbytes/include/nbytes.h
|
|
||||||
+++ b/deps/nbytes/include/nbytes.h
|
|
||||||
@@ -4,6 +4,7 @@
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
+#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
@@ -548,7 +549,11 @@ size_t StringSearch<Char>::BoyerMooreSearch(Vector subject,
|
|
||||||
size_t start = start_;
|
|
||||||
|
|
||||||
int *bad_char_occurrence = bad_char_shift_table_;
|
|
||||||
- int *good_suffix_shift = good_suffix_shift_table_ - start_;
|
|
||||||
+
|
|
||||||
+ auto good_suffix_get = [&](size_t idx) -> int {
|
|
||||||
+ if (idx < start || idx - start > kBMMaxShift) return 0;
|
|
||||||
+ return good_suffix_shift_table_[idx - start];
|
|
||||||
+ };
|
|
||||||
|
|
||||||
Char last_char = pattern_[pattern_length - 1];
|
|
||||||
size_t index = start_index;
|
|
||||||
@@ -575,7 +580,7 @@ size_t StringSearch<Char>::BoyerMooreSearch(Vector subject,
|
|
||||||
index +=
|
|
||||||
pattern_length - 1 - CharOccurrence(bad_char_occurrence, last_char);
|
|
||||||
} else {
|
|
||||||
- int gs_shift = good_suffix_shift[j + 1];
|
|
||||||
+ int gs_shift = good_suffix_get(j + 1);
|
|
||||||
int bc_occ = CharOccurrence(bad_char_occurrence, c);
|
|
||||||
int shift = j - bc_occ;
|
|
||||||
if (gs_shift > shift) {
|
|
||||||
@@ -596,17 +601,22 @@ void StringSearch<Char>::PopulateBoyerMooreTable() {
|
|
||||||
const size_t start = start_;
|
|
||||||
const size_t length = pattern_length - start;
|
|
||||||
|
|
||||||
- // Biased tables so that we can use pattern indices as table indices,
|
|
||||||
- // even if we only cover the part of the pattern from offset start.
|
|
||||||
- int *shift_table = good_suffix_shift_table_ - start_;
|
|
||||||
- int *suffix_table = suffix_table_ - start_;
|
|
||||||
+ auto shift_get = [&](size_t idx) -> int& {
|
|
||||||
+ if (idx < start) abort();
|
|
||||||
+ return good_suffix_shift_table_[idx - start];
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ auto suffix_get = [&](size_t idx) -> int& {
|
|
||||||
+ if (idx < start) abort();
|
|
||||||
+ return suffix_table_[idx - start];
|
|
||||||
+ };
|
|
||||||
|
|
||||||
// Initialize table.
|
|
||||||
for (size_t i = start; i < pattern_length; i++) {
|
|
||||||
- shift_table[i] = length;
|
|
||||||
+ shift_get(i) = length;
|
|
||||||
}
|
|
||||||
- shift_table[pattern_length] = 1;
|
|
||||||
- suffix_table[pattern_length] = pattern_length + 1;
|
|
||||||
+ shift_get(pattern_length) = 1;
|
|
||||||
+ suffix_get(pattern_length) = pattern_length + 1;
|
|
||||||
|
|
||||||
if (pattern_length <= start) {
|
|
||||||
return;
|
|
||||||
@@ -620,22 +630,22 @@ void StringSearch<Char>::PopulateBoyerMooreTable() {
|
|
||||||
while (i > start) {
|
|
||||||
Char c = pattern_[i - 1];
|
|
||||||
while (suffix <= pattern_length && c != pattern_[suffix - 1]) {
|
|
||||||
- if (static_cast<size_t>(shift_table[suffix]) == length) {
|
|
||||||
- shift_table[suffix] = suffix - i;
|
|
||||||
+ if (static_cast<size_t>(shift_get(suffix)) == length) {
|
|
||||||
+ shift_get(suffix) = suffix - i;
|
|
||||||
}
|
|
||||||
- suffix = suffix_table[suffix];
|
|
||||||
+ suffix = suffix_get(suffix);
|
|
||||||
}
|
|
||||||
- suffix_table[--i] = --suffix;
|
|
||||||
+ suffix_get(--i) = --suffix;
|
|
||||||
if (suffix == pattern_length) {
|
|
||||||
// No suffix to extend, so we check against last_char only.
|
|
||||||
while ((i > start) && (pattern_[i - 1] != last_char)) {
|
|
||||||
- if (static_cast<size_t>(shift_table[pattern_length]) == length) {
|
|
||||||
- shift_table[pattern_length] = pattern_length - i;
|
|
||||||
+ if (static_cast<size_t>(shift_get(pattern_length)) == length) {
|
|
||||||
+ shift_get(pattern_length) = pattern_length - i;
|
|
||||||
}
|
|
||||||
- suffix_table[--i] = pattern_length;
|
|
||||||
+ suffix_get(--i) = pattern_length;
|
|
||||||
}
|
|
||||||
if (i > start) {
|
|
||||||
- suffix_table[--i] = --suffix;
|
|
||||||
+ suffix_get(--i) = --suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -643,11 +653,11 @@ void StringSearch<Char>::PopulateBoyerMooreTable() {
|
|
||||||
// Build shift table using suffixes.
|
|
||||||
if (suffix < pattern_length) {
|
|
||||||
for (size_t i = start; i <= pattern_length; i++) {
|
|
||||||
- if (static_cast<size_t>(shift_table[i]) == length) {
|
|
||||||
- shift_table[i] = suffix - start;
|
|
||||||
+ if (static_cast<size_t>(shift_get(i)) == length) {
|
|
||||||
+ shift_get(i) = suffix - start;
|
|
||||||
}
|
|
||||||
if (i == suffix) {
|
|
||||||
- suffix = suffix_table[suffix];
|
|
||||||
+ suffix = suffix_get(suffix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,7 @@ This can be removed/refactored once Node.js upgrades to a version of V8
|
|||||||
containing the above CL.
|
containing the above CL.
|
||||||
|
|
||||||
diff --git a/src/node.cc b/src/node.cc
|
diff --git a/src/node.cc b/src/node.cc
|
||||||
index b99b5170553af51466fd1ee69af3be5026f3fada..ccb644007b8ebbf3899e64d8097d97208c0de182 100644
|
index 0bc4aff4573ccd0e53de5f288b5bccdb6063652a..e1b195f25fe6069ececf3b8c516c5e27f3bf39ab 100644
|
||||||
--- a/src/node.cc
|
--- a/src/node.cc
|
||||||
+++ b/src/node.cc
|
+++ b/src/node.cc
|
||||||
@@ -1239,7 +1239,7 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
|
@@ -1239,7 +1239,7 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
|
||||||
|
|||||||
@@ -77,10 +77,10 @@ index 78985575beb3df7722ba90968e8f085574b5afdf..e032c016efe227c26364e81804ad183c
|
|||||||
// Check if the ESM initiating import CJS is being required by the same CJS module.
|
// Check if the ESM initiating import CJS is being required by the same CJS module.
|
||||||
if (cjsModule?.[kIsExecuting]) {
|
if (cjsModule?.[kIsExecuting]) {
|
||||||
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
||||||
index 859b6bfedac4bbee2df054f9ebca7cbaaed45f18..5aa946f66c71beff0b7a43c30638ab28a1a5dfc0 100644
|
index ec28ea021909071557277c2c98600afb203dfaa1..cb44ec468edb22adc7a159cabec528cc135c9ec5 100644
|
||||||
--- a/lib/internal/modules/esm/resolve.js
|
--- a/lib/internal/modules/esm/resolve.js
|
||||||
+++ b/lib/internal/modules/esm/resolve.js
|
+++ b/lib/internal/modules/esm/resolve.js
|
||||||
@@ -750,6 +750,9 @@ function packageImportsResolve(name, base, conditions) {
|
@@ -751,6 +751,9 @@ function packageImportsResolve(name, base, conditions) {
|
||||||
throw importNotDefined(name, packageJSONUrl, base);
|
throw importNotDefined(name, packageJSONUrl, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ index 859b6bfedac4bbee2df054f9ebca7cbaaed45f18..5aa946f66c71beff0b7a43c30638ab28
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a package specifier to a URL.
|
* Resolves a package specifier to a URL.
|
||||||
@@ -764,6 +767,11 @@ function packageResolve(specifier, base, conditions) {
|
@@ -765,6 +768,11 @@ function packageResolve(specifier, base, conditions) {
|
||||||
return new URL('node:' + specifier);
|
return new URL('node:' + specifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,10 +138,10 @@ index 757f093becd112002f3422302f4c29bb464f1a6c..c8cea2117080930105b33e4e50586a2c
|
|||||||
// This translator function must be sync, as `require` is sync.
|
// This translator function must be sync, as `require` is sync.
|
||||||
translators.set('require-commonjs-typescript', (url, source, isMain) => {
|
translators.set('require-commonjs-typescript', (url, source, isMain) => {
|
||||||
diff --git a/lib/internal/url.js b/lib/internal/url.js
|
diff --git a/lib/internal/url.js b/lib/internal/url.js
|
||||||
index ad1c2c9966085b8febd261b2fc776ce49bc1bd36..96fdce31168ae70ce20f3bfb81931705b2d55f31 100644
|
index 62e240a8a0488c826339b92eb62e78162e0a32b8..f4019eeb831423f9fc1249ed9581ba9492b6c738 100644
|
||||||
--- a/lib/internal/url.js
|
--- a/lib/internal/url.js
|
||||||
+++ b/lib/internal/url.js
|
+++ b/lib/internal/url.js
|
||||||
@@ -1608,6 +1608,8 @@ function fileURLToPath(path, options = kEmptyObject) {
|
@@ -1603,6 +1603,8 @@ function fileURLToPath(path, options = kEmptyObject) {
|
||||||
path = new URL(path);
|
path = new URL(path);
|
||||||
else if (!isURL(path))
|
else if (!isURL(path))
|
||||||
throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);
|
throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||||
|
Date: Tue, 10 Feb 2026 16:48:47 +0100
|
||||||
|
Subject: fix: generate_config_gypi needs to generate valid JSON
|
||||||
|
|
||||||
|
Node.js added new process.config.variables entries, which the GN generator
|
||||||
|
emitted with Python repr (single quotes). This made the JSON parse blow
|
||||||
|
up. Fix this by switching to json.dumps.
|
||||||
|
|
||||||
|
This should be upstreamed.
|
||||||
|
|
||||||
|
diff --git a/tools/generate_config_gypi.py b/tools/generate_config_gypi.py
|
||||||
|
index abd11e1dbda8d400cb900343c6e8d2d6e84fe944..436767e633e1f492fa858645e25ce9b904a5fccb 100755
|
||||||
|
--- a/tools/generate_config_gypi.py
|
||||||
|
+++ b/tools/generate_config_gypi.py
|
||||||
|
@@ -58,7 +58,7 @@ def translate_config(out_dir, config, v8_config):
|
||||||
|
'llvm_version': 13,
|
||||||
|
'napi_build_version': config['napi_build_version'],
|
||||||
|
'node_builtin_shareable_builtins':
|
||||||
|
- eval(config['node_builtin_shareable_builtins']),
|
||||||
|
+ json.loads(config['node_builtin_shareable_builtins']),
|
||||||
|
'node_module_version': int(config['node_module_version']),
|
||||||
|
'node_use_openssl': config['node_use_openssl'],
|
||||||
|
'node_use_amaro': config['node_use_amaro'],
|
||||||
|
@@ -102,7 +102,8 @@ def main():
|
||||||
|
|
||||||
|
# Write output.
|
||||||
|
with open(args.target, 'w') as f:
|
||||||
|
- f.write(repr(translate_config(args.out_dir, config, v8_config)))
|
||||||
|
+ f.write(json.dumps(translate_config(args.out_dir, config, v8_config),
|
||||||
|
+ sort_keys=True))
|
||||||
|
|
||||||
|
# Write depfile. Force regenerating config.gypi when GN configs change.
|
||||||
|
if args.dep_file:
|
||||||
@@ -185,10 +185,10 @@ index e2407027ab05e59b2f0f1c213b98ea469db7a91b..c64761b730e61edcdc0e46a48699f2fd
|
|||||||
# The location of simdutf - use the one from node's deps by default.
|
# The location of simdutf - use the one from node's deps by default.
|
||||||
node_simdutf_path = "//third_party/simdutf"
|
node_simdutf_path = "//third_party/simdutf"
|
||||||
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
|
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
|
||||||
index 2176fb6982484e2c42538478eeb4dd81c9d50ee1..c00d3616e08b00b1e0a3a29b2dbb5278e1e14fcc 100644
|
index 07eb79acdf5e2d236b36daa1b314ed1afa19a545..c862f91bf1f9494b747b2950e8e37547ba08b6b8 100644
|
||||||
--- a/src/crypto/crypto_cipher.cc
|
--- a/src/crypto/crypto_cipher.cc
|
||||||
+++ b/src/crypto/crypto_cipher.cc
|
+++ b/src/crypto/crypto_cipher.cc
|
||||||
@@ -1027,7 +1027,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
@@ -1026,7 +1026,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
||||||
if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
|
if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
|
||||||
return ThrowCryptoError(env, ERR_get_error());
|
return ThrowCryptoError(env, ERR_get_error());
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ index 2176fb6982484e2c42538478eeb4dd81c9d50ee1..c00d3616e08b00b1e0a3a29b2dbb5278
|
|||||||
int rsa_pkcs1_implicit_rejection =
|
int rsa_pkcs1_implicit_rejection =
|
||||||
EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
|
EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
|
||||||
// From the doc -2 means that the option is not supported.
|
// From the doc -2 means that the option is not supported.
|
||||||
@@ -1042,6 +1042,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
@@ -1041,6 +1041,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
|
||||||
env,
|
env,
|
||||||
"RSA_PKCS1_PADDING is no longer supported for private decryption");
|
"RSA_PKCS1_PADDING is no longer supported for private decryption");
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ index d94f6e1c82c4a62547b3b395f375c86ce4deb5de..b81b9005365272217c77e2b9289bd9f8
|
|||||||
X509View ca(sk_X509_value(peer_certs.get(), i));
|
X509View ca(sk_X509_value(peer_certs.get(), i));
|
||||||
if (!cert->view().isIssuedBy(ca)) continue;
|
if (!cert->view().isIssuedBy(ca)) continue;
|
||||||
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
||||||
index d1430cd66dd045dcb52dd166e1eabc7202d1bd94..8f50d0cc132ac65fa74cf1fc2172247b5ad42962 100644
|
index 8028f6db70f481e291aca2b8e0e6129900fbf67e..2cd7cd67c1c480eb9ec549a12bc2b9584d5a53b3 100644
|
||||||
--- a/src/crypto/crypto_context.cc
|
--- a/src/crypto/crypto_context.cc
|
||||||
+++ b/src/crypto/crypto_context.cc
|
+++ b/src/crypto/crypto_context.cc
|
||||||
@@ -141,7 +141,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
|
@@ -141,7 +141,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
|
||||||
@@ -240,7 +240,7 @@ index d1430cd66dd045dcb52dd166e1eabc7202d1bd94..8f50d0cc132ac65fa74cf1fc2172247b
|
|||||||
X509* ca = sk_X509_value(extra_certs, i);
|
X509* ca = sk_X509_value(extra_certs, i);
|
||||||
|
|
||||||
// NOTE: Increments reference count on `ca`
|
// NOTE: Increments reference count on `ca`
|
||||||
@@ -1831,11 +1831,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
|
@@ -1854,11 +1854,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
|
||||||
// If the user specified "auto" for dhparams, the JavaScript layer will pass
|
// If the user specified "auto" for dhparams, the JavaScript layer will pass
|
||||||
// true to this function instead of the original string. Any other string
|
// true to this function instead of the original string. Any other string
|
||||||
// value will be interpreted as custom DH parameters below.
|
// value will be interpreted as custom DH parameters below.
|
||||||
@@ -254,7 +254,7 @@ index d1430cd66dd045dcb52dd166e1eabc7202d1bd94..8f50d0cc132ac65fa74cf1fc2172247b
|
|||||||
DHPointer dh;
|
DHPointer dh;
|
||||||
{
|
{
|
||||||
BIOPointer bio(LoadBIO(env, args[0]));
|
BIOPointer bio(LoadBIO(env, args[0]));
|
||||||
@@ -2061,7 +2062,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
|
@@ -2084,7 +2085,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add CA certs too
|
// Add CA certs too
|
||||||
@@ -519,7 +519,7 @@ index 9c2360df7150571377eff37fc5e958d17900da30..4505786745c54a529f904d5e7813a862
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
diff --git a/src/env.h b/src/env.h
|
diff --git a/src/env.h b/src/env.h
|
||||||
index 874e5f4d15a75307e45cf70c06fc104fed843a6a..35e16159a94bb97f19d17767e3ad4bb798660f44 100644
|
index 7a63acde77d28c0f11c7f2563c8c3cb2ebdce780..723e4738dd1c32710e521775d66e0d957334344c 100644
|
||||||
--- a/src/env.h
|
--- a/src/env.h
|
||||||
+++ b/src/env.h
|
+++ b/src/env.h
|
||||||
@@ -51,7 +51,7 @@
|
@@ -51,7 +51,7 @@
|
||||||
@@ -554,7 +554,7 @@ index d9c533f100d25aeab1fe8589932a8ddead431258..2acab8786a8a752b17961445edeb872c
|
|||||||
#if NODE_OPENSSL_HAS_QUIC
|
#if NODE_OPENSSL_HAS_QUIC
|
||||||
#include <openssl/quic.h>
|
#include <openssl/quic.h>
|
||||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||||
index 31fc23fdbfabceab3cffd81a3e6650dde1ccd13a..3026b3d814ae652a9996c1dcba62b4fa678ac871 100644
|
index 5b74045886e91a27e766a7f0a8f2dddfacaa1d46..41de3936265f0544831521fe753d2050e91b58e1 100644
|
||||||
--- a/src/node_options.cc
|
--- a/src/node_options.cc
|
||||||
+++ b/src/node_options.cc
|
+++ b/src/node_options.cc
|
||||||
@@ -8,7 +8,7 @@
|
@@ -8,7 +8,7 @@
|
||||||
@@ -567,7 +567,7 @@ index 31fc23fdbfabceab3cffd81a3e6650dde1ccd13a..3026b3d814ae652a9996c1dcba62b4fa
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
diff --git a/src/node_options.h b/src/node_options.h
|
diff --git a/src/node_options.h b/src/node_options.h
|
||||||
index 2e73fd2a05e329910d4c064474880f770c9f5957..d8751a6ee734233e2fc24866ed87d9cd516072ae 100644
|
index c1bcc063a001194bb76efe9a202fb4ab271ba834..b7d9b429f0b498dfd70301074948a13a2d35532e 100644
|
||||||
--- a/src/node_options.h
|
--- a/src/node_options.h
|
||||||
+++ b/src/node_options.h
|
+++ b/src/node_options.h
|
||||||
@@ -11,7 +11,7 @@
|
@@ -11,7 +11,7 @@
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ index 3676a9852bcd42de0a3a380de117de58035f757b..eaecfcfd8b922908957c3fefea65fb9d
|
|||||||
const result = dataURLProcessor(url);
|
const result = dataURLProcessor(url);
|
||||||
if (result === 'failure') {
|
if (result === 'failure') {
|
||||||
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
|
||||||
index 5aa946f66c71beff0b7a43c30638ab28a1a5dfc0..e3afd30ba1f591d0298793bc42fd7166a4219bce 100644
|
index cb44ec468edb22adc7a159cabec528cc135c9ec5..4216e136d01a119264de1523ed466efb783311c3 100644
|
||||||
--- a/lib/internal/modules/esm/resolve.js
|
--- a/lib/internal/modules/esm/resolve.js
|
||||||
+++ b/lib/internal/modules/esm/resolve.js
|
+++ b/lib/internal/modules/esm/resolve.js
|
||||||
@@ -25,7 +25,7 @@ const {
|
@@ -25,7 +25,7 @@ const {
|
||||||
@@ -40,7 +40,7 @@ index 5aa946f66c71beff0b7a43c30638ab28a1a5dfc0..e3afd30ba1f591d0298793bc42fd7166
|
|||||||
const { getOptionValue } = require('internal/options');
|
const { getOptionValue } = require('internal/options');
|
||||||
// Do not eagerly grab .manifest, it may be in TDZ
|
// Do not eagerly grab .manifest, it may be in TDZ
|
||||||
const { sep, posix: { relative: relativePosixPath }, resolve } = require('path');
|
const { sep, posix: { relative: relativePosixPath }, resolve } = require('path');
|
||||||
@@ -276,7 +276,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
|
@@ -277,7 +277,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!preserveSymlinks) {
|
if (!preserveSymlinks) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ index fe669d40c31a29334b047b9cfee3067f64ef0a7b..9e5de7bbe574add017cd12ee091304d0
|
|||||||
|
|
||||||
static CFunction fast_timing_safe_equal(CFunction::Make(FastTimingSafeEqual));
|
static CFunction fast_timing_safe_equal(CFunction::Make(FastTimingSafeEqual));
|
||||||
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
||||||
index b9f0c97938203b4652780a7d707c5e83319330b0..8a5b6b57321c2843a965a7e51b2ebed991a1e424 100644
|
index 2fdada446c5d1ffa460f483a3360aeca658d9eef..b87b53843c3369832e561b9ffd40ca7c2134e74c 100644
|
||||||
--- a/src/node_buffer.cc
|
--- a/src/node_buffer.cc
|
||||||
+++ b/src/node_buffer.cc
|
+++ b/src/node_buffer.cc
|
||||||
@@ -44,6 +44,14 @@
|
@@ -44,6 +44,14 @@
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ This patch can be removed when we upgrade to a V8 version that
|
|||||||
contains the above CLs.
|
contains the above CLs.
|
||||||
|
|
||||||
diff --git a/src/node.cc b/src/node.cc
|
diff --git a/src/node.cc b/src/node.cc
|
||||||
index 2d8d0000d52411992d2bd513cc7dd96b2292bab9..0ffc69d54631fa3dbac20337b26f7a0679560b96 100644
|
index db0011b429f25cab296ca425564effe87383f506..152a9d9b17f9b14922421e2fe9866b6056f13ec7 100644
|
||||||
--- a/src/node.cc
|
--- a/src/node.cc
|
||||||
+++ b/src/node.cc
|
+++ b/src/node.cc
|
||||||
@@ -816,7 +816,7 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
|
@@ -816,7 +816,7 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ This is already applied in newer versions of Node so we can drop
|
|||||||
this patch once we upgrade to v23.
|
this patch once we upgrade to v23.
|
||||||
|
|
||||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||||
index 79327877b0f34cbafb3efcc21617027d4011f806..8a12475857135bd3e904610b7eb887c397c8e73c 100644
|
index 6034b779fe05850cfc4e7f7af221489be9369b54..d19cae298147f1b310506eec49b6fbd036fb1195 100644
|
||||||
--- a/src/api/environment.cc
|
--- a/src/api/environment.cc
|
||||||
+++ b/src/api/environment.cc
|
+++ b/src/api/environment.cc
|
||||||
@@ -827,7 +827,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
@@ -832,7 +832,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||||
|
|
||||||
Local<Object> private_symbols_object;
|
Local<Object> private_symbols_object;
|
||||||
if (!private_symbols->NewInstance(context).ToLocal(&private_symbols_object) ||
|
if (!private_symbols->NewInstance(context).ToLocal(&private_symbols_object) ||
|
||||||
@@ -21,7 +21,7 @@ index 79327877b0f34cbafb3efcc21617027d4011f806..8a12475857135bd3e904610b7eb887c3
|
|||||||
.IsNothing()) {
|
.IsNothing()) {
|
||||||
return MaybeLocal<Object>();
|
return MaybeLocal<Object>();
|
||||||
}
|
}
|
||||||
@@ -853,7 +853,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
@@ -858,7 +858,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||||
Local<Object> per_isolate_symbols_object;
|
Local<Object> per_isolate_symbols_object;
|
||||||
if (!per_isolate_symbols->NewInstance(context).ToLocal(
|
if (!per_isolate_symbols->NewInstance(context).ToLocal(
|
||||||
&per_isolate_symbols_object) ||
|
&per_isolate_symbols_object) ||
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Subject: Pass all globals through "require"
|
|||||||
(cherry picked from commit 7d015419cb7a0ecfe6728431a4ed2056cd411d62)
|
(cherry picked from commit 7d015419cb7a0ecfe6728431a4ed2056cd411d62)
|
||||||
|
|
||||||
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
|
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
|
||||||
index a7d8fa1139c82054ac37a4e11cfb68605dc21f31..589c239aa544e118b7d9b7fff86d7deefe903896 100644
|
index b87f557c16820ea52eece22813a8a218587a62dc..21730d32e0dd16065ae15ad6a0aae90e81a4c9b2 100644
|
||||||
--- a/lib/internal/modules/cjs/loader.js
|
--- a/lib/internal/modules/cjs/loader.js
|
||||||
+++ b/lib/internal/modules/cjs/loader.js
|
+++ b/lib/internal/modules/cjs/loader.js
|
||||||
@@ -202,6 +202,13 @@ const {
|
@@ -202,6 +202,13 @@ const {
|
||||||
@@ -23,7 +23,7 @@ index a7d8fa1139c82054ac37a4e11cfb68605dc21f31..589c239aa544e118b7d9b7fff86d7dee
|
|||||||
const {
|
const {
|
||||||
isProxy,
|
isProxy,
|
||||||
} = require('internal/util/types');
|
} = require('internal/util/types');
|
||||||
@@ -1701,10 +1708,12 @@ Module.prototype._compile = function(content, filename, format) {
|
@@ -1700,10 +1707,12 @@ Module.prototype._compile = function(content, filename, format) {
|
||||||
if (this[kIsMainSymbol] && getOptionValue('--inspect-brk')) {
|
if (this[kIsMainSymbol] && getOptionValue('--inspect-brk')) {
|
||||||
const { callAndPauseOnStart } = internalBinding('inspector');
|
const { callAndPauseOnStart } = internalBinding('inspector');
|
||||||
result = callAndPauseOnStart(compiledWrapper, thisValue, exports,
|
result = callAndPauseOnStart(compiledWrapper, thisValue, exports,
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ This can be removed when Node.js upgrades to a version of V8 containing CLs
|
|||||||
from the above issue.
|
from the above issue.
|
||||||
|
|
||||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||||
index fd71ceac65ccef1d2832b45b0b5612877cee22c1..ceac508418f489a8077c1bc85a2feaf85bf60480 100644
|
index 8356e588659d2208700659f3e3ce5438fba9462f..d2614bba9463056e931b6d5c1f3153e2f576b779 100644
|
||||||
--- a/src/api/environment.cc
|
--- a/src/api/environment.cc
|
||||||
+++ b/src/api/environment.cc
|
+++ b/src/api/environment.cc
|
||||||
@@ -308,6 +308,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
|
@@ -313,6 +313,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
|
||||||
MultiIsolatePlatform* platform,
|
MultiIsolatePlatform* platform,
|
||||||
const SnapshotData* snapshot_data,
|
const SnapshotData* snapshot_data,
|
||||||
const IsolateSettings& settings) {
|
const IsolateSettings& settings) {
|
||||||
@@ -32,7 +32,7 @@ index fd71ceac65ccef1d2832b45b0b5612877cee22c1..ceac508418f489a8077c1bc85a2feaf8
|
|||||||
Isolate* isolate = Isolate::Allocate();
|
Isolate* isolate = Isolate::Allocate();
|
||||||
if (isolate == nullptr) return nullptr;
|
if (isolate == nullptr) return nullptr;
|
||||||
|
|
||||||
@@ -351,9 +355,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator,
|
@@ -356,9 +360,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator,
|
||||||
uv_loop_t* event_loop,
|
uv_loop_t* event_loop,
|
||||||
MultiIsolatePlatform* platform,
|
MultiIsolatePlatform* platform,
|
||||||
const EmbedderSnapshotData* snapshot_data,
|
const EmbedderSnapshotData* snapshot_data,
|
||||||
@@ -82,7 +82,7 @@ index 85641b68b1e6f6dd4149f33ba13f76bccc8bf47d..c6209cc7cf317de1bb9217e39dd760e5
|
|||||||
void SetCppgcReference(Isolate* isolate,
|
void SetCppgcReference(Isolate* isolate,
|
||||||
Local<Object> object,
|
Local<Object> object,
|
||||||
diff --git a/src/env.h b/src/env.h
|
diff --git a/src/env.h b/src/env.h
|
||||||
index 2d5fa8dbd75851bca30453548f6cbe0159509f26..c346e3a9c827993036438685d758a734f9ce8c05 100644
|
index 888f0a5572254d775cbf672dcf07b789782292ea..2af2846af6ba7d8ad6e0edca5e2f6279e4c672a3 100644
|
||||||
--- a/src/env.h
|
--- a/src/env.h
|
||||||
+++ b/src/env.h
|
+++ b/src/env.h
|
||||||
@@ -157,7 +157,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
|
@@ -157,7 +157,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
|
||||||
@@ -102,7 +102,7 @@ index 2d5fa8dbd75851bca30453548f6cbe0159509f26..c346e3a9c827993036438685d758a734
|
|||||||
worker::Worker* worker_context_ = nullptr;
|
worker::Worker* worker_context_ = nullptr;
|
||||||
PerIsolateWrapperData* wrapper_data_;
|
PerIsolateWrapperData* wrapper_data_;
|
||||||
diff --git a/src/node.cc b/src/node.cc
|
diff --git a/src/node.cc b/src/node.cc
|
||||||
index 0ffc69d54631fa3dbac20337b26f7a0679560b96..f012b365455bb111cddea44fcff020804086ab72 100644
|
index 152a9d9b17f9b14922421e2fe9866b6056f13ec7..f85b5ed687180d7a12648b87398a734fb321f346 100644
|
||||||
--- a/src/node.cc
|
--- a/src/node.cc
|
||||||
+++ b/src/node.cc
|
+++ b/src/node.cc
|
||||||
@@ -1288,6 +1288,14 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
|
@@ -1288,6 +1288,14 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
|
||||||
@@ -136,10 +136,10 @@ index 0ffc69d54631fa3dbac20337b26f7a0679560b96..f012b365455bb111cddea44fcff02080
|
|||||||
bool use_wasm_trap_handler =
|
bool use_wasm_trap_handler =
|
||||||
!per_process::cli_options->disable_wasm_trap_handler;
|
!per_process::cli_options->disable_wasm_trap_handler;
|
||||||
diff --git a/src/node.h b/src/node.h
|
diff --git a/src/node.h b/src/node.h
|
||||||
index d3a965661d068db359bb1bb4b14e59c28bb615f9..16a0c71aef949b0ddd27def9dc843298f9a6b75f 100644
|
index 91468bfd755db6adde5cc8cecb184312db90a654..fe44369dff7519ea0d960ae478d5caf524e17366 100644
|
||||||
--- a/src/node.h
|
--- a/src/node.h
|
||||||
+++ b/src/node.h
|
+++ b/src/node.h
|
||||||
@@ -590,7 +590,8 @@ NODE_EXTERN v8::Isolate* NewIsolate(
|
@@ -589,7 +589,8 @@ NODE_EXTERN v8::Isolate* NewIsolate(
|
||||||
struct uv_loop_s* event_loop,
|
struct uv_loop_s* event_loop,
|
||||||
MultiIsolatePlatform* platform,
|
MultiIsolatePlatform* platform,
|
||||||
const EmbedderSnapshotData* snapshot_data = nullptr,
|
const EmbedderSnapshotData* snapshot_data = nullptr,
|
||||||
@@ -174,7 +174,7 @@ index 4119ac1b002681d39711eac810ca2fcc2702ffc7..790347056cde949ffe6cf8498a7eca0c
|
|||||||
|
|
||||||
ExitCode NodeMainInstance::Run() {
|
ExitCode NodeMainInstance::Run() {
|
||||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
||||||
index 29c4b1de42b3127a98871d200c80197bf974b31f..8555ab556b5b74a1cf9cf30747f1f417bfe4e4d9 100644
|
index 083abea7d744e552dd349e5e1ceb75dfaaa79eaa..ddfea91272d03d4ef1d4ac1b982ada5dcd24b601 100644
|
||||||
--- a/src/node_worker.cc
|
--- a/src/node_worker.cc
|
||||||
+++ b/src/node_worker.cc
|
+++ b/src/node_worker.cc
|
||||||
@@ -177,6 +177,9 @@ class WorkerThreadData {
|
@@ -177,6 +177,9 @@ class WorkerThreadData {
|
||||||
|
|||||||
@@ -16,24 +16,28 @@ that is exposed to JS
|
|||||||
Refs https://github.com/nodejs/node/commit/3cdb1cd437f63dd256ae2ab3b7e9016257326cb4
|
Refs https://github.com/nodejs/node/commit/3cdb1cd437f63dd256ae2ab3b7e9016257326cb4
|
||||||
|
|
||||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||||
index 8a12475857135bd3e904610b7eb887c397c8e73c..3702672f4e2c3b1bff9f9f5c66ca251af447826a 100644
|
index d19cae298147f1b310506eec49b6fbd036fb1195..ecd2d481d97e5dab934481b085b949f47904a6c4 100644
|
||||||
--- a/src/api/environment.cc
|
--- a/src/api/environment.cc
|
||||||
+++ b/src/api/environment.cc
|
+++ b/src/api/environment.cc
|
||||||
@@ -107,11 +107,7 @@ MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
|
@@ -108,14 +108,8 @@ MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
|
||||||
}
|
}
|
||||||
|
|
||||||
void* NodeArrayBufferAllocator::Allocate(size_t size) {
|
void* NodeArrayBufferAllocator::Allocate(size_t size) {
|
||||||
- void* ret;
|
- void* ret;
|
||||||
- if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers)
|
- if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) {
|
||||||
|
- COUNT_GENERIC_USAGE("NodeArrayBufferAllocator.Allocate.ZeroFilled");
|
||||||
- ret = allocator_->Allocate(size);
|
- ret = allocator_->Allocate(size);
|
||||||
- else
|
- } else {
|
||||||
|
- COUNT_GENERIC_USAGE("NodeArrayBufferAllocator.Allocate.Uninitialized");
|
||||||
- ret = allocator_->AllocateUninitialized(size);
|
- ret = allocator_->AllocateUninitialized(size);
|
||||||
|
- }
|
||||||
+ void* ret = allocator_->Allocate(size);
|
+ void* ret = allocator_->Allocate(size);
|
||||||
|
+ COUNT_GENERIC_USAGE("NodeArrayBufferAllocator.Allocate.Uninitialized");
|
||||||
if (ret != nullptr) [[likely]] {
|
if (ret != nullptr) [[likely]] {
|
||||||
total_mem_usage_.fetch_add(size, std::memory_order_relaxed);
|
total_mem_usage_.fetch_add(size, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
|
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
|
||||||
index c00d3616e08b00b1e0a3a29b2dbb5278e1e14fcc..8939c5e5085d00b098f66074b9ee033f5be55d08 100644
|
index c862f91bf1f9494b747b2950e8e37547ba08b6b8..9fd48697845fca304e1dabf7c57ab208d9649a73 100644
|
||||||
--- a/src/crypto/crypto_cipher.cc
|
--- a/src/crypto/crypto_cipher.cc
|
||||||
+++ b/src/crypto/crypto_cipher.cc
|
+++ b/src/crypto/crypto_cipher.cc
|
||||||
@@ -20,6 +20,7 @@ using ncrypto::SSLPointer;
|
@@ -20,6 +20,7 @@ using ncrypto::SSLPointer;
|
||||||
@@ -44,7 +48,7 @@ index c00d3616e08b00b1e0a3a29b2dbb5278e1e14fcc..8939c5e5085d00b098f66074b9ee033f
|
|||||||
using v8::Context;
|
using v8::Context;
|
||||||
using v8::FunctionCallbackInfo;
|
using v8::FunctionCallbackInfo;
|
||||||
using v8::FunctionTemplate;
|
using v8::FunctionTemplate;
|
||||||
@@ -774,10 +775,10 @@ CipherBase::UpdateResult CipherBase::Update(
|
@@ -773,10 +774,10 @@ CipherBase::UpdateResult CipherBase::Update(
|
||||||
return kErrorState;
|
return kErrorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +63,7 @@ index c00d3616e08b00b1e0a3a29b2dbb5278e1e14fcc..8939c5e5085d00b098f66074b9ee033f
|
|||||||
|
|
||||||
buffer = {
|
buffer = {
|
||||||
.data = reinterpret_cast<const unsigned char*>(data),
|
.data = reinterpret_cast<const unsigned char*>(data),
|
||||||
@@ -852,11 +853,10 @@ bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
|
@@ -851,11 +852,10 @@ bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
|
||||||
|
|
||||||
const int mode = ctx_.getMode();
|
const int mode = ctx_.getMode();
|
||||||
|
|
||||||
@@ -75,7 +79,7 @@ index c00d3616e08b00b1e0a3a29b2dbb5278e1e14fcc..8939c5e5085d00b098f66074b9ee033f
|
|||||||
|
|
||||||
if (kind_ == kDecipher &&
|
if (kind_ == kDecipher &&
|
||||||
Cipher::FromCtx(ctx_).isSupportedAuthenticatedMode()) {
|
Cipher::FromCtx(ctx_).isSupportedAuthenticatedMode()) {
|
||||||
@@ -972,10 +972,10 @@ bool PublicKeyCipher::Cipher(
|
@@ -971,10 +971,10 @@ bool PublicKeyCipher::Cipher(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +363,7 @@ index fd29d17de195017970856ce30d7a9c5785b0b8ee..7fe3d09851d4476fa3f77ea0a0b49e8a
|
|||||||
unsigned char* serialized = reinterpret_cast<unsigned char*>(bs->Data());
|
unsigned char* serialized = reinterpret_cast<unsigned char*>(bs->Data());
|
||||||
CHECK_GE(i2d_RSA_PUBKEY(rsa, &serialized), 0);
|
CHECK_GE(i2d_RSA_PUBKEY(rsa, &serialized), 0);
|
||||||
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
|
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
|
||||||
index 5ace688bb7ffc86eedf5aff11ab0ab487ad9440e..31058543a164bb45ba989e8c433994e0857a98b9 100644
|
index 22eecffa437a9e0f4a0e170953aa35fa527511b5..5b45f2223cece766bd7d27ac0d3a853c82f8ce07 100644
|
||||||
--- a/src/encoding_binding.cc
|
--- a/src/encoding_binding.cc
|
||||||
+++ b/src/encoding_binding.cc
|
+++ b/src/encoding_binding.cc
|
||||||
@@ -15,6 +15,7 @@ namespace encoding_binding {
|
@@ -15,6 +15,7 @@ namespace encoding_binding {
|
||||||
@@ -383,7 +387,7 @@ index 5ace688bb7ffc86eedf5aff11ab0ab487ad9440e..31058543a164bb45ba989e8c433994e0
|
|||||||
CHECK(bs);
|
CHECK(bs);
|
||||||
|
|
||||||
diff --git a/src/env-inl.h b/src/env-inl.h
|
diff --git a/src/env-inl.h b/src/env-inl.h
|
||||||
index 98e1e1e75bae94038bba0049447ab48b0acfb8cc..fe395bf89f9c1e5bb2dabc8fceda7b9b2b877415 100644
|
index d1a7e1212da46a8e5c2fffee46542ac8bec828ee..97018f2378fe4848944f26f51684b21ac118d1b3 100644
|
||||||
--- a/src/env-inl.h
|
--- a/src/env-inl.h
|
||||||
+++ b/src/env-inl.h
|
+++ b/src/env-inl.h
|
||||||
@@ -44,16 +44,6 @@
|
@@ -44,16 +44,6 @@
|
||||||
@@ -432,7 +436,7 @@ index 161d577e0ea6a251c83ba1903b1ec9a582a5317c..52713421465c23c959afac1955168294
|
|||||||
released_allocated_buffers_.emplace(buf.base, std::move(bs));
|
released_allocated_buffers_.emplace(buf.base, std::move(bs));
|
||||||
return buf;
|
return buf;
|
||||||
diff --git a/src/env.h b/src/env.h
|
diff --git a/src/env.h b/src/env.h
|
||||||
index c346e3a9c827993036438685d758a734f9ce8c05..28c8df87c8e2f06e2ed8c554260bfdedb860bb4a 100644
|
index 2af2846af6ba7d8ad6e0edca5e2f6279e4c672a3..87cff857bbe65c32e1931886b953c5e32deba193 100644
|
||||||
--- a/src/env.h
|
--- a/src/env.h
|
||||||
+++ b/src/env.h
|
+++ b/src/env.h
|
||||||
@@ -114,19 +114,6 @@ class ModuleWrap;
|
@@ -114,19 +114,6 @@ class ModuleWrap;
|
||||||
@@ -456,7 +460,7 @@ index c346e3a9c827993036438685d758a734f9ce8c05..28c8df87c8e2f06e2ed8c554260bfded
|
|||||||
std::vector<SnapshotIndex> primitive_values;
|
std::vector<SnapshotIndex> primitive_values;
|
||||||
std::vector<PropInfo> template_values;
|
std::vector<PropInfo> template_values;
|
||||||
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
||||||
index e844fe6cb33acefd075516e675075421ad5c3cff..06c84eb6ec097e3cb39502116135a7802aed13ce 100644
|
index 0cf2a07deb382dfd96607f84b583ffbd62447769..f2943d5ceca106564e421c668ec8815c43c21085 100644
|
||||||
--- a/src/node_buffer.cc
|
--- a/src/node_buffer.cc
|
||||||
+++ b/src/node_buffer.cc
|
+++ b/src/node_buffer.cc
|
||||||
@@ -66,6 +66,7 @@ namespace Buffer {
|
@@ -66,6 +66,7 @@ namespace Buffer {
|
||||||
@@ -525,7 +529,7 @@ index e844fe6cb33acefd075516e675075421ad5c3cff..06c84eb6ec097e3cb39502116135a780
|
|||||||
return env->ThrowRangeError("Array buffer allocation failed");
|
return env->ThrowRangeError("Array buffer allocation failed");
|
||||||
}
|
}
|
||||||
diff --git a/src/node_http2.cc b/src/node_http2.cc
|
diff --git a/src/node_http2.cc b/src/node_http2.cc
|
||||||
index 8237c9b7d325dd925ae8798d7795fcd94eeb13d0..a22cf6c4e33e5cf2d3168ce03dc35af8a9584af7 100644
|
index 7c070ae09e77afc7773724a516217059189138a7..bb761c0a201cbed568258d07d8ec0d6a80de8b3b 100644
|
||||||
--- a/src/node_http2.cc
|
--- a/src/node_http2.cc
|
||||||
+++ b/src/node_http2.cc
|
+++ b/src/node_http2.cc
|
||||||
@@ -27,6 +27,7 @@ using v8::Array;
|
@@ -27,6 +27,7 @@ using v8::Array;
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joyee Cheung <joyeec9h3@gmail.com>
|
|
||||||
Date: Thu, 20 Nov 2025 13:50:28 +0900
|
|
||||||
Subject: src: handle DER decoding errors from system certificates
|
|
||||||
|
|
||||||
When decoding certificates from the system store, it's not actually
|
|
||||||
guaranteed to succeed. In case the system returns a certificate
|
|
||||||
that cannot be decoded (might be related to SSL implementation issues),
|
|
||||||
skip them.
|
|
||||||
|
|
||||||
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
|
||||||
index 0c6b12f8e17b4a7e86ebc836a4e1cc77333f211a..dacf10c3c2e663b03a251c86d69276d0be0dff9d 100644
|
|
||||||
--- a/src/crypto/crypto_context.cc
|
|
||||||
+++ b/src/crypto/crypto_context.cc
|
|
||||||
@@ -505,7 +505,11 @@ void ReadMacOSKeychainCertificates(
|
|
||||||
CFRelease(search);
|
|
||||||
|
|
||||||
if (ortn) {
|
|
||||||
- fprintf(stderr, "ERROR: SecItemCopyMatching failed %d\n", ortn);
|
|
||||||
+ per_process::Debug(DebugCategory::CRYPTO,
|
|
||||||
+ "Cannot read certificates from system because "
|
|
||||||
+ "SecItemCopyMatching failed %d\n",
|
|
||||||
+ ortn);
|
|
||||||
+ return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFIndex count = CFArrayGetCount(curr_anchors);
|
|
||||||
@@ -516,7 +520,9 @@ void ReadMacOSKeychainCertificates(
|
|
||||||
|
|
||||||
CFDataRef der_data = SecCertificateCopyData(cert_ref);
|
|
||||||
if (!der_data) {
|
|
||||||
- fprintf(stderr, "ERROR: SecCertificateCopyData failed\n");
|
|
||||||
+ per_process::Debug(DebugCategory::CRYPTO,
|
|
||||||
+ "Skipping read of a system certificate "
|
|
||||||
+ "because SecCertificateCopyData failed\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto data_buffer_pointer = CFDataGetBytePtr(der_data);
|
|
||||||
@@ -524,9 +530,19 @@ void ReadMacOSKeychainCertificates(
|
|
||||||
X509* cert =
|
|
||||||
d2i_X509(nullptr, &data_buffer_pointer, CFDataGetLength(der_data));
|
|
||||||
CFRelease(der_data);
|
|
||||||
+
|
|
||||||
+ if (cert == nullptr) {
|
|
||||||
+ per_process::Debug(DebugCategory::CRYPTO,
|
|
||||||
+ "Skipping read of a system certificate "
|
|
||||||
+ "because decoding failed\n");
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
bool is_valid = IsCertificateTrustedForPolicy(cert, cert_ref);
|
|
||||||
if (is_valid) {
|
|
||||||
system_root_certificates_X509->emplace_back(cert);
|
|
||||||
+ } else {
|
|
||||||
+ X509_free(cert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CFRelease(curr_anchors);
|
|
||||||
@@ -636,7 +652,14 @@ void GatherCertsForLocation(std::vector<X509*>* vector,
|
|
||||||
reinterpret_cast<const unsigned char*>(cert_from_store->pbCertEncoded);
|
|
||||||
const size_t cert_size = cert_from_store->cbCertEncoded;
|
|
||||||
|
|
||||||
- vector->emplace_back(d2i_X509(nullptr, &cert_data, cert_size));
|
|
||||||
+ X509* x509 = d2i_X509(nullptr, &cert_data, cert_size);
|
|
||||||
+ if (x509 == nullptr) {
|
|
||||||
+ per_process::Debug(DebugCategory::CRYPTO,
|
|
||||||
+ "Skipping read of a system certificate "
|
|
||||||
+ "because decoding failed\n");
|
|
||||||
+ } else {
|
|
||||||
+ vector->emplace_back(x509);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -212,10 +212,10 @@ index 7fe3d09851d4476fa3f77ea0a0b49e8af13fae4f..b60ad6b1cdb0b923ba2de1b7205ed5ce
|
|||||||
Local<Value> ret;
|
Local<Value> ret;
|
||||||
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {};
|
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {};
|
||||||
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
||||||
index 413db3ed9b88d7b7fb2ac6dd1153dade9ff830fd..6da93b8569a34841e846c320ec0a6ca7f1ea0da6 100644
|
index e62dce7a3e5f32ebb926ad2ffe57887ab1887b8d..878d9764e072f0b0105508541beff205bf97b1ab 100644
|
||||||
--- a/src/js_native_api_v8.cc
|
--- a/src/js_native_api_v8.cc
|
||||||
+++ b/src/js_native_api_v8.cc
|
+++ b/src/js_native_api_v8.cc
|
||||||
@@ -114,7 +114,7 @@ napi_status NewExternalString(napi_env env,
|
@@ -116,7 +116,7 @@ napi_status NewExternalString(napi_env env,
|
||||||
CHECK_NEW_STRING_ARGS(env, str, length, result);
|
CHECK_NEW_STRING_ARGS(env, str, length, result);
|
||||||
|
|
||||||
napi_status status;
|
napi_status status;
|
||||||
@@ -225,10 +225,10 @@ index 413db3ed9b88d7b7fb2ac6dd1153dade9ff830fd..6da93b8569a34841e846c320ec0a6ca7
|
|||||||
if (status == napi_ok) {
|
if (status == napi_ok) {
|
||||||
if (copied != nullptr) {
|
if (copied != nullptr) {
|
||||||
diff --git a/src/node_api.cc b/src/node_api.cc
|
diff --git a/src/node_api.cc b/src/node_api.cc
|
||||||
index 2769997f0ede0e921fcb8826942609e497e5f9cb..d9b17780f6143f1c3f8488a20144376963e43fbc 100644
|
index 26583f964edadef46ee65e52844a4d9a0ddacc2f..9086dd9d6f409f266a1e9ae603733ecfd0fb8d72 100644
|
||||||
--- a/src/node_api.cc
|
--- a/src/node_api.cc
|
||||||
+++ b/src/node_api.cc
|
+++ b/src/node_api.cc
|
||||||
@@ -1056,7 +1056,7 @@ napi_create_external_buffer(napi_env env,
|
@@ -1058,7 +1058,7 @@ napi_create_external_buffer(napi_env env,
|
||||||
NAPI_PREAMBLE(env);
|
NAPI_PREAMBLE(env);
|
||||||
CHECK_ARG(env, result);
|
CHECK_ARG(env, result);
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ index 2769997f0ede0e921fcb8826942609e497e5f9cb..d9b17780f6143f1c3f8488a201443769
|
|||||||
#else
|
#else
|
||||||
v8::Isolate* isolate = env->isolate;
|
v8::Isolate* isolate = env->isolate;
|
||||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||||
index e93e8684e518b30a2514768a269be6d32d1f5b94..547cda780376f578b0f78eb9158dc14a3faf874d 100644
|
index 1ebc7bfca2d89f78898873e8b6f838f3f4c2e576..bec62634d153e2311959ad2fb56f54dfbbb80f09 100644
|
||||||
--- a/src/node_options.cc
|
--- a/src/node_options.cc
|
||||||
+++ b/src/node_options.cc
|
+++ b/src/node_options.cc
|
||||||
@@ -83,6 +83,8 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors,
|
@@ -83,6 +83,8 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ patch:
|
|||||||
(cherry picked from commit 30329d06235a9f9733b1d4da479b403462d1b326)
|
(cherry picked from commit 30329d06235a9f9733b1d4da479b403462d1b326)
|
||||||
|
|
||||||
diff --git a/src/env-inl.h b/src/env-inl.h
|
diff --git a/src/env-inl.h b/src/env-inl.h
|
||||||
index da2c468f11cdc320cfec794b1b8b24904b93491e..98e1e1e75bae94038bba0049447ab48b0acfb8cc 100644
|
index bcf5fb6104ccf937304d109f1c0f5d07ca54acd4..d1a7e1212da46a8e5c2fffee46542ac8bec828ee 100644
|
||||||
--- a/src/env-inl.h
|
--- a/src/env-inl.h
|
||||||
+++ b/src/env-inl.h
|
+++ b/src/env-inl.h
|
||||||
@@ -62,31 +62,6 @@ inline uv_loop_t* IsolateData::event_loop() const {
|
@@ -62,31 +62,6 @@ inline uv_loop_t* IsolateData::event_loop() const {
|
||||||
@@ -146,7 +146,7 @@ index 926645dc647fe7ca01165462f08eac1ade71ac4e..85641b68b1e6f6dd4149f33ba13f76bc
|
|||||||
|
|
||||||
void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
|
void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
|
||||||
diff --git a/src/env.h b/src/env.h
|
diff --git a/src/env.h b/src/env.h
|
||||||
index 35e16159a94bb97f19d17767e3ad4bb798660f44..2d5fa8dbd75851bca30453548f6cbe0159509f26 100644
|
index 723e4738dd1c32710e521775d66e0d957334344c..888f0a5572254d775cbf672dcf07b789782292ea 100644
|
||||||
--- a/src/env.h
|
--- a/src/env.h
|
||||||
+++ b/src/env.h
|
+++ b/src/env.h
|
||||||
@@ -177,10 +177,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
|
@@ -177,10 +177,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
|
||||||
@@ -161,10 +161,10 @@ index 35e16159a94bb97f19d17767e3ad4bb798660f44..2d5fa8dbd75851bca30453548f6cbe01
|
|||||||
inline MultiIsolatePlatform* platform() const;
|
inline MultiIsolatePlatform* platform() const;
|
||||||
inline const SnapshotData* snapshot_data() const;
|
inline const SnapshotData* snapshot_data() const;
|
||||||
diff --git a/src/node.h b/src/node.h
|
diff --git a/src/node.h b/src/node.h
|
||||||
index 96c599aa6448e2aa8e57e84f811564a5281c139a..d3a965661d068db359bb1bb4b14e59c28bb615f9 100644
|
index 4e66924e4ca5b5d787fc6259de940a3fb40bff38..91468bfd755db6adde5cc8cecb184312db90a654 100644
|
||||||
--- a/src/node.h
|
--- a/src/node.h
|
||||||
+++ b/src/node.h
|
+++ b/src/node.h
|
||||||
@@ -1576,24 +1576,14 @@ void RegisterSignalHandler(int signal,
|
@@ -1575,24 +1575,14 @@ void RegisterSignalHandler(int signal,
|
||||||
bool reset_handler = false);
|
bool reset_handler = false);
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
|
|||||||
Reviewed-By: James M Snell <jasnell@gmail.com>
|
Reviewed-By: James M Snell <jasnell@gmail.com>
|
||||||
|
|
||||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||||
index 33827edce63c9fe08b52aea59571391a83853443..79327877b0f34cbafb3efcc21617027d4011f806 100644
|
index f3a992b634e9532cba34ec4d54b3a1d0f68a8545..6034b779fe05850cfc4e7f7af221489be9369b54 100644
|
||||||
--- a/src/api/environment.cc
|
--- a/src/api/environment.cc
|
||||||
+++ b/src/api/environment.cc
|
+++ b/src/api/environment.cc
|
||||||
@@ -878,7 +878,7 @@ Maybe<void> InitializePrimordials(Local<Context> context,
|
@@ -882,7 +882,7 @@ Maybe<void> InitializePrimordials(Local<Context> context,
|
||||||
CHECK(!exports->Has(context, primordials_string).FromJust());
|
CHECK(!exports->Has(context, primordials_string).FromJust());
|
||||||
|
|
||||||
Local<Object> primordials = Object::New(isolate);
|
Local<Object> primordials = Object::New(isolate);
|
||||||
@@ -38,10 +38,10 @@ index 487b8b7adfd35646d20fdb15be5fd6f2bee9315b..6a3c4e6952a8f3250bf1b57652a1622e
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
||||||
index 7b2efa49468c0bed2f5935552addd3ab37d0a50b..413db3ed9b88d7b7fb2ac6dd1153dade9ff830fd 100644
|
index 4a748957431da4b3a55ecaa5db9c45e2061f76f1..e62dce7a3e5f32ebb926ad2ffe57887ab1887b8d 100644
|
||||||
--- a/src/js_native_api_v8.cc
|
--- a/src/js_native_api_v8.cc
|
||||||
+++ b/src/js_native_api_v8.cc
|
+++ b/src/js_native_api_v8.cc
|
||||||
@@ -1577,7 +1577,7 @@ napi_status NAPI_CDECL napi_get_prototype(napi_env env,
|
@@ -1578,7 +1578,7 @@ napi_status NAPI_CDECL napi_get_prototype(napi_env env,
|
||||||
CHECK_TO_OBJECT(env, context, obj, object);
|
CHECK_TO_OBJECT(env, context, obj, object);
|
||||||
|
|
||||||
// This doesn't invokes Proxy's [[GetPrototypeOf]] handler.
|
// This doesn't invokes Proxy's [[GetPrototypeOf]] handler.
|
||||||
@@ -51,7 +51,7 @@ index 7b2efa49468c0bed2f5935552addd3ab37d0a50b..413db3ed9b88d7b7fb2ac6dd1153dade
|
|||||||
return GET_RETURN_STATUS(env);
|
return GET_RETURN_STATUS(env);
|
||||||
}
|
}
|
||||||
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
||||||
index 8a5b6b57321c2843a965a7e51b2ebed991a1e424..e844fe6cb33acefd075516e675075421ad5c3cff 100644
|
index b87b53843c3369832e561b9ffd40ca7c2134e74c..0cf2a07deb382dfd96607f84b583ffbd62447769 100644
|
||||||
--- a/src/node_buffer.cc
|
--- a/src/node_buffer.cc
|
||||||
+++ b/src/node_buffer.cc
|
+++ b/src/node_buffer.cc
|
||||||
@@ -283,8 +283,9 @@ MaybeLocal<Uint8Array> New(Environment* env,
|
@@ -283,8 +283,9 @@ MaybeLocal<Uint8Array> New(Environment* env,
|
||||||
@@ -135,7 +135,7 @@ index b1ee513fc0873a51b4885f612dbf7b950b5cf2ca..2f23cc63f148a792f1302e1d2d888227
|
|||||||
Local<Object> internal_constants = Object::New(isolate);
|
Local<Object> internal_constants = Object::New(isolate);
|
||||||
CHECK(internal_constants->SetPrototype(env->context(),
|
CHECK(internal_constants->SetPrototype(env->context(),
|
||||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||||
index b067685822dc056e446e1a9402a5a6cba86cc722..e93e8684e518b30a2514768a269be6d32d1f5b94 100644
|
index 5a1675f2b4448e5da71f0badee8ac5f2d2a9c6ee..1ebc7bfca2d89f78898873e8b6f838f3f4c2e576 100644
|
||||||
--- a/src/node_options.cc
|
--- a/src/node_options.cc
|
||||||
+++ b/src/node_options.cc
|
+++ b/src/node_options.cc
|
||||||
@@ -1552,7 +1552,8 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
|
@@ -1552,7 +1552,8 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
|
||||||
@@ -159,10 +159,10 @@ index b067685822dc056e446e1a9402a5a6cba86cc722..e93e8684e518b30a2514768a269be6d3
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
|
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
|
||||||
index 9a7b7db881a564a68683c55cb10919454e80edbf..bf88ce68f9173ef24a283dd370e71903220b0077 100644
|
index d6dee522023a4e65d948b1554e9ae472f1e96e40..e7d0c4e2e1150a62a1ccfbe9e9ec08b6b2e5be65 100644
|
||||||
--- a/src/node_webstorage.cc
|
--- a/src/node_webstorage.cc
|
||||||
+++ b/src/node_webstorage.cc
|
+++ b/src/node_webstorage.cc
|
||||||
@@ -532,7 +532,7 @@ template <typename T>
|
@@ -536,7 +536,7 @@ template <typename T>
|
||||||
static bool ShouldIntercept(Local<Name> property,
|
static bool ShouldIntercept(Local<Name> property,
|
||||||
const PropertyCallbackInfo<T>& info) {
|
const PropertyCallbackInfo<T>& info) {
|
||||||
Environment* env = Environment::GetCurrent(info);
|
Environment* env = Environment::GetCurrent(info);
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
|
|||||||
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
|
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
|
||||||
|
|
||||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||||
index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca6d764960 100644
|
index 57c8dc35dc86efed6e8736e4649b90905a8da54b..89c51a3fd0752ac1586de6840243e93ef5bc080e 100644
|
||||||
--- a/src/node_file.cc
|
--- a/src/node_file.cc
|
||||||
+++ b/src/node_file.cc
|
+++ b/src/node_file.cc
|
||||||
@@ -3056,42 +3056,6 @@ static void GetFormatOfExtensionlessFile(
|
@@ -3066,42 +3066,6 @@ static void GetFormatOfExtensionlessFile(
|
||||||
return args.GetReturnValue().Set(EXTENSIONLESS_FORMAT_JAVASCRIPT);
|
return args.GetReturnValue().Set(EXTENSIONLESS_FORMAT_JAVASCRIPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
Isolate* isolate = env->isolate();
|
Isolate* isolate = env->isolate();
|
||||||
@@ -3104,7 +3068,7 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
@@ -3114,7 +3078,7 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
||||||
THROW_IF_INSUFFICIENT_PERMISSIONS(
|
THROW_IF_INSUFFICIENT_PERMISSIONS(
|
||||||
env, permission::PermissionScope::kFileSystemRead, src.ToStringView());
|
env, permission::PermissionScope::kFileSystemRead, src.ToStringView());
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
|
|
||||||
BufferValue dest(isolate, args[1]);
|
BufferValue dest(isolate, args[1]);
|
||||||
CHECK_NOT_NULL(*dest);
|
CHECK_NOT_NULL(*dest);
|
||||||
@@ -3112,7 +3076,7 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
@@ -3122,7 +3086,7 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
||||||
THROW_IF_INSUFFICIENT_PERMISSIONS(
|
THROW_IF_INSUFFICIENT_PERMISSIONS(
|
||||||
env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView());
|
env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView());
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
bool dereference = args[2]->IsTrue();
|
bool dereference = args[2]->IsTrue();
|
||||||
bool recursive = args[3]->IsTrue();
|
bool recursive = args[3]->IsTrue();
|
||||||
|
|
||||||
@@ -3141,8 +3105,8 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
@@ -3151,8 +3115,8 @@ static void CpSyncCheckPaths(const FunctionCallbackInfo<Value>& args) {
|
||||||
(src_status.type() == std::filesystem::file_type::directory) ||
|
(src_status.type() == std::filesystem::file_type::directory) ||
|
||||||
(dereference && src_status.type() == std::filesystem::file_type::symlink);
|
(dereference && src_status.type() == std::filesystem::file_type::symlink);
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
|
|
||||||
if (!error_code) {
|
if (!error_code) {
|
||||||
// Check if src and dest are identical.
|
// Check if src and dest are identical.
|
||||||
@@ -3237,7 +3201,7 @@ static bool CopyUtimes(const std::filesystem::path& src,
|
@@ -3247,7 +3211,7 @@ static bool CopyUtimes(const std::filesystem::path& src,
|
||||||
uv_fs_t req;
|
uv_fs_t req;
|
||||||
auto cleanup = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
|
auto cleanup = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
int result = uv_fs_stat(nullptr, &req, src_path_str.c_str(), nullptr);
|
int result = uv_fs_stat(nullptr, &req, src_path_str.c_str(), nullptr);
|
||||||
if (is_uv_error(result)) {
|
if (is_uv_error(result)) {
|
||||||
env->ThrowUVException(result, "stat", nullptr, src_path_str.c_str());
|
env->ThrowUVException(result, "stat", nullptr, src_path_str.c_str());
|
||||||
@@ -3248,7 +3212,7 @@ static bool CopyUtimes(const std::filesystem::path& src,
|
@@ -3258,7 +3222,7 @@ static bool CopyUtimes(const std::filesystem::path& src,
|
||||||
const double source_atime = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
|
const double source_atime = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
|
||||||
const double source_mtime = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
|
const double source_mtime = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
int utime_result = uv_fs_utime(nullptr,
|
int utime_result = uv_fs_utime(nullptr,
|
||||||
&req,
|
&req,
|
||||||
dest_file_path_str.c_str(),
|
dest_file_path_str.c_str(),
|
||||||
@@ -3383,7 +3347,7 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
@@ -3393,7 +3357,7 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
for (auto dir_entry : std::filesystem::directory_iterator(src)) {
|
for (auto dir_entry : std::filesystem::directory_iterator(src)) {
|
||||||
auto dest_file_path = dest / dir_entry.path().filename();
|
auto dest_file_path = dest / dir_entry.path().filename();
|
||||||
@@ -126,7 +126,7 @@ index 75be21c9e8b413f522240a906da06d26c44d5b71..e94c2b5f2cf7cac413cd5cb782fa1cca
|
|||||||
|
|
||||||
if (dir_entry.is_symlink()) {
|
if (dir_entry.is_symlink()) {
|
||||||
if (verbatim_symlinks) {
|
if (verbatim_symlinks) {
|
||||||
@@ -3446,7 +3410,7 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
@@ -3452,7 +3416,7 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||||
}
|
}
|
||||||
} else if (std::filesystem::is_regular_file(dest_file_path)) {
|
} else if (std::filesystem::is_regular_file(dest_file_path)) {
|
||||||
if (!dereference || (!force && error_on_exist)) {
|
if (!dereference || (!force && error_on_exist)) {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ index f616223cfb0f6e10f7cf57ada9704316bde2797e..eb6dad44a49d997097c8fb5009eeb60a
|
|||||||
Local<Value> ret;
|
Local<Value> ret;
|
||||||
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {};
|
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {};
|
||||||
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
||||||
index 357dc5f6d1c1c2d3756a94c1326b0502403e1eaf..b9f0c97938203b4652780a7d707c5e83319330b0 100644
|
index 70fdb52de7b3394df52d327cb485b7c615f8be2d..2fdada446c5d1ffa460f483a3360aeca658d9eef 100644
|
||||||
--- a/src/node_buffer.cc
|
--- a/src/node_buffer.cc
|
||||||
+++ b/src/node_buffer.cc
|
+++ b/src/node_buffer.cc
|
||||||
@@ -1412,7 +1412,7 @@ inline size_t CheckNumberToSize(Local<Value> number) {
|
@@ -1412,7 +1412,7 @@ inline size_t CheckNumberToSize(Local<Value> number) {
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
|
||||||
Date: Tue, 4 Nov 2025 21:20:26 +0100
|
|
||||||
Subject: test: correct conditional secure heap flags test
|
|
||||||
|
|
||||||
PR-URL: https://github.com/nodejs/node/pull/60385
|
|
||||||
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
|
|
||||||
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
|
|
||||||
(cherry picked from commit 53c4a39fec941e04150554fdd3e654b48f2e1b31)
|
|
||||||
|
|
||||||
diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js
|
|
||||||
index afd43cfffe638f4f084f1c36949068e7239eadc3..c70e073bab888c349e8f5c691f5679a3796c896c 100644
|
|
||||||
--- a/test/parallel/test-process-env-allowed-flags-are-documented.js
|
|
||||||
+++ b/test/parallel/test-process-env-allowed-flags-are-documented.js
|
|
||||||
@@ -49,6 +49,8 @@ if (!hasOpenSSL3) {
|
|
||||||
documented.delete('--openssl-shared-config');
|
|
||||||
}
|
|
||||||
|
|
||||||
+const isV8Sandboxed = process.config.variables.v8_enable_sandbox;
|
|
||||||
+
|
|
||||||
// Filter out options that are conditionally present.
|
|
||||||
const conditionalOpts = [
|
|
||||||
{
|
|
||||||
@@ -74,6 +76,9 @@ const conditionalOpts = [
|
|
||||||
}, {
|
|
||||||
include: process.features.inspector,
|
|
||||||
filter: (opt) => opt.startsWith('--inspect') || opt === '--debug-port'
|
|
||||||
+ }, {
|
|
||||||
+ include: !isV8Sandboxed,
|
|
||||||
+ filter: (opt) => ['--secure-heap', '--secure-heap-min'].includes(opt)
|
|
||||||
},
|
|
||||||
];
|
|
||||||
documented.forEach((opt) => {
|
|
||||||
@@ -7,7 +7,7 @@ Instead of disabling the tests, flag them as flaky so they still run
|
|||||||
but don't cause CI failures on flakes.
|
but don't cause CI failures on flakes.
|
||||||
|
|
||||||
diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
|
diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
|
||||||
index 9822dc622ebfc2d1a31539474b78e03e64426195..045a415f7b9f461bd9b2c97d42051f2580b7df1a 100644
|
index 0d3ed11813f0df93374a1f683add4c621ee8d0c8..c6e7866405ced71aaa2a884addf493f7366fd377 100644
|
||||||
--- a/test/parallel/parallel.status
|
--- a/test/parallel/parallel.status
|
||||||
+++ b/test/parallel/parallel.status
|
+++ b/test/parallel/parallel.status
|
||||||
@@ -5,6 +5,16 @@ prefix parallel
|
@@ -5,6 +5,16 @@ prefix parallel
|
||||||
@@ -28,7 +28,7 @@ index 9822dc622ebfc2d1a31539474b78e03e64426195..045a415f7b9f461bd9b2c97d42051f25
|
|||||||
test-net-write-fully-async-hex-string: PASS, FLAKY
|
test-net-write-fully-async-hex-string: PASS, FLAKY
|
||||||
# https://github.com/nodejs/node/issues/52273
|
# https://github.com/nodejs/node/issues/52273
|
||||||
diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status
|
diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status
|
||||||
index f6c9c77379930a8234cd4c5f933c261d6bd1a238..28d5378e4051b78e9a7ff81886c3382e92a5da2e 100644
|
index 33d1109b015ba1abcd52eb6400afff32b82afb3c..6e088c2273d4b034dc458608505cabe8aa304ea1 100644
|
||||||
--- a/test/sequential/sequential.status
|
--- a/test/sequential/sequential.status
|
||||||
+++ b/test/sequential/sequential.status
|
+++ b/test/sequential/sequential.status
|
||||||
@@ -7,6 +7,18 @@ prefix sequential
|
@@ -7,6 +7,18 @@ prefix sequential
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
graphite_add_insertstatus_koutoforderrecording.patch
|
graphite_add_insertstatus_koutoforderrecording.patch
|
||||||
|
cherry-pick-03d405099043.patch
|
||||||
|
cherry-pick-7911bee5d90e.patch
|
||||||
|
|||||||
166
patches/skia/cherry-pick-03d405099043.patch
Normal file
166
patches/skia/cherry-pick-03d405099043.patch
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Ludwig <michaelludwig@google.com>
|
||||||
|
Date: Thu, 19 Feb 2026 16:29:16 -0500
|
||||||
|
Subject: [ganesh] Guard verb counts in tessellation accumulation against
|
||||||
|
overflow
|
||||||
|
|
||||||
|
Rejects adding a path if the total verb count would overflow.
|
||||||
|
Rejects merging ops if their total verb counts would overflow.
|
||||||
|
Clamps the min allocation size in the GrVertexChunkArray to prevent
|
||||||
|
overflow.
|
||||||
|
Clamps the preallocation verb count parameter to avoid overflow in their
|
||||||
|
intermediate calculations.
|
||||||
|
|
||||||
|
Bug: b/484983991
|
||||||
|
Change-Id: I32359cf10a996baf46b023a6cb8c608834942e0b
|
||||||
|
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1169977
|
||||||
|
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
|
||||||
|
Reviewed-by: Thomas Smith <thomsmit@google.com>
|
||||||
|
|
||||||
|
diff --git a/src/gpu/ganesh/GrVertexChunkArray.cpp b/src/gpu/ganesh/GrVertexChunkArray.cpp
|
||||||
|
index b920c81df0c1c8dd76672ba84989b72322833847..ccfd8ef10f101072a8023584f7e0db8fc3195685 100644
|
||||||
|
--- a/src/gpu/ganesh/GrVertexChunkArray.cpp
|
||||||
|
+++ b/src/gpu/ganesh/GrVertexChunkArray.cpp
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
+#include <limits>
|
||||||
|
|
||||||
|
GrVertexChunkBuilder::~GrVertexChunkBuilder() {
|
||||||
|
if (!fChunks->empty()) {
|
||||||
|
@@ -37,6 +38,12 @@ bool GrVertexChunkBuilder::allocChunk(int minCount) {
|
||||||
|
fCurrChunkVertexCapacity = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
- fMinVerticesPerChunk *= 2;
|
||||||
|
+
|
||||||
|
+ int maxVerticesPerChunk = std::numeric_limits<int>::max() / fStride;
|
||||||
|
+ if (maxVerticesPerChunk / 2 > fMinVerticesPerChunk) {
|
||||||
|
+ fMinVerticesPerChunk *= 2;
|
||||||
|
+ } else {
|
||||||
|
+ fMinVerticesPerChunk = maxVerticesPerChunk;
|
||||||
|
+ }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
diff --git a/src/gpu/ganesh/ops/AtlasRenderTask.cpp b/src/gpu/ganesh/ops/AtlasRenderTask.cpp
|
||||||
|
index 5f05079cfa740ecf140ed7c43d6e04102893a21a..13b2ff4a85d091427c8a95344dfa788cf0ecccbe 100644
|
||||||
|
--- a/src/gpu/ganesh/ops/AtlasRenderTask.cpp
|
||||||
|
+++ b/src/gpu/ganesh/ops/AtlasRenderTask.cpp
|
||||||
|
@@ -54,6 +54,17 @@ bool AtlasRenderTask::addPath(const SkMatrix& viewMatrix, const SkPath& path,
|
||||||
|
SkASSERT(this->isEmpty());
|
||||||
|
SkASSERT(!fDynamicAtlas->isInstantiated()); // Paths can't be added after instantiate().
|
||||||
|
|
||||||
|
+ // Check for room in the list first and return false if prior draws need to be flushed first.
|
||||||
|
+ if (GrFillRuleForSkPath(path) == GrFillRule::kNonzero) {
|
||||||
|
+ if (!fWindingPathList.canAdd(path)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ if (!fEvenOddPathList.canAdd(path)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!fDynamicAtlas->addRect(widthInAtlas, heightInAtlas, locationInAtlas)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
diff --git a/src/gpu/ganesh/ops/AtlasRenderTask.h b/src/gpu/ganesh/ops/AtlasRenderTask.h
|
||||||
|
index c44b426db504f2e108f131fa42bf6a5bd31f7a78..de056f1961ba6cbced6b2ea9ffe630e63785da71 100644
|
||||||
|
--- a/src/gpu/ganesh/ops/AtlasRenderTask.h
|
||||||
|
+++ b/src/gpu/ganesh/ops/AtlasRenderTask.h
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include "src/gpu/ganesh/ops/OpsTask.h"
|
||||||
|
#include "src/gpu/ganesh/tessellate/PathTessellator.h"
|
||||||
|
|
||||||
|
+#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
@@ -89,6 +90,7 @@ private:
|
||||||
|
class AtlasPathList : SkNoncopyable {
|
||||||
|
public:
|
||||||
|
void add(PathDrawAllocator* alloc, const SkMatrix& pathMatrix, const SkPath& path) {
|
||||||
|
+ SkASSERT(this->canAdd(path));
|
||||||
|
fPathDrawList = &alloc->emplace_back(pathMatrix, path, SK_PMColor4fTRANSPARENT,
|
||||||
|
fPathDrawList);
|
||||||
|
if (path.isInverseFillType()) {
|
||||||
|
@@ -98,6 +100,12 @@ private:
|
||||||
|
fTotalCombinedPathVerbCnt += path.countVerbs();
|
||||||
|
++fPathCount;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ bool canAdd(const SkPath& path) const {
|
||||||
|
+ // Return true so long as we won't overflow the total verb count
|
||||||
|
+ return std::numeric_limits<int>::max() - fTotalCombinedPathVerbCnt >= path.countVerbs();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
const PathDrawList* pathDrawList() const { return fPathDrawList; }
|
||||||
|
int totalCombinedPathVerbCnt() const { return fTotalCombinedPathVerbCnt; }
|
||||||
|
int pathCount() const { return fPathCount; }
|
||||||
|
diff --git a/src/gpu/ganesh/ops/PathTessellateOp.cpp b/src/gpu/ganesh/ops/PathTessellateOp.cpp
|
||||||
|
index 3bc370f046751a155b11085188ca152853c52263..f879a2ec1dd28e7ec0438d99226f28612eb8b9ec 100644
|
||||||
|
--- a/src/gpu/ganesh/ops/PathTessellateOp.cpp
|
||||||
|
+++ b/src/gpu/ganesh/ops/PathTessellateOp.cpp
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
#include "src/gpu/ganesh/ops/PathTessellateOp.h"
|
||||||
|
+#include <limits>
|
||||||
|
|
||||||
|
#include "include/core/SkColor.h"
|
||||||
|
#include "include/gpu/ganesh/GrRecordingContext.h"
|
||||||
|
@@ -53,10 +54,13 @@ GrDrawOp::CombineResult PathTessellateOp::onCombineIfPossible(GrOp* grOp,
|
||||||
|
SkArenaAlloc*,
|
||||||
|
const GrCaps&) {
|
||||||
|
auto* op = grOp->cast<PathTessellateOp>();
|
||||||
|
+ bool verbCountOverflow = std::numeric_limits<int>::max() - fTotalCombinedPathVerbCnt <
|
||||||
|
+ op->fTotalCombinedPathVerbCnt;
|
||||||
|
bool canMerge = fAAType == op->fAAType &&
|
||||||
|
fStencil == op->fStencil &&
|
||||||
|
fProcessors == op->fProcessors &&
|
||||||
|
- fShaderMatrix == op->fShaderMatrix;
|
||||||
|
+ fShaderMatrix == op->fShaderMatrix &&
|
||||||
|
+ !verbCountOverflow;
|
||||||
|
if (canMerge) {
|
||||||
|
fTotalCombinedPathVerbCnt += op->fTotalCombinedPathVerbCnt;
|
||||||
|
fPatchAttribs |= op->fPatchAttribs;
|
||||||
|
diff --git a/src/gpu/tessellate/FixedCountBufferUtils.h b/src/gpu/tessellate/FixedCountBufferUtils.h
|
||||||
|
index f2ab0f427c1fa08ac3a11c5a285f51243cb7ad27..055f6a026656f69bf6ef5feeba21695a99e7f9f2 100644
|
||||||
|
--- a/src/gpu/tessellate/FixedCountBufferUtils.h
|
||||||
|
+++ b/src/gpu/tessellate/FixedCountBufferUtils.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
+#include <limits>
|
||||||
|
|
||||||
|
namespace skgpu { struct VertexWriter; }
|
||||||
|
|
||||||
|
@@ -44,6 +45,8 @@ public:
|
||||||
|
// Over-allocate enough curves for 1 in 4 to chop. Every chop introduces 2 new patches:
|
||||||
|
// another curve patch and a triangle patch that glues the two chops together,
|
||||||
|
// i.e. + 2 * ((count + 3) / 4) == (count + 3) / 2
|
||||||
|
+ constexpr int kMaxVerbCount = std::numeric_limits<int>::max() >> 2;
|
||||||
|
+ totalCombinedPathVerbCnt = std::min(kMaxVerbCount, totalCombinedPathVerbCnt);
|
||||||
|
return totalCombinedPathVerbCnt + (totalCombinedPathVerbCnt + 3) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -88,6 +91,8 @@ public:
|
||||||
|
|
||||||
|
static constexpr int PreallocCount(int totalCombinedPathVerbCnt) {
|
||||||
|
// Over-allocate enough wedges for 1 in 4 to chop, i.e., ceil(maxWedges * 5/4)
|
||||||
|
+ constexpr int kMaxVerbCount = std::numeric_limits<int>::max() >> 3;
|
||||||
|
+ totalCombinedPathVerbCnt = std::min(kMaxVerbCount, totalCombinedPathVerbCnt);
|
||||||
|
return (totalCombinedPathVerbCnt * 5 + 3) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -140,6 +145,8 @@ public:
|
||||||
|
// Over-allocate enough patches for each stroke to chop once, and for 8 extra caps. Since
|
||||||
|
// we have to chop at inflections, points of 180 degree rotation, and anywhere a stroke
|
||||||
|
// requires too many parametric segments, many strokes will end up getting choppped.
|
||||||
|
+ constexpr int kMaxVerbCount = std::numeric_limits<int>::max() >> 2;
|
||||||
|
+ totalCombinedPathVerbCnt = std::min(kMaxVerbCount, totalCombinedPathVerbCnt);
|
||||||
|
return (totalCombinedPathVerbCnt * 2) + 8/* caps */;
|
||||||
|
}
|
||||||
|
|
||||||
544
patches/skia/cherry-pick-7911bee5d90e.patch
Normal file
544
patches/skia/cherry-pick-7911bee5d90e.patch
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Daniel <egdaniel@google.com>
|
||||||
|
Date: Wed, 11 Mar 2026 15:29:58 -0400
|
||||||
|
Subject: Make sure we are getting the correct atlas for glyph mask format.
|
||||||
|
|
||||||
|
Bug: b/491421267
|
||||||
|
Change-Id: I4eacd46599eca2df8c10a3fc894b9ce890fae1e2
|
||||||
|
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1184076
|
||||||
|
Commit-Queue: Greg Daniel <egdaniel@google.com>
|
||||||
|
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
|
||||||
|
(cherry picked from commit 0cab3e4ee34b3bca6ba7df676639d73ffe4b2135)
|
||||||
|
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1184917
|
||||||
|
|
||||||
|
diff --git a/bench/GlyphQuadFillBench.cpp b/bench/GlyphQuadFillBench.cpp
|
||||||
|
index d5de90c5afd20e85662443c2019521d71bef6fc4..edad3c19f1826e4aecdba74f5c1f04a4d3f9ebf6 100644
|
||||||
|
--- a/bench/GlyphQuadFillBench.cpp
|
||||||
|
+++ b/bench/GlyphQuadFillBench.cpp
|
||||||
|
@@ -68,7 +68,7 @@ class DirectMaskGlyphVertexFillBenchmark : public Benchmark {
|
||||||
|
const sktext::gpu::AtlasSubRun* subRun =
|
||||||
|
sktext::gpu::TextBlobTools::FirstSubRun(fBlob.get());
|
||||||
|
SkASSERT_RELEASE(subRun);
|
||||||
|
- subRun->testingOnly_packedGlyphIDToGlyph(&fCache);
|
||||||
|
+ subRun->testingOnly_packedGlyphIDToGlyph(&fCache, subRun->maskFormat());
|
||||||
|
fVertices.reset(new char[subRun->vertexStride(drawMatrix) * subRun->glyphCount() * 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/gn/tests.gni b/gn/tests.gni
|
||||||
|
index 6fc06d23db5357a05a8be5f3e6040be257a34fdf..d3cfbdafdefd766bb910c33007bd7e0bf85c5ff4 100644
|
||||||
|
--- a/gn/tests.gni
|
||||||
|
+++ b/gn/tests.gni
|
||||||
|
@@ -485,6 +485,12 @@ pathops_tests_sources = [
|
||||||
|
]
|
||||||
|
|
||||||
|
ganesh_tests_sources = [
|
||||||
|
+ "$_tests/AdvancedBlendTest.cpp",
|
||||||
|
+ "$_tests/ApplyGammaTest.cpp",
|
||||||
|
+ "$_tests/AtlasOobTest.cpp",
|
||||||
|
+ "$_tests/BackendAllocationTest.cpp",
|
||||||
|
+ "$_tests/BackendSurfaceMutableStateTest.cpp",
|
||||||
|
+ "$_tests/BlendTest.cpp",
|
||||||
|
"$_tests/BulkRectTest.cpp",
|
||||||
|
"$_tests/ClearTest.cpp",
|
||||||
|
"$_tests/DMSAATest.cpp",
|
||||||
|
diff --git a/src/gpu/ganesh/text/GrAtlasManager.cpp b/src/gpu/ganesh/text/GrAtlasManager.cpp
|
||||||
|
index 403bfe274e56293bfe2382b02525ae742ba541a7..1e7d9aa0ce14f19e09d79544730c6aa922ae37d6 100644
|
||||||
|
--- a/src/gpu/ganesh/text/GrAtlasManager.cpp
|
||||||
|
+++ b/src/gpu/ganesh/text/GrAtlasManager.cpp
|
||||||
|
@@ -178,8 +178,7 @@ GrDrawOpAtlas::ErrorCode GrAtlasManager::addGlyphToAtlas(const SkGlyph& skGlyph,
|
||||||
|
}
|
||||||
|
SkASSERT(glyph != nullptr);
|
||||||
|
|
||||||
|
- MaskFormat glyphFormat = Glyph::FormatFromSkGlyph(skGlyph.maskFormat());
|
||||||
|
- MaskFormat expectedMaskFormat = this->resolveMaskFormat(glyphFormat);
|
||||||
|
+ MaskFormat expectedMaskFormat = this->resolveMaskFormat(glyph->fGlyphEntryKey.fFormat);
|
||||||
|
int bytesPerPixel = MaskFormatBytesPerPixel(expectedMaskFormat);
|
||||||
|
|
||||||
|
int padding;
|
||||||
|
@@ -299,7 +298,7 @@ std::tuple<bool, int> GlyphVector::regenerateAtlasForGanesh(
|
||||||
|
|
||||||
|
uint64_t currentAtlasGen = atlasManager->atlasGeneration(maskFormat);
|
||||||
|
|
||||||
|
- this->packedGlyphIDToGlyph(target->strikeCache());
|
||||||
|
+ this->packedGlyphIDToGlyph(target->strikeCache(), maskFormat);
|
||||||
|
|
||||||
|
if (fAtlasGeneration != currentAtlasGen) {
|
||||||
|
// Calculate the texture coordinates for the vertexes during first use (fAtlasGeneration
|
||||||
|
@@ -316,9 +315,10 @@ std::tuple<bool, int> GlyphVector::regenerateAtlasForGanesh(
|
||||||
|
for (const Variant& variant : glyphs) {
|
||||||
|
Glyph* gpuGlyph = variant.glyph;
|
||||||
|
SkASSERT(gpuGlyph != nullptr);
|
||||||
|
-
|
||||||
|
+ SkASSERT(gpuGlyph->fGlyphEntryKey.fFormat == maskFormat);
|
||||||
|
if (!atlasManager->hasGlyph(maskFormat, gpuGlyph)) {
|
||||||
|
- const SkGlyph& skGlyph = *metricsAndImages.glyph(gpuGlyph->fPackedID);
|
||||||
|
+ const SkGlyph& skGlyph =
|
||||||
|
+ *metricsAndImages.glyph(gpuGlyph->fGlyphEntryKey.fPackedID);
|
||||||
|
auto code = atlasManager->addGlyphToAtlas(
|
||||||
|
skGlyph, gpuGlyph, srcPadding, target->resourceProvider(), uploadTarget);
|
||||||
|
if (code != GrDrawOpAtlas::ErrorCode::kSucceeded) {
|
||||||
|
diff --git a/src/gpu/graphite/Device.cpp b/src/gpu/graphite/Device.cpp
|
||||||
|
index 1bc1f0d51712df81118a67bb22f5d28a6ead8606..e2b8e40b80d44ccfff9bdbd14f657fbbbfe3a3d9 100644
|
||||||
|
--- a/src/gpu/graphite/Device.cpp
|
||||||
|
+++ b/src/gpu/graphite/Device.cpp
|
||||||
|
@@ -1325,6 +1325,7 @@ void Device::drawAtlasSubRun(const sktext::gpu::AtlasSubRun* subRun,
|
||||||
|
int padding) {
|
||||||
|
return glyphs->regenerateAtlasForGraphite(begin, end, maskFormat, padding, fRecorder);
|
||||||
|
};
|
||||||
|
+
|
||||||
|
for (int subRunCursor = 0; subRunCursor < subRunEnd;) {
|
||||||
|
// For the remainder of the run, add any atlas uploads to the Recorder's TextAtlasManager
|
||||||
|
auto[ok, glyphsRegenerated] = subRun->regenerateAtlas(subRunCursor, subRunEnd,
|
||||||
|
diff --git a/src/gpu/graphite/text/TextAtlasManager.cpp b/src/gpu/graphite/text/TextAtlasManager.cpp
|
||||||
|
index 6602a76c150bff077666fb91b990d3e45d528ce2..cbb51a66846922995912c3159afba879a2487313 100644
|
||||||
|
--- a/src/gpu/graphite/text/TextAtlasManager.cpp
|
||||||
|
+++ b/src/gpu/graphite/text/TextAtlasManager.cpp
|
||||||
|
@@ -207,8 +207,7 @@ DrawAtlas::ErrorCode TextAtlasManager::addGlyphToAtlas(const SkGlyph& skGlyph,
|
||||||
|
}
|
||||||
|
SkASSERT(glyph != nullptr);
|
||||||
|
|
||||||
|
- MaskFormat glyphFormat = Glyph::FormatFromSkGlyph(skGlyph.maskFormat());
|
||||||
|
- MaskFormat expectedMaskFormat = this->resolveMaskFormat(glyphFormat);
|
||||||
|
+ MaskFormat expectedMaskFormat = this->resolveMaskFormat(glyph->fGlyphEntryKey.fFormat);
|
||||||
|
int bytesPerPixel = MaskFormatBytesPerPixel(expectedMaskFormat);
|
||||||
|
|
||||||
|
int padding;
|
||||||
|
@@ -359,7 +358,7 @@ std::tuple<bool, int> GlyphVector::regenerateAtlasForGraphite(int begin,
|
||||||
|
|
||||||
|
uint64_t currentAtlasGen = atlasManager->atlasGeneration(maskFormat);
|
||||||
|
|
||||||
|
- this->packedGlyphIDToGlyph(recorder->priv().strikeCache());
|
||||||
|
+ this->packedGlyphIDToGlyph(recorder->priv().strikeCache(), maskFormat);
|
||||||
|
|
||||||
|
if (fAtlasGeneration != currentAtlasGen) {
|
||||||
|
// Calculate the texture coordinates for the vertexes during first use (fAtlasGeneration
|
||||||
|
@@ -375,9 +374,10 @@ std::tuple<bool, int> GlyphVector::regenerateAtlasForGraphite(int begin,
|
||||||
|
for (const Variant& variant : glyphs) {
|
||||||
|
Glyph* gpuGlyph = variant.glyph;
|
||||||
|
SkASSERT(gpuGlyph != nullptr);
|
||||||
|
-
|
||||||
|
+ SkASSERT(gpuGlyph->fGlyphEntryKey.fFormat == maskFormat);
|
||||||
|
if (!atlasManager->hasGlyph(maskFormat, gpuGlyph)) {
|
||||||
|
- const SkGlyph& skGlyph = *metricsAndImages.glyph(gpuGlyph->fPackedID);
|
||||||
|
+ const SkGlyph& skGlyph =
|
||||||
|
+ *metricsAndImages.glyph(gpuGlyph->fGlyphEntryKey.fPackedID);
|
||||||
|
auto code = atlasManager->addGlyphToAtlas(skGlyph, gpuGlyph, srcPadding);
|
||||||
|
if (code != DrawAtlas::ErrorCode::kSucceeded) {
|
||||||
|
success = code != DrawAtlas::ErrorCode::kError;
|
||||||
|
diff --git a/src/text/gpu/Glyph.h b/src/text/gpu/Glyph.h
|
||||||
|
index 2c6f828ca6f9941b1dc8d73d428370b11d1d52bd..7942006a563bcab925ea2129ab6f6beea438a4c8 100644
|
||||||
|
--- a/src/text/gpu/Glyph.h
|
||||||
|
+++ b/src/text/gpu/Glyph.h
|
||||||
|
@@ -14,6 +14,25 @@
|
||||||
|
|
||||||
|
namespace sktext::gpu {
|
||||||
|
|
||||||
|
+struct GlyphEntryKey {
|
||||||
|
+ explicit GlyphEntryKey(SkPackedGlyphID id, skgpu::MaskFormat format)
|
||||||
|
+ : fPackedID(id), fFormat(format) {}
|
||||||
|
+
|
||||||
|
+ const SkPackedGlyphID fPackedID;
|
||||||
|
+ skgpu::MaskFormat fFormat;
|
||||||
|
+
|
||||||
|
+ bool operator==(const GlyphEntryKey& that) const {
|
||||||
|
+ return fPackedID == that.fPackedID && fFormat == that.fFormat;
|
||||||
|
+ }
|
||||||
|
+ bool operator!=(const GlyphEntryKey& that) const {
|
||||||
|
+ return !(*this == that);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uint32_t hash() const {
|
||||||
|
+ return fPackedID.hash();
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
class Glyph {
|
||||||
|
public:
|
||||||
|
static skgpu::MaskFormat FormatFromSkGlyph(SkMask::Format format) {
|
||||||
|
@@ -34,10 +53,11 @@ public:
|
||||||
|
SkUNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- Glyph(SkPackedGlyphID packedGlyphID) : fPackedID(packedGlyphID) {}
|
||||||
|
+ explicit Glyph(SkPackedGlyphID packedGlyphID, skgpu::MaskFormat format)
|
||||||
|
+ : fGlyphEntryKey(packedGlyphID, format) {}
|
||||||
|
|
||||||
|
- const SkPackedGlyphID fPackedID;
|
||||||
|
- skgpu::AtlasLocator fAtlasLocator;
|
||||||
|
+ const GlyphEntryKey fGlyphEntryKey;
|
||||||
|
+ skgpu::AtlasLocator fAtlasLocator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sktext::gpu
|
||||||
|
diff --git a/src/text/gpu/GlyphVector.cpp b/src/text/gpu/GlyphVector.cpp
|
||||||
|
index 2a8e85f926aa547169f4b85372e9d3fb99816956..7bec7a0b77d8560d5ef978281edd7df6c45cb56f 100644
|
||||||
|
--- a/src/text/gpu/GlyphVector.cpp
|
||||||
|
+++ b/src/text/gpu/GlyphVector.cpp
|
||||||
|
@@ -99,14 +99,14 @@ SkSpan<const Glyph*> GlyphVector::glyphs() const {
|
||||||
|
|
||||||
|
// packedGlyphIDToGlyph must be run in single-threaded mode.
|
||||||
|
// If fSkStrike is not sk_sp<SkStrike> then the conversion to Glyph* has not happened.
|
||||||
|
-void GlyphVector::packedGlyphIDToGlyph(StrikeCache* cache) {
|
||||||
|
+void GlyphVector::packedGlyphIDToGlyph(StrikeCache* cache, MaskFormat maskFormat) {
|
||||||
|
if (fTextStrike == nullptr) {
|
||||||
|
SkStrike* strike = fStrikePromise.strike();
|
||||||
|
fTextStrike = cache->findOrCreateStrike(strike->strikeSpec());
|
||||||
|
|
||||||
|
// Get all the atlas locations for each glyph.
|
||||||
|
for (Variant& variant : fGlyphs) {
|
||||||
|
- variant.glyph = fTextStrike->getGlyph(variant.packedGlyphID);
|
||||||
|
+ variant.glyph = fTextStrike->getGlyph(variant.packedGlyphID, maskFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This must be pinned for the Atlas filling to work.
|
||||||
|
diff --git a/src/text/gpu/GlyphVector.h b/src/text/gpu/GlyphVector.h
|
||||||
|
index 42b92a93f70cc6d86d0a87dd07c2244e0da1281c..1eec6327d38fb4472b027faae68eecb9ad7509d7 100644
|
||||||
|
--- a/src/text/gpu/GlyphVector.h
|
||||||
|
+++ b/src/text/gpu/GlyphVector.h
|
||||||
|
@@ -68,7 +68,7 @@ public:
|
||||||
|
// the sub runs.
|
||||||
|
int unflattenSize() const { return GlyphVectorSize(fGlyphs.size()); }
|
||||||
|
|
||||||
|
- void packedGlyphIDToGlyph(StrikeCache* cache);
|
||||||
|
+ void packedGlyphIDToGlyph(StrikeCache* cache, skgpu::MaskFormat);
|
||||||
|
|
||||||
|
static size_t GlyphVectorSize(size_t count) {
|
||||||
|
return sizeof(Variant) * count;
|
||||||
|
diff --git a/src/text/gpu/StrikeCache.cpp b/src/text/gpu/StrikeCache.cpp
|
||||||
|
index add3127c92fdbfe56d6b56209a2235ce5a9f5acb..19df48329fd500f8682669ec96eb883b58243fdd 100644
|
||||||
|
--- a/src/text/gpu/StrikeCache.cpp
|
||||||
|
+++ b/src/text/gpu/StrikeCache.cpp
|
||||||
|
@@ -207,10 +207,11 @@ TextStrike::TextStrike(StrikeCache* strikeCache, const SkStrikeSpec& strikeSpec)
|
||||||
|
: fStrikeCache(strikeCache)
|
||||||
|
, fStrikeSpec{strikeSpec} {}
|
||||||
|
|
||||||
|
-Glyph* TextStrike::getGlyph(SkPackedGlyphID packedGlyphID) {
|
||||||
|
- Glyph* glyph = fCache.findOrNull(packedGlyphID);
|
||||||
|
+Glyph* TextStrike::getGlyph(SkPackedGlyphID packedGlyphID, skgpu::MaskFormat format) {
|
||||||
|
+ GlyphEntryKey localKey(packedGlyphID, format);
|
||||||
|
+ Glyph* glyph = fCache.findOrNull(localKey);
|
||||||
|
if (glyph == nullptr) {
|
||||||
|
- glyph = fAlloc.make<Glyph>(packedGlyphID);
|
||||||
|
+ glyph = fAlloc.make<Glyph>(packedGlyphID, format);
|
||||||
|
fCache.set(glyph);
|
||||||
|
fMemoryUsed += sizeof(Glyph);
|
||||||
|
if (!fRemoved) {
|
||||||
|
@@ -220,11 +221,11 @@ Glyph* TextStrike::getGlyph(SkPackedGlyphID packedGlyphID) {
|
||||||
|
return glyph;
|
||||||
|
}
|
||||||
|
|
||||||
|
-const SkPackedGlyphID& TextStrike::HashTraits::GetKey(const Glyph* glyph) {
|
||||||
|
- return glyph->fPackedID;
|
||||||
|
+const GlyphEntryKey& TextStrike::HashTraits::GetKey(const Glyph* glyph) {
|
||||||
|
+ return glyph->fGlyphEntryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
-uint32_t TextStrike::HashTraits::Hash(SkPackedGlyphID key) {
|
||||||
|
+uint32_t TextStrike::HashTraits::Hash(GlyphEntryKey key) {
|
||||||
|
return key.hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/text/gpu/StrikeCache.h b/src/text/gpu/StrikeCache.h
|
||||||
|
index 007c45c6c6feecba3ff031ba3939ad2402e082b9..014afd5286602e3e049d8e48ae328273e599dc41 100644
|
||||||
|
--- a/src/text/gpu/StrikeCache.h
|
||||||
|
+++ b/src/text/gpu/StrikeCache.h
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
#include "src/core/SkDescriptor.h"
|
||||||
|
#include "src/core/SkStrikeSpec.h"
|
||||||
|
#include "src/core/SkTHash.h"
|
||||||
|
+#include "src/gpu/AtlasTypes.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
@@ -32,6 +33,7 @@ struct SkPackedGlyphID;
|
||||||
|
namespace sktext::gpu {
|
||||||
|
|
||||||
|
class Glyph;
|
||||||
|
+struct GlyphEntryKey;
|
||||||
|
class StrikeCache;
|
||||||
|
|
||||||
|
// The TextStrike manages an SkArenaAlloc for Glyphs. The SkStrike is what actually creates
|
||||||
|
@@ -43,7 +45,7 @@ public:
|
||||||
|
TextStrike(StrikeCache* strikeCache,
|
||||||
|
const SkStrikeSpec& strikeSpec);
|
||||||
|
|
||||||
|
- Glyph* getGlyph(SkPackedGlyphID);
|
||||||
|
+ Glyph* getGlyph(SkPackedGlyphID, skgpu::MaskFormat format);
|
||||||
|
const SkStrikeSpec& strikeSpec() const { return fStrikeSpec; }
|
||||||
|
const SkDescriptor& getDescriptor() const { return fStrikeSpec.descriptor(); }
|
||||||
|
|
||||||
|
@@ -54,11 +56,11 @@ private:
|
||||||
|
const SkStrikeSpec fStrikeSpec;
|
||||||
|
|
||||||
|
struct HashTraits {
|
||||||
|
- static const SkPackedGlyphID& GetKey(const Glyph* glyph);
|
||||||
|
- static uint32_t Hash(SkPackedGlyphID key);
|
||||||
|
+ static const GlyphEntryKey& GetKey(const Glyph* glyph);
|
||||||
|
+ static uint32_t Hash(GlyphEntryKey key);
|
||||||
|
};
|
||||||
|
// Map SkPackedGlyphID -> Glyph*.
|
||||||
|
- skia_private::THashTable<Glyph*, SkPackedGlyphID, HashTraits> fCache;
|
||||||
|
+ skia_private::THashTable<Glyph*, GlyphEntryKey, HashTraits> fCache;
|
||||||
|
|
||||||
|
// Store for the glyph information.
|
||||||
|
SkArenaAlloc fAlloc{512};
|
||||||
|
diff --git a/src/text/gpu/SubRunContainer.cpp b/src/text/gpu/SubRunContainer.cpp
|
||||||
|
index 3a061a2012cd99de9ee4b3674f78ae99e0385d6c..a19460c82593c6713c047ab19e71caa27e375a6d 100644
|
||||||
|
--- a/src/text/gpu/SubRunContainer.cpp
|
||||||
|
+++ b/src/text/gpu/SubRunContainer.cpp
|
||||||
|
@@ -651,8 +651,9 @@ public:
|
||||||
|
|
||||||
|
int glyphSrcPadding() const override { return 0; }
|
||||||
|
|
||||||
|
- void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache) const override {
|
||||||
|
- fGlyphs.packedGlyphIDToGlyph(cache);
|
||||||
|
+ void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache,
|
||||||
|
+ skgpu::MaskFormat maskFormat) const override {
|
||||||
|
+ fGlyphs.packedGlyphIDToGlyph(cache, maskFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<bool, SkRect> deviceRectAndNeedsTransform(
|
||||||
|
@@ -755,8 +756,9 @@ public:
|
||||||
|
|
||||||
|
const AtlasSubRun* testingOnly_atlasSubRun() const override { return this; }
|
||||||
|
|
||||||
|
- void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const override {
|
||||||
|
- fGlyphs.packedGlyphIDToGlyph(cache);
|
||||||
|
+ void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache,
|
||||||
|
+ skgpu::MaskFormat maskFormat) const override {
|
||||||
|
+ fGlyphs.packedGlyphIDToGlyph(cache, maskFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
int glyphSrcPadding() const override { return 1; }
|
||||||
|
@@ -884,8 +886,9 @@ public:
|
||||||
|
|
||||||
|
const AtlasSubRun* testingOnly_atlasSubRun() const override { return this; }
|
||||||
|
|
||||||
|
- void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const override {
|
||||||
|
- fGlyphs.packedGlyphIDToGlyph(cache);
|
||||||
|
+ void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache,
|
||||||
|
+ skgpu::MaskFormat maskFormat) const override {
|
||||||
|
+ fGlyphs.packedGlyphIDToGlyph(cache, maskFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
int glyphSrcPadding() const override { return SK_DistanceFieldInset; }
|
||||||
|
diff --git a/src/text/gpu/SubRunContainer.h b/src/text/gpu/SubRunContainer.h
|
||||||
|
index 2573dbb3964e9ab2cc0e276b60d4ab4f9804f0d9..4d1a3c8c2d55015d3d351d322ef039c45be2a398 100644
|
||||||
|
--- a/src/text/gpu/SubRunContainer.h
|
||||||
|
+++ b/src/text/gpu/SubRunContainer.h
|
||||||
|
@@ -167,7 +167,7 @@ public:
|
||||||
|
|
||||||
|
const VertexFiller& vertexFiller() const { return fVertexFiller; }
|
||||||
|
|
||||||
|
- virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache) const = 0;
|
||||||
|
+ virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache, skgpu::MaskFormat) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const VertexFiller fVertexFiller;
|
||||||
|
diff --git a/tests/AtlasOobTest.cpp b/tests/AtlasOobTest.cpp
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..4e6fb02ee6af6543df285d8112f1a2ced5bd9ac9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/AtlasOobTest.cpp
|
||||||
|
@@ -0,0 +1,201 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright 2026 Google LLC
|
||||||
|
+ *
|
||||||
|
+ * Use of this source code is governed by a BSD-style license that can be
|
||||||
|
+ * found in the LICENSE file.
|
||||||
|
+ */
|
||||||
|
+#include "include/core/SkCanvas.h"
|
||||||
|
+#include "include/core/SkGraphics.h"
|
||||||
|
+#include "include/core/SkSerialProcs.h"
|
||||||
|
+#include "include/core/SkSurface.h"
|
||||||
|
+#include "include/private/chromium/SkChromeRemoteGlyphCache.h"
|
||||||
|
+#include "include/private/chromium/Slug.h"
|
||||||
|
+#include "src/core/SkDescriptor.h"
|
||||||
|
+#include "src/core/SkReadBuffer.h"
|
||||||
|
+#include "src/core/SkTypeface_remote.h"
|
||||||
|
+#include "src/core/SkWriteBuffer.h"
|
||||||
|
+#include "src/gpu/AtlasTypes.h"
|
||||||
|
+#include "tests/CtsEnforcement.h"
|
||||||
|
+#include "tests/Test.h"
|
||||||
|
+#include "tools/ToolUtils.h"
|
||||||
|
+
|
||||||
|
+#if defined(SK_GANESH)
|
||||||
|
+#include "include/gpu/ganesh/GrDirectContext.h"
|
||||||
|
+#include "include/gpu/ganesh/SkSurfaceGanesh.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(SK_GRAPHITE)
|
||||||
|
+#include "include/gpu/graphite/Context.h"
|
||||||
|
+#include "include/gpu/graphite/Surface.h"
|
||||||
|
+#include "tools/graphite/GraphiteTestContext.h"
|
||||||
|
+#endif // defined(SK_GRAPHITE)
|
||||||
|
+
|
||||||
|
+#include <vector>
|
||||||
|
+#include <cstring>
|
||||||
|
+
|
||||||
|
+namespace {
|
||||||
|
+class FakeDiscardableManager : public SkStrikeClient::DiscardableHandleManager {
|
||||||
|
+public:
|
||||||
|
+ bool deleteHandle(SkDiscardableHandleId) override { return false; }
|
||||||
|
+ void notifyCacheMiss(SkStrikeClient::CacheMissType, int) override {}
|
||||||
|
+ void notifyReadFailure(const ReadFailureData&) override {}
|
||||||
|
+ void assertHandleValid(SkDiscardableHandleId) override {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+unsigned char kStrikeData[] = {
|
||||||
|
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x07, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x65, 0xd8, 0x50, 0xda, 0x99, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x63, 0x65, 0x72, 0x73, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x80, 0x41,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x64, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x66, 0x86, 0x07, 0xc2, 0x42,
|
||||||
|
+ 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x63, 0x65, 0x72, 0x73, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+unsigned char kDrawSlugOp[] = {
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x41,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
|
||||||
|
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x86, 0x07, 0xc2, 0x42, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x63, 0x65, 0x72, 0x73,
|
||||||
|
+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+} // namespace
|
||||||
|
+
|
||||||
|
+// TODO: We expect this test to correctly hit an SkUnreachable and then crash. That does not work
|
||||||
|
+// with our current testing framework because we have no to "expect" a crash. So for now we will
|
||||||
|
+// land this test with only the valid loop enabled, but to test this is working locally, you should
|
||||||
|
+// change the loop to have both iterations.
|
||||||
|
+static void run_atlas_oob_test(skiatest::Reporter* reporter, SkCanvas* canvas) {
|
||||||
|
+ auto discardableManager = sk_make_sp<FakeDiscardableManager>();
|
||||||
|
+ SkStrikeClient client(discardableManager, false);
|
||||||
|
+
|
||||||
|
+ // 1. Prepare Strike Data
|
||||||
|
+ if (!client.readStrikeData(kStrikeData, sizeof(kStrikeData))) {
|
||||||
|
+ REPORTER_ASSERT(reporter, false, "Failed to read initial strike data");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // 2. Prepare and Execute DrawSlug ops
|
||||||
|
+ SkPaint paint;
|
||||||
|
+ for (int idx = 0; idx < 1; ++idx) {
|
||||||
|
+// for (int idx = 0; idx < 2; ++idx) {
|
||||||
|
+ if (idx == 0) {
|
||||||
|
+ kDrawSlugOp[0x48] = (unsigned char)skgpu::MaskFormat::kARGB;
|
||||||
|
+ } else if (idx == 1) {
|
||||||
|
+ kDrawSlugOp[0x48] = (unsigned char)skgpu::MaskFormat::kA8;
|
||||||
|
+ }
|
||||||
|
+ kDrawSlugOp[0xd8] = SkMask::kARGB32_Format;
|
||||||
|
+ kDrawSlugOp[0xe0] = 0x99;
|
||||||
|
+
|
||||||
|
+ auto slug = client.deserializeSlugForTest(kDrawSlugOp, sizeof(kDrawSlugOp));
|
||||||
|
+ if (slug) {
|
||||||
|
+ slug->draw(canvas, paint);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#if defined(SK_GANESH)
|
||||||
|
+DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(Atlas_Oob_ganesh, reporter, ctxInfo, CtsEnforcement::kNextRelease) {
|
||||||
|
+ auto dContext = ctxInfo.directContext();
|
||||||
|
+ SkImageInfo info = SkImageInfo::MakeN32Premul(1024, 1024);
|
||||||
|
+ auto surface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, info);
|
||||||
|
+ if (!surface) return;
|
||||||
|
+ auto canvas = surface->getCanvas();
|
||||||
|
+
|
||||||
|
+ run_atlas_oob_test(reporter, canvas);
|
||||||
|
+
|
||||||
|
+ dContext->flushAndSubmit();
|
||||||
|
+}
|
||||||
|
+#endif // defined(SK_GANESH)
|
||||||
|
+
|
||||||
|
+#if defined(SK_GRAPHITE)
|
||||||
|
+DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(Atlas_Oob_graphite, reporter, context, CtsEnforcement::kNextRelease) {
|
||||||
|
+ using namespace skgpu::graphite;
|
||||||
|
+ std::unique_ptr<Recorder> recorder = context->makeRecorder();
|
||||||
|
+ SkImageInfo info = SkImageInfo::MakeN32Premul(1024, 1024);
|
||||||
|
+ auto surface = SkSurfaces::RenderTarget(recorder.get(), info);
|
||||||
|
+ if (!surface) return;
|
||||||
|
+ auto canvas = surface->getCanvas();
|
||||||
|
+
|
||||||
|
+ run_atlas_oob_test(reporter, canvas);
|
||||||
|
+
|
||||||
|
+ std::unique_ptr<Recording> recording = recorder->snap();
|
||||||
|
+ InsertRecordingInfo recordingInfo;
|
||||||
|
+ recordingInfo.fRecording = recording.get();
|
||||||
|
+ context->insertRecording(recordingInfo);
|
||||||
|
+ context->submit();
|
||||||
|
+}
|
||||||
|
+#endif // defined(SK_GRAPHITE)
|
||||||
@@ -9,4 +9,4 @@ refactor_use_non-deprecated_nskeyedarchiver_apis.patch
|
|||||||
chore_turn_off_launchapplicationaturl_deprecation_errors_in_squirrel.patch
|
chore_turn_off_launchapplicationaturl_deprecation_errors_in_squirrel.patch
|
||||||
fix_crash_when_process_to_extract_zip_cannot_be_launched.patch
|
fix_crash_when_process_to_extract_zip_cannot_be_launched.patch
|
||||||
use_uttype_class_instead_of_deprecated_uttypeconformsto.patch
|
use_uttype_class_instead_of_deprecated_uttypeconformsto.patch
|
||||||
fix_clean_up_old_staged_updates_before_downloading_new_update.patch
|
fix_clean_up_orphaned_staged_updates_before_downloading_new_update.patch
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Andy Locascio <loc@anthropic.com>
|
|
||||||
Date: Tue, 6 Jan 2026 08:23:03 -0800
|
|
||||||
Subject: fix: clean up old staged updates before downloading new update
|
|
||||||
|
|
||||||
When checkForUpdates() is called while an update is already staged,
|
|
||||||
Squirrel creates a new temporary directory for the download without
|
|
||||||
cleaning up the old one. This can lead to significant disk usage if
|
|
||||||
the app keeps checking for updates without restarting.
|
|
||||||
|
|
||||||
This change adds a force parameter to pruneUpdateDirectories that
|
|
||||||
bypasses the AwaitingRelaunch state check. This is called before
|
|
||||||
creating a new temp directory, ensuring old staged updates are
|
|
||||||
cleaned up when a new download starts.
|
|
||||||
|
|
||||||
diff --git a/Squirrel/SQRLUpdater.m b/Squirrel/SQRLUpdater.m
|
|
||||||
index d156616e81e6f25a3bded30e6216b8fc311f31bc..6cd4346bf43b191147aff819cb93387e71275a46 100644
|
|
||||||
--- a/Squirrel/SQRLUpdater.m
|
|
||||||
+++ b/Squirrel/SQRLUpdater.m
|
|
||||||
@@ -543,11 +543,17 @@ - (RACSignal *)downloadBundleForUpdate:(SQRLUpdate *)update intoDirectory:(NSURL
|
|
||||||
#pragma mark File Management
|
|
||||||
|
|
||||||
- (RACSignal *)uniqueTemporaryDirectoryForUpdate {
|
|
||||||
- return [[[RACSignal
|
|
||||||
+ // Clean up any old staged update directories before creating a new one.
|
|
||||||
+ // This prevents disk usage from growing when checkForUpdates() is called
|
|
||||||
+ // multiple times without the app restarting.
|
|
||||||
+ return [[[[[self
|
|
||||||
+ pruneUpdateDirectoriesWithForce:YES]
|
|
||||||
+ ignoreValues]
|
|
||||||
+ concat:[RACSignal
|
|
||||||
defer:^{
|
|
||||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
|
||||||
return [directoryManager storageURL];
|
|
||||||
- }]
|
|
||||||
+ }]]
|
|
||||||
flattenMap:^(NSURL *storageURL) {
|
|
||||||
NSURL *updateDirectoryTemplate = [storageURL URLByAppendingPathComponent:[SQRLUpdaterUniqueTemporaryDirectoryPrefix stringByAppendingString:@"XXXXXXX"]];
|
|
||||||
char *updateDirectoryCString = strdup(updateDirectoryTemplate.path.fileSystemRepresentation);
|
|
||||||
@@ -643,7 +649,7 @@ - (BOOL)isRunningOnReadOnlyVolume {
|
|
||||||
|
|
||||||
- (RACSignal *)performHousekeeping {
|
|
||||||
return [[RACSignal
|
|
||||||
- merge:@[ [self pruneUpdateDirectories], [self truncateLogs] ]]
|
|
||||||
+ merge:@[ [self pruneUpdateDirectoriesWithForce:NO], [self truncateLogs] ]]
|
|
||||||
catch:^(NSError *error) {
|
|
||||||
NSLog(@"Error doing housekeeping: %@", error);
|
|
||||||
return [RACSignal empty];
|
|
||||||
@@ -658,11 +664,12 @@ - (RACSignal *)performHousekeeping {
|
|
||||||
///
|
|
||||||
/// Sends each removed directory then completes, or errors, on an unspecified
|
|
||||||
/// thread.
|
|
||||||
-- (RACSignal *)pruneUpdateDirectories {
|
|
||||||
+- (RACSignal *)pruneUpdateDirectoriesWithForce:(BOOL)force {
|
|
||||||
return [[[RACSignal
|
|
||||||
defer:^{
|
|
||||||
- // If we already have updates downloaded we don't wanna prune them.
|
|
||||||
- if (self.state == SQRLUpdaterStateAwaitingRelaunch) return [RACSignal empty];
|
|
||||||
+ // If we already have updates downloaded we don't wanna prune them,
|
|
||||||
+ // unless force is YES (used when starting a new download).
|
|
||||||
+ if (!force && self.state == SQRLUpdaterStateAwaitingRelaunch) return [RACSignal empty];
|
|
||||||
|
|
||||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
|
||||||
return [directoryManager storageURL];
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andy Locascio <loc@anthropic.com>
|
||||||
|
Date: Tue, 6 Jan 2026 08:23:03 -0800
|
||||||
|
Subject: fix: clean up orphaned staged updates before downloading new update
|
||||||
|
|
||||||
|
When checkForUpdates() is called while an update is already staged,
|
||||||
|
Squirrel creates a new temporary directory for the download without
|
||||||
|
cleaning up the old one. This can lead to significant disk usage if
|
||||||
|
the app keeps checking for updates without restarting.
|
||||||
|
|
||||||
|
This change adds a pruneOrphanedUpdateDirectories step before creating
|
||||||
|
a new temp directory. Unlike a blanket prune, this reads the current
|
||||||
|
ShipItState.plist and preserves the directory it references, deleting
|
||||||
|
only truly orphaned update directories. This keeps the on-disk
|
||||||
|
footprint bounded (at most 2 dirs) while ensuring quitAndInstall
|
||||||
|
remains safe to call even when a new check is in progress.
|
||||||
|
|
||||||
|
Refs https://github.com/electron/electron/issues/50200
|
||||||
|
|
||||||
|
diff --git a/Squirrel/SQRLUpdater.m b/Squirrel/SQRLUpdater.m
|
||||||
|
index d156616e81e6f25a3bded30e6216b8fc311f31bc..41856e5754228d33982db72f97f2ff241615a357 100644
|
||||||
|
--- a/Squirrel/SQRLUpdater.m
|
||||||
|
+++ b/Squirrel/SQRLUpdater.m
|
||||||
|
@@ -543,11 +543,19 @@ - (RACSignal *)downloadBundleForUpdate:(SQRLUpdate *)update intoDirectory:(NSURL
|
||||||
|
#pragma mark File Management
|
||||||
|
|
||||||
|
- (RACSignal *)uniqueTemporaryDirectoryForUpdate {
|
||||||
|
- return [[[RACSignal
|
||||||
|
+ // Clean up any orphaned update directories before creating a new one.
|
||||||
|
+ // This prevents disk usage from growing when checkForUpdates() is called
|
||||||
|
+ // multiple times without the app restarting. The currently staged update
|
||||||
|
+ // (referenced by ShipItState.plist) is always preserved so quitAndInstall
|
||||||
|
+ // remains safe to call while a new check is in progress.
|
||||||
|
+ return [[[[[self
|
||||||
|
+ pruneOrphanedUpdateDirectories]
|
||||||
|
+ ignoreValues]
|
||||||
|
+ concat:[RACSignal
|
||||||
|
defer:^{
|
||||||
|
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
||||||
|
return [directoryManager storageURL];
|
||||||
|
- }]
|
||||||
|
+ }]]
|
||||||
|
flattenMap:^(NSURL *storageURL) {
|
||||||
|
NSURL *updateDirectoryTemplate = [storageURL URLByAppendingPathComponent:[SQRLUpdaterUniqueTemporaryDirectoryPrefix stringByAppendingString:@"XXXXXXX"]];
|
||||||
|
char *updateDirectoryCString = strdup(updateDirectoryTemplate.path.fileSystemRepresentation);
|
||||||
|
@@ -668,25 +676,68 @@ - (RACSignal *)pruneUpdateDirectories {
|
||||||
|
return [directoryManager storageURL];
|
||||||
|
}]
|
||||||
|
flattenMap:^(NSURL *storageURL) {
|
||||||
|
- NSFileManager *manager = [[NSFileManager alloc] init];
|
||||||
|
- NSDirectoryEnumerator *enumerator = [manager enumeratorAtURL:storageURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:^(NSURL *URL, NSError *error) {
|
||||||
|
- NSLog(@"Error enumerating item %@ within directory %@: %@", URL, storageURL, error);
|
||||||
|
- return YES;
|
||||||
|
- }];
|
||||||
|
+ return [self removeUpdateDirectoriesInStorageURL:storageURL excludingURL:nil];
|
||||||
|
+ }]
|
||||||
|
+ setNameWithFormat:@"%@ -prunedUpdateDirectories", self];
|
||||||
|
+}
|
||||||
|
|
||||||
|
- return [[enumerator.rac_sequence.signal
|
||||||
|
- filter:^(NSURL *enumeratedURL) {
|
||||||
|
- NSString *name = enumeratedURL.lastPathComponent;
|
||||||
|
- return [name hasPrefix:SQRLUpdaterUniqueTemporaryDirectoryPrefix];
|
||||||
|
- }]
|
||||||
|
- doNext:^(NSURL *directoryURL) {
|
||||||
|
- NSError *error = nil;
|
||||||
|
- if (![manager removeItemAtURL:directoryURL error:&error]) {
|
||||||
|
- NSLog(@"Error removing old update directory at %@: %@", directoryURL, error.sqrl_verboseDescription);
|
||||||
|
- }
|
||||||
|
+/// Lazily removes orphaned temporary directories upon subscription, always
|
||||||
|
+/// preserving the directory currently referenced by ShipItState.plist so that
|
||||||
|
+/// quitAndInstall remains safe to call mid-check.
|
||||||
|
+///
|
||||||
|
+/// Safe to call in any state. Sends each removed directory then completes on
|
||||||
|
+/// an unspecified thread. Errors reading the staged request are swallowed
|
||||||
|
+/// (treated as "nothing staged").
|
||||||
|
+- (RACSignal *)pruneOrphanedUpdateDirectories {
|
||||||
|
+ return [[[[[SQRLShipItRequest
|
||||||
|
+ readUsingURL:self.shipItStateURL]
|
||||||
|
+ map:^(SQRLShipItRequest *request) {
|
||||||
|
+ // The request holds the URL to the staged .app bundle; its parent
|
||||||
|
+ // is the update.XXXXXXX directory we must preserve.
|
||||||
|
+ return [request.updateBundleURL URLByDeletingLastPathComponent];
|
||||||
|
+ }]
|
||||||
|
+ catch:^(NSError *error) {
|
||||||
|
+ // No staged request (or unreadable) — nothing to preserve.
|
||||||
|
+ return [RACSignal return:nil];
|
||||||
|
+ }]
|
||||||
|
+ flattenMap:^(NSURL *stagedDirectoryURL) {
|
||||||
|
+ SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
||||||
|
+ return [[directoryManager storageURL]
|
||||||
|
+ flattenMap:^(NSURL *storageURL) {
|
||||||
|
+ return [self removeUpdateDirectoriesInStorageURL:storageURL excludingURL:stagedDirectoryURL];
|
||||||
|
}];
|
||||||
|
}]
|
||||||
|
- setNameWithFormat:@"%@ -prunedUpdateDirectories", self];
|
||||||
|
+ setNameWithFormat:@"%@ -pruneOrphanedUpdateDirectories", self];
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/// Shared enumerate-and-delete logic for update temp directories.
|
||||||
|
+///
|
||||||
|
+/// storageURL - The Squirrel storage root to enumerate. Must not be nil.
|
||||||
|
+/// excludedURL - Directory to skip (compared by standardized path). May be nil.
|
||||||
|
+- (RACSignal *)removeUpdateDirectoriesInStorageURL:(NSURL *)storageURL excludingURL:(NSURL *)excludedURL {
|
||||||
|
+ NSParameterAssert(storageURL != nil);
|
||||||
|
+
|
||||||
|
+ NSFileManager *manager = [[NSFileManager alloc] init];
|
||||||
|
+ NSDirectoryEnumerator *enumerator = [manager enumeratorAtURL:storageURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:^(NSURL *URL, NSError *error) {
|
||||||
|
+ NSLog(@"Error enumerating item %@ within directory %@: %@", URL, storageURL, error);
|
||||||
|
+ return YES;
|
||||||
|
+ }];
|
||||||
|
+
|
||||||
|
+ NSString *excludedPath = excludedURL.URLByStandardizingPath.path;
|
||||||
|
+
|
||||||
|
+ return [[enumerator.rac_sequence.signal
|
||||||
|
+ filter:^(NSURL *enumeratedURL) {
|
||||||
|
+ NSString *name = enumeratedURL.lastPathComponent;
|
||||||
|
+ if (![name hasPrefix:SQRLUpdaterUniqueTemporaryDirectoryPrefix]) return NO;
|
||||||
|
+ if (excludedPath != nil && [enumeratedURL.URLByStandardizingPath.path isEqualToString:excludedPath]) return NO;
|
||||||
|
+ return YES;
|
||||||
|
+ }]
|
||||||
|
+ doNext:^(NSURL *directoryURL) {
|
||||||
|
+ NSError *error = nil;
|
||||||
|
+ if (![manager removeItemAtURL:directoryURL error:&error]) {
|
||||||
|
+ NSLog(@"Error removing old update directory at %@: %@", directoryURL, error.sqrl_verboseDescription);
|
||||||
|
+ }
|
||||||
|
+ }];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3,3 +3,4 @@ turboshaft_avoid_introducing_too_many_variables.patch
|
|||||||
runtime_setprototypeproperties_handling_of.patch
|
runtime_setprototypeproperties_handling_of.patch
|
||||||
runtime_correcting_setprototypeproperties.patch
|
runtime_correcting_setprototypeproperties.patch
|
||||||
reduce_stack_memory_consumption_in_bytecodegenerator.patch
|
reduce_stack_memory_consumption_in_bytecodegenerator.patch
|
||||||
|
cherry-pick-d5b0cb2acffe.patch
|
||||||
|
|||||||
50
patches/v8/cherry-pick-d5b0cb2acffe.patch
Normal file
50
patches/v8/cherry-pick-d5b0cb2acffe.patch
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Darius Mercadier <dmercadier@chromium.org>
|
||||||
|
Date: Wed, 25 Feb 2026 12:56:18 +0100
|
||||||
|
Subject: [M144 Merge] [maglev] fix CanElideWriteBarrier Smi recording for phis
|
||||||
|
|
||||||
|
Recording a Tagged use is not enough for 2 reasons:
|
||||||
|
|
||||||
|
* Tagged uses are sometimes ignored, in particular for loop phis
|
||||||
|
where we distinguish in-loop and out-of-loop uses.
|
||||||
|
|
||||||
|
* This Tagged use could only prevent untagging of this specific phi,
|
||||||
|
but none of its inputs. So we could have a Smi phi as input to the
|
||||||
|
current phi which gets untagged and retagged to a non-Smi, all
|
||||||
|
while the current phi doesn't get untagged.
|
||||||
|
|
||||||
|
(cherry picked from commit a54bf5cd45e5b119e2afe6019428e81c3d626fb3)
|
||||||
|
|
||||||
|
Change-Id: I9b3a2ea339f2c9d81dbb74a44425ba55d8c73871
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7604255
|
||||||
|
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
|
||||||
|
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||||||
|
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
|
||||||
|
Cr-Original-Commit-Position: refs/heads/main@{#105444}
|
||||||
|
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7659106
|
||||||
|
Auto-Submit: Srinivas Sista <srinivassista@chromium.org>
|
||||||
|
Reviewed-by: Rezvan Mahdavi Hezaveh <rezvan@chromium.org>
|
||||||
|
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
|
||||||
|
Reviewed-by: Deepti Gandluri <gdeepti@chromium.org>
|
||||||
|
Owners-Override: Srinivas Sista <srinivassista@chromium.org>
|
||||||
|
Cr-Commit-Position: refs/branch-heads/14.4@{#64}
|
||||||
|
Cr-Branched-From: 80acc26727d5a34e77dabeebe7c9213ec1bd4768-refs/heads/14.4.258@{#1}
|
||||||
|
Cr-Branched-From: ce7e597e90f6df3fa4b6df224bc613b80c635450-refs/heads/main@{#104020}
|
||||||
|
|
||||||
|
diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
|
||||||
|
index 4664ca78b4413da6a3d9d6cafa705d33f5c02ee2..c682aec3ff109e42290c2e2ddec350f913e4e063 100644
|
||||||
|
--- a/src/maglev/maglev-graph-builder.cc
|
||||||
|
+++ b/src/maglev/maglev-graph-builder.cc
|
||||||
|
@@ -4496,7 +4496,11 @@ bool MaglevGraphBuilder::CanElideWriteBarrier(ValueNode* object,
|
||||||
|
ValueNode* value) {
|
||||||
|
if (value->Is<RootConstant>() || value->Is<ConsStringMap>()) return true;
|
||||||
|
if (!IsEmptyNodeType(GetType(value)) && CheckType(value, NodeType::kSmi)) {
|
||||||
|
- value->MaybeRecordUseReprHint(UseRepresentation::kTagged);
|
||||||
|
+ if constexpr (SmiValuesAre31Bits()) {
|
||||||
|
+ if (Phi* value_as_phi = value->TryCast<Phi>()) {
|
||||||
|
+ value_as_phi->SetUseRequires31BitValue();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,8 @@ async function main () {
|
|||||||
}));
|
}));
|
||||||
const hitRate = stats.CacheHit / (stats.Remote + stats.CacheHit + stats.LocalFallback);
|
const hitRate = stats.CacheHit / (stats.Remote + stats.CacheHit + stats.LocalFallback);
|
||||||
|
|
||||||
console.log(`Effective cache hit rate: ${(hitRate * 100).toFixed(2)}%`);
|
const messagePrefix = process.env.GITHUB_ACTIONS ? '::notice title=Build Stats::' : '';
|
||||||
|
console.log(`${messagePrefix}Effective cache hit rate: ${(hitRate * 100).toFixed(2)}%`);
|
||||||
|
|
||||||
if (uploadStats) {
|
if (uploadStats) {
|
||||||
if (!process.env.DD_API_KEY) {
|
if (!process.env.DD_API_KEY) {
|
||||||
|
|||||||
21
script/codesign/cleanup-identity.sh
Executable file
21
script/codesign/cleanup-identity.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Removes the codesigning keychain created by generate-identity.sh.
|
||||||
|
# Safe to run even if generate-identity.sh was never run (each step
|
||||||
|
# is guarded).
|
||||||
|
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
KEYCHAIN="electron-codesign.keychain-db"
|
||||||
|
|
||||||
|
# delete-keychain also removes it from the search list
|
||||||
|
if security list-keychains -d user | grep -q "$KEYCHAIN"; then
|
||||||
|
security delete-keychain "$KEYCHAIN"
|
||||||
|
echo "Deleted keychain: $KEYCHAIN"
|
||||||
|
else
|
||||||
|
echo "Keychain not found, nothing to delete"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up working directory
|
||||||
|
rm -rf "$(dirname $0)"/.working
|
||||||
|
echo "Cleanup complete"
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
dir="$(dirname $0)"/.working
|
dir="$(dirname $0)"/.working
|
||||||
|
KEYCHAIN="electron-codesign.keychain-db"
|
||||||
|
KEYCHAIN_TEMP="$(openssl rand -hex 12)"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -rf "$dir"
|
rm -rf "$dir"
|
||||||
@@ -18,30 +20,16 @@ mkdir -p "$dir"
|
|||||||
|
|
||||||
# Generate Certs
|
# Generate Certs
|
||||||
openssl req -new -newkey rsa:2048 -x509 -days 7300 -nodes -config "$(dirname $0)"/codesign.cnf -extensions extended -batch -out "$dir"/certificate.cer -keyout "$dir"/certificate.key
|
openssl req -new -newkey rsa:2048 -x509 -days 7300 -nodes -config "$(dirname $0)"/codesign.cnf -extensions extended -batch -out "$dir"/certificate.cer -keyout "$dir"/certificate.key
|
||||||
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "$dir"/certificate.cer
|
|
||||||
sudo security import "$dir"/certificate.key -A -k /Library/Keychains/System.keychain
|
|
||||||
|
|
||||||
# restart(reload) taskgated daemon
|
# macOS 15+ blocks modifications to the system keychain via SIP/TCC,
|
||||||
sudo pkill -f /usr/libexec/taskgated
|
# so we use a custom user-scoped keychain instead.
|
||||||
|
# Refs https://github.com/electron/electron/issues/48182
|
||||||
|
security create-keychain -p "$KEYCHAIN_TEMP" "$KEYCHAIN"
|
||||||
|
security set-keychain-settings -t 3600 -u "$KEYCHAIN"
|
||||||
|
security unlock-keychain -p "$KEYCHAIN_TEMP" "$KEYCHAIN"
|
||||||
|
|
||||||
# need once
|
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | tr -d '"')
|
||||||
sudo security authorizationdb write system.privilege.taskport allow
|
security import "$dir"/certificate.cer -k "$KEYCHAIN" -T /usr/bin/codesign
|
||||||
# need once
|
security import "$dir"/certificate.key -k "$KEYCHAIN" -T /usr/bin/codesign -A
|
||||||
DevToolsSecurity -enable
|
|
||||||
|
|
||||||
# openssl req -newkey rsa:2048 -nodes -keyout "$dir"/private.pem -x509 -days 1 -out "$dir"/certificate.pem -extensions extended -config "$(dirname $0)"/codesign.cnf
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_TEMP" "$KEYCHAIN"
|
||||||
# openssl x509 -inform PEM -in "$dir"/certificate.pem -outform DER -out "$dir"/certificate.cer
|
|
||||||
# openssl x509 -pubkey -noout -in "$dir"/certificate.pem > "$dir"/public.key
|
|
||||||
# rm -f "$dir"/certificate.pem
|
|
||||||
|
|
||||||
# Import Certs
|
|
||||||
# security import "$dir"/certificate.cer -k $KEY_CHAIN
|
|
||||||
# security import "$dir"/private.pem -k $KEY_CHAIN
|
|
||||||
# security import "$dir"/public.key -k $KEY_CHAIN
|
|
||||||
|
|
||||||
# Generate Trust Settings
|
|
||||||
# TODO: Remove NPX
|
|
||||||
npm_config_yes=true npx ts-node "$(dirname $0)"/gen-trust.ts "$dir"/certificate.cer "$dir"/trust.xml
|
|
||||||
|
|
||||||
# Import Trust Settings
|
|
||||||
sudo security trust-settings-import -d "$dir/trust.xml"
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user