From 0e1cda420f6db3f2486db54e2bc2f6be188f047d Mon Sep 17 00:00:00 2001 From: John Breton <55368611+john-breton@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:38:56 -0400 Subject: [PATCH 1/6] Fix double free in ContentEncoding Origin: https://github.com/webmproject/libvpx/commit/6a7c84a2449dcc70de2525df209afea908622399 Author: James Zern ----- This is a security fix for CVE-2019-2126. Godot currently contains a vulnerable version of libwebm in its 3.6 branch that is susceptible to a double free due to a missing reset of a freed pointer. This commit corrects that issue. --- .../libsimplewebm/libwebm/mkvparser/mkvparser.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc index e7b76f7da11..83e8aa9e4a5 100644 --- a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc +++ b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc @@ -4232,6 +4232,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, new (std::nothrow) ContentEncryption*[encryption_count]; if (!encryption_entries_) { delete[] compression_entries_; + compression_entries_ = NULL; return -1; } encryption_entries_end_ = encryption_entries_; @@ -4263,6 +4264,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, delete compression; return status; } + assert(compression_count > 0); *compression_entries_end_++ = compression; } else if (id == libwebm::kMkvContentEncryption) { ContentEncryption* const encryption = @@ -4275,6 +4277,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, delete encryption; return status; } + assert(encryption_count > 0); *encryption_entries_end_++ = encryption; } @@ -4326,7 +4329,12 @@ long ContentEncoding::ParseCompressionEntry(long long start, long long size, delete[] buf; return status; } - + // There should be only one settings element per content compression. + if (compression->settings != NULL) { + delete[] buf; + return E_FILE_FORMAT_INVALID; + } + compression->settings = buf; compression->settings_len = buflen; } From 45e30e4438134a8dd873ae5a10fdf5e079193088 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Thu, 19 Jun 2025 12:06:28 +0800 Subject: [PATCH 2/6] Revert "Fix Button not listing `hover_pressed` stylebox" This reverts commit cc11089786de6fc84a58f4b0af004997131b5b02. (cherry picked from commit 62feeaab33d3e753790bc99b3d1a07b9a9c9661b) --- doc/classes/Button.xml | 3 --- scene/resources/default_theme/default_theme.cpp | 1 - 2 files changed, 4 deletions(-) diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index 6ea73ca4075..a520fbbd0fb 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -113,9 +113,6 @@ [StyleBox] used when the [Button] is being hovered. - - [StyleBox] used when the [Button] is being hovered and pressed. - Default [StyleBox] for the [Button]. diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index bb94d2e22c5..375d711e4d5 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -230,7 +230,6 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const theme->set_stylebox("normal", "Button", sb_button_normal); theme->set_stylebox("pressed", "Button", sb_button_pressed); theme->set_stylebox("hover", "Button", sb_button_hover); - theme->set_stylebox("hover_pressed", "Button", sb_button_hover); theme->set_stylebox("disabled", "Button", sb_button_disabled); theme->set_stylebox("focus", "Button", sb_button_focus); From 6ba38858f691f014e3a258efc74207c215c9fa39 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Wed, 16 Oct 2024 20:23:59 +0800 Subject: [PATCH 3/6] Cache results for `TranslationServer.compare_locales()` (cherry picked from commit 7ebb63628d01a1d42a354c33a2898c0f4cd4c542) --- core/translation.cpp | 40 +++++++++++++++++++++++++++------------- core/translation.h | 2 ++ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/core/translation.cpp b/core/translation.cpp index 4ad17f1d159..0db222494e7 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -359,32 +359,46 @@ String TranslationServer::standardize_locale(const String &p_locale) const { } int TranslationServer::compare_locales(const String &p_locale_a, const String &p_locale_b) const { + if (p_locale_a == p_locale_b) { + // Exact match. + return 10; + } + + const String cache_key = p_locale_a + "|" + p_locale_b; + const int *cached_result = locale_compare_cache.getptr(cache_key); + if (cached_result) { + return *cached_result; + } + String locale_a = standardize_locale(p_locale_a); String locale_b = standardize_locale(p_locale_b); if (locale_a == locale_b) { // Exact match. + locale_compare_cache.set(cache_key, 10); return 10; } Vector locale_a_elements = locale_a.split("_"); Vector locale_b_elements = locale_b.split("_"); - if (locale_a_elements[0] == locale_b_elements[0]) { - // Matching language, both locales have extra parts. - // Return number of matching elements. - int matching_elements = 1; - for (int i = 1; i < locale_a_elements.size(); i++) { - for (int j = 1; j < locale_b_elements.size(); j++) { - if (locale_a_elements[i] == locale_b_elements[j]) { - matching_elements++; - } - } - } - return matching_elements; - } else { + if (locale_a_elements[0] != locale_b_elements[0]) { // No match. + locale_compare_cache.set(cache_key, 0); return 0; } + + // Matching language, both locales have extra parts. + // Return number of matching elements. + int matching_elements = 1; + for (int i = 1; i < locale_a_elements.size(); i++) { + for (int j = 1; j < locale_b_elements.size(); j++) { + if (locale_a_elements[i] == locale_b_elements[j]) { + matching_elements++; + } + } + } + locale_compare_cache.set(cache_key, matching_elements); + return matching_elements; } String TranslationServer::get_locale_name(const String &p_locale) const { diff --git a/core/translation.h b/core/translation.h index d4b2b0fb5fa..815c0409e57 100644 --- a/core/translation.h +++ b/core/translation.h @@ -87,6 +87,8 @@ class TranslationServer : public Object { Ref tool_translation; Ref doc_translation; + mutable HashMap locale_compare_cache; + bool enabled; static TranslationServer *singleton; From d240313513ada7654ea587836052a2f8cd31ed60 Mon Sep 17 00:00:00 2001 From: DeeJayLSP Date: Thu, 19 Jun 2025 00:02:40 -0300 Subject: [PATCH 4/6] [3.x] ResourceImporterWAV: Detect if data chunk size is larger than the actual size (cherry picked from commit 57159bcb8c352c33d972e8a8de6a2f4dd9748b38) --- editor/import/resource_importer_wav.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index f03c49dcd6c..22904cc9d29 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -111,7 +111,15 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } /* GET FILESIZE */ - file->get_32(); // filesize + + // The file size in header is 8 bytes less than the actual size. + // See https://docs.fileformat.com/audio/wav/ + const int FILE_SIZE_HEADER_OFFSET = 8; + uint32_t file_size_header = file->get_32() + FILE_SIZE_HEADER_OFFSET; + uint64_t file_size = file->get_len(); + if (file_size != file_size_header) { + WARN_PRINT(vformat("File size %d is %s than the expected size %d.", file_size, file_size > file_size_header ? "larger" : "smaller", file_size_header)); + } /* CHECK WAVE */ @@ -208,7 +216,12 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s break; } + uint64_t remaining_bytes = file_size - file_pos; frames = chunksize; + if (remaining_bytes < chunksize) { + WARN_PRINT("Data chunk size is smaller than expected. Proceeding with actual data size."); + frames = remaining_bytes; + } if (format_channels == 0) { file->close(); From 49966f6927a5f7bd7f6ea12ffe7fe5073fd9fc72 Mon Sep 17 00:00:00 2001 From: John Breton <55368611+john-breton@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:38:56 -0400 Subject: [PATCH 5/6] libwebm: Fix double free in mkvparser ContentEncoding Origin: https://github.com/webmproject/libvpx/commit/6a7c84a2449dcc70de2525df209afea908622399 Author: James Zern ----- This is a security fix for CVE-2019-2126. Godot currently contains a vulnerable version of libwebm in its 3.x branch that is susceptible to a double free due to a missing reset of a freed pointer. This commit corrects that issue. (cherry picked from commit 53d8b958c5237e685b20ed24fbe85289099ea70e) --- thirdparty/README.md | 1 + .../libwebm/mkvparser/mkvparser.cc | 3 +- .../patches/libwebm-CVE-2019-2126.patch | 41 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 thirdparty/libsimplewebm/patches/libwebm-CVE-2019-2126.patch diff --git a/thirdparty/README.md b/thirdparty/README.md index a0f7a13693e..ded611af900 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -220,6 +220,7 @@ Files extracted from upstream source: Important: Some files have Godot-made changes. They are marked with `// -- GODOT start --` and `// -- GODOT end --` comments. +A patch is included to fix CVE-2019-2126 in libwebm. ## libtheora diff --git a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc index 83e8aa9e4a5..820ca28bf1d 100644 --- a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc +++ b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc @@ -4329,12 +4329,13 @@ long ContentEncoding::ParseCompressionEntry(long long start, long long size, delete[] buf; return status; } + // There should be only one settings element per content compression. if (compression->settings != NULL) { delete[] buf; return E_FILE_FORMAT_INVALID; } - + compression->settings = buf; compression->settings_len = buflen; } diff --git a/thirdparty/libsimplewebm/patches/libwebm-CVE-2019-2126.patch b/thirdparty/libsimplewebm/patches/libwebm-CVE-2019-2126.patch new file mode 100644 index 00000000000..755be8ec55a --- /dev/null +++ b/thirdparty/libsimplewebm/patches/libwebm-CVE-2019-2126.patch @@ -0,0 +1,41 @@ +diff --git a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc +index e7b76f7da1..820ca28bf1 100644 +--- a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc ++++ b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc +@@ -4232,6 +4232,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, + new (std::nothrow) ContentEncryption*[encryption_count]; + if (!encryption_entries_) { + delete[] compression_entries_; ++ compression_entries_ = NULL; + return -1; + } + encryption_entries_end_ = encryption_entries_; +@@ -4263,6 +4264,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, + delete compression; + return status; + } ++ assert(compression_count > 0); + *compression_entries_end_++ = compression; + } else if (id == libwebm::kMkvContentEncryption) { + ContentEncryption* const encryption = +@@ -4275,6 +4277,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, + delete encryption; + return status; + } ++ assert(encryption_count > 0); + *encryption_entries_end_++ = encryption; + } + +@@ -4327,6 +4330,12 @@ long ContentEncoding::ParseCompressionEntry(long long start, long long size, + return status; + } + ++ // There should be only one settings element per content compression. ++ if (compression->settings != NULL) { ++ delete[] buf; ++ return E_FILE_FORMAT_INVALID; ++ } ++ + compression->settings = buf; + compression->settings_len = buflen; + } From 7e369e13123b5020307855d4addab3c42e5a8b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Sun, 10 Nov 2024 21:45:32 +0200 Subject: [PATCH 6/6] [Windows] Rename `PKEY_Device_FriendlyName` to avoid duplicate symbols with newer MinGW SDKs. (cherry picked from commit c363e130519281d9bdaf421d9ba84ad33564d38d) --- drivers/wasapi/audio_driver_wasapi.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 330f1ae7244..1cb4ab37f0e 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -37,7 +37,7 @@ #include -#ifndef PKEY_Device_FriendlyName +#ifndef PKEY_Device_FriendlyNameGodot #undef DEFINE_PROPERTYKEY /* clang-format off */ @@ -45,7 +45,7 @@ const PROPERTYKEY id = { { a, b, c, { d, e, f, g, h, i, j, k, } }, l }; /* clang-format on */ -DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); +DEFINE_PROPERTYKEY(PKEY_Device_FriendlyNameGodot, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); #endif const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); @@ -178,7 +178,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c PROPVARIANT propvar; PropVariantInit(&propvar); - hr = props->GetValue(PKEY_Device_FriendlyName, &propvar); + hr = props->GetValue(PKEY_Device_FriendlyNameGodot, &propvar); ERR_BREAK(hr != S_OK); if (p_device->device_name == String(propvar.pwszVal)) { @@ -449,7 +449,7 @@ Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) { PROPVARIANT propvar; PropVariantInit(&propvar); - hr = props->GetValue(PKEY_Device_FriendlyName, &propvar); + hr = props->GetValue(PKEY_Device_FriendlyNameGodot, &propvar); ERR_BREAK(hr != S_OK); list.push_back(String(propvar.pwszVal));