From e6dc3c291e6f431044a764ed3c32c98216e0497c Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 14 Mar 2023 12:16:33 -0400 Subject: [PATCH] LibWeb: Prevent variadic arguments from reserving heaps of memory Don't try to reserve capacity for a variadic arguments list unless we actually have enough arguments to fill it with anything. Otherwise we may overflow to an extremely large size if, e.g., the argument count is 0 and the start of the variadic arguments is index 1. --- .../BindingsGenerator/IDLGenerators.cpp | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index f527f1a14f..eefe3109af 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -265,11 +265,14 @@ static void generate_to_deprecated_string(SourceGenerator& scoped_generator, Par if (variadic) { scoped_generator.append(R"~~~( Vector @cpp_name@; - @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_deprecated_string(vm)); - @cpp_name@.append(move(to_string_result)); + if (vm.argument_count() > @js_suffix@) { + TRY_OR_THROW_OOM(vm, @cpp_name@.try_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_deprecated_string(vm)); + @cpp_name@.unchecked_append(move(to_string_result)); + } } )~~~"); } else if (!optional) { @@ -316,11 +319,14 @@ static void generate_to_new_string(SourceGenerator& scoped_generator, ParameterT if (variadic) { scoped_generator.append(R"~~~( Vector @cpp_name@; - @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)); - @cpp_name@.append(move(to_string_result)); + if (vm.argument_count() > @js_suffix@) { + TRY_OR_THROW_OOM(vm, @cpp_name@.try_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)); + @cpp_name@.unchecked_append(move(to_string_result)); + } } )~~~"); } else if (!optional) { @@ -614,10 +620,13 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter if (variadic) { scoped_generator.append(R"~~~( JS::MarkedVector @cpp_name@ { vm.heap() }; - TRY_OR_THROW_OOM(vm, @cpp_name@.try_ensure_capacity(vm.argument_count() - @js_suffix@)); - for (size_t i = @js_suffix@; i < vm.argument_count(); ++i) - @cpp_name@.unchecked_append(vm.argument(i)); + if (vm.argument_count() > @js_suffix@) { + TRY_OR_THROW_OOM(vm, @cpp_name@.try_ensure_capacity(vm.argument_count() - @js_suffix@)); + + for (size_t i = @js_suffix@; i < vm.argument_count(); ++i) + @cpp_name@.unchecked_append(vm.argument(i)); + } )~~~"); } else if (!optional) { scoped_generator.append(R"~~~( @@ -1370,11 +1379,14 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter } else { union_generator.append(R"~~~( Vector<@union_type@> @cpp_name@; - @cpp_name@.ensure_capacity(vm.argument_count() - @js_suffix@); - for (size_t i = @js_suffix@; i < vm.argument_count(); ++i) { - auto result = TRY(@js_name@@js_suffix@_to_variant(vm.argument(i))); - @cpp_name@.append(move(result)); + if (vm.argument_count() > @js_suffix@) { + TRY_OR_THROW_OOM(vm, @cpp_name@.try_ensure_capacity(vm.argument_count() - @js_suffix@)); + + for (size_t i = @js_suffix@; i < vm.argument_count(); ++i) { + auto result = TRY(@js_name@@js_suffix@_to_variant(vm.argument(i))); + @cpp_name@.unchecked_append(move(result)); + } } )~~~"); }