Slicing an ArrayBuffer with a long number returns an ArrayBuffer with byteLength...
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Aug 2018 23:31:50 +0000 (23:31 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Aug 2018 23:31:50 +0000 (23:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185127

Reviewed by Saam Barati.

JSTests:

Rebaseline the expectations.

* test262/expectations.yaml:

Source/JavaScriptCore:

Previously, we would truncate the indicies passed to slice to an
int. This meant that the value was not getting properly clamped
later.

This patch also removes a non-spec compliant check that slice was
passed at least one argument.

* runtime/ArrayBuffer.cpp:
(JSC::ArrayBuffer::clampValue):
(JSC::ArrayBuffer::clampIndex const):
(JSC::ArrayBuffer::slice const):
* runtime/ArrayBuffer.h:
(JSC::ArrayBuffer::clampValue): Deleted.
(JSC::ArrayBuffer::clampIndex const): Deleted.
* runtime/JSArrayBufferPrototype.cpp:
(JSC::arrayBufferProtoFuncSlice):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234777 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/test262/expectations.yaml
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/ArrayBuffer.cpp
Source/JavaScriptCore/runtime/ArrayBuffer.h
Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp

index 731ab24..88c2011 100644 (file)
@@ -1,3 +1,14 @@
+2018-08-10  Keith Miller  <keith_miller@apple.com>
+
+        Slicing an ArrayBuffer with a long number returns an ArrayBuffer with byteLength zero
+        https://bugs.webkit.org/show_bug.cgi?id=185127
+
+        Reviewed by Saam Barati.
+
+        Rebaseline the expectations.
+
+        * test262/expectations.yaml:
+
 2018-08-10  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
 
         Date.UTC should not return NaN with only Year param
index 090f79e..2d4a0a3 100644 (file)
@@ -708,33 +708,30 @@ test/built-ins/ArrayBuffer/proto-from-ctor-realm.js:
 test/built-ins/ArrayBuffer/prototype/byteLength/detached-buffer.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-test/built-ins/ArrayBuffer/prototype/slice/end-default-if-undefined.js:
-  default: 'Test262Error: Expected SameValue(«0», Â«2») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«0», Â«2») to be true'
-test/built-ins/ArrayBuffer/prototype/slice/end-exceeds-length.js:
-  default: 'Test262Error: slice(2, 0x100000000) Expected SameValue(«0», Â«6») to be true'
-  strict mode: 'Test262Error: slice(2, 0x100000000) Expected SameValue(«0», Â«6») to be true'
-test/built-ins/ArrayBuffer/prototype/slice/species-constructor-is-undefined.js:
-  default: 'TypeError: Slice requires at least one argument.'
-  strict mode: 'TypeError: Slice requires at least one argument.'
-test/built-ins/ArrayBuffer/prototype/slice/species-is-null.js:
-  default: 'TypeError: Slice requires at least one argument.'
-  strict mode: 'TypeError: Slice requires at least one argument.'
-test/built-ins/ArrayBuffer/prototype/slice/species-is-undefined.js:
-  default: 'TypeError: Slice requires at least one argument.'
-  strict mode: 'TypeError: Slice requires at least one argument.'
+test/built-ins/ArrayBuffer/prototype/slice/species-constructor-is-not-object.js:
+  default: 'Test262Error: `constructor` value is null Expected a TypeError to be thrown but no exception was thrown at all'
+  strict mode: 'Test262Error: `constructor` value is null Expected a TypeError to be thrown but no exception was thrown at all'
+test/built-ins/ArrayBuffer/prototype/slice/species-is-not-constructor.js:
+  default: 'Test262Error: `constructor[Symbol.species]` value is Object Expected a TypeError to be thrown but no exception was thrown at all'
+  strict mode: 'Test262Error: `constructor[Symbol.species]` value is Object Expected a TypeError to be thrown but no exception was thrown at all'
+test/built-ins/ArrayBuffer/prototype/slice/species-is-not-object.js:
+  default: 'Test262Error: `constructor[Symbol.species]` value is Boolean Expected a TypeError to be thrown but no exception was thrown at all'
+  strict mode: 'Test262Error: `constructor[Symbol.species]` value is Boolean Expected a TypeError to be thrown but no exception was thrown at all'
 test/built-ins/ArrayBuffer/prototype/slice/species-returns-larger-arraybuffer.js:
-  default: 'TypeError: Slice requires at least one argument.'
-  strict mode: 'TypeError: Slice requires at least one argument.'
+  default: 'Test262Error: Expected SameValue(«8», Â«10») to be true'
+  strict mode: 'Test262Error: Expected SameValue(«8», Â«10») to be true'
+test/built-ins/ArrayBuffer/prototype/slice/species-returns-not-arraybuffer.js:
+  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
+  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
+test/built-ins/ArrayBuffer/prototype/slice/species-returns-same-arraybuffer.js:
+  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
+  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
+test/built-ins/ArrayBuffer/prototype/slice/species-returns-smaller-arraybuffer.js:
+  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
+  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
 test/built-ins/ArrayBuffer/prototype/slice/species.js:
-  default: 'TypeError: Slice requires at least one argument.'
-  strict mode: 'TypeError: Slice requires at least one argument.'
-test/built-ins/ArrayBuffer/prototype/slice/start-default-if-absent.js:
-  default: 'TypeError: Slice requires at least one argument.'
-  strict mode: 'TypeError: Slice requires at least one argument.'
-test/built-ins/ArrayBuffer/prototype/slice/start-exceeds-length.js:
-  default: 'Test262Error: slice(0x100000000, 7) Expected SameValue(«7», Â«0») to be true'
-  strict mode: 'Test262Error: slice(0x100000000, 7) Expected SameValue(«7», Â«0») to be true'
+  default: 'Test262Error: Expected SameValue(«[object ArrayBuffer]», Â«undefined») to be true'
+  strict mode: 'Test262Error: Expected SameValue(«[object ArrayBuffer]», Â«undefined») to be true'
 test/built-ins/ArrayIteratorPrototype/next/detach-typedarray-in-progress.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
index f4e9825..a0e3ed7 100644 (file)
@@ -1,3 +1,27 @@
+2018-08-10  Keith Miller  <keith_miller@apple.com>
+
+        Slicing an ArrayBuffer with a long number returns an ArrayBuffer with byteLength zero
+        https://bugs.webkit.org/show_bug.cgi?id=185127
+
+        Reviewed by Saam Barati.
+
+        Previously, we would truncate the indicies passed to slice to an
+        int. This meant that the value was not getting properly clamped
+        later.
+
+        This patch also removes a non-spec compliant check that slice was
+        passed at least one argument.
+
+        * runtime/ArrayBuffer.cpp:
+        (JSC::ArrayBuffer::clampValue):
+        (JSC::ArrayBuffer::clampIndex const):
+        (JSC::ArrayBuffer::slice const):
+        * runtime/ArrayBuffer.h:
+        (JSC::ArrayBuffer::clampValue): Deleted.
+        (JSC::ArrayBuffer::clampIndex const): Deleted.
+        * runtime/JSArrayBufferPrototype.cpp:
+        (JSC::arrayBufferProtoFuncSlice):
+
 2018-08-10  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
 
         Date.UTC should not return NaN with only Year param
index 726d664..25ea890 100644 (file)
@@ -267,12 +267,30 @@ ArrayBuffer::ArrayBuffer(ArrayBufferContents&& contents)
 {
 }
 
-RefPtr<ArrayBuffer> ArrayBuffer::slice(int begin, int end) const
+unsigned ArrayBuffer::clampValue(double x, unsigned left, unsigned right)
+{
+    ASSERT(left <= right);
+    if (x < left)
+        x = left;
+    if (right < x)
+        x = right;
+    return x;
+}
+
+unsigned ArrayBuffer::clampIndex(double index) const
+{
+    unsigned currentLength = byteLength();
+    if (index < 0)
+        index = currentLength + index;
+    return clampValue(index, 0, currentLength);
+}
+
+RefPtr<ArrayBuffer> ArrayBuffer::slice(double begin, double end) const
 {
     return sliceImpl(clampIndex(begin), clampIndex(end));
 }
 
-RefPtr<ArrayBuffer> ArrayBuffer::slice(int begin) const
+RefPtr<ArrayBuffer> ArrayBuffer::slice(double begin) const
 {
     return sliceImpl(clampIndex(begin), byteLength());
 }
index fc027ea..deea254 100644 (file)
@@ -126,8 +126,8 @@ public:
 
     inline size_t gcSizeEstimateInBytes() const;
 
-    JS_EXPORT_PRIVATE RefPtr<ArrayBuffer> slice(int begin, int end) const;
-    JS_EXPORT_PRIVATE RefPtr<ArrayBuffer> slice(int begin) const;
+    JS_EXPORT_PRIVATE RefPtr<ArrayBuffer> slice(double begin, double end) const;
+    JS_EXPORT_PRIVATE RefPtr<ArrayBuffer> slice(double begin) const;
     
     inline void pin();
     inline void unpin();
@@ -153,8 +153,8 @@ private:
     static RefPtr<ArrayBuffer> tryCreate(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy);
     ArrayBuffer(ArrayBufferContents&&);
     RefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const;
-    inline unsigned clampIndex(int index) const;
-    static inline int clampValue(int x, int left, int right);
+    inline unsigned clampIndex(double index) const;
+    static inline unsigned clampValue(double x, unsigned left, unsigned right);
 
     void notifyIncommingReferencesOfTransfer(VM&);
 
@@ -169,16 +169,6 @@ public:
     Weak<JSArrayBuffer> m_wrapper;
 };
 
-int ArrayBuffer::clampValue(int x, int left, int right)
-{
-    ASSERT(left <= right);
-    if (x < left)
-        x = left;
-    if (right < x)
-        x = right;
-    return x;
-}
-
 void* ArrayBuffer::data()
 {
     return m_contents.m_data.getMayBeNull();
@@ -205,14 +195,6 @@ size_t ArrayBuffer::gcSizeEstimateInBytes() const
     return sizeof(ArrayBuffer) + static_cast<size_t>(byteLength());
 }
 
-unsigned ArrayBuffer::clampIndex(int index) const
-{
-    unsigned currentLength = byteLength();
-    if (index < 0)
-        index = currentLength + index;
-    return clampValue(index, 0, currentLength);
-}
-
 void ArrayBuffer::pin()
 {
     m_pinCount++;
index a3ac968..28811cc 100644 (file)
@@ -43,18 +43,15 @@ static EncodedJSValue JSC_HOST_CALL arrayBufferProtoFuncSlice(ExecState* exec)
     JSFunction* callee = jsCast<JSFunction*>(exec->jsCallee());
     
     JSArrayBuffer* thisObject = jsDynamicCast<JSArrayBuffer*>(vm, exec->thisValue());
-    if (!thisObject)
-        return throwVMTypeError(exec, scope, "Receiver of slice must be an array buffer."_s);
-    
-    if (!exec->argumentCount())
-        return throwVMTypeError(exec, scope, "Slice requires at least one argument."_s);
-    
-    int32_t begin = exec->argument(0).toInt32(exec);
+    if (!thisObject || thisObject->impl()->isShared())
+        return throwVMTypeError(exec, scope, "Receiver of slice must be an ArrayBuffer."_s);
+
+    double begin = exec->argument(0).toInteger(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
-    int32_t end;
-    if (exec->argumentCount() >= 2) {
-        end = exec->uncheckedArgument(1).toInt32(exec);
+    double end;
+    if (!exec->argument(1).isUndefined()) {
+        end = exec->uncheckedArgument(1).toInteger(exec);
         RETURN_IF_EXCEPTION(scope, encodedJSValue());
     } else
         end = thisObject->impl()->byteLength();