https://gcc.gnu.org/g:fc276742e0db337c4d13e6c474abafd4796a6b69
commit r16-1608-gfc276742e0db337c4d13e6c474abafd4796a6b69 Author: Gaius Mulley <gaiusm...@gmail.com> Date: Sun Jun 22 04:13:26 2025 +0100 [PR modula2/120731] error in Strings.Pos causing sigsegv This patch corrects the m2log library procedure function Strings.Pos which incorrectly sliced the wrong component of the source string. The incorrect slice could cause a sigsegv if negative slice indices were generated. gcc/m2/ChangeLog: PR modula2/120731 * gm2-libs-log/Strings.def (Delete): Rewrite comment. * gm2-libs-log/Strings.mod (Pos): Rewrite. (PosLower): New procedure function. gcc/testsuite/ChangeLog: PR modula2/120731 * gm2/pimlib/logitech/run/pass/teststrings.mod: New test. Signed-off-by: Gaius Mulley <gaiusm...@gmail.com> Diff: --- gcc/m2/gm2-libs-log/Strings.def | 4 +- gcc/m2/gm2-libs-log/Strings.mod | 77 ++++++++++++++-------- .../gm2/pimlib/logitech/run/pass/teststrings.mod | 16 +++++ 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/gcc/m2/gm2-libs-log/Strings.def b/gcc/m2/gm2-libs-log/Strings.def index aea35f894889..2be4e4236d73 100644 --- a/gcc/m2/gm2-libs-log/Strings.def +++ b/gcc/m2/gm2-libs-log/Strings.def @@ -53,7 +53,9 @@ PROCEDURE Delete (VAR str: ARRAY OF CHAR; index: CARDINAL; length: CARDINAL) ; (* - Pos - return the first position of, substr, in, str. + Pos - return the first position of substr in str. + If substr is not found in str then it returns + HIGH (str) + 1. *) PROCEDURE Pos (substr, str: ARRAY OF CHAR) : CARDINAL ; diff --git a/gcc/m2/gm2-libs-log/Strings.mod b/gcc/m2/gm2-libs-log/Strings.mod index 6046a102a52e..44f47b322505 100644 --- a/gcc/m2/gm2-libs-log/Strings.mod +++ b/gcc/m2/gm2-libs-log/Strings.mod @@ -83,39 +83,62 @@ END Delete ; (* - Pos - return the first position of, substr, in, str. + PosLower - return the first position of substr in str. *) -PROCEDURE Pos (substr, str: ARRAY OF CHAR) : CARDINAL ; +PROCEDURE PosLower (substr, str: ARRAY OF CHAR) : CARDINAL ; VAR - i, k, l : INTEGER ; - s1, s2, s3: DynamicStrings.String ; + i, strLen, substrLen : INTEGER ; + strS, substrS, scratchS: DynamicStrings.String ; BEGIN - s1 := DynamicStrings.InitString(str) ; - s2 := DynamicStrings.InitString(substr) ; - k := DynamicStrings.Length(s1) ; - l := DynamicStrings.Length(s2) ; + strS := DynamicStrings.InitString (str) ; + substrS := DynamicStrings.InitString (substr) ; + strLen := DynamicStrings.Length (strS) ; + substrLen := DynamicStrings.Length (substrS) ; i := 0 ; REPEAT - i := DynamicStrings.Index(s1, DynamicStrings.char(s2, 0), i) ; - IF i>=0 + i := DynamicStrings.Index (strS, DynamicStrings.char (substrS, 0), i) ; + IF i < 0 + THEN + (* No match on first character therefore return now. *) + strS := DynamicStrings.KillString (strS) ; + substrS := DynamicStrings.KillString (substrS) ; + scratchS := DynamicStrings.KillString (scratchS) ; + RETURN( HIGH (str) + 1 ) + ELSIF i + substrLen <= strLen THEN - s3 := DynamicStrings.Slice(s1, i, l) ; - IF DynamicStrings.Equal(s3, s2) + scratchS := DynamicStrings.Slice (strS, i, i + substrLen) ; + IF DynamicStrings.Equal (scratchS, substrS) THEN - s1 := DynamicStrings.KillString(s1) ; - s2 := DynamicStrings.KillString(s2) ; - s3 := DynamicStrings.KillString(s3) ; + strS := DynamicStrings.KillString (strS) ; + substrS := DynamicStrings.KillString (substrS) ; + scratchS := DynamicStrings.KillString (scratchS) ; RETURN( i ) END ; - s3 := DynamicStrings.KillString(s3) + scratchS := DynamicStrings.KillString (scratchS) END ; - INC(i) - UNTIL i>=k ; - s1 := DynamicStrings.KillString(s1) ; - s2 := DynamicStrings.KillString(s2) ; - s3 := DynamicStrings.KillString(s3) ; - RETURN( HIGH(str)+1 ) + INC (i) + UNTIL i >= strLen ; + strS := DynamicStrings.KillString (strS) ; + substrS := DynamicStrings.KillString (substrS) ; + scratchS := DynamicStrings.KillString (scratchS) ; + RETURN( HIGH (str) + 1 ) +END PosLower ; + + +(* + Pos - return the first position of substr in str. + If substr is not found in str then it returns + HIGH (str) + 1. +*) + +PROCEDURE Pos (substr, str: ARRAY OF CHAR) : CARDINAL ; +BEGIN + IF Length (substr) <= Length (str) + THEN + RETURN PosLower (substr, str) + END ; + RETURN( HIGH (str) + 1 ) END Pos ; @@ -129,11 +152,11 @@ PROCEDURE Copy (str: ARRAY OF CHAR; VAR s1, s2: DynamicStrings.String ; BEGIN - s1 := DynamicStrings.InitString(str) ; - s2 := DynamicStrings.Slice(s1, index, index+length) ; - DynamicStrings.CopyOut(result, s2) ; - s1 := DynamicStrings.KillString(s1) ; - s2 := DynamicStrings.KillString(s2) + s1 := DynamicStrings.InitString (str) ; + s2 := DynamicStrings.Slice (s1, index, index+length) ; + DynamicStrings.CopyOut (result, s2) ; + s1 := DynamicStrings.KillString (s1) ; + s2 := DynamicStrings.KillString (s2) END Copy ; diff --git a/gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod b/gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod new file mode 100644 index 000000000000..1085d9cf4ecc --- /dev/null +++ b/gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod @@ -0,0 +1,16 @@ +MODULE teststrings ; + +IMPORT InOut,Strings; + +VAR + content : ARRAY[1..256] OF CHAR; + position: CARDINAL; + +(* the content is just random text. *) + +BEGIN + content := "erreur: In program module « essai3 »: attempting to pass (1) parameters to procedure"; + InOut.WriteString(content); + InOut.WriteLn; + position := Strings.Pos ("IMPORT", content); +END teststrings .