[Ada] Overflow in string streaming
authorArnaud Charlet <charlet@adacore.com>
Fri, 5 Jun 2020 15:50:16 +0000 (11:50 -0400)
committerPierre-Marie de Rodat <derodat@adacore.com>
Thu, 16 Jul 2020 09:17:57 +0000 (05:17 -0400)
gcc/ada/

* libgnat/s-ststop.ads: Fix typo.
* libgnat/s-ststop.adb (Read, Write): Fix block number
computation to avoid overflows in case of large strings.

gcc/ada/libgnat/s-ststop.adb
gcc/ada/libgnat/s-ststop.ads

index d07342e..cc2a352 100644 (file)
@@ -216,21 +216,25 @@ package body System.Strings.Stream_Ops is
             declare
                --  Determine the size in BITS of the block necessary to contain
                --  the whole string.
+               --  Since we are dealing with strings indexed by natural, there
+               --  is no risk of overflow when using a Long_Long_Integer.
 
-               Block_Size : constant Natural :=
-                              Integer (Item'Last - Item'First + 1) * ET_Size;
+               Block_Size : constant Long_Long_Integer :=
+                 Item'Length * Long_Long_Integer (ET_Size);
 
                --  Item can be larger than what the default block can store,
-               --  determine the number of whole reads necessary to read the
+               --  determine the number of whole writes necessary to output the
                --  string.
 
-               Blocks : constant Natural := Block_Size / Default_Block_Size;
+               Blocks : constant Natural :=
+                 Natural (Block_Size / Long_Long_Integer (Default_Block_Size));
 
                --  The size of Item may not be a multiple of the default block
-               --  size, determine the size of the remaining chunk in BITS.
+               --  size, determine the size of the remaining chunk.
 
                Rem_Size : constant Natural :=
-                            Block_Size mod Default_Block_Size;
+                 Natural
+                   (Block_Size mod Long_Long_Integer (Default_Block_Size));
 
                --  String indexes
 
@@ -337,20 +341,25 @@ package body System.Strings.Stream_Ops is
             declare
                --  Determine the size in BITS of the block necessary to contain
                --  the whole string.
+               --  Since we are dealing with strings indexed by natural, there
+               --  is no risk of overflow when using a Long_Long_Integer.
 
-               Block_Size : constant Natural := Item'Length * ET_Size;
+               Block_Size : constant Long_Long_Integer :=
+                 Item'Length * Long_Long_Integer (ET_Size);
 
                --  Item can be larger than what the default block can store,
                --  determine the number of whole writes necessary to output the
                --  string.
 
-               Blocks : constant Natural := Block_Size / Default_Block_Size;
+               Blocks : constant Natural :=
+                 Natural (Block_Size / Long_Long_Integer (Default_Block_Size));
 
                --  The size of Item may not be a multiple of the default block
                --  size, determine the size of the remaining chunk.
 
                Rem_Size : constant Natural :=
-                            Block_Size mod Default_Block_Size;
+                 Natural
+                   (Block_Size mod Long_Long_Integer (Default_Block_Size));
 
                --  String indexes
 
index 321460b..5f35fed 100644 (file)
@@ -53,7 +53,7 @@
 --       or
 --     String_Output_Blk_IO (Some_Stream, Some_String);
 
---  String_Output form is used if pragma Restrictions (No_String_Optimziations)
+--  String_Output form is used if pragma Restrictions (No_String_Optimizations)
 --  is active, which requires element by element operations. The BLK_IO form
 --  is used if this restriction is not set, allowing block optimization.