]> git.kaiwu.me - njs.git/commitdiff
Correctly setting length of UTF8 string in fs.readFileSync().
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 6 Mar 2019 16:39:21 +0000 (19:39 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 6 Mar 2019 16:39:21 +0000 (19:39 +0300)
This closes #109 issue on Github.

njs/njs_fs.c
njs/test/fs/ascii [new file with mode: 0644]
njs/test/fs/non_utf8 [moved from njs/test/non_utf8 with 100% similarity]
njs/test/fs/utf8 [new file with mode: 0644]
njs/test/njs_expect_test.exp

index 06574ac394aa39a2712476e857f1d497b9188839..f255ed77f69e6222aa1faeff2ab0495aa4a0898a 100644 (file)
@@ -213,6 +213,16 @@ njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     if (encoding.length != 0) {
         length = sb.st_size;
 
+        if (length > NJS_STRING_MAP_STRIDE) {
+            /*
+             * At this point length is not known, in order to set it to
+             * the correct value after file is read, we need to ensure that
+             * offset_map is allocated by njs_string_alloc(). This can be
+             * achieved by making length != size.
+             */
+            length += 1;
+        }
+
     } else {
         length = 0;
     }
@@ -245,7 +255,6 @@ njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
         length = nxt_utf8_length(start, sb.st_size);
 
         if (length >= 0) {
-            njs_string_offset_map_init(start, sb.st_size);
             njs_string_length_set(&arguments[2], length);
 
         } else {
@@ -408,6 +417,16 @@ njs_fs_read_file_sync(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     if (encoding.length != 0) {
         length = sb.st_size;
 
+        if (length > NJS_STRING_MAP_STRIDE) {
+            /*
+             * At this point length is not known, in order to set it to
+             * the correct value after file is read, we need to ensure that
+             * offset_map is allocated by njs_string_alloc(). This can be
+             * achieved by making length != size.
+             */
+            length += 1;
+        }
+
     } else {
         length = 0;
     }
@@ -440,7 +459,6 @@ njs_fs_read_file_sync(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
         length = nxt_utf8_length(start, sb.st_size);
 
         if (length >= 0) {
-            njs_string_offset_map_init(start, sb.st_size);
             njs_string_length_set(&vm->retval, length);
 
         } else {
diff --git a/njs/test/fs/ascii b/njs/test/fs/ascii
new file mode 100644 (file)
index 0000000..c058bff
--- /dev/null
@@ -0,0 +1 @@
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
\ No newline at end of file
similarity index 100%
rename from njs/test/non_utf8
rename to njs/test/fs/non_utf8
diff --git a/njs/test/fs/utf8 b/njs/test/fs/utf8
new file mode 100644 (file)
index 0000000..535b427
--- /dev/null
@@ -0,0 +1 @@
+αβZγ
\ No newline at end of file
index 86c88942ef16786fc616bf28ff49a416afc91ab6..748a0ae67ae35ed726c5df3f5d4e137e906843b4 100644 (file)
@@ -367,10 +367,6 @@ njs_test {
 
 # require('fs')
 
-set file [open njs_test_file w]
-puts -nonewline $file "αβZγ"
-flush $file
-
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
@@ -383,37 +379,44 @@ njs_test {
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFile('njs_test_file', 'utf8', function (e, data) {console.log(data[2]+data.length)})\r\n"
+    {"fs.readFile('njs/test/fs/utf8', 'utf8', function (e, data) {console.log(data[2]+data.length)})\r\n"
      "'Z4'\r\nundefined\r\n>> "}
 }
 
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFile('njs_test_file', function (e, data) {console.log(data[4]+data.length)})\r\n"
+    {"fs.readFile('njs/test/fs/utf8', function (e, data) {console.log(data[4]+data.length)})\r\n"
      "'Z7'\r\nundefined\r\n>> "}
 }
 
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFile('njs_test_file', {encoding:'utf8',flag:'r+'}, function (e, data) {console.log(data)})\r\n"
+    {"fs.readFile('njs/test/fs/utf8', {encoding:'utf8',flag:'r+'}, function (e, data) {console.log(data)})\r\n"
      "'αβZγ'\r\nundefined\r\n>> "}
 }
 
-exec rm -fr njs_unknown_path
+njs_test {
+    {"var fs = require('fs')\r\n"
+     "undefined\r\n>> "}
+    {"fs.readFile('njs/test/fs/ascii', function (e, data) {console.log(data[599])})\r\n"
+     "'x'\r\nundefined\r\n>> "}
+    {"fs.readFile('njs/test/fs/ascii', {encoding:'utf8',flag:'r+'}, function (e, data) {console.log(data[599])})\r\n"
+     "'x'\r\nundefined\r\n>> "}
+}
 
 njs_test {
     {"var fs = require('fs'); \r\n"
      "undefined\r\n>> "}
-    {"fs.readFile('njs_unknown_path', 'utf8', function (e) {console.log(JSON.stringify(e))})\r\n"
-     "'{\"errno\":2,\"path\":\"njs_unknown_path\",\"syscall\":\"open\"}'\r\nundefined\r\n>> "}
+    {"fs.readFile('njs/test/fs/nonexistent', 'utf8', function (e) {console.log(JSON.stringify(e))})\r\n"
+     "'{\"errno\":2,\"path\":\"njs/test/fs/nonexistent\",\"syscall\":\"open\"}'\r\nundefined\r\n>> "}
 }
 
 njs_test {
     {"var fs = require('fs'); \r\n"
      "undefined\r\n>> "}
-    {"fs.readFile('njs_unknown_path', {encoding:'utf8', flag:'r+'}, function (e) {console.log(e)})\r\n"
+    {"fs.readFile('njs/test/fs/nonexistent', {encoding:'utf8', flag:'r+'}, function (e) {console.log(e)})\r\n"
      "Error: No such file or directory\r\nundefined\r\n>> "}
 }
 
@@ -422,49 +425,56 @@ njs_test {
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFileSync('njs_test_file').toString('base64')\r\n"
+    {"fs.readFileSync('njs/test/fs/utf8').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"
+    {"fs.readFileSync('njs/test/fs/utf8', 'utf8')[2]\r\n"
      "'Z'\r\n>> "}
 }
 
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFileSync('njs_test_file')[4]\r\n"
+    {"fs.readFileSync('njs/test/fs/utf8')[4]\r\n"
      "'Z'\r\n>> "}
 }
 
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFileSync('njs_test_file', {encoding:'utf8',flag:'r+'})\r\n"
+    {"fs.readFileSync('njs/test/fs/utf8', {encoding:'utf8',flag:'r+'})\r\n"
      "'αβZγ'\r\n>> "}
 }
 
+njs_test {
+    {"var fs = require('fs'), fn = 'njs/test/fs/ascii'\r\n"
+     "undefined\r\n>> "}
+    {"fs.readFileSync(fn)[599] + fs.readFileSync(fn, 'utf8')[599]\r\n"
+     "'xx'\r\n>> "}
+}
+
 njs_test {
     {"var fs = require('fs'); \r\n"
      "undefined\r\n>> "}
-    {"try { fs.readFileSync('njs_unknown_path')} catch (e) {console.log(JSON.stringify(e))}\r\n"
-     "'{\"errno\":2,\"path\":\"njs_unknown_path\",\"syscall\":\"open\"}'\r\nundefined\r\n>> "}
+    {"try { fs.readFileSync('njs/test/fs/nonexistent')} catch (e) {console.log(JSON.stringify(e))}\r\n"
+     "'{\"errno\":2,\"path\":\"njs/test/fs/nonexistent\",\"syscall\":\"open\"}'\r\nundefined\r\n>> "}
 }
 
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFileSync('./njs/test/non_utf8').charCodeAt(1)\r\n"
+    {"fs.readFileSync('njs/test/fs/non_utf8').charCodeAt(1)\r\n"
      "128"}
 }
 
 njs_test {
     {"var fs = require('fs')\r\n"
      "undefined\r\n>> "}
-    {"fs.readFileSync('./njs/test/non_utf8', 'utf8')\r\n"
+    {"fs.readFileSync('njs/test/fs/non_utf8', 'utf8')\r\n"
      "Error: Non-UTF8 file, convertion is not implemented"}
 }