1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-19 13:17:39 +00:00

LibJS: Stop propagating small OOM errors from Intl.DurationFormat

This commit is contained in:
Timothy Flynn 2023-08-30 11:35:04 -04:00 committed by Andreas Kling
parent b78cbf88db
commit 20aaa2c236
4 changed files with 23 additions and 23 deletions

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/StringBuilder.h>
#include <LibJS/Runtime/AbstractOperations.h> #include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/DurationFormat.h> #include <LibJS/Runtime/Intl/DurationFormat.h>
@ -15,7 +16,6 @@
#include <LibJS/Runtime/Intl/PluralRulesConstructor.h> #include <LibJS/Runtime/Intl/PluralRulesConstructor.h>
#include <LibJS/Runtime/Intl/RelativeTimeFormat.h> #include <LibJS/Runtime/Intl/RelativeTimeFormat.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h> #include <LibJS/Runtime/Temporal/AbstractOperations.h>
#include <LibJS/Runtime/ThrowableStringBuilder.h>
namespace JS::Intl { namespace JS::Intl {
@ -313,7 +313,7 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, String
} }
// 4. Let displayField be the string-concatenation of unit and "Display". // 4. Let displayField be the string-concatenation of unit and "Display".
auto display_field = TRY_OR_THROW_OOM(vm, String::formatted("{}Display", unit)); auto display_field = MUST(String::formatted("{}Display", unit));
// 5. Let display be ? GetOption(options, displayField, string, « "auto", "always" », displayDefault). // 5. Let display be ? GetOption(options, displayField, string, « "auto", "always" », displayDefault).
auto display = TRY(get_option(vm, options, display_field.to_deprecated_string(), OptionType::String, { "auto"sv, "always"sv }, display_default)); auto display = TRY(get_option(vm, options, display_field.to_deprecated_string(), OptionType::String, { "auto"sv, "always"sv }, display_default));
@ -333,11 +333,11 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, String
} }
// 7. Return the Record { [[Style]]: style, [[Display]]: display }. // 7. Return the Record { [[Style]]: style, [[Display]]: display }.
return DurationUnitOptions { .style = TRY_OR_THROW_OOM(vm, String::from_utf8(style)), .display = display.as_string().utf8_string() }; return DurationUnitOptions { .style = MUST(String::from_utf8(style)), .display = display.as_string().utf8_string() };
} }
// 1.1.7 PartitionDurationFormatPattern ( durationFormat, duration ), https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern // 1.1.7 PartitionDurationFormatPattern ( durationFormat, duration ), https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern
ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM& vm, DurationFormat const& duration_format, Temporal::DurationRecord const& duration) Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationFormat const& duration_format, Temporal::DurationRecord const& duration)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
@ -446,10 +446,10 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
// 3. Let dataLocaleData be %DurationFormat%.[[LocaleData]].[[<dataLocale>]]. // 3. Let dataLocaleData be %DurationFormat%.[[LocaleData]].[[<dataLocale>]].
// 4. Let num be ! FormatNumeric(nf, 𝔽(value)). // 4. Let num be ! FormatNumeric(nf, 𝔽(value)).
auto number = MUST_OR_THROW_OOM(format_numeric(vm, *number_format, MathematicalValue(value))); auto number = MUST(format_numeric(vm, *number_format, MathematicalValue(value)));
// 5. Append the new Record { [[Type]]: unit, [[Value]]: num} to the end of result. // 5. Append the new Record { [[Type]]: unit, [[Value]]: num} to the end of result.
TRY_OR_THROW_OOM(vm, result.try_append({ unit, move(number) })); result.append({ unit, move(number) });
// 6. If unit is "hours" or "minutes", then // 6. If unit is "hours" or "minutes", then
if (unit.is_one_of("hours"sv, "minutes"sv)) { if (unit.is_one_of("hours"sv, "minutes"sv)) {
@ -485,7 +485,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
auto separator = ::Locale::get_number_system_symbol(data_locale, duration_format.numbering_system(), ::Locale::NumericSymbol::TimeSeparator).value_or(":"sv); auto separator = ::Locale::get_number_system_symbol(data_locale, duration_format.numbering_system(), ::Locale::NumericSymbol::TimeSeparator).value_or(":"sv);
// ii. Append the new Record { [[Type]]: "literal", [[Value]]: separator} to the end of result. // ii. Append the new Record { [[Type]]: "literal", [[Value]]: separator} to the end of result.
TRY_OR_THROW_OOM(vm, result.try_append({ "literal"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(separator)) })); result.append({ "literal"sv, MUST(String::from_utf8(separator)) });
} }
} }
} }
@ -505,19 +505,19 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)).ptr()); auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)).ptr());
// 5. Let parts be ! PartitionNumberPattern(nf, 𝔽(value)). // 5. Let parts be ! PartitionNumberPattern(nf, 𝔽(value)).
auto parts = MUST_OR_THROW_OOM(partition_number_pattern(vm, *number_format, MathematicalValue(value))); auto parts = MUST(partition_number_pattern(vm, *number_format, MathematicalValue(value)));
// 6. Let concat be an empty String. // 6. Let concat be an empty String.
ThrowableStringBuilder concat(vm); StringBuilder concat;
// 7. For each Record { [[Type]], [[Value]], [[Unit]] } part in parts, do // 7. For each Record { [[Type]], [[Value]], [[Unit]] } part in parts, do
for (auto const& part : parts) { for (auto const& part : parts) {
// a. Set concat to the string-concatenation of concat and part.[[Value]]. // a. Set concat to the string-concatenation of concat and part.[[Value]].
TRY(concat.append(part.value)); concat.append(part.value);
} }
// 8. Append the new Record { [[Type]]: unit, [[Value]]: concat } to the end of result. // 8. Append the new Record { [[Type]]: unit, [[Value]]: concat } to the end of result.
TRY_OR_THROW_OOM(vm, result.try_append({ unit, MUST_OR_THROW_OOM(concat.to_string()) })); result.append({ unit, MUST(concat.to_string()) });
} }
} }
} }
@ -552,20 +552,20 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
for (size_t i = 0; i < result.size(); ++i) { for (size_t i = 0; i < result.size(); ++i) {
auto const& part = result[i]; auto const& part = result[i];
if (part.type == "literal") { if (part.type == "literal") {
string_result.last() = TRY_OR_THROW_OOM(vm, String::formatted("{}{}", string_result.last(), part.value)); string_result.last() = MUST(String::formatted("{}{}", string_result.last(), part.value));
merge = true; merge = true;
continue; continue;
} }
if (merge) { if (merge) {
string_result.last() = TRY_OR_THROW_OOM(vm, String::formatted("{}{}", string_result.last(), part.value)); string_result.last() = MUST(String::formatted("{}{}", string_result.last(), part.value));
merge = false; merge = false;
continue; continue;
} }
TRY_OR_THROW_OOM(vm, string_result.try_append(part.value)); string_result.append(part.value);
} }
// 10. Set result to ! CreatePartsFromList(lf, result). // 10. Set result to ! CreatePartsFromList(lf, result).
auto final_result = MUST_OR_THROW_OOM(create_parts_from_list(vm, *list_format, string_result)); auto final_result = MUST(create_parts_from_list(vm, *list_format, string_result));
// 11. Return result. // 11. Return result.
return final_result; return final_result;

View file

@ -225,6 +225,6 @@ ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(VM&, Value input)
i8 duration_record_sign(Temporal::DurationRecord const&); i8 duration_record_sign(Temporal::DurationRecord const&);
bool is_valid_duration_record(Temporal::DurationRecord const&); bool is_valid_duration_record(Temporal::DurationRecord const&);
ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM&, String const& unit, Object const& options, StringView base_style, ReadonlySpan<StringView> styles_list, StringView digital_base, StringView previous_style); ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM&, String const& unit, Object const& options, StringView base_style, ReadonlySpan<StringView> styles_list, StringView digital_base, StringView previous_style);
ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM&, DurationFormat const&, Temporal::DurationRecord const& duration); Vector<PatternPartition> partition_duration_format_pattern(VM&, DurationFormat const&, Temporal::DurationRecord const& duration);
} }

View file

@ -110,7 +110,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DurationFormatConstructor::construct(Fun
auto display_slot = duration_instances_component.set_display_slot; auto display_slot = duration_instances_component.set_display_slot;
// c. Let unit be the Unit value. // c. Let unit be the Unit value.
auto unit = TRY_OR_THROW_OOM(vm, String::from_utf8(duration_instances_component.unit)); auto unit = MUST(String::from_utf8(duration_instances_component.unit));
// d. Let valueList be the Values value. // d. Let valueList be the Values value.
auto value_list = duration_instances_component.values; auto value_list = duration_instances_component.values;

View file

@ -5,10 +5,10 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/StringBuilder.h>
#include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/DurationFormatPrototype.h> #include <LibJS/Runtime/Intl/DurationFormatPrototype.h>
#include <LibJS/Runtime/ThrowableStringBuilder.h>
namespace JS::Intl { namespace JS::Intl {
@ -44,19 +44,19 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format)
auto record = TRY(to_duration_record(vm, vm.argument(0))); auto record = TRY(to_duration_record(vm, vm.argument(0)));
// 4. Let parts be PartitionDurationFormatPattern(df, record). // 4. Let parts be PartitionDurationFormatPattern(df, record).
auto parts = MUST_OR_THROW_OOM(partition_duration_format_pattern(vm, duration_format, record)); auto parts = partition_duration_format_pattern(vm, duration_format, record);
// 5. Let result be a new empty String. // 5. Let result be a new empty String.
ThrowableStringBuilder result(vm); StringBuilder result;
// 6. For each Record { [[Type]], [[Value]] } part in parts, do // 6. For each Record { [[Type]], [[Value]] } part in parts, do
for (auto const& part : parts) { for (auto const& part : parts) {
// a. Set result to the string-concatenation of result and part.[[Value]]. // a. Set result to the string-concatenation of result and part.[[Value]].
MUST_OR_THROW_OOM(result.append(part.value)); result.append(part.value);
} }
// 7. Return result. // 7. Return result.
return PrimitiveString::create(vm, MUST_OR_THROW_OOM(result.to_string())); return PrimitiveString::create(vm, MUST(result.to_string()));
} }
// 1.4.4 Intl.DurationFormat.prototype.formatToParts ( duration ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.formatToParts // 1.4.4 Intl.DurationFormat.prototype.formatToParts ( duration ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.formatToParts
@ -72,7 +72,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
auto record = TRY(to_duration_record(vm, vm.argument(0))); auto record = TRY(to_duration_record(vm, vm.argument(0)));
// 4. Let parts be PartitionDurationFormatPattern(df, record). // 4. Let parts be PartitionDurationFormatPattern(df, record).
auto parts = MUST_OR_THROW_OOM(partition_duration_format_pattern(vm, duration_format, record)); auto parts = partition_duration_format_pattern(vm, duration_format, record);
// 5. Let result be ! ArrayCreate(0). // 5. Let result be ! ArrayCreate(0).
auto result = MUST(Array::create(realm, 0)); auto result = MUST(Array::create(realm, 0));