From: Dmitry Volyntsev Date: Fri, 30 Mar 2018 12:46:39 +0000 (+0300) Subject: Byte string to hex, base64, base64url encodings. X-Git-Tag: 0.2.0~8 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=e39fbaa280b4c34f348d53f6bd7103d8cbf66868;p=njs.git Byte string to hex, base64, base64url encodings. --- diff --git a/njs/njs_string.c b/njs/njs_string.c index 7842b4b8..03465159 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -730,6 +730,67 @@ njs_string_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, return NXT_OK; } + +/* + * String.toString([encoding]). + * Returns the string as is if no additional argument is provided, + * otherwise converts a byte string into an encoded string: hex, base64, + * base64url. + */ + +static njs_ret_t +njs_string_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + nxt_int_t ret; + nxt_str_t enc, str; + njs_value_t value; + njs_string_prop_t string; + + ret = njs_string_prototype_value_of(vm, args, nargs, unused); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + if (nargs < 2) { + return NJS_OK; + } + + if (nxt_slow_path(!njs_is_string(&args[1]))) { + njs_type_error(vm, "encoding must be a string", NULL); + return NJS_ERROR; + } + + value = vm->retval; + + (void) njs_string_prop(&string, &value); + + if (nxt_slow_path(string.length != 0)) { + njs_type_error(vm, "argument must be a byte string", NULL); + return NJS_ERROR; + } + + njs_string_get(&args[1], &enc); + + str.length = string.size; + str.start = string.start; + + if (enc.length == 3 && memcmp(enc.start, "hex", 3) == 0) { + return njs_string_hex(vm, &vm->retval, &str); + + } else if (enc.length == 6 && memcmp(enc.start, "base64", 6) == 0) { + return njs_string_base64(vm, &vm->retval, &str); + + } else if (enc.length == 9 && memcmp(enc.start, "base64url", 9) == 0) { + return njs_string_base64url(vm, &vm->retval, &str); + } + + njs_type_error(vm, "Unknown encoding: '%.*s'", (int) enc.length, enc.start); + + return NJS_ERROR; +} + + /* * String.concat(string2[, ..., stringN]). * JavaScript 1.2, ECMAScript 3. @@ -3305,7 +3366,7 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_METHOD, .name = njs_string("toString"), - .value = njs_native_function(njs_string_prototype_value_of, 0, 0), + .value = njs_native_function(njs_string_prototype_to_string, 0, 0), }, { diff --git a/njs/test/njs_expect_test.exp b/njs/test/njs_expect_test.exp index 2d5c2a62..ba91edc7 100644 --- a/njs/test/njs_expect_test.exp +++ b/njs/test/njs_expect_test.exp @@ -255,6 +255,13 @@ njs_test { # require('fs').readFileSync() +njs_test { + {"var fs = require('fs')\r\n" + "undefined\r\n>> "} + {"fs.readFileSync('njs_test_file').toString('base64')\r\n" + "zrHOslrOsw==\r\n>> "} +} + njs_test { {"var fs = require('fs')\r\n" "undefined\r\n>> "} diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index ed6528df..61b20e45 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -447,6 +447,59 @@ static njs_unit_test_t njs_test[] = { nxt_string("undefined - undefined"), nxt_string("NaN") }, + /* String.toString() method. */ + + { nxt_string("'A'.toString()"), + nxt_string("A") }, + + { nxt_string("'A'.toString('hex')"), + nxt_string("TypeError: argument must be a byte string") }, + + { nxt_string("'A'.toBytes().toString('latin1')"), + nxt_string("TypeError: Unknown encoding: 'latin1'") }, + + { nxt_string("'ABCD'.toBytes().toString('hex')"), + nxt_string("41424344") }, + + { nxt_string("'\\x00\\xAA\\xBB\\xFF'.toBytes().toString('hex')"), + nxt_string("00aabbff") }, + + { nxt_string("'\\x00\\xAA\\xBB\\xFF'.toBytes().toString('base64')"), + nxt_string("AKq7/w==") }, + + { nxt_string("'ABCD'.toBytes().toString('base64')"), + nxt_string("QUJDRA==") }, + + { nxt_string("'ABC'.toBytes().toString('base64')"), + nxt_string("QUJD") }, + + { nxt_string("'AB'.toBytes().toString('base64')"), + nxt_string("QUI=") }, + + { nxt_string("'A'.toBytes().toString('base64')"), + nxt_string("QQ==") }, + + { nxt_string("''.toBytes().toString('base64')"), + nxt_string("") }, + + { nxt_string("'\\x00\\xAA\\xBB\\xFF'.toBytes().toString('base64url')"), + nxt_string("AKq7_w") }, + + { nxt_string("'ABCD'.toBytes().toString('base64url')"), + nxt_string("QUJDRA") }, + + { nxt_string("'ABC'.toBytes().toString('base64url')"), + nxt_string("QUJD") }, + + { nxt_string("'AB'.toBytes().toString('base64url')"), + nxt_string("QUI") }, + + { nxt_string("'A'.toBytes().toString('base64url')"), + nxt_string("QQ") }, + + { nxt_string("''.toBytes().toString('base64url')"), + nxt_string("") }, + /* Assignment. */ { nxt_string("var a, b = (a = [2]) * (3 * 4); a +' '+ b"),