diff options
author | Fraser Adams <fraser.adams@blueyonder.co.uk> | 2014-01-02 16:40:09 +0000 |
---|---|---|
committer | Fraser Adams <fraser.adams@blueyonder.co.uk> | 2014-01-02 16:40:09 +0000 |
commit | 385a660a1868dc1777b251dfcf83371ccd388b02 (patch) | |
tree | c254e924656076501441b607364e2a67232e419d | |
parent | 32e1d73d605a7c4c3dc162b7c0d626b3dcce27ce (diff) |
Added crypto quality random number generators for Node.js and browser environment if available
-rw-r--r-- | src/library_uuid.js | 30 | ||||
-rw-r--r-- | tests/test_browser.py | 20 | ||||
-rw-r--r-- | tests/test_other.py | 11 | ||||
-rw-r--r-- | tests/uuid/test.c | 12 |
4 files changed, 54 insertions, 19 deletions
diff --git a/src/library_uuid.js b/src/library_uuid.js index 0c1bdf91..cce0a4f8 100644 --- a/src/library_uuid.js +++ b/src/library_uuid.js @@ -27,12 +27,30 @@ mergeInto(LibraryManager.library, { // tweaked slightly in order to use the 'compact' UUID form used by libuuid. uuid_generate: function(out) { // void uuid_generate(uuid_t out); - var uuid = new Array(16); - var d = new Date().getTime(); - for (var i = 0; i < 16; i++) { - var r = (d + Math.random()*256)%256 | 0; - d = Math.floor(d/256); - uuid[i] = r; + var uuid = null; + + if (ENVIRONMENT_IS_NODE) { + // If Node.js try to use crypto.randomBytes + try { + var rb = require('crypto').randomBytes; + uuid = rb(16); + } catch(e) {} + } else if (typeof(window.crypto) != 'undefined' && + typeof(window.crypto.getRandomValues) != 'undefined') { + // If crypto.getRandomValues is available try to use it. + uuid = new Uint8Array(16); + window.crypto.getRandomValues(uuid); + } + + // Fall back to Math.random if a higher quality random number generator is not available. + if (!uuid) { + uuid = new Array(16); + var d = new Date().getTime(); + for (var i = 0; i < 16; i++) { + var r = (d + Math.random()*256)%256 | 0; + d = Math.floor(d/256); + uuid[i] = r; + } } uuid[6] = (uuid[6] & 0x0F) | 0x40; diff --git a/tests/test_browser.py b/tests/test_browser.py index 920c6f8c..3d344c14 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -1717,3 +1717,23 @@ keydown(100);keyup(100); // trigger the end assert 'argv[3]: 3' in stdout assert 'hello, world!' in stdout assert 'hello, error stream!' in stderr + + def test_uuid(self): + # Run with ./runner.py browser.test_uuid + # We run this test in Node/SPIDERMONKEY and browser environments because we try to make use of + # high quality crypto random number generators such as crypto.getRandomValues or randomBytes (if available). + + # First run tests in Node and/or SPIDERMONKEY using run_js + Popen([PYTHON, EMCC, path_from_root('tests', 'uuid', 'test.c'), '-o', path_from_root('tests', 'uuid', 'test.js')], stdout=PIPE, stderr=PIPE).communicate() + + out = run_js(path_from_root('tests', 'uuid', 'test.js'), full_output=True) + print out + + # Tidy up files that might have been created by this test. + try_delete(path_from_root('tests', 'uuid', 'test.js')) + try_delete(path_from_root('tests', 'uuid', 'test.js.map')) + + # Now run test in browser + self.btest(path_from_root('tests', 'uuid', 'test.c'), '1') + + diff --git a/tests/test_other.py b/tests/test_other.py index f229fef1..c75362af 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2197,14 +2197,3 @@ mergeInto(LibraryManager.library, { process.communicate() assert(os.path.isfile(outdir + 'hello_world.obj')) - def test_uuid(self): - # Run with ./runner.py other.test_uuid - Popen([PYTHON, EMCC, path_from_root('tests', 'uuid', 'test.c'), '-o', path_from_root('tests', 'uuid', 'test.js')], stdout=PIPE, stderr=PIPE).communicate() - - out = run_js(path_from_root('tests', 'uuid', 'test.js'), full_output=True) - print out - - # Tidy up files that might have been created by this test. - try_delete(path_from_root('tests', 'uuid', 'test.js')) - try_delete(path_from_root('tests', 'uuid', 'test.js.map')) - diff --git a/tests/uuid/test.c b/tests/uuid/test.c index ea3b116c..dc2c6589 100644 --- a/tests/uuid/test.c +++ b/tests/uuid/test.c @@ -1,8 +1,9 @@ - #include <uuid/uuid.h> #include <assert.h> +#include <ctype.h> #include <stdio.h> #include <stdlib.h> +#include <emscripten.h> int isUUID(char* p, int upper) { char* p1 = p; @@ -56,6 +57,13 @@ int main() { assert(uuid_is_null(uuid) == 1); - return 0; + // The following lets the browser test exit cleanly. + int result = 1; + #if EMSCRIPTEN + #ifdef REPORT_RESULT + REPORT_RESULT(); + #endif + #endif + exit(0); } |