]> git.kaiwu.me - njs.git/commitdiff
Byte string to hex, base64, base64url encodings.
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 30 Mar 2018 12:46:39 +0000 (15:46 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Fri, 30 Mar 2018 12:46:39 +0000 (15:46 +0300)
njs/njs_string.c
njs/test/njs_expect_test.exp
njs/test/njs_unit_test.c

index 7842b4b888c8736ef5cdbb049867a0ad1f2ee31b..03465159ad4abff31f0907f71d04050861b2bf35 100644 (file)
@@ -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),
     },
 
     {
index 2d5c2a62b24fd3bb0284229bbff799968d3186ff..ba91edc7946f0dc93166adccb5a3ef5217d9d18e 100644 (file)
@@ -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>> "}
index ed6528dfdccc3825745d6bbc58208d20ed6a00fa..61b20e45b36ea965f70252d3e70e58cf2eb1e355 100644 (file)
@@ -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"),