]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR modula2/115057 TextIO.ReadRestLine raises an exception when buffer is exceeded
authorGaius Mulley <gaiusmod2@gmail.com>
Wed, 15 May 2024 15:58:21 +0000 (16:58 +0100)
committerGaius Mulley <gaiusmod2@gmail.com>
Wed, 15 May 2024 15:58:21 +0000 (16:58 +0100)
TextIO.ReadRestLine will raise an "attempting to read beyond end of file"
exception if the buffer is exceeded.  This bug is caused by the
TextIO.ReadRestLine calling IOChan.Skip without a preceeding IOChan.Look.
The Look procedure will update the status result whereas
Skip always sets read result to allRight.

gcc/m2/ChangeLog:

PR modula2/115057
* gm2-libs-iso/TextIO.mod (ReadRestLine): Use ReadChar to
skip unwanted characters as this calls IOChan.Look and updates
the cid result status.  A Skip without a Look does not update
the status.  Skip always sets read result to allRight.
* gm2-libs-iso/TextUtil.def (SkipSpaces): Improve comments.
(CharAvailable): Improve comments.
* gm2-libs-iso/TextUtil.mod (SkipSpaces): Improve comments.
(CharAvailable): Improve comments.

gcc/testsuite/ChangeLog:

PR modula2/115057
* gm2/isolib/run/pass/testrestline.mod: New test.
* gm2/isolib/run/pass/testrestline2.mod: New test.
* gm2/isolib/run/pass/testrestline3.mod: New test.

Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
gcc/m2/gm2-libs-iso/TextIO.mod
gcc/m2/gm2-libs-iso/TextUtil.def
gcc/m2/gm2-libs-iso/TextUtil.mod
gcc/testsuite/gm2/isolib/run/pass/testrestline.mod [new file with mode: 0644]
gcc/testsuite/gm2/isolib/run/pass/testrestline2.mod [new file with mode: 0644]
gcc/testsuite/gm2/isolib/run/pass/testrestline3.mod [new file with mode: 0644]

index 78d67187b7991740836fd1e43f43e92e34c449a8..5204467b19213a76a6dd8cb2748a158f669cf975 100644 (file)
@@ -114,13 +114,19 @@ PROCEDURE ReadRestLine (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
   *)
 VAR
    i, h    : CARDINAL ;
+   ignore  : CHAR ;
    finished: BOOLEAN ;
 BEGIN
    h := HIGH(s) ;
    i := 0 ;
    finished := FALSE ;
-   WHILE (i<=h) AND CharAvailable (cid) AND (NOT finished) DO
-      ReadChar (cid, s[i]) ;
+   WHILE CharAvailable (cid) AND (NOT finished) DO
+      IF i <= h
+      THEN
+         ReadChar (cid, s[i])
+      ELSE
+         ReadChar (cid, ignore)
+      END ;
       IF EofOrEoln (cid)
       THEN
          finished := TRUE
@@ -128,9 +134,6 @@ BEGIN
          INC (i)
       END
    END ;
-   WHILE CharAvailable (cid) DO
-      IOChan.Skip (cid)
-   END ;
    SetNul (cid, i, s, TRUE)
 END ReadRestLine ;
 
index ead045617233d401ac564bf555d263790c10095c..7e6b3ed07dcedbcba6b70a1cf96eefa8b8534548 100644 (file)
@@ -45,11 +45,15 @@ IMPORT IOChan ;
 PROCEDURE SkipSpaces (cid: IOChan.ChanId) ;
 
 
-(* The following procedures do not read past line marks.  *)
+(* CharAvailable returns TRUE if IOChan.ReadResult is notKnown or
+   allRight.  *)
 
 PROCEDURE CharAvailable (cid: IOChan.ChanId) : BOOLEAN ;
 
 
+(* EofOrEoln returns TRUE if IOChan.ReadResult is endOfLine or
+   endOfInput.  *)
+
 PROCEDURE EofOrEoln (cid: IOChan.ChanId) : BOOLEAN ;
 
 
index 44dbd1c69f8b9bead426fdcb03449b1cbc97d9aa..ad5786ca2fb28f8dd318d2c256305bee4d209b98 100644 (file)
@@ -23,7 +23,8 @@ BEGIN
 END SkipSpaces ;
 
 
-(* The following procedures do not read past line marks.  *)
+(* CharAvailable returns TRUE if IOChan.ReadResult is notKnown or
+   allRight.  *)
 
 PROCEDURE CharAvailable (cid: IOChan.ChanId) : BOOLEAN ;
 BEGIN
@@ -32,6 +33,9 @@ BEGIN
 END CharAvailable ;
 
 
+(* EofOrEoln returns TRUE if IOChan.ReadResult is endOfLine or
+   endOfInput.  *)
+
 PROCEDURE EofOrEoln (cid: IOChan.ChanId) : BOOLEAN ;
 BEGIN
    RETURN( (IOChan.ReadResult (cid) = IOConsts.endOfLine) OR
diff --git a/gcc/testsuite/gm2/isolib/run/pass/testrestline.mod b/gcc/testsuite/gm2/isolib/run/pass/testrestline.mod
new file mode 100644 (file)
index 0000000..7702e88
--- /dev/null
@@ -0,0 +1,20 @@
+MODULE testrestline ;
+
+IMPORT SeqFile, TextIO ;
+
+VAR
+   chan    : SeqFile.ChanId ;
+   line    : ARRAY [0..5] OF CHAR ;
+   results : SeqFile.OpenResults ;
+BEGIN
+   SeqFile.OpenWrite (chan, "test.input", SeqFile.write, results) ;
+   TextIO.WriteString (chan, "a line of text exceeding 6 chars") ;
+   TextIO.WriteLn (chan) ;
+   TextIO.WriteString (chan, "a second lineline of text exceeding 6 chars") ;
+   TextIO.WriteLn (chan) ;
+   SeqFile.Close (chan) ;
+
+   (* Now see if we can read the first line.  *)
+   SeqFile.OpenRead (chan, "test.input", SeqFile.read, results) ;
+   TextIO.ReadRestLine (chan, line)
+END testrestline.
\ No newline at end of file
diff --git a/gcc/testsuite/gm2/isolib/run/pass/testrestline2.mod b/gcc/testsuite/gm2/isolib/run/pass/testrestline2.mod
new file mode 100644 (file)
index 0000000..00e5c80
--- /dev/null
@@ -0,0 +1,17 @@
+MODULE testrestline2 ;
+
+IMPORT SeqFile, TextIO ;
+
+VAR
+   chan    : SeqFile.ChanId ;
+   line    : ARRAY [0..5] OF CHAR ;
+   results : SeqFile.OpenResults ;
+BEGIN
+   SeqFile.OpenWrite (chan, "test.input", SeqFile.write, results) ;
+   TextIO.WriteString (chan, "a line of text exceeding 6 chars") ;
+   TextIO.WriteLn (chan) ;
+
+   (* Now see if we can read the first line.  *)
+   SeqFile.OpenRead (chan, "test.input", SeqFile.read, results) ;
+   TextIO.ReadRestLine (chan, line)
+END testrestline2.
\ No newline at end of file
diff --git a/gcc/testsuite/gm2/isolib/run/pass/testrestline3.mod b/gcc/testsuite/gm2/isolib/run/pass/testrestline3.mod
new file mode 100644 (file)
index 0000000..04fbad4
--- /dev/null
@@ -0,0 +1,16 @@
+MODULE testrestline3 ;
+
+IMPORT SeqFile, TextIO ;
+
+VAR
+   chan    : SeqFile.ChanId ;
+   line    : ARRAY [0..5] OF CHAR ;
+   results : SeqFile.OpenResults ;
+BEGIN
+   SeqFile.OpenWrite (chan, "test.input", SeqFile.write, results) ;
+   TextIO.WriteString (chan, "a line of text exceeding 6 chars") ;
+
+   (* Now see if we can read the first line.  *)
+   SeqFile.OpenRead (chan, "test.input", SeqFile.read, results) ;
+   TextIO.ReadRestLine (chan, line)
+END testrestline3.
\ No newline at end of file