From 9ed0fadd24940552825ab15b1253a025334c4139 Mon Sep 17 00:00:00 2001 From: buffermet <29265684+buffermet@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:11:48 +0100 Subject: [PATCH] Begin implementing JavaScript Crypto API, add basic Uint8Array methods. --- js/crypto.go | 29 +++++++++++++++++++++++++++++ js/data.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ js/init.go | 6 ++++++ 3 files changed, 82 insertions(+) create mode 100644 js/crypto.go diff --git a/js/crypto.go b/js/crypto.go new file mode 100644 index 00000000..7128b965 --- /dev/null +++ b/js/crypto.go @@ -0,0 +1,29 @@ +package js + +import ( + "crypto/sha1" + + "github.com/robertkrimen/otto" +) + +func cryptoSha1(call otto.FunctionCall) otto.Value { + argv := call.ArgumentList + argc := len(argv) + if argc != 1 { + return ReportError("Crypto.sha1: expected 1 argument, %d given instead.", argc) + } + + arg := argv[0] + if (!arg.IsString()) { + return ReportError("Crypto.sha1: single argument must be a string.") + } + + hasher := sha1.New() + hasher.Write([]byte(arg.String())) + v, err := otto.ToValue(string(hasher.Sum(nil))) + if err != nil { + return ReportError("Crypto.sha1: could not convert to string: %s", err) + } + + return v +} diff --git a/js/data.go b/js/data.go index 42afaee4..c3c2e164 100644 --- a/js/data.go +++ b/js/data.go @@ -8,6 +8,53 @@ import ( "github.com/robertkrimen/otto" ) +func textEncode(call otto.FunctionCall) otto.Value { + argv := call.ArgumentList + argc := len(argv) + if argc != 1 { + return ReportError("textEncode: expected 1 argument, %d given instead.", argc) + } + + arg := argv[0] + if (!arg.IsString()) { + return ReportError("textEncode: single argument must be a string.") + } + + encoded := []byte(arg.String()) + vm := otto.New() + v, err := vm.ToValue(encoded) + if err != nil { + return ReportError("textEncode: could not convert to []uint8: %s", err.Error()) + } + + return v +} + +func textDecode(call otto.FunctionCall) otto.Value { + argv := call.ArgumentList + argc := len(argv) + if argc != 1 { + return ReportError("textDecode: expected 1 argument, %d given instead.", argc) + } + + arg, err := argv[0].Export() + if err != nil { + return ReportError("textDecode: could not export argument value:", err.Error()) + } + byteArr, ok := arg.([]byte) + if !ok { + return ReportError("textDecode: single argument must be of type []uint8.", argc) + } + + decoded := string(byteArr) + v, err := otto.ToValue(decoded) + if err != nil { + return ReportError("textDecode: could not convert to string: %s", err.Error()) + } + + return v +} + func btoa(call otto.FunctionCall) otto.Value { argv := call.ArgumentList argc := len(argv) diff --git a/js/init.go b/js/init.go index 6415dd88..1aaa52cd 100644 --- a/js/init.go +++ b/js/init.go @@ -27,10 +27,16 @@ func init() { plugin.Defines["log_error"] = log_error plugin.Defines["log_fatal"] = log_fatal + plugin.Defines["Crypto"] = map[string]interface{}{ + "sha1": cryptoSha1, + } + plugin.Defines["btoa"] = btoa plugin.Defines["atob"] = atob plugin.Defines["gzipCompress"] = gzipCompress plugin.Defines["gzipDecompress"] = gzipDecompress + plugin.Defines["textEncode"] = textEncode + plugin.Defines["textDecode"] = textDecode plugin.Defines["httpRequest"] = httpRequest plugin.Defines["http"] = httpPackage{}