- Revision
- 234777
- Author
- [email protected]
- Date
- 2018-08-10 16:31:50 -0700 (Fri, 10 Aug 2018)
Log Message
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.
JSTests:
Rebaseline the expectations.
* test262/expectations.yaml:
Source/_javascript_Core:
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):
Modified Paths
Diff
Modified: trunk/JSTests/ChangeLog (234776 => 234777)
--- trunk/JSTests/ChangeLog 2018-08-10 23:03:25 UTC (rev 234776)
+++ trunk/JSTests/ChangeLog 2018-08-10 23:31:50 UTC (rev 234777)
@@ -1,3 +1,14 @@
+2018-08-10 Keith Miller <[email protected]>
+
+ 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 <[email protected]>
Date.UTC should not return NaN with only Year param
Modified: trunk/JSTests/test262/expectations.yaml (234776 => 234777)
--- trunk/JSTests/test262/expectations.yaml 2018-08-10 23:03:25 UTC (rev 234776)
+++ trunk/JSTests/test262/expectations.yaml 2018-08-10 23:31:50 UTC (rev 234777)
@@ -708,33 +708,30 @@
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.)'
Modified: trunk/Source/_javascript_Core/ChangeLog (234776 => 234777)
--- trunk/Source/_javascript_Core/ChangeLog 2018-08-10 23:03:25 UTC (rev 234776)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-08-10 23:31:50 UTC (rev 234777)
@@ -1,3 +1,27 @@
+2018-08-10 Keith Miller <[email protected]>
+
+ 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 <[email protected]>
Date.UTC should not return NaN with only Year param
Modified: trunk/Source/_javascript_Core/runtime/ArrayBuffer.cpp (234776 => 234777)
--- trunk/Source/_javascript_Core/runtime/ArrayBuffer.cpp 2018-08-10 23:03:25 UTC (rev 234776)
+++ trunk/Source/_javascript_Core/runtime/ArrayBuffer.cpp 2018-08-10 23:31:50 UTC (rev 234777)
@@ -267,12 +267,30 @@
{
}
-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());
}
Modified: trunk/Source/_javascript_Core/runtime/ArrayBuffer.h (234776 => 234777)
--- trunk/Source/_javascript_Core/runtime/ArrayBuffer.h 2018-08-10 23:03:25 UTC (rev 234776)
+++ trunk/Source/_javascript_Core/runtime/ArrayBuffer.h 2018-08-10 23:31:50 UTC (rev 234777)
@@ -126,8 +126,8 @@
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 @@
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 @@
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 @@
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++;
Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferPrototype.cpp (234776 => 234777)
--- trunk/Source/_javascript_Core/runtime/JSArrayBufferPrototype.cpp 2018-08-10 23:03:25 UTC (rev 234776)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferPrototype.cpp 2018-08-10 23:31:50 UTC (rev 234777)
@@ -43,18 +43,15 @@
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();