Browse Source

IDLGenerators: Throw TypeError if IDL ByteString contains element > 255

Tim Ledbetter 7 months ago
parent
commit
19a5780f0c

+ 27 - 0
Libraries/LibWeb/WebIDL/AbstractOperations.cpp

@@ -225,6 +225,33 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String
     return clean_up_on_return(stored_realm, relevant_realm, completion, callback.operation_returns_promise);
 }
 
+// https://webidl.spec.whatwg.org/#ref-for-idl-ByteString%E2%91%A7
+JS::ThrowCompletionOr<String> to_byte_string(JS::VM& vm, JS::Value value)
+{
+    // 1. Let x be ? ToString(V).
+    auto x = TRY(value.to_string(vm));
+
+    // 2. If the value of any element of x is greater than 255, then throw a TypeError.
+    for (auto character : x.code_points()) {
+        if (character > 0xFF)
+            return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidCodePoint);
+    }
+
+    // 3. Return an IDL ByteString value whose length is the length of x, and where the value of each element is the value of the corresponding element of x.
+    // FIXME: This should return a ByteString.
+    return x;
+}
+
+JS::ThrowCompletionOr<String> to_string(JS::VM& vm, JS::Value value)
+{
+    return value.to_string(vm);
+}
+
+JS::ThrowCompletionOr<String> to_usv_string(JS::VM& vm, JS::Value value)
+{
+    return value.to_well_formed_string(vm);
+}
+
 // https://webidl.spec.whatwg.org/#invoke-a-callback-function
 // https://whatpr.org/webidl/1437.html#invoke-a-callback-function
 JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional<JS::Value> this_argument, GC::MarkedVector<JS::Value> args)

+ 4 - 0
Libraries/LibWeb/WebIDL/AbstractOperations.h

@@ -23,6 +23,10 @@ ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source);
 
 JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, GC::MarkedVector<JS::Value> args);
 
+JS::ThrowCompletionOr<String> to_string(JS::VM&, JS::Value);
+JS::ThrowCompletionOr<String> to_usv_string(JS::VM&, JS::Value);
+JS::ThrowCompletionOr<String> to_byte_string(JS::VM&, JS::Value);
+
 // https://webidl.spec.whatwg.org/#call-a-user-objects-operation
 template<typename... Args>
 JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, Args&&... args)

+ 10 - 7
Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp

@@ -342,10 +342,13 @@ static void emit_includes_for_all_imports(auto& interface, auto& generator, bool
 template<typename ParameterType>
 static void generate_to_string(SourceGenerator& scoped_generator, ParameterType const& parameter, bool variadic, bool optional, Optional<ByteString> const& optional_default_value)
 {
-    if (parameter.type->name() == "USVString")
-        scoped_generator.set("to_string", "to_well_formed_string"sv);
-    else
+    if (parameter.type->name() == "USVString") {
+        scoped_generator.set("to_string", "to_usv_string"sv);
+    } else if (parameter.type->name() == "ByteString") {
+        scoped_generator.set("to_string", "to_byte_string"sv);
+    } else {
         scoped_generator.set("to_string", "to_string"sv);
+    }
 
     if (variadic) {
         scoped_generator.append(R"~~~(
@@ -355,7 +358,7 @@ static void generate_to_string(SourceGenerator& scoped_generator, ParameterType
         @cpp_name@.ensure_capacity(vm.argument_count() - @js_suffix@);
 
         for (size_t i = @js_suffix@; i < vm.argument_count(); ++i) {
-            auto to_string_result = TRY(vm.argument(i).@to_string@(vm));
+            auto to_string_result = TRY(WebIDL::@to_string@(vm, vm.argument(i)));
             @cpp_name@.unchecked_append(move(to_string_result));
         }
     }
@@ -365,14 +368,14 @@ static void generate_to_string(SourceGenerator& scoped_generator, ParameterType
             scoped_generator.append(R"~~~(
     @string_type@ @cpp_name@;
     if (!@legacy_null_to_empty_string@ || !@js_name@@js_suffix@.is_null()) {
-        @cpp_name@ = TRY(@js_name@@js_suffix@.@to_string@(vm));
+        @cpp_name@ = TRY(WebIDL::@to_string@(vm, @js_name@@js_suffix@));
     }
 )~~~");
         } else {
             scoped_generator.append(R"~~~(
     Optional<@string_type@> @cpp_name@;
     if (!@js_name@@js_suffix@.is_nullish())
-        @cpp_name@ = TRY(@js_name@@js_suffix@.@to_string@(vm));
+        @cpp_name@ = TRY(WebIDL::@to_string@(vm, @js_name@@js_suffix@));
 )~~~");
         }
     } else {
@@ -390,7 +393,7 @@ static void generate_to_string(SourceGenerator& scoped_generator, ParameterType
         scoped_generator.append(R"~~~(
     if (!@js_name@@js_suffix@.is_undefined()) {
         if (!@legacy_null_to_empty_string@ || !@js_name@@js_suffix@.is_null())
-            @cpp_name@ = TRY(@js_name@@js_suffix@.@to_string@(vm));
+            @cpp_name@ = TRY(WebIDL::@to_string@(vm, @js_name@@js_suffix@));
     })~~~");
         if (!may_be_null) {
             scoped_generator.append(R"~~~( else {