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; 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/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)); 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(); 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); 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 e7b76f7da11..820ca28bf1d 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; } 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; + }