]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR modula2/120731] error in Strings.Pos causing sigsegv
authorGaius Mulley <gaiusmod2@gmail.com>
Sun, 22 Jun 2025 03:13:26 +0000 (04:13 +0100)
committerGaius Mulley <gaiusmod2@gmail.com>
Sun, 22 Jun 2025 03:13:26 +0000 (04:13 +0100)
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 <gaiusmod2@gmail.com>
gcc/m2/gm2-libs-log/Strings.def
gcc/m2/gm2-libs-log/Strings.mod
gcc/testsuite/gm2/pimlib/logitech/run/pass/teststrings.mod [new file with mode: 0644]

index aea35f8948890b811f864251776a3719b9773caf..2be4e4236d7330a95fe8437b5953fb0b3194fda5 100644 (file)
@@ -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 ;
index 6046a102a52e9b602b160eb0b0d3350fdc609067..44f47b322505089b3b0ee8342c0807a88595acfd 100644 (file)
@@ -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 (file)
index 0000000..1085d9c
--- /dev/null
@@ -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 .