diff mbox

[Ada] Bounded string slice fails when passed superflat bounds

Message ID 20150304100154.GA5920@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet March 4, 2015, 10:01 a.m. UTC
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  <dewar@adacore.com>

	* a-strsup.adb (Super_Slice): Deal with super flat case.
diff mbox

Patch

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;
 
    ----------------