diff options
author | Gaius Mulley <gaiusmod2@gmail.com> | 2024-05-15 16:58:21 +0100 |
---|---|---|
committer | Gaius Mulley <gaiusmod2@gmail.com> | 2024-05-15 16:58:21 +0100 |
commit | 680af0e1e90d4b80260d173636dfe15654fd470d (patch) | |
tree | dd8157dd5778cffd6c6b874e987afae49f082a48 /gcc | |
parent | 3cefe91b74f65f0db71472e01ca83c69e2cd81cc (diff) | |
download | gcc-680af0e1e90d4b80260d173636dfe15654fd470d.zip gcc-680af0e1e90d4b80260d173636dfe15654fd470d.tar.gz gcc-680af0e1e90d4b80260d173636dfe15654fd470d.tar.bz2 |
PR modula2/115057 TextIO.ReadRestLine raises an exception when buffer is exceeded
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/m2/gm2-libs-iso/TextIO.mod | 13 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/TextUtil.def | 6 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-iso/TextUtil.mod | 6 | ||||
-rw-r--r-- | gcc/testsuite/gm2/isolib/run/pass/testrestline.mod | 20 | ||||
-rw-r--r-- | gcc/testsuite/gm2/isolib/run/pass/testrestline2.mod | 17 | ||||
-rw-r--r-- | gcc/testsuite/gm2/isolib/run/pass/testrestline3.mod | 16 |
6 files changed, 71 insertions, 7 deletions
diff --git a/gcc/m2/gm2-libs-iso/TextIO.mod b/gcc/m2/gm2-libs-iso/TextIO.mod index 78d6718..5204467 100644 --- a/gcc/m2/gm2-libs-iso/TextIO.mod +++ b/gcc/m2/gm2-libs-iso/TextIO.mod @@ -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 ; diff --git a/gcc/m2/gm2-libs-iso/TextUtil.def b/gcc/m2/gm2-libs-iso/TextUtil.def index ead0456..7e6b3ed 100644 --- a/gcc/m2/gm2-libs-iso/TextUtil.def +++ b/gcc/m2/gm2-libs-iso/TextUtil.def @@ -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 ; diff --git a/gcc/m2/gm2-libs-iso/TextUtil.mod b/gcc/m2/gm2-libs-iso/TextUtil.mod index 44dbd1c..ad5786c 100644 --- a/gcc/m2/gm2-libs-iso/TextUtil.mod +++ b/gcc/m2/gm2-libs-iso/TextUtil.mod @@ -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 index 0000000..7702e88 --- /dev/null +++ b/gcc/testsuite/gm2/isolib/run/pass/testrestline.mod @@ -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 index 0000000..00e5c80 --- /dev/null +++ b/gcc/testsuite/gm2/isolib/run/pass/testrestline2.mod @@ -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 index 0000000..04fbad4 --- /dev/null +++ b/gcc/testsuite/gm2/isolib/run/pass/testrestline3.mod @@ -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 |