aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFraser Adams <fraser.adams@blueyonder.co.uk>2014-01-02 16:40:09 +0000
committerFraser Adams <fraser.adams@blueyonder.co.uk>2014-01-02 16:40:09 +0000
commit385a660a1868dc1777b251dfcf83371ccd388b02 (patch)
treec254e924656076501441b607364e2a67232e419d
parent32e1d73d605a7c4c3dc162b7c0d626b3dcce27ce (diff)
Added crypto quality random number generators for Node.js and browser environment if available
-rw-r--r--src/library_uuid.js30
-rw-r--r--tests/test_browser.py20
-rw-r--r--tests/test_other.py11
-rw-r--r--tests/uuid/test.c12
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);
}