window.crypto.getRandomValues should return the input ArrayBufferView
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Dec 2012 22:12:40 +0000 (22:12 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Dec 2012 22:12:40 +0000 (22:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=104845

Source/WebCore:

The W3C Web Crypto API FPWD, as well as the WHATWG February 2012 draft,
define crypto.getRandomValues() as returning the input ArrayBufferView,
to allow function call chaining. Update the implementation to match
the current spec, rather than the old spec of void/undefined.

Patch by Ryan Sleevi <rsleevi@chromium.org> on 2012-12-20
Reviewed by Kentaro Hara.

Test: security/crypto-random-values-types.html

* GNUmakefile.list.am:
* Target.pri:
* UseJSC.cmake:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSBindingsAllInOne.cpp:
* bindings/js/JSCryptoCustom.cpp: Added.
(WebCore):
(WebCore::JSCrypto::getRandomValues):
Added custom getRandomValues implementation so that the input wrapped
ArrayBufferView can be returned directly to the caller. This is to
preserve the underlying type and indexing accessor for the TypedArray
subclass.
* bindings/v8/custom/V8CryptoCustom.cpp: Added.
(WebCore):
(WebCore::V8Crypto::getRandomValuesCallback):
Added custom getRandomValues implementation so that the input wrapped
ArrayBufferView can be returned directly to the caller. This is to
preserve the underlying type and indexing accessor for the TypedArray
subclass.
* page/Crypto.idl:

LayoutTests:

Patch by Ryan Sleevi <rsleevi@chromium.org> on 2012-12-20
Reviewed by Kentaro Hara.

* fast/js/resources/js-test-pre.js:
(shouldBeType):
Added helper to assert that an expression returns an object of the
correct type.
* security/crypto-random-values-types-expected.txt:
* security/crypto-random-values-types.html:
Test all possible TypedArray integer types and ensure that both the
correct TypedArray type is returned and that it is equal to the input
type; that is, that the input type is modified in place, rather then
copied.

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/js/resources/js-test-pre.js
LayoutTests/security/crypto-random-values-types-expected.txt
LayoutTests/security/crypto-random-values-types.html
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/UseJSC.cmake
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
Source/WebCore/bindings/js/JSCryptoCustom.cpp [new file with mode: 0644]
Source/WebCore/bindings/v8/custom/V8CryptoCustom.cpp [new file with mode: 0644]
Source/WebCore/page/Crypto.idl

index 40987fd..6229541 100644 (file)
@@ -1,3 +1,21 @@
+2012-12-20  Ryan Sleevi  <rsleevi@chromium.org>
+
+        window.crypto.getRandomValues should return the input ArrayBufferView
+        https://bugs.webkit.org/show_bug.cgi?id=104845
+
+        Reviewed by Kentaro Hara.
+
+        * fast/js/resources/js-test-pre.js:
+        (shouldBeType):
+        Added helper to assert that an expression returns an object of the
+        correct type.
+        * security/crypto-random-values-types-expected.txt:
+        * security/crypto-random-values-types.html:
+        Test all possible TypedArray integer types and ensure that both the
+        correct TypedArray type is returned and that it is equal to the input
+        type; that is, that the input type is modified in place, rather then
+        copied.
+
 2012-12-20  Tony Chang  <tony@chromium.org>
 
         [chromium] Unreviewed gardening.
index 26c0c5e..9a0c5d7 100644 (file)
@@ -188,6 +188,23 @@ function shouldBe(_a, _b, quiet)
     testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
 }
 
+function shouldBeType(_a, _type) {
+  var exception;
+  var _av;
+  try {
+    _av = eval(_a);
+  } catch (e) {
+    exception = e;
+  }
+
+  var _typev = eval(_type);
+  if (_av instanceof _typev) {
+    testPassed(_a + " is an instance of " + _type);
+  } else {
+    testFailed(_a + " is not an instance of " + _type);
+  }
+}
+
 // Variant of shouldBe()--confirms that result of eval(_to_eval) is within
 // numeric _tolerance of numeric _target.
 function shouldBeCloseTo(_to_eval, _target, _tolerance, quiet)
index 683de32..4213fd4 100644 (file)
@@ -5,13 +5,47 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 PASS 'crypto' in window is true
 PASS 'getRandomValues' in window.crypto is true
-PASS crypto.getRandomValues(new Uint8Array(3)) is undefined.
-PASS crypto.getRandomValues(new Int8Array(3)) is undefined.
-PASS crypto.getRandomValues(new Uint16Array(3)) is undefined.
-PASS crypto.getRandomValues(new Int16Array(3)) is undefined.
-PASS crypto.getRandomValues(new Uint32Array(3)) is undefined.
-PASS crypto.getRandomValues(new Int32Array(3)) is undefined.
+PASS random = crypto.getRandomValues(new Uint8Array(3)) is defined.
+PASS random is an instance of Uint8Array
+PASS view = new Uint8Array(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
+PASS random = crypto.getRandomValues(new Int8Array(3)) is defined.
+PASS random is an instance of Int8Array
+PASS view = new Int8Array(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
+PASS random = crypto.getRandomValues(new Uint8ClampedArray(3)) is defined.
+PASS random is an instance of Uint8ClampedArray
+PASS view = new Uint8ClampedArray(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
+PASS random = crypto.getRandomValues(new Uint16Array(3)) is defined.
+PASS random is an instance of Uint16Array
+PASS view = new Uint16Array(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
+PASS random = crypto.getRandomValues(new Int16Array(3)) is defined.
+PASS random is an instance of Int16Array
+PASS view = new Int16Array(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
+PASS random = crypto.getRandomValues(new Uint32Array(3)) is defined.
+PASS random is an instance of Uint32Array
+PASS view = new Uint32Array(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
+PASS random = crypto.getRandomValues(new Int32Array(3)) is defined.
+PASS random is an instance of Int32Array
+PASS view = new Int32Array(3) is defined.
+PASS random = crypto.getRandomValues(view) is defined.
+PASS random is view
 PASS crypto.getRandomValues(new Float32Array(3)) threw exception Error: TypeMismatchError: DOM Exception 17.
+PASS crypto.getRandomValues(new Float64Array(3)) threw exception Error: TypeMismatchError: DOM Exception 17.
+PASS buffer = new Uint8Array(32) is defined.
+PASS buffer.buffer is defined.
+PASS view = new DataView(buffer.buffer) is defined.
+PASS crypto.getRandomValues(view) threw exception Error: TypeMismatchError: DOM Exception 17.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 2fa5aec..377c593 100644 (file)
@@ -16,14 +16,38 @@ if (!window.ArrayBuffer)
 shouldBe("'crypto' in window", "true");
 shouldBe("'getRandomValues' in window.crypto", "true");
 
-shouldBeUndefined("crypto.getRandomValues(new Uint8Array(3))");
-shouldBeUndefined("crypto.getRandomValues(new Int8Array(3))");
-shouldBeUndefined("crypto.getRandomValues(new Uint16Array(3))");
-shouldBeUndefined("crypto.getRandomValues(new Int16Array(3))");
-shouldBeUndefined("crypto.getRandomValues(new Uint32Array(3))");
-shouldBeUndefined("crypto.getRandomValues(new Int32Array(3))");
-
-shouldThrow("crypto.getRandomValues(new Float32Array(3))");
+function checkIntegerTypes() {
+    var integerTypes = [
+        "Uint8Array", "Int8Array", "Uint8ClampedArray",
+        "Uint16Array", "Int16Array",
+        "Uint32Array", "Int32Array",
+    ];
+    integerTypes.forEach(function(arrayType) {
+        shouldBeDefined("random = crypto.getRandomValues(new "+arrayType+"(3))");
+        shouldBeType("random", arrayType);
+
+        shouldBeDefined("view = new "+arrayType+"(3)");
+        shouldBeDefined("random = crypto.getRandomValues(view)");
+        shouldBe("random", "view");
+    });
+}
+
+function checkNonIntegerTypes() {
+    var floatTypes = [
+        "Float32Array", "Float64Array",
+    ];
+    floatTypes.forEach(function(arrayType) {
+        shouldThrow("crypto.getRandomValues(new "+arrayType+"(3))");
+    });
+
+    shouldBeDefined("buffer = new Uint8Array(32)");
+    shouldBeDefined("buffer.buffer");
+    shouldBeDefined("view = new DataView(buffer.buffer)");
+    shouldThrow("crypto.getRandomValues(view)");
+}
+
+checkIntegerTypes();
+checkNonIntegerTypes();
 
 </script>
 <script src="../fast/js/resources/js-test-post.js"></script>
index fcc4efb..e25f70f 100644 (file)
@@ -1,3 +1,39 @@
+2012-12-20  Ryan Sleevi  <rsleevi@chromium.org>
+
+        window.crypto.getRandomValues should return the input ArrayBufferView
+        https://bugs.webkit.org/show_bug.cgi?id=104845
+
+        The W3C Web Crypto API FPWD, as well as the WHATWG February 2012 draft,
+        define crypto.getRandomValues() as returning the input ArrayBufferView,
+        to allow function call chaining. Update the implementation to match
+        the current spec, rather than the old spec of void/undefined.
+
+        Reviewed by Kentaro Hara.
+
+        Test: security/crypto-random-values-types.html
+
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * UseJSC.cmake:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSBindingsAllInOne.cpp:
+        * bindings/js/JSCryptoCustom.cpp: Added.
+        (WebCore):
+        (WebCore::JSCrypto::getRandomValues):
+        Added custom getRandomValues implementation so that the input wrapped
+        ArrayBufferView can be returned directly to the caller. This is to
+        preserve the underlying type and indexing accessor for the TypedArray
+        subclass.
+        * bindings/v8/custom/V8CryptoCustom.cpp: Added.
+        (WebCore):
+        (WebCore::V8Crypto::getRandomValuesCallback):
+        Added custom getRandomValues implementation so that the input wrapped
+        ArrayBufferView can be returned directly to the caller. This is to
+        preserve the underlying type and indexing accessor for the TypedArray
+        subclass.
+        * page/Crypto.idl:
+
 2012-12-20  Erik Arvidsson  <arv@chromium.org>
 
         CodeGen: Make [Reflect] use getIdAttribute and getNameAttribute
index 5ea3af2..18f0487 100644 (file)
@@ -2274,6 +2274,7 @@ webcore_sources += \
        Source/WebCore/bindings/js/JSClipboardCustom.cpp \
        Source/WebCore/bindings/js/JSConsoleCustom.cpp \
        Source/WebCore/bindings/js/JSCoordinatesCustom.cpp \
+       Source/WebCore/bindings/js/JSCryptoCustom.cpp \
        Source/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp \
        Source/WebCore/bindings/js/JSCustomXPathNSResolver.cpp \
        Source/WebCore/bindings/js/JSCustomXPathNSResolver.h \
index e6d47f6..b1bb8f3 100644 (file)
@@ -86,6 +86,7 @@ SOURCES += \
      bindings/js/JSClipboardCustom.cpp \
      bindings/js/JSConsoleCustom.cpp \
      bindings/js/JSCoordinatesCustom.cpp \
+     bindings/js/JSCryptoCustom.cpp \
      bindings/js/JSCustomXPathNSResolver.cpp \
      bindings/js/JSDictionary.cpp \
      bindings/js/JSDOMBinding.cpp \
index 5644af5..c0caf87 100644 (file)
@@ -49,6 +49,7 @@ list(APPEND WebCore_SOURCES
     bindings/js/JSClipboardCustom.cpp
     bindings/js/JSConsoleCustom.cpp
     bindings/js/JSCoordinatesCustom.cpp
+    bindings/js/JSCryptoCustom.cpp
     bindings/js/JSCustomXPathNSResolver.cpp
     bindings/js/JSDictionary.cpp
     bindings/js/JSDOMBinding.cpp
index 253ddc4..3685a98 100644 (file)
             'bindings/v8/custom/V8ClipboardCustom.cpp',
             'bindings/v8/custom/V8ConsoleCustom.cpp',
             'bindings/v8/custom/V8CoordinatesCustom.cpp',
+            'bindings/v8/custom/V8CryptoCustom.cpp',
             'bindings/v8/custom/V8CustomEventCustom.cpp',
             'bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp',
             'bindings/v8/custom/V8CustomXPathNSResolver.cpp',
index 8353df8..ccfb894 100644 (file)
                1F3F19531499CA7600A5AEA7 /* PODFreeListArena.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3F19521499CA7600A5AEA7 /* PODFreeListArena.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1FAFBF1815A5FA6E00083A20 /* UTIUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FAFBF1715A5FA5200083A20 /* UTIUtilities.mm */; };
                1FAFBF1915A5FA7400083A20 /* UTIUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FAFBF1615A5FA5200083A20 /* UTIUtilities.h */; };
+               209B456B16796A7E00E54E4E /* JSCryptoCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 209B456A16796A7E00E54E4E /* JSCryptoCustom.cpp */; };
                20D629261253690B00081543 /* InspectorInstrumentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 20D629241253690B00081543 /* InspectorInstrumentation.cpp */; };
                20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 20D629251253690B00081543 /* InspectorInstrumentation.h */; };
                227777601345DEA9008EA455 /* InspectorFrontendChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 2277775F1345DEA9008EA455 /* InspectorFrontendChannel.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1F3F19521499CA7600A5AEA7 /* PODFreeListArena.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PODFreeListArena.h; sourceTree = "<group>"; };
                1FAFBF1615A5FA5200083A20 /* UTIUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UTIUtilities.h; sourceTree = "<group>"; };
                1FAFBF1715A5FA5200083A20 /* UTIUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UTIUtilities.mm; sourceTree = "<group>"; };
+               209B456A16796A7E00E54E4E /* JSCryptoCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCryptoCustom.cpp; sourceTree = "<group>"; };
                20D629241253690B00081543 /* InspectorInstrumentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorInstrumentation.cpp; sourceTree = "<group>"; };
                20D629251253690B00081543 /* InspectorInstrumentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentation.h; sourceTree = "<group>"; };
                2277775F1345DEA9008EA455 /* InspectorFrontendChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorFrontendChannel.h; sourceTree = "<group>"; };
                BC4EDEF70C08F414007EDD49 /* Custom */ = {
                        isa = PBXGroup;
                        children = (
+                               209B456A16796A7E00E54E4E /* JSCryptoCustom.cpp */,
                                BC275CB211C5E85C00C9206C /* JSArrayBufferCustom.cpp */,
                                86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */,
                                BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */,
                                9A9CEF8D163B3EA100DE7EFE /* ExclusionShapeOutsideInfo.cpp in Sources */,
                                0FB8890B167D2FA10010CDA5 /* ScrollingTreeStickyNode.mm in Sources */,
                                0FB8890E167D30160010CDA5 /* ScrollingStateStickyNode.cpp in Sources */,
+                               209B456B16796A7E00E54E4E /* JSCryptoCustom.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 357254c..8f71da5 100644 (file)
@@ -51,6 +51,7 @@
 #include "JSClipboardCustom.cpp"
 #include "JSConsoleCustom.cpp"
 #include "JSCoordinatesCustom.cpp"
+#include "JSCryptoCustom.cpp"
 #include "JSCustomSQLStatementErrorCallback.cpp"
 #include "JSCustomXPathNSResolver.cpp"
 #include "JSDictionary.cpp"
diff --git a/Source/WebCore/bindings/js/JSCryptoCustom.cpp b/Source/WebCore/bindings/js/JSCryptoCustom.cpp
new file mode 100644 (file)
index 0000000..a963a74
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCrypto.h"
+
+#include "ExceptionCode.h"
+#include "JSArrayBufferView.h"
+
+#include <runtime/Error.h>
+#include <wtf/ArrayBufferView.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSValue JSCrypto::getRandomValues(ExecState* exec)
+{
+    if (exec->argumentCount() < 1)
+        return throwError(exec, createNotEnoughArgumentsError(exec));
+
+    JSValue buffer = exec->argument(0);
+    ArrayBufferView* arrayBufferView = toArrayBufferView(buffer);
+    if (!arrayBufferView)
+        return throwTypeError(exec);
+
+    ExceptionCode ec = 0;
+    impl()->getRandomValues(arrayBufferView, ec);
+
+    if (ec) {
+        setDOMException(exec, ec);
+        return jsUndefined();
+    }
+
+    return buffer;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/custom/V8CryptoCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CryptoCustom.cpp
new file mode 100644 (file)
index 0000000..6323ddf
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8Crypto.h"
+
+#include "Crypto.h"
+#include "ExceptionCode.h"
+#include "V8ArrayBufferView.h"
+#include "V8Binding.h"
+#include "V8Utilities.h"
+
+#include <wtf/ArrayBufferView.h>
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8Crypto::getRandomValuesCallback(const v8::Arguments& args)
+{
+    if (args.Length() < 1)
+        return throwNotEnoughArgumentsError(args.GetIsolate());
+
+    v8::Handle<v8::Value> buffer = args[0];
+    if (!V8ArrayBufferView::HasInstance(buffer))
+        return throwTypeError("First argument is not an ArrayBufferView", args.GetIsolate());
+
+    ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8::Handle<v8::Object>::Cast(buffer));
+    ASSERT(arrayBufferView);
+
+    Crypto* crypto = V8Crypto::toNative(args.Holder());
+    ExceptionCode ec = 0;
+    crypto->getRandomValues(arrayBufferView, ec);
+
+    if (ec)
+        return setDOMException(ec, args.GetIsolate());
+
+    return buffer;    
+}
+
+} // namespace WebCore
index 589281a..5bec37a 100644 (file)
@@ -29,6 +29,6 @@
 [
     OmitConstructor
 ] interface Crypto {
-    void getRandomValues(in ArrayBufferView array) raises(DOMException);
+    [Custom] ArrayBufferView getRandomValues(in ArrayBufferView array) raises(DOMException);
 };