mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69fe268d4d | ||
|
|
55738ddac3 | ||
|
|
7916733f5f | ||
|
|
6c37483f2c |
@@ -149,3 +149,7 @@ avoid_allocating_recordid_objects_in_elementtiming_and_lcp.patch
|
||||
cherry-pick-80106e31c7ea.patch
|
||||
gpu_use_load_program_shader_shm_count_on_drdc_thread.patch
|
||||
crash_gpu_process_and_clear_shader_cache_when_skia_reports.patch
|
||||
cherry-pick-3df423a5b8de.patch
|
||||
cherry-pick-9384cddc7705.patch
|
||||
cherry-pick-3f45b1af5e41.patch
|
||||
cherry-pick-e13061c50998.patch
|
||||
|
||||
57
patches/chromium/cherry-pick-3df423a5b8de.patch
Normal file
57
patches/chromium/cherry-pick-3df423a5b8de.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Fri, 3 Nov 2023 16:39:55 +0000
|
||||
Subject: Check context status before recreating platform destination
|
||||
|
||||
Changing the channel count in the RealtimeAudioDestinationHandler will
|
||||
trigger the recreation of the platform destination. This in turn can
|
||||
activate the audio rendering thread.
|
||||
|
||||
This CL adds a check to prevent this from happening after the handler
|
||||
is garbage collected.
|
||||
|
||||
(cherry picked from commit 4997f2ba263ff7e1dbc7987dd3665459be14dffe)
|
||||
|
||||
Bug: 1497859
|
||||
Test: Locally confirmed with ASAN
|
||||
Change-Id: I5d2649f3fd3639779ae40b0ca4ef2fe305653421
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4995928
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1217868}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5004961
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5993@{#1520}
|
||||
Cr-Branched-From: 511350718e646be62331ae9d7213d10ec320d514-refs/heads/main@{#1192594}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
|
||||
index 6781dcff462db872d1f5a786aef0c89f43189100..2e4757d155800700b7c6a8b7cbf2e02250cfce65 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
|
||||
@@ -118,12 +118,21 @@ void RealtimeAudioDestinationHandler::SetChannelCount(
|
||||
uint32_t old_channel_count = ChannelCount();
|
||||
AudioHandler::SetChannelCount(channel_count, exception_state);
|
||||
|
||||
- // Stop, re-create and start the destination to apply the new channel count.
|
||||
- if (ChannelCount() != old_channel_count && !exception_state.HadException()) {
|
||||
- StopPlatformDestination();
|
||||
- CreatePlatformDestination();
|
||||
- StartPlatformDestination();
|
||||
+ // After the context is closed, changing channel count will be ignored
|
||||
+ // because it will trigger the recreation of the platform destination. This
|
||||
+ // in turn can activate the audio rendering thread.
|
||||
+ AudioContext* context = static_cast<AudioContext*>(Context());
|
||||
+ CHECK(context);
|
||||
+ if (context->ContextState() == AudioContext::kClosed ||
|
||||
+ ChannelCount() == old_channel_count ||
|
||||
+ exception_state.HadException()) {
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
+ // Stop, re-create and start the destination to apply the new channel count.
|
||||
+ StopPlatformDestination();
|
||||
+ CreatePlatformDestination();
|
||||
+ StartPlatformDestination();
|
||||
}
|
||||
|
||||
void RealtimeAudioDestinationHandler::StartRendering() {
|
||||
48
patches/chromium/cherry-pick-3f45b1af5e41.patch
Normal file
48
patches/chromium/cherry-pick-3f45b1af5e41.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alvin Ji <alvinji@chromium.org>
|
||||
Date: Mon, 13 Nov 2023 20:24:24 +0000
|
||||
Subject: Check context status before creating new platform destination
|
||||
|
||||
RealtimeAudioDestinationHandler::SetSinkDescriptor creates new
|
||||
destination platofrm without validating context status. This can
|
||||
reactivate the audio rendering thread when AudioContext is already in
|
||||
closed state.
|
||||
|
||||
(cherry picked from commit 0f9bb9a1083865d4e51059e588f27f729ab32753)
|
||||
|
||||
Bug: 1500856
|
||||
Change-Id: If1fd531324b56fcdc38d315fd84d4cec577a14bc
|
||||
Test: Locally confirmed with ASAN
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5021160
|
||||
Reviewed-by: Alvin Ji <alvinji@chromium.org>
|
||||
Commit-Queue: Alvin Ji <alvinji@chromium.org>
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1223168}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5026373
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#607}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
|
||||
index 2e4757d155800700b7c6a8b7cbf2e02250cfce65..c27eb3ac07f22a4cd1ae2f86da896d255a761292 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
|
||||
@@ -405,6 +405,17 @@ void RealtimeAudioDestinationHandler::SetSinkDescriptor(
|
||||
GetCallbackBufferSize()));
|
||||
DCHECK(IsMainThread());
|
||||
|
||||
+ // After the context is closed, `SetSinkDescriptor` request will be ignored
|
||||
+ // because it will trigger the recreation of the platform destination. This in
|
||||
+ // turn can activate the audio rendering thread.
|
||||
+ AudioContext* context = static_cast<AudioContext*>(Context());
|
||||
+ CHECK(context);
|
||||
+ if (context->ContextState() == AudioContext::kClosed) {
|
||||
+ std::move(callback).Run(
|
||||
+ media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// Create a pending AudioDestination to replace the current one.
|
||||
scoped_refptr<AudioDestination> pending_platform_destination =
|
||||
AudioDestination::Create(
|
||||
42
patches/chromium/cherry-pick-9384cddc7705.patch
Normal file
42
patches/chromium/cherry-pick-9384cddc7705.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Date: Wed, 8 Nov 2023 04:19:31 +0000
|
||||
Subject: Make URLSearchParams persistent to avoid UaF
|
||||
|
||||
The URLSearchParams::Create() function returns an on-heap object, but it
|
||||
can be garbage collected, so making it a persistent variable in
|
||||
DidFetchDataLoadedString() mitigates the issue.
|
||||
|
||||
(cherry picked from commit 8b1bd7726a1394e2fe287f6a882822d8ee9d4e96)
|
||||
|
||||
Bug: 1497997
|
||||
Change-Id: I4ae0f93fccc561cd8a088d3fa0bf2968bf298acf
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4996929
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Commit-Queue: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1218682}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5007484
|
||||
Commit-Queue: Adam Rice <ricea@chromium.org>
|
||||
Auto-Submit: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5993@{#1546}
|
||||
Cr-Branched-From: 511350718e646be62331ae9d7213d10ec320d514-refs/heads/main@{#1192594}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/fetch/body.cc b/third_party/blink/renderer/core/fetch/body.cc
|
||||
index 1b0ce3c8dceac103c24d513c3c5f4bc3aabcf6b7..5ffef06442a508c4dbf8133d5d20491c159bbfde 100644
|
||||
--- a/third_party/blink/renderer/core/fetch/body.cc
|
||||
+++ b/third_party/blink/renderer/core/fetch/body.cc
|
||||
@@ -135,8 +135,13 @@ class BodyFormDataConsumer final : public BodyConsumerBase {
|
||||
|
||||
void DidFetchDataLoadedString(const String& string) override {
|
||||
auto* formData = MakeGarbageCollected<FormData>();
|
||||
- for (const auto& pair : URLSearchParams::Create(string)->Params())
|
||||
+ // URLSearchParams::Create() returns an on-heap object, but it can be
|
||||
+ // garbage collected, so making it a persistent variable on the stack
|
||||
+ // mitigates use-after-free scenarios. See crbug.com/1497997.
|
||||
+ Persistent<URLSearchParams> search_params = URLSearchParams::Create(string);
|
||||
+ for (const auto& pair : search_params->Params()) {
|
||||
formData->append(pair.first, pair.second);
|
||||
+ }
|
||||
DidFetchDataLoadedFormData(formData);
|
||||
}
|
||||
};
|
||||
116
patches/chromium/cherry-pick-e13061c50998.patch
Normal file
116
patches/chromium/cherry-pick-e13061c50998.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Thu, 16 Nov 2023 23:44:43 +0000
|
||||
Subject: Reland: Fix IPC Channel pipe teardown
|
||||
|
||||
This is a reland with the new test temporarily disabled on Android
|
||||
until it can run without disrupting other tests.
|
||||
|
||||
(cherry picked from commit cd4c1f165c16c6d8161b5372ef7f61c715e01a42)
|
||||
|
||||
Fixed: 1494461
|
||||
Change-Id: If1d83c2dce62020f78dd50abc460973759002a1a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5015115
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Robert Sesek <rsesek@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1221953}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5037764
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Auto-Submit: Ken Rockot <rockot@google.com>
|
||||
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5993@{#1618}
|
||||
Cr-Branched-From: 511350718e646be62331ae9d7213d10ec320d514-refs/heads/main@{#1192594}
|
||||
|
||||
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
|
||||
index 2ab03807d102d8f4e2a22119210d5cb669338c3b..5fa17e2ff108909a8987665dd21bc490118f1147 100644
|
||||
--- a/ipc/ipc_mojo_bootstrap.cc
|
||||
+++ b/ipc/ipc_mojo_bootstrap.cc
|
||||
@@ -787,13 +787,12 @@ class ChannelAssociatedGroupController
|
||||
// handle.
|
||||
DCHECK(!endpoint->client());
|
||||
DCHECK(endpoint->peer_closed());
|
||||
- MarkClosedAndMaybeRemove(endpoint);
|
||||
+ MarkClosed(endpoint);
|
||||
} else {
|
||||
- MarkPeerClosedAndMaybeRemove(endpoint);
|
||||
+ MarkPeerClosed(endpoint);
|
||||
}
|
||||
}
|
||||
-
|
||||
- DCHECK(endpoints_.empty());
|
||||
+ endpoints_.clear();
|
||||
|
||||
GetMemoryDumpProvider().RemoveController(this);
|
||||
}
|
||||
@@ -838,15 +837,19 @@ class ChannelAssociatedGroupController
|
||||
base::AutoLock locker(lock_);
|
||||
encountered_error_ = true;
|
||||
|
||||
+ std::vector<uint32_t> endpoints_to_remove;
|
||||
std::vector<scoped_refptr<Endpoint>> endpoints_to_notify;
|
||||
for (auto iter = endpoints_.begin(); iter != endpoints_.end();) {
|
||||
Endpoint* endpoint = iter->second.get();
|
||||
++iter;
|
||||
|
||||
- if (endpoint->client())
|
||||
+ if (endpoint->client()) {
|
||||
endpoints_to_notify.push_back(endpoint);
|
||||
+ }
|
||||
|
||||
- MarkPeerClosedAndMaybeRemove(endpoint);
|
||||
+ if (MarkPeerClosed(endpoint)) {
|
||||
+ endpoints_to_remove.push_back(endpoint->id());
|
||||
+ }
|
||||
}
|
||||
|
||||
for (auto& endpoint : endpoints_to_notify) {
|
||||
@@ -855,6 +858,10 @@ class ChannelAssociatedGroupController
|
||||
if (endpoint->client())
|
||||
NotifyEndpointOfError(endpoint.get(), false /* force_async */);
|
||||
}
|
||||
+
|
||||
+ for (uint32_t id : endpoints_to_remove) {
|
||||
+ endpoints_.erase(id);
|
||||
+ }
|
||||
}
|
||||
|
||||
void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) {
|
||||
@@ -893,19 +900,33 @@ class ChannelAssociatedGroupController
|
||||
NotifyEndpointOfError(endpoint, false /* force_async */);
|
||||
}
|
||||
|
||||
- void MarkClosedAndMaybeRemove(Endpoint* endpoint) {
|
||||
+ // Marks `endpoint` as closed and returns true if and only if its peer was
|
||||
+ // also already closed.
|
||||
+ bool MarkClosed(Endpoint* endpoint) {
|
||||
lock_.AssertAcquired();
|
||||
endpoint->set_closed();
|
||||
- if (endpoint->closed() && endpoint->peer_closed())
|
||||
- endpoints_.erase(endpoint->id());
|
||||
+ return endpoint->peer_closed();
|
||||
}
|
||||
|
||||
- void MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) {
|
||||
+ // Marks `endpoint` as having a closed peer and returns true if and only if
|
||||
+ // `endpoint` itself was also already closed.
|
||||
+ bool MarkPeerClosed(Endpoint* endpoint) {
|
||||
lock_.AssertAcquired();
|
||||
endpoint->set_peer_closed();
|
||||
endpoint->SignalSyncMessageEvent();
|
||||
- if (endpoint->closed() && endpoint->peer_closed())
|
||||
+ return endpoint->closed();
|
||||
+ }
|
||||
+
|
||||
+ void MarkClosedAndMaybeRemove(Endpoint* endpoint) {
|
||||
+ if (MarkClosed(endpoint)) {
|
||||
endpoints_.erase(endpoint->id());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) {
|
||||
+ if (MarkPeerClosed(endpoint)) {
|
||||
+ endpoints_.erase(endpoint->id());
|
||||
+ }
|
||||
}
|
||||
|
||||
Endpoint* FindOrInsertEndpoint(mojo::InterfaceId id, bool* inserted) {
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
"src/electron/patches/skia": "src/third_party/skia",
|
||||
|
||||
"src/electron/patches/libavif": "src/third_party/libavif/src",
|
||||
|
||||
"src/electron/patches/libwebp": "src/third_party/libwebp/src",
|
||||
|
||||
"src/electron/patches/libvpx": "src/third_party/libvpx/source/libvpx",
|
||||
|
||||
2
patches/libavif/.patches
Normal file
2
patches/libavif/.patches
Normal file
@@ -0,0 +1,2 @@
|
||||
remove_potential_out_of_bound_access_to_alphaitemindices.patch
|
||||
do_not_store_potentially_invalid_pointers.patch
|
||||
@@ -0,0 +1,79 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: VerteDinde <vertedinde@electronjs.org>
|
||||
Date: Thu, 30 Nov 2023 20:39:28 -0800
|
||||
Subject: Do not store potentially invalid pointers
|
||||
|
||||
Manual cherry-pick of PR #1757 into the chromium-m118 branch.
|
||||
|
||||
diff --git a/src/read.c b/src/read.c
|
||||
index 756af390f451eb7e7422248ddc0b3e88e1640a94..5f2c527911f0896f78b26c7313db215671c217dd 100644
|
||||
--- a/src/read.c
|
||||
+++ b/src/read.c
|
||||
@@ -752,6 +752,8 @@ static void avifMetaDestroy(avifMeta * meta)
|
||||
avifFree(meta);
|
||||
}
|
||||
|
||||
+// CAUTION: This function could potentially resize the meta->items array thereby invalidating all existing pointers that are being
|
||||
+// stored locally. So if this function is being called, exercise caution in the caller to not use invalid pointers.
|
||||
static avifDecoderItem * avifMetaFindItem(avifMeta * meta, uint32_t itemID)
|
||||
{
|
||||
if (itemID == 0) {
|
||||
@@ -1259,6 +1261,19 @@ static avifResult avifDecoderItemRead(avifDecoderItem * item,
|
||||
return AVIF_RESULT_OK;
|
||||
}
|
||||
|
||||
+// Returns the avifCodecType of the first tile of the gridItem.
|
||||
+static avifCodecType avifDecoderItemGetGridCodecType(const avifDecoderItem * gridItem)
|
||||
+{
|
||||
+ for (uint32_t i = 0; i < gridItem->meta->items.count; ++i) {
|
||||
+ avifDecoderItem * item = &gridItem->meta->items.item[i];
|
||||
+ const avifCodecType tileCodecType = avifGetCodecType(item->type);
|
||||
+ if ((item->dimgForID == gridItem->id) && (tileCodecType != AVIF_CODEC_TYPE_UNKNOWN)) {
|
||||
+ return tileCodecType;
|
||||
+ }
|
||||
+ }
|
||||
+ return AVIF_CODEC_TYPE_UNKNOWN;
|
||||
+}
|
||||
+
|
||||
static avifBool avifDecoderGenerateImageGridTiles(avifDecoder * decoder, avifImageGrid * grid, avifDecoderItem * gridItem, avifBool alpha)
|
||||
{
|
||||
unsigned int tilesRequested = grid->rows * grid->columns;
|
||||
@@ -3843,16 +3858,28 @@ avifResult avifDecoderReset(avifDecoder * decoder)
|
||||
avifBool isAlphaItemInInput;
|
||||
avifDecoderItem * alphaItem;
|
||||
AVIF_CHECKRES(avifDecoderDataFindAlphaItem(data, &colorItem, &alphaItem, &isAlphaItemInInput));
|
||||
- if (alphaItem && !memcmp(alphaItem->type, "grid", 4)) {
|
||||
- avifROData readData;
|
||||
- AVIF_CHECKRES(avifDecoderItemRead(alphaItem, decoder->io, &readData, 0, 0, data->diag));
|
||||
- AVIF_CHECKERR(avifParseImageGridBox(&data->alpha.grid,
|
||||
- readData.data,
|
||||
- readData.size,
|
||||
- decoder->imageSizeLimit,
|
||||
- decoder->imageDimensionLimit,
|
||||
- data->diag),
|
||||
- AVIF_RESULT_INVALID_IMAGE_GRID);
|
||||
+ avifCodecType alphaCodecType = AVIF_CODEC_TYPE_UNKNOWN;
|
||||
+ if (alphaItem) {
|
||||
+ if (!memcmp(alphaItem->type, "grid", 4)) {
|
||||
+ if (isAlphaItemInInput) {
|
||||
+ avifROData readData;
|
||||
+ AVIF_CHECKRES(avifDecoderItemRead(alphaItem, decoder->io, &readData, 0, 0, data->diag));
|
||||
+ AVIF_CHECKERR(avifParseImageGridBox(&data->alpha.grid,
|
||||
+ readData.data,
|
||||
+ readData.size,
|
||||
+ decoder->imageSizeLimit,
|
||||
+ decoder->imageDimensionLimit,
|
||||
+ data->diag),
|
||||
+ AVIF_RESULT_INVALID_IMAGE_GRID);
|
||||
+ }
|
||||
+ alphaCodecType = avifDecoderItemGetGridCodecType(alphaItem);
|
||||
+ if (alphaCodecType == AVIF_CODEC_TYPE_UNKNOWN) {
|
||||
+ return AVIF_RESULT_INVALID_IMAGE_GRID;
|
||||
+ }
|
||||
+ } else {
|
||||
+ alphaCodecType = avifGetCodecType(alphaItem->type);
|
||||
+ assert(alphaCodecType != AVIF_CODEC_TYPE_UNKNOWN);
|
||||
+ }
|
||||
}
|
||||
|
||||
// Find Exif and/or XMP metadata, if any
|
||||
@@ -0,0 +1,227 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: VerteDinde <vertedinde@electronjs.org>
|
||||
Date: Thu, 30 Nov 2023 20:33:02 -0800
|
||||
Subject: Remove potential out of bound access to alphaItemIndices
|
||||
|
||||
Manual cherry-pick of PR #1756 into the chromium-m118 branch.
|
||||
|
||||
diff --git a/include/avif/internal.h b/include/avif/internal.h
|
||||
index 0d3651fb4fb26baafc756b0033141e50495d9127..8562dce8bb93bee9f151b0321d41692f0a62ea9c 100644
|
||||
--- a/include/avif/internal.h
|
||||
+++ b/include/avif/internal.h
|
||||
@@ -397,6 +397,19 @@ __attribute__((__format__(__printf__, 2, 3)))
|
||||
#endif
|
||||
void avifDiagnosticsPrintf(avifDiagnostics * diag, const char * format, ...);
|
||||
|
||||
+// ---------------------------------------------------------------------------
|
||||
+// avifCodecType (underlying video format)
|
||||
+
|
||||
+// Alliance for Open Media video formats that can be used in the AVIF image format.
|
||||
+typedef enum avifCodecType
|
||||
+{
|
||||
+ AVIF_CODEC_TYPE_UNKNOWN,
|
||||
+ AVIF_CODEC_TYPE_AV1,
|
||||
+#if defined(AVIF_CODEC_AVM)
|
||||
+ AVIF_CODEC_TYPE_AV2, // Experimental.
|
||||
+#endif
|
||||
+} avifCodecType;
|
||||
+
|
||||
// ---------------------------------------------------------------------------
|
||||
// avifStream
|
||||
//
|
||||
diff --git a/src/read.c b/src/read.c
|
||||
index 36a9058abfda94b623609e5ffff5fac2e48d8701..756af390f451eb7e7422248ddc0b3e88e1640a94 100644
|
||||
--- a/src/read.c
|
||||
+++ b/src/read.c
|
||||
@@ -37,6 +37,23 @@ static const size_t xmpContentTypeSize = sizeof(xmpContentType);
|
||||
// can't be more than 4 unique tuples right now.
|
||||
#define MAX_IPMA_VERSION_AND_FLAGS_SEEN 4
|
||||
|
||||
+// ---------------------------------------------------------------------------
|
||||
+// AVIF codec type (AV1 or AV2)
|
||||
+
|
||||
+static avifCodecType avifGetCodecType(const uint8_t * fourcc)
|
||||
+{
|
||||
+ if (!memcmp(fourcc, "av01", 4)) {
|
||||
+ return AVIF_CODEC_TYPE_AV1;
|
||||
+ }
|
||||
+#if defined(AVIF_CODEC_AVM)
|
||||
+ if (!memcmp(fourcc, "av02", 4)) {
|
||||
+ return AVIF_CODEC_TYPE_AV2;
|
||||
+ }
|
||||
+#endif
|
||||
+ return AVIF_CODEC_TYPE_UNKNOWN;
|
||||
+}
|
||||
+
|
||||
+
|
||||
// ---------------------------------------------------------------------------
|
||||
// Box data structures
|
||||
|
||||
@@ -1267,7 +1284,7 @@ static avifBool avifDecoderGenerateImageGridTiles(avifDecoder * decoder, avifIma
|
||||
|
||||
if (tilesRequested != tilesAvailable) {
|
||||
avifDiagnosticsPrintf(&decoder->diag,
|
||||
- "Grid image of dimensions %ux%u requires %u tiles, and only %u were found",
|
||||
+ "Grid image of dimensions %ux%u requires %u tiles, but %u were found",
|
||||
grid->columns,
|
||||
grid->rows,
|
||||
tilesRequested,
|
||||
@@ -3465,6 +3482,135 @@ static avifDecoderItem * avifDecoderDataFindItem(avifDecoderData * data, avifBoo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+// Returns AVIF_TRUE if item is an alpha auxiliary item of the parent color
|
||||
+// item.
|
||||
+static avifBool avifDecoderItemIsAlphaAux(avifDecoderItem * item, uint32_t colorItemId)
|
||||
+{
|
||||
+ if (item->auxForID != colorItemId)
|
||||
+ return AVIF_FALSE;
|
||||
+ const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC");
|
||||
+ return auxCProp && isAlphaURN(auxCProp->u.auxC.auxType);
|
||||
+}
|
||||
+
|
||||
+// Returns AVIF_TRUE if the item should be skipped. Items should be skipped for one of the following reasons:
|
||||
+// * Size is 0.
|
||||
+// * Has an essential property that isn't supported by libavif.
|
||||
+// * Item is not a single image or a grid.
|
||||
+// * Item is a thumbnail.
|
||||
+static avifBool avifDecoderItemShouldBeSkipped(const avifDecoderItem * item)
|
||||
+{
|
||||
+ return !item->size || item->hasUnsupportedEssentialProperty ||
|
||||
+ (avifGetCodecType(item->type) == AVIF_CODEC_TYPE_UNKNOWN && memcmp(item->type, "grid", 4)) || item->thumbnailForID != 0;
|
||||
+}
|
||||
+
|
||||
+// Finds the alpha item whose parent item is *colorItemPtr and sets it in the alphaItem output parameter. Returns AVIF_RESULT_OK
|
||||
+// on success. Note that *alphaItem can be NULL even if the return value is AVIF_RESULT_OK. If the *colorItemPtr is a grid and the
|
||||
+// alpha item is represented as a set of auxl items to each color tile, then a fake item will be created and *isAlphaItemInInput
|
||||
+// will be set to AVIF_FALSE. In this case, the alpha item merely exists to hold the locations of the alpha tile items. The data
|
||||
+// of this item need not be read and the pixi property cannot be validated. Otherwise, *isAlphaItemInInput will be set to
|
||||
+// AVIF_TRUE when *alphaItem is not NULL. If the data->meta->items array is resized, then the value in *colorItemPtr could become
|
||||
+// invalid. This function also resets *colorItemPtr to the right value if an alpha item was found and added to the data->meta->items
|
||||
+// array.
|
||||
+static avifResult avifDecoderDataFindAlphaItem(avifDecoderData * data,
|
||||
+ avifDecoderItem ** colorItemPtr,
|
||||
+ avifDecoderItem ** alphaItem,
|
||||
+ avifBool * isAlphaItemInInput)
|
||||
+{
|
||||
+ const avifDecoderItem * colorItem = *colorItemPtr;
|
||||
+ for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) {
|
||||
+ avifDecoderItem * item = &data->meta->items.item[itemIndex];
|
||||
+ if (avifDecoderItemShouldBeSkipped(item)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (avifDecoderItemIsAlphaAux(item, colorItem->id)) {
|
||||
+ *alphaItem = item;
|
||||
+ *isAlphaItemInInput = AVIF_TRUE;
|
||||
+ return AVIF_RESULT_OK;
|
||||
+ }
|
||||
+ }
|
||||
+ if (memcmp(colorItem->type, "grid", 4)) {
|
||||
+ *alphaItem = NULL;
|
||||
+ *isAlphaItemInInput = AVIF_FALSE;
|
||||
+ return AVIF_RESULT_OK;
|
||||
+ }
|
||||
+ // If color item is a grid, check if there is an alpha channel which is represented as an auxl item to each color tile
|
||||
+ // item.
|
||||
+ uint32_t colorItemCount = data->color.grid.rows * data->color.grid.columns;
|
||||
+ if (colorItemCount == 0) {
|
||||
+ *alphaItem = NULL;
|
||||
+ *isAlphaItemInInput = AVIF_FALSE;
|
||||
+ return AVIF_RESULT_OK;
|
||||
+ }
|
||||
+ uint32_t * alphaItemIndices = avifAlloc(colorItemCount * sizeof(uint32_t));
|
||||
+ AVIF_CHECKERR(alphaItemIndices, AVIF_RESULT_OUT_OF_MEMORY);
|
||||
+ uint32_t alphaItemCount = 0;
|
||||
+ uint32_t maxItemID = 0;
|
||||
+ for (uint32_t i = 0; i < colorItem->meta->items.count; ++i) {
|
||||
+ avifDecoderItem * item = &colorItem->meta->items.item[i];
|
||||
+ if (item->id > maxItemID) {
|
||||
+ maxItemID = item->id;
|
||||
+ }
|
||||
+ if (item->dimgForID == colorItem->id) {
|
||||
+ avifBool seenAlphaForCurrentItem = AVIF_FALSE;
|
||||
+ for (uint32_t j = 0; j < colorItem->meta->items.count; ++j) {
|
||||
+ avifDecoderItem * auxlItem = &colorItem->meta->items.item[j];
|
||||
+ if (avifDecoderItemIsAlphaAux(auxlItem, item->id)) {
|
||||
+ if (seenAlphaForCurrentItem || auxlItem->dimgForID != 0) {
|
||||
+ // One of the following invalid cases:
|
||||
+ // * Multiple items are claiming to be the alpha auxiliary of the current item.
|
||||
+ // * Alpha auxiliary is dimg for another item.
|
||||
+ avifFree(alphaItemIndices);
|
||||
+ *alphaItem = NULL;
|
||||
+ *isAlphaItemInInput = AVIF_FALSE;
|
||||
+ return AVIF_RESULT_INVALID_IMAGE_GRID;
|
||||
+ }
|
||||
+ alphaItemIndices[alphaItemCount++] = j;
|
||||
+ seenAlphaForCurrentItem = AVIF_TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!seenAlphaForCurrentItem) {
|
||||
+ // No alpha auxiliary item was found for the current item. Treat this as an image without alpha.
|
||||
+ avifFree(alphaItemIndices);
|
||||
+ *alphaItem = NULL;
|
||||
+ *isAlphaItemInInput = AVIF_FALSE;
|
||||
+ return AVIF_RESULT_OK;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ assert(alphaItemCount == colorItemCount);
|
||||
+
|
||||
+ int colorItemIndex = -1;
|
||||
+ for (uint32_t i = 0; i < data->meta->items.count; ++i) {
|
||||
+ if (colorItem->id == data->meta->items.item[i].id) {
|
||||
+ colorItemIndex = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ assert(colorItemIndex >= 0);
|
||||
+
|
||||
+ *alphaItem = avifMetaFindItem(colorItem->meta, maxItemID + 1);
|
||||
+ if (*alphaItem == NULL) {
|
||||
+ avifFree(alphaItemIndices);
|
||||
+ *isAlphaItemInInput = AVIF_FALSE;
|
||||
+ return AVIF_RESULT_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+ // avifMetaFindItem() could invalidate all existing item pointers. So reset the colorItem pointers.
|
||||
+ *colorItemPtr = &data->meta->items.item[colorItemIndex];
|
||||
+ colorItem = *colorItemPtr;
|
||||
+
|
||||
+ memcpy((*alphaItem)->type, "grid", 4);
|
||||
+ (*alphaItem)->width = colorItem->width;
|
||||
+ (*alphaItem)->height = colorItem->height;
|
||||
+ for (uint32_t i = 0; i < alphaItemCount; ++i) {
|
||||
+ avifDecoderItem * item = &colorItem->meta->items.item[alphaItemIndices[i]];
|
||||
+ item->dimgForID = (*alphaItem)->id;
|
||||
+ }
|
||||
+ avifFree(alphaItemIndices);
|
||||
+ *isAlphaItemInInput = AVIF_FALSE;
|
||||
+ data->alpha.grid = data->color.grid;
|
||||
+ return AVIF_RESULT_OK;
|
||||
+}
|
||||
+
|
||||
static avifResult avifDecoderGenerateImageTiles(avifDecoder * decoder, avifTileInfo * info, avifDecoderItem * item, avifBool alpha)
|
||||
{
|
||||
const uint32_t previousTileCount = decoder->data->tiles.count;
|
||||
@@ -3682,9 +3828,21 @@ avifResult avifDecoderReset(avifDecoder * decoder)
|
||||
decoder->imageDimensionLimit,
|
||||
data->diag),
|
||||
AVIF_RESULT_INVALID_IMAGE_GRID);
|
||||
+ // Validate that there are exactly the same number of dimg items to form the grid.
|
||||
+ uint32_t dimgItemCount = 0;
|
||||
+ for (uint32_t i = 0; i < colorItem->meta->items.count; ++i) {
|
||||
+ if (colorItem->meta->items.item[i].dimgForID == colorItem->id) {
|
||||
+ ++dimgItemCount;
|
||||
+ }
|
||||
+ }
|
||||
+ if (dimgItemCount != data->color.grid.rows * data->color.grid.columns) {
|
||||
+ return AVIF_RESULT_INVALID_IMAGE_GRID;
|
||||
+ }
|
||||
}
|
||||
|
||||
- avifDecoderItem * alphaItem = avifDecoderDataFindItem(data, /*alpha=*/AVIF_TRUE, /*parentItemID=*/colorItem->id);
|
||||
+ avifBool isAlphaItemInInput;
|
||||
+ avifDecoderItem * alphaItem;
|
||||
+ AVIF_CHECKRES(avifDecoderDataFindAlphaItem(data, &colorItem, &alphaItem, &isAlphaItemInInput));
|
||||
if (alphaItem && !memcmp(alphaItem->type, "grid", 4)) {
|
||||
avifROData readData;
|
||||
AVIF_CHECKRES(avifDecoderItemRead(alphaItem, decoder->io, &readData, 0, 0, data->diag));
|
||||
@@ -1 +1,2 @@
|
||||
enforce_an_upper_limit_of_715_million_path_verbs_in_skpath.patch
|
||||
avoid_combining_extremely_large_meshes.patch
|
||||
|
||||
31
patches/skia/avoid_combining_extremely_large_meshes.patch
Normal file
31
patches/skia/avoid_combining_extremely_large_meshes.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: John Stiles <johnstiles@google.com>
|
||||
Date: Fri, 24 Nov 2023 09:40:11 -0500
|
||||
Subject: Avoid combining extremely large meshes.
|
||||
|
||||
Bug: chromium:1505053
|
||||
Change-Id: I42f2ff872bbf054686ec7af0cc85ff63055fcfbf
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/782936
|
||||
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
|
||||
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
|
||||
Auto-Submit: John Stiles <johnstiles@google.com>
|
||||
|
||||
diff --git a/src/gpu/ganesh/ops/DrawMeshOp.cpp b/src/gpu/ganesh/ops/DrawMeshOp.cpp
|
||||
index b2db7d873a2b2709b474c7a736b3142bc47e1889..fa35a6d72a6600c87ee22ece089c4c631de78ede 100644
|
||||
--- a/src/gpu/ganesh/ops/DrawMeshOp.cpp
|
||||
+++ b/src/gpu/ganesh/ops/DrawMeshOp.cpp
|
||||
@@ -1000,10 +1000,13 @@ GrOp::CombineResult MeshOp::onCombineIfPossible(GrOp* t, SkArenaAlloc*, const Gr
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
|
||||
+ if (fVertexCount > INT32_MAX - that->fVertexCount) {
|
||||
+ return CombineResult::kCannotCombine;
|
||||
+ }
|
||||
if (SkToBool(fIndexCount) != SkToBool(that->fIndexCount)) {
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
- if (SkToBool(fIndexCount) && fVertexCount + that->fVertexCount > SkToInt(UINT16_MAX)) {
|
||||
+ if (SkToBool(fIndexCount) && fVertexCount > UINT16_MAX - that->fVertexCount) {
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user