diff mbox series

[Ada] Indexing error when calling GNAT.Regpat.Match

Message ID 20220706133130.GA2205936@adacore.com
State New
Headers show
Series [Ada] Indexing error when calling GNAT.Regpat.Match | expand

Commit Message

Pierre-Marie de Rodat July 6, 2022, 1:31 p.m. UTC
This patch corrects an error in the compiler whereby a buffer sizing
error fails to get raised when compiling a regex expression with an
insufficiently sized Pattern_Matcher as the documentation indicated.
This, in turn, could lead to indexing errors when attempting to call
Match with the malformed regex program buffer.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

	* libgnat/s-regpat.adb, libgnat/s-regpat.ads (Compile): Add a
	new defaulted parameter Error_When_Too_Small to trigger an
	error, if specified true, when Matcher is too small to hold the
	compiled regex program.
diff mbox series

Patch

diff --git a/gcc/ada/libgnat/s-regpat.adb b/gcc/ada/libgnat/s-regpat.adb
--- a/gcc/ada/libgnat/s-regpat.adb
+++ b/gcc/ada/libgnat/s-regpat.adb
@@ -359,10 +359,11 @@  package body System.Regpat is
    -------------
 
    procedure Compile
-     (Matcher         : out Pattern_Matcher;
-      Expression      : String;
-      Final_Code_Size : out Program_Size;
-      Flags           : Regexp_Flags := No_Flags)
+     (Matcher              : out Pattern_Matcher;
+      Expression           : String;
+      Final_Code_Size      : out Program_Size;
+      Flags                : Regexp_Flags := No_Flags;
+      Error_When_Too_Small : Boolean := True)
    is
       --  We can't allocate space until we know how big the compiled form
       --  will be, but we can't compile it (and thus know how big it is)
@@ -1994,6 +1995,12 @@  package body System.Regpat is
       end if;
 
       PM.Flags := Flags;
+
+      --  Raise the appropriate error when Matcher does not have enough space
+
+      if Error_When_Too_Small and then Matcher.Size < Final_Code_Size then
+         raise Expression_Error with "Pattern_Matcher is too small";
+      end if;
    end Compile;
 
    function Compile
@@ -2009,7 +2016,7 @@  package body System.Regpat is
       Size  : Program_Size;
 
    begin
-      Compile (Dummy, Expression, Size, Flags);
+      Compile (Dummy, Expression, Size, Flags, Error_When_Too_Small => False);
 
       if Size <= Dummy.Size then
          return Pattern_Matcher'
@@ -2023,17 +2030,13 @@  package body System.Regpat is
             Program          =>
               Dummy.Program
                 (Dummy.Program'First .. Dummy.Program'First + Size - 1));
-      else
-         --  We have to recompile now that we know the size
-         --  ??? Can we use Ada 2005's return construct ?
-
-         declare
-            Result : Pattern_Matcher (Size);
-         begin
-            Compile (Result, Expression, Size, Flags);
-            return Result;
-         end;
       end if;
+
+      return
+         Result : Pattern_Matcher (Size)
+      do
+         Compile (Result, Expression, Size, Flags);
+      end return;
    end Compile;
 
    procedure Compile


diff --git a/gcc/ada/libgnat/s-regpat.ads b/gcc/ada/libgnat/s-regpat.ads
--- a/gcc/ada/libgnat/s-regpat.ads
+++ b/gcc/ada/libgnat/s-regpat.ads
@@ -403,10 +403,11 @@  package System.Regpat is
    --  (e.g. case sensitivity,...).
 
    procedure Compile
-     (Matcher         : out Pattern_Matcher;
-      Expression      : String;
-      Final_Code_Size : out Program_Size;
-      Flags           : Regexp_Flags := No_Flags);
+     (Matcher              : out Pattern_Matcher;
+      Expression           : String;
+      Final_Code_Size      : out Program_Size;
+      Flags                : Regexp_Flags := No_Flags;
+      Error_When_Too_Small : Boolean := True);
    --  Compile a regular expression into internal code
 
    --  This procedure is significantly faster than the Compile function since
@@ -426,7 +427,25 @@  package System.Regpat is
    --  expression.
    --
    --  This function raises Storage_Error if Matcher is too small to hold
-   --  the resulting code (i.e. Matcher.Size has too small a value).
+   --  the resulting code (i.e. Matcher.Size has too small a value) only when
+   --  the paramter Error_When_Too_Small is set to True. Otherwise, no error
+   --  will be raised and the required size will be placed in the
+   --  Final_Code_Size parameter.
+   --
+   --  Thus when Error_When_Too_Small is specified as false a check will need
+   --  to be made to ensure successful compilation - as in:
+   --
+   --     ...
+   --     Compile
+   --       (Matcher, Expr, Code_Size, Flags, Error_When_Too_Small => False);
+   --
+   --     if Matcher.Size < Code_Size then
+   --        declare
+   --           New_Matcher : Pattern_Matcher (1..Code_Size);
+   --        begin
+   --           Compile (New_Matcher, Expr, Code_Size, Flags);
+   --        end;
+   --     end if;
    --
    --  Expression_Error is raised if the string Expression does not contain
    --  a valid regular expression.