LibJS: Do not revisit already visited values in update_function_name()

Fixes #3471, adds a test.
This commit is contained in:
AnotherTest 2020-09-18 18:00:57 +04:30 committed by Andreas Kling
parent e317ee7541
commit 21f513fe0f
Notes: sideshowbarker 2024-07-19 02:20:39 +09:00
2 changed files with 19 additions and 2 deletions

View file

@ -26,6 +26,7 @@
*/
#include <AK/HashMap.h>
#include <AK/HashTable.h>
#include <AK/ScopeGuard.h>
#include <AK/StringBuilder.h>
#include <LibCrypto/BigInt/SignedBigInteger.h>
@ -49,10 +50,13 @@
namespace JS {
static void update_function_name(Value& value, const FlyString& name)
static void update_function_name(Value& value, const FlyString& name, HashTable<const JS::Cell*>& visited)
{
if (!value.is_object())
return;
if (visited.contains(value.as_cell()))
return;
visited.set(value.as_cell());
auto& object = value.as_object();
if (object.is_function()) {
auto& function = static_cast<Function&>(object);
@ -61,10 +65,16 @@ static void update_function_name(Value& value, const FlyString& name)
} else if (object.is_array()) {
auto& array = static_cast<Array&>(object);
for (auto& entry : array.indexed_properties().values_unordered())
update_function_name(entry.value, name);
update_function_name(entry.value, name, visited);
}
}
static void update_function_name(Value& value, const FlyString& name)
{
HashTable<const JS::Cell*> visited;
update_function_name(value, name, visited);
}
static String get_function_name(Interpreter& interpreter, Value value)
{
if (value.is_symbol())

View file

@ -48,3 +48,10 @@ test("names of native functions", () => {
expect((console.debug.name = "warn")).toBe("warn");
expect(console.debug.name).toBe("debug");
});
test("cyclic members should not cause infinite recursion (#3471)", () => {
let a = [() => 4];
a[1] = a;
a = a;
expect(a[0].name).toBe("a");
});