If a bounded string slice operation has a lower bound less than the
higher bound minus one, the resulting length can be negative leading
to failures and exceptions.
The following must compile and execute cleanly:
1. with Ada.Strings.Bounded; use Ada.Strings.Bounded;
2. with Ada.Text_IO; use Ada.Text_IO;
3. procedure BSlice is
4. package BS is new Generic_Bounded_Length (1000);
5. use BS;
6. S : Bounded_String := To_Bounded_String ("Hello World!");
7. T : Bounded_String := Bounded_Slice (S, 10, 1);
8. begin
9. Put_Line (Length_Range'Image (Length (S)));
10. Put_line (Length_Range'Image (Length (T)));
11. end Bslice;
Generating the output:
12
0
Tested on x86_64-pc-linux-gnu, committed on trunk
2015-03-04 Robert Dewar <de...@adacore.com>
* a-strsup.adb (Super_Slice): Deal with super flat case.
Index: a-strsup.adb
===================================================================
--- a-strsup.adb (revision 221175)
+++ a-strsup.adb (working copy)
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2003-2014, Free Software Foundation, Inc. --
+-- Copyright (C) 2003-2015, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -1473,6 +1473,9 @@
raise Index_Error;
end if;
+ -- Note: in this case, superflat bounds are not a problem, we just
+ -- get the null string in accordance with normal Ada slice rules.
+
R := Source.Data (Low .. High);
end return;
end Super_Slice;
@@ -1490,7 +1493,9 @@
raise Index_Error;
end if;
- Result.Current_Length := High - Low + 1;
+ -- Note: the Max operation here deals with the superflat case
+
+ Result.Current_Length := Integer'Max (0, High - Low + 1);
Result.Data (1 .. Result.Current_Length) := Source.Data (Low .. High);
end return;
end Super_Slice;
@@ -1506,10 +1511,12 @@
or else High > Source.Current_Length
then
raise Index_Error;
- else
- Target.Current_Length := High - Low + 1;
- Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High);
end if;
+
+ -- Note: the Max operation here deals with the superflat case
+
+ Target.Current_Length := Integer'Max (0, High - Low + 1);
+ Target.Data (1 .. Target.Current_Length) := Source.Data (Low .. High);
end Super_Slice;
----------------