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 e2bfe5b0..6fe48f22 100644 --- a/js/data.go +++ b/js/data.go @@ -8,25 +8,94 @@ import ( "github.com/robertkrimen/otto" ) -func btoa(call otto.FunctionCall) otto.Value { - varValue := base64.StdEncoding.EncodeToString([]byte(call.Argument(0).String())) - v, err := otto.ToValue(varValue) +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("Could not convert to string: %s", varValue) + 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: %s", err.Error()) + } + byteArr, ok := arg.([]uint8) + if !ok { + return ReportError("textDecode: single argument must be of type []uint8.") + } + + 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) + if argc != 1 { + return ReportError("btoa: expected 1 argument, %d given instead.", argc) + } + + arg := argv[0] + if (!arg.IsString()) { + return ReportError("btoa: single argument must be a string.") + } + + encoded := base64.StdEncoding.EncodeToString([]byte(arg.String())) + v, err := otto.ToValue(encoded) + if err != nil { + return ReportError("btoa: could not convert to string: %s", err.Error()) } return v } func atob(call otto.FunctionCall) otto.Value { - varValue, err := base64.StdEncoding.DecodeString(call.Argument(0).String()) - if err != nil { - return ReportError("Could not decode string: %s", call.Argument(0).String()) + argv := call.ArgumentList + argc := len(argv) + if argc != 1 { + return ReportError("atob: expected 1 argument, %d given instead.", argc) } - v, err := otto.ToValue(string(varValue)) + arg := argv[0] + if (!arg.IsString()) { + return ReportError("atob: single argument must be a string.") + } + + decoded, err := base64.StdEncoding.DecodeString(arg.String()) if err != nil { - return ReportError("Could not convert to string: %s", varValue) + return ReportError("atob: could not decode string: %s", err.Error()) + } + + v, err := otto.ToValue(string(decoded)) + if err != nil { + return ReportError("atob: could not convert to string: %s", err.Error()) } return v @@ -39,7 +108,12 @@ func gzipCompress(call otto.FunctionCall) otto.Value { return ReportError("gzipCompress: expected 1 argument, %d given instead.", argc) } - uncompressedBytes := []byte(argv[0].String()) + arg := argv[0] + if (!arg.IsString()) { + return ReportError("gzipCompress: single argument must be a string.") + } + + uncompressedBytes := []byte(arg.String()) var writerBuffer bytes.Buffer gzipWriter := gzip.NewWriter(&writerBuffer) @@ -53,7 +127,7 @@ func gzipCompress(call otto.FunctionCall) otto.Value { v, err := otto.ToValue(string(compressedBytes)) if err != nil { - return ReportError("Could not convert to string: %s", err.Error()) + return ReportError("gzipCompress: could not convert to string: %s", err.Error()) } return v @@ -83,7 +157,7 @@ func gzipDecompress(call otto.FunctionCall) otto.Value { decompressedBytes := decompressedBuffer.Bytes() v, err := otto.ToValue(string(decompressedBytes)) if err != nil { - return ReportError("Could not convert to string: %s", err.Error()) + return ReportError("gzipDecompress: could not convert to string: %s", err.Error()) } return v 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{}