From e4a99831f4fee023e50f4116318e678757bdf4ed Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Fri, 5 Jun 2020 11:50:16 -0400 Subject: [PATCH] [Ada] Overflow in string streaming 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 | 27 ++++++++++++++++++--------- gcc/ada/libgnat/s-ststop.ads | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/gcc/ada/libgnat/s-ststop.adb b/gcc/ada/libgnat/s-ststop.adb index d07342e12a7..cc2a352d162 100644 --- a/gcc/ada/libgnat/s-ststop.adb +++ b/gcc/ada/libgnat/s-ststop.adb @@ -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 diff --git a/gcc/ada/libgnat/s-ststop.ads b/gcc/ada/libgnat/s-ststop.ads index 321460b89d8..5f35fed6c3e 100644 --- a/gcc/ada/libgnat/s-ststop.ads +++ b/gcc/ada/libgnat/s-ststop.ads @@ -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. -- 2.30.2