Skip to content

Commit 0107766

Browse files
Jake ChampionJakeChampion
authored andcommitted
extract crypto namespace into its own files
1 parent a393e07 commit 0107766

File tree

3 files changed

+90
-60
lines changed

3 files changed

+90
-60
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// TODO: remove these once the warnings are fixed
2+
#pragma clang diagnostic push
3+
#pragma clang diagnostic ignored "-Winvalid-offsetof"
4+
#include "js/experimental/TypedData.h" // used in "js/Conversions.h"
5+
#pragma clang diagnostic pop
6+
7+
#include "crypto.h"
8+
9+
bool is_int_typed_array(JSObject *obj) {
10+
return JS_IsInt8Array(obj) || JS_IsUint8Array(obj) || JS_IsInt16Array(obj) ||
11+
JS_IsUint16Array(obj) || JS_IsInt32Array(obj) || JS_IsUint32Array(obj) ||
12+
JS_IsUint8ClampedArray(obj) || JS_IsBigInt64Array(obj) || JS_IsBigUint64Array(obj);
13+
}
14+
15+
namespace builtins {
16+
#define MAX_BYTE_LENGTH 65536
17+
/**
18+
* Implementation of
19+
* https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
20+
* TODO: investigate ways to automatically wipe the buffer passed in here when
21+
* it is GC'd. Content can roughly approximate that using finalizers for views
22+
* of the buffer, but it's far from ideal.
23+
*/
24+
bool Crypto::get_random_values(JSContext *cx, unsigned argc, JS::Value *vp) {
25+
JS::CallArgs args = CallArgsFromVp(argc, vp);
26+
if (!args.requireAtLeast(cx, "crypto.getRandomValues", 1))
27+
return false;
28+
29+
if (!args[0].isObject() || !is_int_typed_array(&args[0].toObject())) {
30+
JS_ReportErrorUTF8(cx, "crypto.getRandomValues: input must be an integer-typed TypedArray");
31+
return false;
32+
}
33+
34+
JS::RootedObject typed_array(cx, &args[0].toObject());
35+
size_t byte_length = JS_GetArrayBufferViewByteLength(typed_array);
36+
if (byte_length > MAX_BYTE_LENGTH) {
37+
JS_ReportErrorUTF8(cx,
38+
"crypto.getRandomValues: input byteLength must be at most %u, "
39+
"but is %zu",
40+
MAX_BYTE_LENGTH, byte_length);
41+
return false;
42+
}
43+
44+
JS::AutoCheckCannotGC noGC(cx);
45+
bool is_shared;
46+
void *buffer = JS_GetArrayBufferViewData(typed_array, &is_shared, noGC);
47+
arc4random_buf(buffer, byte_length);
48+
49+
args.rval().setObject(*typed_array);
50+
return true;
51+
}
52+
53+
const JSFunctionSpec Crypto::methods[] = {
54+
JS_FN("getRandomValues", get_random_values, 1, JSPROP_ENUMERATE), JS_FS_END};
55+
56+
const JSPropertySpec Crypto::properties[] = {JS_PS_END};
57+
58+
bool Crypto::create(JSContext *cx, JS::HandleObject global) {
59+
JS::RootedObject crypto(cx, JS_NewPlainObject(cx));
60+
if (!crypto)
61+
return false;
62+
if (!JS_DefineProperty(cx, global, "crypto", crypto, JSPROP_ENUMERATE))
63+
return false;
64+
return JS_DefineFunctions(cx, crypto, Crypto::methods);
65+
}
66+
} // namespace builtins
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef JS_COMPUTE_RUNTIME_BUILTIN_CRYPTO_H
2+
#define JS_COMPUTE_RUNTIME_BUILTIN_CRYPTO_H
3+
4+
#include "builtin.h"
5+
6+
namespace builtins {
7+
8+
class Crypto : public BuiltinNoConstructor<Crypto> {
9+
private:
10+
public:
11+
static constexpr const char *class_name = "Crypto";
12+
enum Slots { Count };
13+
static const JSFunctionSpec methods[];
14+
static const JSPropertySpec properties[];
15+
16+
static bool get_random_values(JSContext *cx, unsigned argc, JS::Value *vp);
17+
static bool create(JSContext *cx, JS::HandleObject global);
18+
};
19+
20+
} // namespace builtins
21+
22+
#endif

c-dependencies/js-compute-runtime/js-compute-builtins.cpp

Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "builtins/cache-override.h"
3535
#include "builtins/compression-stream.h"
3636
#include "builtins/console.h"
37+
#include "builtins/crypto.h"
3738
#include "builtins/decompression-stream.h"
3839
#include "builtins/dictionary.h"
3940
#include "builtins/env.h"
@@ -427,65 +428,6 @@ JSObject *create(JSContext *cx, HandleObject self, HandleValue url_val, HandleOb
427428
JSObject *create(JSContext *cx, HandleObject self, HandleValue url_val, HandleValue base_val);
428429
} // namespace URL
429430

430-
bool is_int_typed_array(JSObject *obj) {
431-
return JS_IsInt8Array(obj) || JS_IsUint8Array(obj) || JS_IsInt16Array(obj) ||
432-
JS_IsUint16Array(obj) || JS_IsInt32Array(obj) || JS_IsUint32Array(obj) ||
433-
JS_IsUint8ClampedArray(obj) || JS_IsBigInt64Array(obj) || JS_IsBigUint64Array(obj);
434-
}
435-
436-
namespace Crypto {
437-
438-
#define MAX_BYTE_LENGTH 65536
439-
440-
/**
441-
* Implementation of
442-
* https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
443-
* TODO: investigate ways to automatically wipe the buffer passed in here when
444-
* it is GC'd. Content can roughly approximate that using finalizers for views
445-
* of the buffer, but it's far from ideal.
446-
*/
447-
bool get_random_values(JSContext *cx, unsigned argc, Value *vp) {
448-
CallArgs args = CallArgsFromVp(argc, vp);
449-
if (!args.requireAtLeast(cx, "crypto.getRandomValues", 1))
450-
return false;
451-
452-
if (!args[0].isObject() || !is_int_typed_array(&args[0].toObject())) {
453-
JS_ReportErrorUTF8(cx, "crypto.getRandomValues: input must be an integer-typed TypedArray");
454-
return false;
455-
}
456-
457-
RootedObject typed_array(cx, &args[0].toObject());
458-
size_t byte_length = JS_GetArrayBufferViewByteLength(typed_array);
459-
if (byte_length > MAX_BYTE_LENGTH) {
460-
JS_ReportErrorUTF8(cx,
461-
"crypto.getRandomValues: input byteLength must be at most %u, "
462-
"but is %zu",
463-
MAX_BYTE_LENGTH, byte_length);
464-
return false;
465-
}
466-
467-
JS::AutoCheckCannotGC noGC(cx);
468-
bool is_shared;
469-
void *buffer = JS_GetArrayBufferViewData(typed_array, &is_shared, noGC);
470-
arc4random_buf(buffer, byte_length);
471-
472-
args.rval().setObject(*typed_array);
473-
return true;
474-
}
475-
476-
const JSFunctionSpec methods[] = {JS_FN("getRandomValues", get_random_values, 1, JSPROP_ENUMERATE),
477-
JS_FS_END};
478-
479-
static bool create(JSContext *cx, HandleObject global) {
480-
RootedObject crypto(cx, JS_NewPlainObject(cx));
481-
if (!crypto)
482-
return false;
483-
if (!JS_DefineProperty(cx, global, "crypto", crypto, JSPROP_ENUMERATE))
484-
return false;
485-
return JS_DefineFunctions(cx, crypto, methods);
486-
}
487-
} // namespace Crypto
488-
489431
enum class BodyReadResult {
490432
ArrayBuffer,
491433
JSON,
@@ -4947,7 +4889,7 @@ bool define_fastly_sys(JSContext *cx, HandleObject global) {
49474889
return false;
49484890
if (!Console::create(cx, global))
49494891
return false;
4950-
if (!Crypto::create(cx, global))
4892+
if (!builtins::Crypto::create(cx, global))
49514893
return false;
49524894

49534895
if (!NativeStreamSource::init_class(cx, global))

0 commit comments

Comments
 (0)