diff --git a/Jint.Tests.Test262/Test262Harness.settings.json b/Jint.Tests.Test262/Test262Harness.settings.json index d28529732..97dd99cce 100644 --- a/Jint.Tests.Test262/Test262Harness.settings.json +++ b/Jint.Tests.Test262/Test262Harness.settings.json @@ -1,5 +1,5 @@ { - "SuiteGitSha": "2b2ecead6e828dd9af13a9ec72065e645724a50f", + "SuiteGitSha": "673e9bacbe28590f501e2dcd817aadcc31899191", //"SuiteDirectory": "//mnt/c/work/test262", "TargetPath": "./Generated", "Namespace": "Jint.Tests.Test262", diff --git a/Jint/Native/ArrayBuffer/ArrayBufferPrototype.cs b/Jint/Native/ArrayBuffer/ArrayBufferPrototype.cs index 3f241759f..606cf69d6 100644 --- a/Jint/Native/ArrayBuffer/ArrayBufferPrototype.cs +++ b/Jint/Native/ArrayBuffer/ArrayBufferPrototype.cs @@ -272,26 +272,23 @@ private JsValue TransferToImmutable(JsValue thisObject, JsValue newLength) private JsValue SliceToImmutable(JsValue thisObject, JsValue start, JsValue end) { // 1. Let O be the this value. + // 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). + // 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. var o = thisObject as JsArrayBuffer; if (o is null || o.IsSharedArrayBuffer) { Throw.TypeError(_realm, "Method ArrayBuffer.prototype.sliceToImmutable called on incompatible receiver " + thisObject); } - // 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). - // 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception. - // (already checked above) - // 4. If IsDetachedBuffer(O) is true, throw a TypeError exception. o.AssertNotDetached(); // 5. Let len be O.[[ArrayBufferByteLength]]. var len = o.ArrayBufferByteLength; - // 6. Let relativeStart be ? ToIntegerOrInfinity(start). + // 6. Let bounds be ? ResolveBounds(len, start, end). + // 6.1 Let relativeStart be ? ToIntegerOrInfinity(start). var relativeStart = TypeConverter.ToIntegerOrInfinity(start); - - // 7-8. Set first based on relativeStart var first = relativeStart switch { double.NegativeInfinity => 0, @@ -299,18 +296,8 @@ private JsValue SliceToImmutable(JsValue thisObject, JsValue start, JsValue end) _ => (int) System.Math.Min(relativeStart, len) }; - // 9-10. Set relativeEnd based on end - double relativeEnd; - if (end.IsUndefined()) - { - relativeEnd = len; - } - else - { - relativeEnd = TypeConverter.ToIntegerOrInfinity(end); - } - - // 11-12. Set final based on relativeEnd + // 6.5 If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end). + var relativeEnd = end.IsUndefined() ? len : TypeConverter.ToIntegerOrInfinity(end); var final = relativeEnd switch { double.NegativeInfinity => 0, @@ -318,28 +305,29 @@ private JsValue SliceToImmutable(JsValue thisObject, JsValue start, JsValue end) _ => (int) System.Math.Min(relativeEnd, len) }; - // 13. Let newLen be max(final - first, 0). - var newLen = (uint) System.Math.Max(final - first, 0); - - // 14. Let new be ? AllocateArrayBuffer(%ArrayBuffer%, newLen). - var newBuffer = _engine.Realm.Intrinsics.ArrayBuffer.AllocateArrayBuffer(_engine.Realm.Intrinsics.ArrayBuffer, newLen); - - // 15. If IsDetachedBuffer(O) is true, throw a TypeError exception. + // After coercion, the buffer may have been detached and/or resized — re-check detachment + // *before* the currentLen items) } var newObj = TypedArrayCreate(_realm, (IConstructor) thisObject, [len]); + newObj._viewedArrayBuffer.AssertNotImmutable(); for (var k = 0; k < len; k++) { diff --git a/Jint/Native/TypedArray/TypedArrayConstructor.cs b/Jint/Native/TypedArray/TypedArrayConstructor.cs index 1a38474b6..11969846f 100644 --- a/Jint/Native/TypedArray/TypedArrayConstructor.cs +++ b/Jint/Native/TypedArray/TypedArrayConstructor.cs @@ -102,7 +102,7 @@ public override ObjectInstance Construct(JsCallArguments arguments, JsValue newT /// internal static List IterableToList(Realm realm, JsValue items, ICallable? method = null) { - var iteratorRecord = items.GetIterator(realm); + var iteratorRecord = items.GetIterator(realm, method: method); var values = new List(); while (iteratorRecord.TryIteratorStep(out var nextItem)) { diff --git a/Jint/Native/TypedArray/Uint8ArrayPrototype.cs b/Jint/Native/TypedArray/Uint8ArrayPrototype.cs index 2d7b915fa..53b32152b 100644 --- a/Jint/Native/TypedArray/Uint8ArrayPrototype.cs +++ b/Jint/Native/TypedArray/Uint8ArrayPrototype.cs @@ -47,6 +47,7 @@ private JsObject SetFromBase64(JsValue thisObject, JsValue s, JsValue options) { Throw.TypeError(_realm, "TypedArray is out of bounds"); } + into._viewedArrayBuffer.AssertNotImmutable(); var byteLength = taRecord.TypedArrayLength; var result = Uint8ArrayConstructor.FromBase64(_engine, s.ToString(), alphabet.ToString(), lastChunkHandling.ToString(), byteLength); @@ -92,6 +93,7 @@ private JsObject SetFromHex(JsValue thisObject, JsValue s) { Throw.TypeError(_realm, "TypedArray is out of bounds"); } + into._viewedArrayBuffer.AssertNotImmutable(); var byteLength = taRecord.TypedArrayLength; var result = Uint8ArrayConstructor.FromHex(_engine, s.ToString(), byteLength); diff --git a/Jint/Runtime/TypeConverter.cs b/Jint/Runtime/TypeConverter.cs index a75f7c249..aad528dae 100644 --- a/Jint/Runtime/TypeConverter.cs +++ b/Jint/Runtime/TypeConverter.cs @@ -232,6 +232,12 @@ private static double ToNumber(string input) } input = StringPrototype.TrimEx(input); + if (input.Length == 0) + { + // The pre-trim IsNullOrWhiteSpace check can miss BOM and other characters + // that Jint's TrimEx considers whitespace per the ECMAScript spec. + return 0; + } firstChar = input[0]; const NumberStyles NumberStyles = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign |