From 2b170c9d135930f80fa86dc2f92120a70c2720d9 Mon Sep 17 00:00:00 2001 From: Dylan Conway <35280289+dylan-conway@users.noreply.github.com> Date: Thu, 6 Apr 2023 14:49:07 -0700 Subject: Fix `toEqual` when the second array has extra array holes (#2580) * iterate through remaining indexes, keep prop identifier * tests * format --- src/bun.js/bindings/bindings.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src/bun.js/bindings/bindings.cpp') diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 8c1712338..450c9bc28 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -488,12 +488,16 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2, JSC::JSArray* array1 = JSC::jsCast(v1); JSC::JSArray* array2 = JSC::jsCast(v2); - size_t length = array1->length(); - if (length != array2->length()) { - return false; + size_t array1Length = array1->length(); + size_t array2Length = array2->length(); + if constexpr (isStrict) { + if (array1Length != array2Length) { + return false; + } } - for (uint64_t i = 0; i < length; i++) { + uint64_t i = 0; + for (; i < array1Length; i++) { JSValue left = getIndexWithoutAccessors(globalObject, o1, i); RETURN_IF_EXCEPTION(*scope, false); JSValue right = getIndexWithoutAccessors(globalObject, o2, i); @@ -521,6 +525,17 @@ bool Bun__deepEquals(JSC__JSGlobalObject* globalObject, JSValue v1, JSValue v2, RETURN_IF_EXCEPTION(*scope, false); } + for (; i < array2Length; i++) { + JSValue right = getIndexWithoutAccessors(globalObject, o2, i); + RETURN_IF_EXCEPTION(*scope, false); + + if (((right.isEmpty() || right.isUndefined()))) { + continue; + } + + return false; + } + JSC::PropertyNameArray a1(vm, PropertyNameMode::Symbols, PrivateSymbolMode::Include); JSC::PropertyNameArray a2(vm, PropertyNameMode::Symbols, PrivateSymbolMode::Include); JSObject::getOwnPropertyNames(o1, globalObject, a1, DontEnumPropertiesMode::Exclude); @@ -3844,7 +3859,7 @@ restart: } } -inline bool propertyCompare(const std::pair& a, const std::pair& b) +inline bool propertyCompare(const std::pair>& a, const std::pair>& b) { return codePointCompare(a.first.impl(), b.first.impl()) < 0; } @@ -3862,19 +3877,20 @@ void JSC__JSValue__forEachPropertyOrdered(JSC__JSValue JSValue0, JSC__JSGlobalOb JSC::PropertyNameArray properties(vm, PropertyNameMode::StringsAndSymbols, PrivateSymbolMode::Exclude); JSC::JSObject::getOwnPropertyNames(object, globalObject, properties, DontEnumPropertiesMode::Include); - Vector> ordered_properties; + Vector>> ordered_properties; for (auto property : properties) { JSValue propertyValue = object->getDirect(vm, property); - ordered_properties.append(std::pair(property.isSymbol() && !property.isPrivateName() ? property.impl() : property.string(), propertyValue)); + ordered_properties.append(std::pair>(property.isSymbol() && !property.isPrivateName() ? property.impl() : property.string(), std::pair(property, propertyValue))); } std::sort(ordered_properties.begin(), ordered_properties.end(), propertyCompare); for (auto item : ordered_properties) { ZigString key = toZigString(item.first); - JSValue propertyValue = item.second; + Identifier property = item.second.first; + JSValue propertyValue = item.second.second; JSC::EnsureStillAliveScope ensureStillAliveScope(propertyValue); - iter(globalObject, arg2, &key, JSC::JSValue::encode(propertyValue), propertyValue.isSymbol()); + iter(globalObject, arg2, &key, JSC::JSValue::encode(propertyValue), property.isSymbol()); } } -- cgit v1.2.3