summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-01-26 03:56:19 +0800
committerGitHub <noreply@github.com>2023-01-25 14:56:19 -0500
commitc4d3d650baa88820dadeafa81ca75b6e495084f2 (patch)
tree51abc7bbe6aa06965a0ef2e335775ab35e474662
parentd54a7f078d29445bc79ec5f117a2ceb73761b4c4 (diff)
downloadNim-c4d3d650baa88820dadeafa81ca75b6e495084f2.tar.gz
fixes #21273; fixes an io.readLine off by one bug [backport 1.0] (#21276)
fixes #21273; io.readLine off by one
-rw-r--r--lib/std/syncio.nim7
-rw-r--r--tests/stdlib/tio.nim18
2 files changed, 22 insertions, 3 deletions
diff --git a/lib/std/syncio.nim b/lib/std/syncio.nim
index 46f113450..83b2d6d13 100644
--- a/lib/std/syncio.nim
+++ b/lib/std/syncio.nim
@@ -484,11 +484,12 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
       if last > 0 and line[last-1] == '\c':
         line.setLen(last-1)
         return last > 1 or fgetsSuccess
-        # We have to distinguish between two possible cases:
+      elif last > 0 and line[last-1] == '\0':
+        # We have to distinguish among three possible cases:
         # \0\l\0 => line ending in a null character.
         # \0\l\l => last line without newline, null was put there by fgets.
-      elif last > 0 and line[last-1] == '\0':
-        if last < pos + sp - 1 and line[last+1] != '\0':
+        #   \0\l => last line without newline, null was put there by fgets.
+        if last >= pos + sp - 1 or line[last+1] != '\0': # bug #21273
           dec last
       line.setLen(last)
       return last > 0 or fgetsSuccess
diff --git a/tests/stdlib/tio.nim b/tests/stdlib/tio.nim
index 0e20d6495..ca411379c 100644
--- a/tests/stdlib/tio.nim
+++ b/tests/stdlib/tio.nim
@@ -36,3 +36,21 @@ block: # readChars
         break
     doAssert n2s == @[2,2,2,1,0]
     doAssert s2 == s
+
+
+import std/strutils
+
+block: # bug #21273
+  let FILE = buildDir / "D20220119T134305.txt"
+
+  let hex = "313632313920313632343720313632353920313632363020313632393020323035363520323037323120323131353020323239393820323331303520323332313020323332343820323332363820"
+
+
+  writeFile FILE, parseHexStr(hex)
+
+  doAssert readFile(FILE).toHex == hex
+
+  let f = open(FILE)
+  var s = newString(80)
+  while f.readLine(s):
+    doAssert s.toHex == hex