]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Fix unnecessarily large allocation in New_String
authorRonan Desplanques <desplanques@adacore.com>
Mon, 20 Jan 2025 12:37:08 +0000 (13:37 +0100)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Thu, 5 Jun 2025 08:18:35 +0000 (10:18 +0200)
This patches fixes an issue where Interfaces.C.Strings.New_String
allocates more memory than necessary when passed a string that contains
a NUL character.

gcc/ada/ChangeLog:

* libgnat/i-cstrin.adb (New_String): Fix size of allocation.

gcc/ada/libgnat/i-cstrin.adb

index 6d329254aff3c701431ff018eb0f9bc776d50de5..974ba3a0e8ca33609daea9c0bda25482bb60103b 100644 (file)
@@ -153,20 +153,33 @@ is
       --  the result, and doesn't copy the string on the stack, otherwise its
       --  use is limited when used from tasks on large strings.
 
-      Result : constant chars_ptr := Memory_Alloc (Str'Length + 1);
+      Len : Natural := 0;
+      --  Length of the longest prefix of Str that doesn't contain NUL
 
-      Result_Array : char_array  (1 .. Str'Length + 1);
-      for Result_Array'Address use To_Address (Result);
-      pragma Import (Ada, Result_Array);
+      Result : chars_ptr;
+   begin
+      for C of Str loop
+         if C = ASCII.NUL then
+            exit;
+         end if;
+         Len := Len + 1;
+      end loop;
 
-      Count : size_t;
+      Result := Memory_Alloc (size_t (Len) + 1);
+
+      declare
+         Result_Array : char_array (1 .. size_t (Len) + 1)
+         with Address => To_Address (Result), Import, Convention => Ada;
+
+         Count : size_t;
+      begin
+         To_C
+           (Item       => Str (Str'First .. Str'First + Len - 1),
+            Target     => Result_Array,
+            Count      => Count,
+            Append_Nul => True);
+      end;
 
-   begin
-      To_C
-        (Item       => Str,
-         Target     => Result_Array,
-         Count      => Count,
-         Append_Nul => True);
       return Result;
    end New_String;