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 .

Reply via email to