[njs] Byte string to hex, base64, base64url encodings.

Dmitry Volyntsev xeioex at nginx.com
Fri Mar 30 12:47:10 UTC 2018


details:   http://hg.nginx.org/njs/rev/6343166cb0ea
branches:  
changeset: 475:6343166cb0ea
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Mar 30 15:46:39 2018 +0300
description:
Byte string to hex, base64, base64url encodings.

diffstat:

 njs/njs_string.c             |  63 +++++++++++++++++++++++++++++++++++++++++++-
 njs/test/njs_expect_test.exp |   7 ++++
 njs/test/njs_unit_test.c     |  53 +++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+), 1 deletions(-)

diffs (160 lines):

diff -r d35406201c78 -r 6343166cb0ea njs/njs_string.c
--- a/njs/njs_string.c	Fri Mar 30 15:46:38 2018 +0300
+++ b/njs/njs_string.c	Fri Mar 30 15:46:39 2018 +0300
@@ -730,6 +730,67 @@ njs_string_prototype_value_of(njs_vm_t *
     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_stri
     {
         .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 -r d35406201c78 -r 6343166cb0ea njs/test/njs_expect_test.exp
--- a/njs/test/njs_expect_test.exp	Fri Mar 30 15:46:38 2018 +0300
+++ b/njs/test/njs_expect_test.exp	Fri Mar 30 15:46:39 2018 +0300
@@ -258,6 +258,13 @@ njs_test {
 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>> "}
     {"fs.readFileSync('njs_test_file', 'utf8')[2]\r\n"
      "Z\r\n>> "}
 }
diff -r d35406201c78 -r 6343166cb0ea njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Mar 30 15:46:38 2018 +0300
+++ b/njs/test/njs_unit_test.c	Fri Mar 30 15:46:39 2018 +0300
@@ -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"),


More information about the nginx-devel mailing list