summary refs log tree commit diff stats
path: root/lib/system/sysio.nim
diff options
context:
space:
mode:
authorReimer Behrends <behrends@gmail.com>2015-08-28 17:21:03 +0200
committerReimer Behrends <behrends@gmail.com>2015-08-28 17:21:03 +0200
commit7dd263f506453a849b585d586b27606235123277 (patch)
tree36fe990912c408b6f1a56a2d1daee6c47c1341a8 /lib/system/sysio.nim
parent370781b773739b2a580b661b5e444548dbf48411 (diff)
downloadNim-7dd263f506453a849b585d586b27606235123277.tar.gz
Fix readLine handling of long lines.
Diffstat (limited to 'lib/system/sysio.nim')
-rw-r--r--lib/system/sysio.nim11
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 265f92fa2..3d0b2aa8a 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -90,12 +90,21 @@ proc readLine(f: File, line: var TaintedString): bool =
     let m = memchr(addr line.string[pos], '\l'.ord, space)
     if m != nil:
       # \l found: Could be our own or the one by fgets, in any case, we're done
-      let last = cast[ByteAddress](m) - cast[ByteAddress](addr line.string[0])
+      var last = cast[ByteAddress](m) - cast[ByteAddress](addr line.string[0])
       if last > 0 and line.string[last-1] == '\c':
         line.string.setLen(last-1)
         return true
+        # We have to distinguish between two 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.string[last-1] == '\0':
+        if last < pos + space - 1 and line.string[last+1] != '\0':
+          dec last
       line.string.setLen(last)
       return true
+    else:
+      # fgets will have inserted a null byte at the end of the string.
+      dec space
     # No \l found: Increase buffer and read more
     inc pos, space
     space = 128 # read in 128 bytes at a time