Title: [115599] trunk
Revision
115599
Author
[email protected]
Date
2012-04-29 13:08:39 -0700 (Sun, 29 Apr 2012)

Log Message

Add support for the Blob constructor (Part 2)
https://bugs.webkit.org/show_bug.cgi?id=84555

Address additional feedback on Blob construction.
- Add exception when the dictionary is not an object.
- Ensure the proper ordering of dictionary access. Tested via
  throwing exceptions in toString, and ensuring correct one is
  fired first.
- Changed type of exception throw for invalid enumeration to a
  TypeError.

Patch by Sam Weinig <[email protected]> on 2012-04-29
Reviewed by Kentaro Hara.

Source/WebCore:

Updated fast/files/blob-constructor.html to be more comprehensive.

* bindings/js/JSBlobCustom.cpp:
(WebCore::JSBlobConstructor::constructJSBlob):
* bindings/v8/custom/V8BlobCustom.cpp:
(WebCore::V8Blob::constructorCallback):

LayoutTests:

* fast/files/blob-constructor-expected.txt:
* fast/files/script-tests/blob-constructor.js:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (115598 => 115599)


--- trunk/LayoutTests/ChangeLog	2012-04-29 18:22:22 UTC (rev 115598)
+++ trunk/LayoutTests/ChangeLog	2012-04-29 20:08:39 UTC (rev 115599)
@@ -1,3 +1,21 @@
+2012-04-29  Sam Weinig  <[email protected]>
+
+        Add support for the Blob constructor (Part 2)
+        https://bugs.webkit.org/show_bug.cgi?id=84555
+
+        Address additional feedback on Blob construction.
+        - Add exception when the dictionary is not an object.
+        - Ensure the proper ordering of dictionary access. Tested via
+          throwing exceptions in toString, and ensuring correct one is
+          fired first.
+        - Changed type of exception throw for invalid enumeration to a
+          TypeError.
+
+        Reviewed by Kentaro Hara.
+
+        * fast/files/blob-constructor-expected.txt:
+        * fast/files/script-tests/blob-constructor.js:
+
 2012-04-29  Sudarsana Nagineni  <[email protected]>
 
         [GTK] DRT needs an implementation of layoutTestController.setDomainRelaxationForbiddenForURLScheme

Modified: trunk/LayoutTests/fast/files/blob-constructor-expected.txt (115598 => 115599)


--- trunk/LayoutTests/fast/files/blob-constructor-expected.txt	2012-04-29 18:22:22 UTC (rev 115598)
+++ trunk/LayoutTests/fast/files/blob-constructor-expected.txt	2012-04-29 20:08:39 UTC (rev 115599)
@@ -23,18 +23,21 @@
 PASS (new Blob([{}])).size is 15
 PASS (new Blob([document])).size is 21
 PASS (new Blob([toStringingObj])).size is 8
-PASS new Blob([throwingObj]) threw exception error.
+PASS new Blob([throwingObj]) threw exception Error.
 PASS (new Blob([], {unknownKey:'value'})) instanceof window.Blob is true
-PASS new Blob([], {endings:'illegalValue'}) threw exception Error: INVALID_STATE_ERR: DOM Exception 11.
-PASS new Blob([], {endings:throwingObj}) threw exception error.
-PASS new Blob([], {type:throwingObj}) threw exception error.
-PASS (new Blob([], null)) instanceof window.Blob is true
-PASS (new Blob([], undefined)) instanceof window.Blob is true
-PASS (new Blob([], 123)) instanceof window.Blob is true
-PASS (new Blob([], 123.4)) instanceof window.Blob is true
+PASS new Blob([], {endings:'illegalValue'}) threw exception TypeError: The endings property must be either "transparent" or "native".
+PASS new Blob([], {endings:throwingObj}) threw exception Error.
+PASS new Blob([], {type:throwingObj}) threw exception Error.
+PASS new Blob([], {endings:throwingObj1, type:throwingObj2}) threw exception Error 1.
+PASS new Blob([], {type:throwingObj2, endings:throwingObj1}) threw exception Error 1.
+PASS new Blob([], {type:throwingObj2, endings:'illegal'}) threw exception TypeError: The endings property must be either "transparent" or "native".
+PASS (new Blob([], null)) instanceof window.Blob threw exception TypeError: Second argument of the constructor is not of type Object.
+PASS (new Blob([], undefined)) instanceof window.Blob threw exception TypeError: Second argument of the constructor is not of type Object.
+PASS (new Blob([], 123)) instanceof window.Blob threw exception TypeError: Second argument of the constructor is not of type Object.
+PASS (new Blob([], 123.4)) instanceof window.Blob threw exception TypeError: Second argument of the constructor is not of type Object.
+PASS (new Blob([], true)) instanceof window.Blob threw exception TypeError: Second argument of the constructor is not of type Object.
+PASS (new Blob([], 'abc')) instanceof window.Blob threw exception TypeError: Second argument of the constructor is not of type Object.
 PASS (new Blob([], [])) instanceof window.Blob is true
-PASS (new Blob([], true)) instanceof window.Blob is true
-PASS (new Blob([], 'abc')) instanceof window.Blob is true
 PASS (new Blob([], /abc/)) instanceof window.Blob is true
 PASS (new Blob([], function () {})) instanceof window.Blob is true
 PASS (new Blob([], {type:'text/html'})).type is 'text/html'

Modified: trunk/LayoutTests/fast/files/script-tests/blob-constructor.js (115598 => 115599)


--- trunk/LayoutTests/fast/files/script-tests/blob-constructor.js	2012-04-29 18:22:22 UTC (rev 115598)
+++ trunk/LayoutTests/fast/files/script-tests/blob-constructor.js	2012-04-29 20:08:39 UTC (rev 115599)
@@ -9,9 +9,9 @@
 shouldBeTrue("(new Blob(['hello'], {type:'text/html', endings:'native'})) instanceof window.Blob");
 shouldBeTrue("(new Blob(['hello'], {type:'text/html', endings:'transparent'})) instanceof window.Blob");
 
-// Test some error cases
-shouldThrow("new Blob('hello')");
-shouldThrow("new Blob(0)");
+// Test invalid blob parts
+shouldThrow("new Blob('hello')", "'TypeError: First argument of the constructor is not of type Array'");
+shouldThrow("new Blob(0)", "'TypeError: First argument of the constructor is not of type Array'");
 
 // Test valid blob parts.
 shouldBeTrue("(new Blob([])) instanceof window.Blob");
@@ -30,27 +30,33 @@
 var toStringingObj = { toString: function() { return "A string"; } };
 shouldBe("(new Blob([toStringingObj])).size", "8");
 
-var throwingObj = { toString: function() { throw "error"; } };
-shouldThrow("new Blob([throwingObj])");
+var throwingObj = { toString: function() { throw "Error"; } };
+shouldThrow("new Blob([throwingObj])", "'Error'");
 
-
 // Test some invalid property bags
 shouldBeTrue("(new Blob([], {unknownKey:'value'})) instanceof window.Blob");    // Ignore invalid keys
-shouldThrow("new Blob([], {endings:'illegalValue'})");                          // Throw for invalid value to endings
-shouldThrow("new Blob([], {endings:throwingObj})");                             // Throws during toString
-shouldThrow("new Blob([], {type:throwingObj})");                                // Throws during toString
+shouldThrow("new Blob([], {endings:'illegalValue'})", "'TypeError: The endings property must be either \"transparent\" or \"native\"'");
+shouldThrow("new Blob([], {endings:throwingObj})", "'Error'");
+shouldThrow("new Blob([], {type:throwingObj})", "'Error'");
 
-shouldBeTrue("(new Blob([], null)) instanceof window.Blob");
-shouldBeTrue("(new Blob([], undefined)) instanceof window.Blob");
-shouldBeTrue("(new Blob([], 123)) instanceof window.Blob");
-shouldBeTrue("(new Blob([], 123.4)) instanceof window.Blob");
+// Test that order of property bag evaluation is lexigraphical
+var throwingObj1 = { toString: function() { throw "Error 1"; } };
+var throwingObj2 = { toString: function() { throw "Error 2"; } };
+shouldThrow("new Blob([], {endings:throwingObj1, type:throwingObj2})", "'Error 1'");
+shouldThrow("new Blob([], {type:throwingObj2, endings:throwingObj1})", "'Error 1'");
+shouldThrow("new Blob([], {type:throwingObj2, endings:'illegal'})", "'TypeError: The endings property must be either \"transparent\" or \"native\"'");
+
+// Test various non-object literals being used as property bags
+shouldThrow("(new Blob([], null)) instanceof window.Blob", "'TypeError: Second argument of the constructor is not of type Object'");
+shouldThrow("(new Blob([], undefined)) instanceof window.Blob", "'TypeError: Second argument of the constructor is not of type Object'");
+shouldThrow("(new Blob([], 123)) instanceof window.Blob", "'TypeError: Second argument of the constructor is not of type Object'");
+shouldThrow("(new Blob([], 123.4)) instanceof window.Blob", "'TypeError: Second argument of the constructor is not of type Object'");
+shouldThrow("(new Blob([], true)) instanceof window.Blob", "'TypeError: Second argument of the constructor is not of type Object'");
+shouldThrow("(new Blob([], 'abc')) instanceof window.Blob", "'TypeError: Second argument of the constructor is not of type Object'");
 shouldBeTrue("(new Blob([], [])) instanceof window.Blob");
-shouldBeTrue("(new Blob([], true)) instanceof window.Blob");
-shouldBeTrue("(new Blob([], 'abc')) instanceof window.Blob");
 shouldBeTrue("(new Blob([], /abc/)) instanceof window.Blob");
 shouldBeTrue("(new Blob([], function () {})) instanceof window.Blob");
 
-
 // Test that the type/size is correctly added to the Blob
 shouldBe("(new Blob([], {type:'text/html'})).type", "'text/html'");
 shouldBe("(new Blob([], {type:'text/html'})).size", "0");

Modified: trunk/Source/WebCore/ChangeLog (115598 => 115599)


--- trunk/Source/WebCore/ChangeLog	2012-04-29 18:22:22 UTC (rev 115598)
+++ trunk/Source/WebCore/ChangeLog	2012-04-29 20:08:39 UTC (rev 115599)
@@ -1,3 +1,25 @@
+2012-04-29  Sam Weinig  <[email protected]>
+
+        Add support for the Blob constructor (Part 2)
+        https://bugs.webkit.org/show_bug.cgi?id=84555
+
+        Address additional feedback on Blob construction.
+        - Add exception when the dictionary is not an object.
+        - Ensure the proper ordering of dictionary access. Tested via
+          throwing exceptions in toString, and ensuring correct one is
+          fired first.
+        - Changed type of exception throw for invalid enumeration to a
+          TypeError.
+
+        Reviewed by Kentaro Hara.
+
+        Updated fast/files/blob-constructor.html to be more comprehensive.
+
+        * bindings/js/JSBlobCustom.cpp:
+        (WebCore::JSBlobConstructor::constructJSBlob):
+        * bindings/v8/custom/V8BlobCustom.cpp:
+        (WebCore::V8Blob::constructorCallback):
+
 2012-04-29  No'am Rosenthal  <[email protected]>
 
         [Texmap] Leaves demo: wrong geometry when opacity animation kicks in

Modified: trunk/Source/WebCore/bindings/js/JSBlobCustom.cpp (115598 => 115599)


--- trunk/Source/WebCore/bindings/js/JSBlobCustom.cpp	2012-04-29 18:22:22 UTC (rev 115598)
+++ trunk/Source/WebCore/bindings/js/JSBlobCustom.cpp	2012-04-29 20:08:39 UTC (rev 115599)
@@ -80,32 +80,29 @@
     if (exec->argumentCount() > 1) {
         JSValue blobPropertyBagValue = exec->argument(1);
 
-        // FIXME: Should we throw if the blobPropertyBag is not an object?
+        if (!blobPropertyBagValue.isObject())
+            return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type Object"));
 
-        if (blobPropertyBagValue.isObject()) {
-            // Given the above test, this will always yield an object.
-            JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec);
+        // Given the above test, this will always yield an object.
+        JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec);
 
-            // Create the dictionary wrapper from the initializer object.
-            JSDictionary dictionary(exec, blobPropertyBagObject);
+        // Create the dictionary wrapper from the initializer object.
+        JSDictionary dictionary(exec, blobPropertyBagObject);
 
-            // Attempt to get the type property.
-            dictionary.get("type", type);
-            if (exec->hadException())
-                return JSValue::encode(jsUndefined());
+        // Attempt to get the endings property and validate it.
+        bool containsEndings = dictionary.get("endings", endings);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
 
-            // Attempt to get the endings property and validate it.
-            bool containsEndings = dictionary.get("endings", endings);
-            if (exec->hadException())
-                return JSValue::encode(jsUndefined());
-
-            if (containsEndings) {
-                if (endings != "transparent" && endings != "native") {
-                    setDOMException(exec, INVALID_STATE_ERR);
-                    return JSValue::encode(jsUndefined());
-                }
-            }
+        if (containsEndings) {
+            if (endings != "transparent" && endings != "native")
+                return throwVMError(exec, createTypeError(exec, "The endings property must be either \"transparent\" or \"native\""));
         }
+
+        // Attempt to get the type property.
+        dictionary.get("type", type);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
     }
 
     ASSERT(endings == "transparent" || endings == "native");

Modified: trunk/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp (115598 => 115599)


--- trunk/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp	2012-04-29 18:22:22 UTC (rev 115598)
+++ trunk/Source/WebCore/bindings/v8/custom/V8BlobCustom.cpp	2012-04-29 20:08:39 UTC (rev 115599)
@@ -79,36 +79,39 @@
     if (!firstArg->IsArray())
         return throwError("First argument of the constructor is not of type Array", V8Proxy::TypeError);
 
-    EXCEPTION_BLOCK(v8::Local<v8::Array>, blobParts, v8::Local<v8::Array>::Cast(firstArg));
-
     String type;
     String endings = "transparent";
 
-    if (args.Length() > 1 && args[1]->IsObject()) {
+    if (args.Length() > 1) {
+        if (!args[1]->IsObject())
+            return throwError("Second argument of the constructor is not of type Object", V8Proxy::TypeError);
+
         Dictionary dictionary(args[1]);
 
-        v8::TryCatch tryCatchType;
-        dictionary.get("type", type);
-        if (tryCatchType.HasCaught())
-            return throwError(tryCatchType.Exception());
-
         v8::TryCatch tryCatchEndings;
         bool containsEndings = dictionary.get("endings", endings);
         if (tryCatchEndings.HasCaught())
             return throwError(tryCatchEndings.Exception());
 
         if (containsEndings) {
-            if (endings != "transparent" && endings != "native") {
-                V8Proxy::setDOMException(INVALID_STATE_ERR, args.GetIsolate());
-                return v8::Undefined();
-            }
+            if (endings != "transparent" && endings != "native")
+                return throwError("The endings property must be either \"transparent\" or \"native\"", V8Proxy::TypeError);
         }
+
+        v8::TryCatch tryCatchType;
+        dictionary.get("type", type);
+        if (tryCatchType.HasCaught())
+            return throwError(tryCatchType.Exception());
     }
 
     ASSERT(endings == "transparent" || endings == "native");
 
     RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create();
-    for (uint32_t i = 0; i < blobParts->Length(); ++i) {
+
+    EXCEPTION_BLOCK(v8::Local<v8::Array>, blobParts, v8::Local<v8::Array>::Cast(firstArg));
+    uint32_t length = blobParts->Length();
+
+    for (uint32_t i = 0; i < length; ++i) {
         v8::Local<v8::Value> item = blobParts->Get(v8::Uint32::New(i));
         ASSERT(!item.IsEmpty());
 #if ENABLE(BLOB)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to