1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 21:07:34 +00:00

LibJS+Everywhere: Make PrimitiveString and Utf16String fallible

This makes construction of Utf16String fallible in OOM conditions. The
immediate impact is that PrimitiveString must then be fallible as well,
as it may either transcode UTF-8 to UTF-16, or create a UTF-16 string
from ropes.

There are a couple of places where it is very non-trivial to propagate
the error further. A FIXME has been added to those locations.
This commit is contained in:
Timothy Flynn 2023-01-07 12:24:05 -05:00 committed by Linus Groh
parent d793262beb
commit 115baa7e32
57 changed files with 306 additions and 295 deletions

View file

@ -146,8 +146,8 @@ ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey c
if (!values.is_empty()) {
// NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
VERIFY(value.is_string());
if (!values.contains_slow(value.as_string().deprecated_string()))
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value.as_string().deprecated_string(), property.as_string());
if (auto const& value_string = TRY(value.as_string().deprecated_string()); !values.contains_slow(value_string))
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value_string, property.as_string());
}
// 9. Return value.
@ -165,7 +165,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_overflow(VM& vm, Object const* o
auto option = TRY(get_option(vm, *options, vm.names.overflow, OptionType::String, { "constrain"sv, "reject"sv }, "constrain"sv));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.5 ToTemporalDisambiguation ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation
@ -179,7 +179,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_disambiguation(VM& vm, Object co
auto option = TRY(get_option(vm, *options, vm.names.disambiguation, OptionType::String, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, "compatible"sv));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.6 ToTemporalRoundingMode ( normalizedOptions, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingmode
@ -202,7 +202,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_rounding_mode(VM& vm, Object con
fallback.view()));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.7 NegateTemporalRoundingMode ( roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-negatetemporalroundingmode
@ -239,7 +239,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_offset(VM& vm, Object const* opt
auto option = TRY(get_option(vm, *options, vm.names.offset, OptionType::String, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, fallback.view()));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.9 ToCalendarNameOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-tocalendarnameoption
@ -249,7 +249,7 @@ ThrowCompletionOr<DeprecatedString> to_calendar_name_option(VM& vm, Object const
auto option = TRY(get_option(vm, normalized_options, vm.names.calendarName, OptionType::String, { "auto"sv, "always"sv, "never"sv, "critical"sv }, "auto"sv));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.10 ToTimeZoneNameOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totimezonenameoption
@ -259,7 +259,7 @@ ThrowCompletionOr<DeprecatedString> to_time_zone_name_option(VM& vm, Object cons
auto option = TRY(get_option(vm, normalized_options, vm.names.timeZoneName, OptionType::String, { "auto"sv, "never"sv, "critical"sv }, "auto"sv));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.11 ToShowOffsetOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-toshowoffsetoption
@ -269,7 +269,7 @@ ThrowCompletionOr<DeprecatedString> to_show_offset_option(VM& vm, Object const&
auto option = TRY(get_option(vm, normalized_options, vm.names.offset, OptionType::String, { "auto"sv, "never"sv }, "auto"sv));
VERIFY(option.is_string());
return option.as_string().deprecated_string();
return TRY(option.as_string().deprecated_string());
}
// 13.12 ToTemporalRoundingIncrement ( normalizedOptions, dividend, inclusive ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingincrement
@ -530,7 +530,7 @@ ThrowCompletionOr<Optional<DeprecatedString>> get_temporal_unit(VM& vm, Object c
Optional<DeprecatedString> value = option_value.is_undefined()
? Optional<DeprecatedString> {}
: option_value.as_string().deprecated_string();
: TRY(option_value.as_string().deprecated_string());
// 11. If value is listed in the Plural column of Table 13, then
for (auto const& row : temporal_units) {

View file

@ -126,7 +126,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> calendar_fields(VM& vm, Object& cale
Vector<DeprecatedString> result;
for (auto& value : list)
result.append(value.as_string().deprecated_string());
result.append(TRY(value.as_string().deprecated_string()));
return result;
}
@ -781,7 +781,7 @@ ThrowCompletionOr<double> resolve_iso_month(VM& vm, Object const& fields)
// 6. Assert: Type(monthCode) is String.
VERIFY(month_code.is_string());
auto& month_code_string = month_code.as_string().deprecated_string();
auto const& month_code_string = TRY(month_code.as_string().deprecated_string());
// 7. If the length of monthCode is not 3, throw a RangeError exception.
auto month_length = month_code_string.length();
@ -943,7 +943,7 @@ ThrowCompletionOr<Object*> default_merge_calendar_fields(VM& vm, Object const& f
// 3. For each element key of fieldsKeys, do
for (auto& key : fields_keys) {
// a. If key is not "month" or "monthCode", then
if (key.as_string().deprecated_string() != vm.names.month.as_string() && key.as_string().deprecated_string() != vm.names.monthCode.as_string()) {
if (!TRY(key.as_string().deprecated_string()).is_one_of(vm.names.month.as_string(), vm.names.monthCode.as_string())) {
auto property_key = MUST(PropertyKey::from_value(vm, key));
// i. Let propValue be ? Get(fields, key).
@ -977,7 +977,7 @@ ThrowCompletionOr<Object*> default_merge_calendar_fields(VM& vm, Object const& f
}
// See comment above.
additional_fields_keys_contains_month_or_month_code_property |= key.as_string().deprecated_string() == vm.names.month.as_string() || key.as_string().deprecated_string() == vm.names.monthCode.as_string();
additional_fields_keys_contains_month_or_month_code_property |= TRY(key.as_string().deprecated_string()) == vm.names.month.as_string() || TRY(key.as_string().deprecated_string()) == vm.names.monthCode.as_string();
}
// 6. If additionalFieldsKeys does not contain either "month" or "monthCode", then

View file

@ -559,19 +559,21 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
return TRY(iterator_close(vm, iterator_record, move(completion)));
}
auto const& next_value_string = TRY(next_value.as_string().deprecated_string());
// iii. If fieldNames contains nextValue, then
if (field_names.contains_slow(next_value)) {
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value.as_string().deprecated_string());
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value_string);
// 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(vm, iterator_record, move(completion)));
}
// iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
if (!next_value.as_string().deprecated_string().is_one_of("year"sv, "month"sv, "monthCode"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
if (!next_value_string.is_one_of("year"sv, "month"sv, "monthCode"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().deprecated_string());
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value_string);
// 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(vm, iterator_record, move(completion)));

View file

@ -801,7 +801,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with)
// 18. Assert: Type(offsetString) is String.
VERIFY(offset_string_value.is_string());
auto const& offset_string = offset_string_value.as_string().deprecated_string();
auto const& offset_string = TRY(offset_string_value.as_string().deprecated_string());
// 19. Let dateTimeResult be ? InterpretTemporalDateTimeFields(calendar, fields, options).
auto date_time_result = TRY(interpret_temporal_date_time_fields(vm, calendar, *fields, *options));