<!DOCTYPE HTML> <html><head> <title>Test window.crypto.getRandomValues</title> <script type="text/javascript" src="/MochiKit/packed.js"></script> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body onload="onWindowLoad()"> <script class="testbody" type="text/javascript"> SimpleTest.waitForExplicitFinish(); var testData = [ { len: 32, type: "Int8", pass: true }, { len: 32, type: "Int16", pass: true }, { len: 32, type: "Int32", pass: true }, { len: 32, type: "Uint8", pass: true }, { len: 32, type: "Uint16", pass: true }, { len: 32, type: "Uint32", pass: true }, { len: 65536, type: "Uint8", pass: true }, { len: 32, type: "Uint8Clamped", pass: true }, { len: 65537, type: "Uint8", pass: false }, { len: 32, type: "Float32", pass: false }, { len: 32, type: "Float64", pass: false } ]; var testCount = 0; function testNsCryptoGetRandomValues(aLength, aType) { var arrayTypes = { Int8: Int8Array, Int16: Int16Array, Int32: Int32Array, Uint8: Uint8Array, Uint16: Uint16Array, Uint32: Uint32Array, Float32: Float32Array, Float64: Float64Array, Uint8Clamped: Uint8ClampedArray, }; testCount++; var buf = new ArrayBuffer(aLength); var arBuf = new arrayTypes[aType](buf); var pass = false; var b = window.crypto.getRandomValues(arBuf); ok(b === arBuf, "ArrayBuffer result is argument buffer"); for (var i = 0; i < arBuf.length; i++) { if (arBuf.length > 6) { // XXXddahl: THIS MIGHT FAIL EVERY FULL MOON, SORRY QA!!! if (arBuf[i] != 0) { pass = true; break; } } else { pass = true; } } is(pass, true, "Non-zero result: " + i + " found in the " + aType + ": " + aLength + " ArrayBufferView"); } function onWindowLoad() { window.removeEventListener("load", onWindowLoad, false); var failedWithCorrectError = false; try { for (var i = 0; i < testData.length; i++) { if (testData[i].pass) { try { testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass); } catch (ex) { ok(false, "testNsCryptoGetRandomValues failed, test should have passed: " + testData[i].type); } } else { // failing tests are dealt with here if (i == 8) { try { testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass); } catch (ex) { todo("QuotaExceededError" in window && ex instanceof QuotaExceededError, "Exception was the correct type"); failedWithCorrectError = ex.toString().search(/QUOTA_EXCEEDED_ERR/); ok(failedWithCorrectError, "Extended length array buffer fails, NS_ERROR_DOM_QUOTA_EXCEEDED_ERR thrown"); } } // 8 if (i == 9) { try { testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass); } catch (ex) { failedWithCorrectError = ex.toString().search(/TYPE_MISMATCH_ERR/); ok(failedWithCorrectError, "Expected TYPE_MISMATCH_ERR: Float32Array is not valid, got " + ex + "."); } } // 9 if (i == 10) { try { testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass); } catch (ex) { failedWithCorrectError = ex.toString().search(/TYPE_MISMATCH_ERR/); ok(failedWithCorrectError, "Expected TYPE_MISMATCH_ERR: Float64Array is not valid, got " + ex + "."); } } } } // end main for loop } catch (ex) { ok(false, "Unexpected Error: " + ex); } // Count the tests in the testData array ok(testCount == 11, "11 tests run via testData"); // Test a null argument try { window.crypto.getRandomValues(null); } catch (ex) { var test = ex.toString().search(/1003|TypeError/); ok((test > -1), "Expected TYPE_ERR, got " + ex + "."); } // Test a zero-length buffer view try { var a = new Int8Array(0); window.crypto.getRandomValues(a); ok(a[0] === undefined, "The array buffer is unchanged, still 0 length"); } catch (ex) { ok(false, "A zero-length array buffer view should not fail"); } // Test a one-length buffer view var randomVal = 0; // The probability of getRandomValues generating a zero value is 1/256 so we // run this in a loop until it returns a non-zero value to guard against // false failures do { try { var a = new Uint8Array(1); var b = window.crypto.getRandomValues(a); randomVal = a[0]; ok(a === b, "ArrayBuffer result is argument buffer"); } catch (ex) { ok(false, "A one-length array buffer view should not fail"); } } while (randomVal == 0); ok(randomVal !== 0, "The array buffer eventually had one random value"); // Test a 16 byte length buffer var testConfig = { len: 16, type: "Int8", pass: true }; testNsCryptoGetRandomValues(testConfig.len, testConfig.type, testConfig.pass); // Test a 31 byte length buffer testConfig = { len: 31, type: "Int8", pass: true }; testNsCryptoGetRandomValues(testConfig.len, testConfig.type, testConfig.pass); // Test a 33 byte length buffer testConfig = { len: 33, type: "Int8", pass: true }; testNsCryptoGetRandomValues(testConfig.len, testConfig.type, testConfig.pass); // Test a range of an array buffer view var buffer = new ArrayBuffer(32); var view = new Int8Array(buffer, 0, 16); var view2 = new Int8Array(buffer, 16, 16); for (var i = 0; i < view2.byteLength; i++) { view2[i] = 1; } var b = window.crypto.getRandomValues(view); ok(b === view, "ArrayBuffer result is argument buffer"); for (var i = 0; i < view.byteLength; i++) { is(view2[i], 1, "view2 is unchanged"); } // test an offset view var result = false; var b = window.crypto.getRandomValues(view2); for (var i = 0; i < view2.length; i++) { if (view2[i] != 1) { result = true; break; } } ok(result, "view2 has been updated correctly"); ok(b === view2, "ArrayBuffer result is argument buffer"); // test the return value buffer = new ArrayBuffer(32); view = new Int8Array(buffer, 0, 16); var retval = window.crypto.getRandomValues(view); ok(view === retval, "The view and return value are the same"); SimpleTest.finish(); } </script> </body></html>