Changeset 159275 in webkit


Ignore:
Timestamp:
Nov 13, 2013 9:46:10 PM (10 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebCore: Blob constructor accepts a sequence (array-like object) as first arg.
https://bugs.webkit.org/show_bug.cgi?id=124175

Patch by Victor Costan <costan@gmail.com> on 2013-11-13
Reviewed by Christophe Dumez.

Added test cases to fast/files/script-tests/blob-constructor.js.

  • bindings/js/JSBlobCustom.cpp: Make the constructor work with sequences.

(WebCore::JSBlobConstructor::constructJSBlob):

  • bindings/js/JSDOMBinding.h:

(WebCore::toJSSequence): Slightly better error message when conversion fails.
(WebCore::toJS): Whitespace.
(WebCore::jsArray): Whitespace.

LayoutTests: Blob constructor accepts a sequence (array-like object) as first arg.
https://bugs.webkit.org/show_bug.cgi?id=124175

Patch by Victor Costan <costan@gmail.com> on 2013-11-13
Reviewed by Christophe Dumez.

  • crypto/subtle/argument-conversion-expected.txt: Updated sequence error expectations.
  • fast/dom/Window/window-postmessage-args-expected.txt: Updated sequence error expectations.
  • fast/events/constructors/message-event-constructor-expected.txt: Updated sequence error expectations.
  • fast/events/message-port-multi-expected.txt: Updated sequence error expectations.
  • fast/files/blob-constructor-expected.txt: Updated error text and added expectations.
  • fast/files/script-tests/blob-constructor.js: Added sequence test cases.
  • fast/workers/worker-context-multi-port-expected.txt: Updated sequence error expectations.
  • fast/workers/worker-multi-port-expected.txt: Updated sequence error expectations.
Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r159274 r159275  
     12013-11-13  Victor Costan  <costan@gmail.com>
     2
     3        Blob constructor accepts a sequence (array-like object) as first arg.
     4        https://bugs.webkit.org/show_bug.cgi?id=124175
     5
     6        Reviewed by Christophe Dumez.
     7
     8
     9        * crypto/subtle/argument-conversion-expected.txt: Updated sequence error expectations.
     10        * fast/dom/Window/window-postmessage-args-expected.txt: Updated sequence error expectations.
     11        * fast/events/constructors/message-event-constructor-expected.txt: Updated sequence error expectations.
     12        * fast/events/message-port-multi-expected.txt: Updated sequence error expectations.
     13        * fast/files/blob-constructor-expected.txt: Updated error text and added expectations.
     14        * fast/files/script-tests/blob-constructor.js: Added sequence test cases.
     15        * fast/workers/worker-context-multi-port-expected.txt: Updated sequence error expectations.
     16        * fast/workers/worker-multi-port-expected.txt: Updated sequence error expectations.
     17
    1182013-11-13  Sun-woo Nam  <sunny.nam@samsung.com>
    219
  • trunk/LayoutTests/crypto/subtle/argument-conversion-expected.txt

    r158396 r159275  
    1818Passing invalid data to digest()
    1919PASS crypto.subtle.digest({name: 'sha-1'}) threw exception TypeError: Not enough arguments.
    20 PASS crypto.subtle.digest({name: 'sha-1'}, null) threw exception TypeError: Type error.
    21 PASS crypto.subtle.digest({name: 'sha-1'}, 10) threw exception TypeError: Type error.
     20PASS crypto.subtle.digest({name: 'sha-1'}, null) threw exception TypeError: Value is not a sequence.
     21PASS crypto.subtle.digest({name: 'sha-1'}, 10) threw exception TypeError: Value is not a sequence.
    2222PASS crypto.subtle.digest({name: 'sha-1'}, [10]) threw exception TypeError: Only ArrayBuffer and ArrayBufferView objects can be part of CryptoOperationData sequence.
    2323PASS crypto.subtle.digest({name: 'sha-1'}, new Uint8Array([0])) threw exception TypeError: Only ArrayBuffer and ArrayBufferView objects can be part of CryptoOperationData sequence.
  • trunk/LayoutTests/fast/dom/Window/window-postmessage-args-expected.txt

    r128658 r159275  
    11Test that the second argument of window.postMessage is ignored or triggers an error if it is not a message port. You should see PASS message '1' through '7', followed by 'done', with messages 4-7 received below.
    22
    3 PASS: Posting message ('1', 1): threw exception TypeError: Type error
    4 PASS: Posting message ('2', c): threw exception TypeError: Type error
    5 PASS: Posting message ('3', [object Object]): threw exception TypeError: Type error
     3PASS: Posting message ('1', 1): threw exception TypeError: Value is not a sequence
     4PASS: Posting message ('2', c): threw exception TypeError: Value is not a sequence
     5PASS: Posting message ('3', [object Object]): threw exception TypeError: Value is not a sequence
    66PASS: Posting message ('4', [object Window]) did not throw an exception
    77PASS: Posting message ('4a', *) did not throw an exception
  • trunk/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt

    r155959 r159275  
    8484PASS new MessageEvent('eventType', { ports: null }).ports is []
    8585PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: Type error.
    86 PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Type error.
    87 PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: Type error.
    88 PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: Type error.
    89 PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: Type error.
    90 PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: Type error.
    91 PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: Type error.
    92 PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: Type error.
    93 PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: Type error.
    94 PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Type error.
    95 PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Type error.
     86PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Value is not a sequence.
     87PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: Value is not a sequence.
     88PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: Value is not a sequence.
     89PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: Value is not a sequence.
     90PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: Value is not a sequence.
     91PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: Value is not a sequence.
     92PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: Value is not a sequence.
     93PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: Value is not a sequence.
     94PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Value is not a sequence.
     95PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Value is not a sequence.
    9696PASS new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
    97 PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Type error.
     97PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Value is not a sequence.
    9898PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).bubbles is true
    9999PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).cancelable is true
  • trunk/LayoutTests/fast/events/message-port-multi-expected.txt

    r135168 r159275  
    99PASS channel.port1.postMessage("notAPort", [channel3.port1, {}, channel3.port2]) threw exception TypeError: Type error.
    1010PASS channel.port1.postMessage("duplicate port", [channel3.port1, channel3.port1]) threw exception Error: InvalidStateError: DOM Exception 11.
    11 PASS channel.port1.postMessage("notAnArray", channel3.port1) threw exception TypeError: Type error.
     11PASS channel.port1.postMessage("notAnArray", channel3.port1) threw exception TypeError: Value is not a sequence.
    1212PASS channel.port1.postMessage("notASequence", [{length: 3}]) threw exception TypeError: Type error.
    1313PASS channel.port1.postMessage("largeSequence", largePortArray) threw exception Error: InvalidStateError: DOM Exception 11.
  • trunk/LayoutTests/fast/files/blob-constructor-expected.txt

    r148997 r159275  
    1111PASS (new Blob(['hello'], {type:'text/html', endings:'native'})) instanceof window.Blob is true
    1212PASS (new Blob(['hello'], {type:'text/html', endings:'transparent'})) instanceof window.Blob is true
    13 PASS new Blob('hello') threw exception TypeError: First argument of the constructor is not of type Array.
    14 PASS new Blob(0) threw exception TypeError: First argument of the constructor is not of type Array.
     13PASS new Blob('hello') threw exception TypeError: Value is not a sequence.
     14PASS new Blob(0) threw exception TypeError: Value is not a sequence.
    1515PASS (new Blob([])) instanceof window.Blob is true
    1616PASS (new Blob(['stringPrimitive'])) instanceof window.Blob is true
     
    7373PASS new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1400
    7474PASS new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1000
     75PASS new Blob({length: 0}) instanceof window.Blob is true
     76PASS new Blob({length: 0}).size is 0
     77PASS new Blob({length: 1, 0: 'string'}).size is 6
     78PASS new Blob({length: 2, 0: new Uint8Array(100), 1: new Int16Array(100)}).size is 300
     79PASS new Blob({length: 1, 0: 'string'}, {type: 'text/html'}).type is 'text/html'
     80PASS new Blob({length: 0}, {endings:'illegal'}) threw exception TypeError: The endings property must be either "transparent" or "native".
    7581PASS successfullyParsed is true
    7682
  • trunk/LayoutTests/fast/files/script-tests/blob-constructor.js

    r148997 r159275  
    1111
    1212// Test invalid blob parts
    13 shouldThrow("new Blob('hello')", "'TypeError: First argument of the constructor is not of type Array'");
    14 shouldThrow("new Blob(0)", "'TypeError: First argument of the constructor is not of type Array'");
     13shouldThrow("new Blob('hello')", "'TypeError: Value is not a sequence'");
     14shouldThrow("new Blob(0)", "'TypeError: Value is not a sequence'");
    1515
    1616// Test valid blob parts.
     
    9999shouldBe("new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size", "1400");
    100100shouldBe("new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size", "1000");
     101
     102// Test passing blob parts in sequences.
     103shouldBeTrue("new Blob({length: 0}) instanceof window.Blob");
     104shouldBe("new Blob({length: 0}).size", "0");
     105shouldBe("new Blob({length: 1, 0: 'string'}).size", "6");
     106shouldBe("new Blob({length: 2, 0: new Uint8Array(100), 1: new Int16Array(100)}).size", "300");
     107shouldBe("new Blob({length: 1, 0: 'string'}, {type: 'text/html'}).type", "'text/html'");
     108shouldThrow("new Blob({length: 0}, {endings:'illegal'})", "'TypeError: The endings property must be either \"transparent\" or \"native\"'");
  • trunk/LayoutTests/fast/workers/worker-context-multi-port-expected.txt

    r134648 r159275  
    1010PASS posting a non-port did throw: TypeError: Type error
    1111PASS event.ports contains two ports when two ports re-sent after error
    12 PASS posting a non-array did throw: TypeError: Type error
     12PASS posting a non-array did throw: TypeError: Value is not a sequence
    1313PASS posting a non-sequence did throw: TypeError: Type error
    1414
  • trunk/LayoutTests/fast/workers/worker-multi-port-expected.txt

    r134648 r159275  
    66PASS worker.postMessage("null port", [channel3.port1, null, channel3.port2]) threw exception Error: InvalidStateError: DOM Exception 11.
    77PASS worker.postMessage("notAPort", [channel3.port1, {}, channel3.port2]) threw exception TypeError: Type error.
    8 PASS worker.postMessage("notAnArray", channel3.port1) threw exception TypeError: Type error.
     8PASS worker.postMessage("notAnArray", channel3.port1) threw exception TypeError: Value is not a sequence.
    99PASS worker.postMessage("notASequence", [{length: 3}]) threw exception TypeError: Type error.
    1010PASS event.ports is non-null and zero length when no port sent
  • trunk/Source/WebCore/ChangeLog

    r159272 r159275  
     12013-11-13  Victor Costan  <costan@gmail.com>
     2
     3        Blob constructor accepts a sequence (array-like object) as first arg.
     4        https://bugs.webkit.org/show_bug.cgi?id=124175
     5
     6        Reviewed by Christophe Dumez.
     7
     8        Added test cases to fast/files/script-tests/blob-constructor.js.
     9
     10        * bindings/js/JSBlobCustom.cpp: Make the constructor work with sequences.
     11        (WebCore::JSBlobConstructor::constructJSBlob):
     12        * bindings/js/JSDOMBinding.h:
     13        (WebCore::toJSSequence): Slightly better error message when conversion fails.
     14        (WebCore::toJS): Whitespace.
     15        (WebCore::jsArray): Whitespace.
     16
    1172013-11-13  Joseph Pecoraro  <pecoraro@apple.com>
    218
  • trunk/Source/WebCore/bindings/js/JSBlobCustom.cpp

    r154127 r159275  
    7272    }
    7373
    74     JSValue firstArg = exec->argument(0);
    75     if (!isJSArray(firstArg))
    76         return throwVMError(exec, createTypeError(exec, "First argument of the constructor is not of type Array"));
     74    unsigned blobPartsLength = 0;
     75    JSObject* blobParts = toJSSequence(exec, exec->argument(0), blobPartsLength);
     76    if (exec->hadException())
     77        return JSValue::encode(jsUndefined());
     78    ASSERT(blobParts);
    7779
    7880    String type;
     
    111113    BlobBuilder blobBuilder;
    112114
    113     JSArray* array = asArray(firstArg);
    114     unsigned length = array->length();
    115 
    116     for (unsigned i = 0; i < length; ++i) {
    117         JSValue item = array->getIndex(exec, i);
     115    for (unsigned i = 0; i < blobPartsLength; ++i) {
     116        JSValue item = blobParts->get(exec, i);
    118117#if ENABLE(BLOB)
    119118        if (item.inherits(JSArrayBuffer::info()))
  • trunk/Source/WebCore/bindings/js/JSDOMBinding.h

    r158997 r159275  
    120120    return static_cast<WebCoreTypedArrayController*>(world.vm()->m_typedArrayController.get())->wrapperOwner();
    121121}
    122    
     122
    123123inline void* wrapperContext(DOMWrapperWorld& world, JSC::ArrayBuffer*)
    124124{
     
    198198    weakRemove(world.m_wrappers, (void*)domObject, wrapper);
    199199}
    200    
     200
    201201#define CREATE_DOM_WRAPPER(exec, globalObject, className, object) createWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
    202202template<class WrapperClass, class DOMClass> inline JSDOMWrapper* createWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
     
    252252    return jsStringWithCache(exec, s.string());
    253253}
    254        
     254
    255255JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null
    256256JSC::JSValue jsStringOrNull(JSC::ExecState*, const URL&); // null if the URL is null
     
    326326    JSC::JSObject* object = value.getObject();
    327327    if (!object) {
    328         throwTypeError(exec);
     328        throwVMError(exec, createTypeError(exec, "Value is not a sequence"));
    329329        return 0;
    330330    }
     
    335335
    336336    if (lengthValue.isUndefinedOrNull()) {
    337         throwTypeError(exec);
     337        throwVMError(exec, createTypeError(exec, "Value is not a sequence"));
    338338        return 0;
    339339    }
     
    375375{
    376376    JSC::JSArray* array = constructEmptyArray(exec, 0, vector.size());
    377    
     377
    378378    for (size_t i = 0; i < vector.size(); ++i)
    379379        array->putDirectIndex(exec, i, toJS(exec, globalObject, vector[i]));
    380    
     380
    381381    return array;
    382382}
     
    386386{
    387387    JSC::JSArray* array = constructEmptyArray(exec, 0, vector.size());
    388    
     388
    389389    for (size_t i = 0; i < vector.size(); ++i)
    390390        array->putDirectIndex(exec, i, toJS(exec, globalObject, vector[i].get()));
    391    
     391
    392392    return array;
    393393}
     
    429429{
    430430    JSC::MarkedArgumentBuffer list;
    431     typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();       
     431    typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
    432432    typedef JSValueTraits<T> TraitsType;
    433433
Note: See TracChangeset for help on using the changeset viewer.