[njs] Correctly setting length of UTF8 string in fs.readFileSync().

Dmitry Volyntsev xeioex at nginx.com
Wed Mar 6 16:40:37 UTC 2019


details:   https://hg.nginx.org/njs/rev/bfd57048376e
branches:  
changeset: 818:bfd57048376e
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Mar 06 19:39:21 2019 +0300
description:
Correctly setting length of UTF8 string in fs.readFileSync().

This closes #109 issue on Github.

diffstat:

 njs/njs_fs.c                 |  22 ++++++++++++++++-
 njs/test/fs/ascii            |   1 +
 njs/test/fs/non_utf8         |   1 +
 njs/test/fs/utf8             |   1 +
 njs/test/njs_expect_test.exp |  52 ++++++++++++++++++++++++++-----------------
 njs/test/non_utf8            |   1 -
 6 files changed, 54 insertions(+), 24 deletions(-)

diffs (210 lines):

diff -r acc5fc4be35b -r bfd57048376e njs/njs_fs.c
--- a/njs/njs_fs.c	Tue Mar 05 19:54:23 2019 +0300
+++ b/njs/njs_fs.c	Wed Mar 06 19:39:21 2019 +0300
@@ -213,6 +213,16 @@ njs_fs_read_file(njs_vm_t *vm, njs_value
     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
         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_
     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_
         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 -r acc5fc4be35b -r bfd57048376e njs/test/fs/ascii
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/njs/test/fs/ascii	Wed Mar 06 19:39:21 2019 +0300
@@ -0,0 +1,1 @@
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
\ No newline at end of file
diff -r acc5fc4be35b -r bfd57048376e njs/test/fs/non_utf8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/njs/test/fs/non_utf8	Wed Mar 06 19:39:21 2019 +0300
@@ -0,0 +1,1 @@
+€€
\ No newline at end of file
diff -r acc5fc4be35b -r bfd57048376e njs/test/fs/utf8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/njs/test/fs/utf8	Wed Mar 06 19:39:21 2019 +0300
@@ -0,0 +1,1 @@
+αβZγ
\ No newline at end of file
diff -r acc5fc4be35b -r bfd57048376e njs/test/njs_expect_test.exp
--- a/njs/test/njs_expect_test.exp	Tue Mar 05 19:54:23 2019 +0300
+++ b/njs/test/njs_expect_test.exp	Wed Mar 06 19:39:21 2019 +0300
@@ -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"
+    {"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/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', {encoding:'utf8', flag:'r+'}, function (e) {console.log(e)})\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/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"}
 }
 
diff -r acc5fc4be35b -r bfd57048376e njs/test/non_utf8
--- a/njs/test/non_utf8	Tue Mar 05 19:54:23 2019 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-€€
\ No newline at end of file


More information about the nginx-devel mailing list