From b8816258a7c4f04b9862710a9091ae8ab6d50f17 Mon Sep 17 00:00:00 2001 From: oleiade Date: Fri, 12 Jan 2024 17:34:30 +0100 Subject: [PATCH 1/2] Switch to use common.IsNullish --- webcrypto/goja.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/webcrypto/goja.go b/webcrypto/goja.go index 52140b4..d7cc011 100644 --- a/webcrypto/goja.go +++ b/webcrypto/goja.go @@ -5,12 +5,13 @@ import ( "strings" "github.com/dop251/goja" + "go.k6.io/k6/js/common" ) // exportArrayBuffer interprets the given value as an ArrayBuffer, TypedArray or DataView // and returns a copy of the underlying byte slice. func exportArrayBuffer(rt *goja.Runtime, v goja.Value) ([]byte, error) { - if isNullish(v) { + if common.IsNullish(v) { return nil, NewError(TypeError, "data is null or undefined") } @@ -45,18 +46,18 @@ func exportArrayBuffer(rt *goja.Runtime, v goja.Value) ([]byte, error) { // traverseObject traverses the given object using the given fields and returns the value // at the end of the traversal. It assumes that all the traversed fields are Objects. func traverseObject(rt *goja.Runtime, src goja.Value, fields ...string) (goja.Value, error) { - if isNullish(src) { + if common.IsNullish(src) { return nil, NewError(TypeError, "Object is null or undefined") } obj := src.ToObject(rt) - if isNullish(obj) { + if common.IsNullish(obj) { return nil, NewError(TypeError, "Object is null or undefined") } for idx, field := range fields { src = obj.Get(field) - if isNullish(src) { + if common.IsNullish(src) { return nil, NewError( TypeError, fmt.Sprintf("field %s is null or undefined", strings.Join(fields[:idx+1], ".")), @@ -64,7 +65,7 @@ func traverseObject(rt *goja.Runtime, src goja.Value, fields ...string) (goja.Va } obj = src.ToObject(rt) - if isNullish(obj) { + if common.IsNullish(obj) { return nil, NewError( TypeError, fmt.Sprintf("field %s is not an Object", strings.Join(fields[:idx+1], ".")), @@ -155,12 +156,6 @@ const ( BigUint64ArrayConstructor = "BigUint64Array" ) -// IsNullish checks if the given value is nullish, i.e. nil, undefined or null. -// FIXME @oleiade: this declaration can be removed once the k6 version including it is released -func isNullish(v goja.Value) bool { - return v == nil || goja.IsUndefined(v) || goja.IsNull(v) -} - // makeHandledPromise will create a promise and return its resolve and reject methods, // wrapped in such a way that it will block the eventloop from exiting before they are // called even if the promise isn't resolved by the time the current script ends executing. From 334e146133ebdccc4994cca71b847a0572660ded Mon Sep 17 00:00:00 2001 From: oleiade Date: Fri, 12 Jan 2024 17:37:20 +0100 Subject: [PATCH 2/2] Replace makeHandledPromise with usage of the promises.New package --- webcrypto/goja.go | 23 ----------------------- webcrypto/subtle_crypto.go | 17 +++++++++-------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/webcrypto/goja.go b/webcrypto/goja.go index d7cc011..8782d35 100644 --- a/webcrypto/goja.go +++ b/webcrypto/goja.go @@ -155,26 +155,3 @@ const ( // BigUint64ArrayConstructor is the name of the BigUint64ArrayConstructor constructor BigUint64ArrayConstructor = "BigUint64Array" ) - -// makeHandledPromise will create a promise and return its resolve and reject methods, -// wrapped in such a way that it will block the eventloop from exiting before they are -// called even if the promise isn't resolved by the time the current script ends executing. -func (sc *SubtleCrypto) makeHandledPromise() (*goja.Promise, func(interface{}), func(interface{})) { - runtime := sc.vu.Runtime() - callback := sc.vu.RegisterCallback() - p, resolve, reject := runtime.NewPromise() - - return p, func(i interface{}) { - // more stuff - callback(func() error { - resolve(i) - return nil - }) - }, func(i interface{}) { - // more stuff - callback(func() error { - reject(i) - return nil - }) - } -} diff --git a/webcrypto/subtle_crypto.go b/webcrypto/subtle_crypto.go index 10ec17c..4d5f443 100644 --- a/webcrypto/subtle_crypto.go +++ b/webcrypto/subtle_crypto.go @@ -7,6 +7,7 @@ import ( "github.com/dop251/goja" "go.k6.io/k6/js/modules" + "go.k6.io/k6/js/promises" ) // FIXME: SubtleCrypto is described as an "interface", should it be a nested module @@ -37,7 +38,7 @@ type SubtleCrypto struct { // The `data` parameter should contain the data to be encryption. func (sc *SubtleCrypto) Encrypt(algorithm, key, data goja.Value) *goja.Promise { rt := sc.vu.Runtime() - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) // 2. // We obtain a copy of the key data, because we might need to modify it. @@ -129,7 +130,7 @@ func (sc *SubtleCrypto) Encrypt(algorithm, key, data goja.Value) *goja.Promise { // The `data` parameter should contain the data to be decrypted. func (sc *SubtleCrypto) Decrypt(algorithm, key, data goja.Value) *goja.Promise { rt := sc.vu.Runtime() - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) // 2. // We obtain a copy of the key data, because we might need to modify it. @@ -219,7 +220,7 @@ func (sc *SubtleCrypto) Decrypt(algorithm, key, data goja.Value) *goja.Promise { // The `data` parameter should contain the data to be signed. func (sc *SubtleCrypto) Sign(algorithm, key, data goja.Value) *goja.Promise { rt := sc.vu.Runtime() - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) // 2. // We obtain a copy of the key data, because we might need to modify it. @@ -322,7 +323,7 @@ func (sc *SubtleCrypto) Sign(algorithm, key, data goja.Value) *goja.Promise { // The `data` parameter should contain the original signed data. func (sc *SubtleCrypto) Verify(algorithm, key, signature, data goja.Value) *goja.Promise { rt := sc.vu.Runtime() - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) // 2. signatureData, err := exportArrayBuffer(sc.vu.Runtime(), signature) @@ -421,7 +422,7 @@ func (sc *SubtleCrypto) Verify(algorithm, key, signature, data goja.Value) *goja // // The `data` parameter should contain the data to be digested. func (sc *SubtleCrypto) Digest(algorithm goja.Value, data goja.Value) *goja.Promise { - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) rt := sc.vu.Runtime() // Validate that the value we received is either an ArrayBuffer, TypedArray, or DataView @@ -488,7 +489,7 @@ func (sc *SubtleCrypto) Digest(algorithm goja.Value, data goja.Value) *goja.Prom // // The `keyUsages` parameter is an array of strings indicating what the key can be used for. func (sc *SubtleCrypto) GenerateKey(algorithm goja.Value, extractable bool, keyUsages []CryptoKeyUsage) *goja.Promise { - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) normalized, err := normalizeAlgorithm(sc.vu.Runtime(), algorithm, OperationIdentifierGenerateKey) if err != nil { @@ -630,7 +631,7 @@ func (sc *SubtleCrypto) ImportKey( keyUsages []CryptoKeyUsage, ) *goja.Promise { rt := sc.vu.Runtime() - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) // 2. ab, err := exportArrayBuffer(rt, keyData) @@ -703,7 +704,7 @@ func (sc *SubtleCrypto) ImportKey( // TODO @oleiade: implement support for JWK format func (sc *SubtleCrypto) ExportKey(format KeyFormat, key goja.Value) *goja.Promise { rt := sc.vu.Runtime() - promise, resolve, reject := sc.makeHandledPromise() + promise, resolve, reject := promises.New(sc.vu) var algorithm Algorithm algValue := key.ToObject(rt).Get("algorithm")