window.crypto.getRandomValues should return the input ArrayBufferView

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: http://svn.webkit.org/repository/webkit/trunk@138298 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 838edde6
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.
......@@ -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)
......
......@@ -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
......
......@@ -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>
......
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
......@@ -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 \
......
......@@ -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 \
......
......@@ -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
......
......@@ -1308,6 +1308,7 @@
'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',
......
......@@ -697,6 +697,7 @@
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, ); }; };
......@@ -7888,6 +7889,7 @@
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>"; };
......@@ -20618,6 +20620,7 @@
BC4EDEF70C08F414007EDD49 /* Custom */ = {
isa = PBXGroup;
children = (
209B456A16796A7E00E54E4E /* JSCryptoCustom.cpp */,
BC275CB211C5E85C00C9206C /* JSArrayBufferCustom.cpp */,
86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */,
BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */,
......@@ -29096,6 +29099,7 @@
9A9CEF8D163B3EA100DE7EFE /* ExclusionShapeOutsideInfo.cpp in Sources */,
0FB8890B167D2FA10010CDA5 /* ScrollingTreeStickyNode.mm in Sources */,
0FB8890E167D30160010CDA5 /* ScrollingStateStickyNode.cpp in Sources */,
209B456B16796A7E00E54E4E /* JSCryptoCustom.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -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"
......
/*
* 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
/*
* 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
......@@ -29,6 +29,6 @@
[
OmitConstructor
] interface Crypto {
void getRandomValues(in ArrayBufferView array) raises(DOMException);
[Custom] ArrayBufferView getRandomValues(in ArrayBufferView array) raises(DOMException);
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment