===================================================================
@@ -641,10 +641,22 @@
Header_Separator : constant Character := '#';
function Internal_Tag (External : String) return Tag is
- Ext_Copy : aliased String (External'First .. External'Last + 1);
- Res : Tag := null;
+ pragma Unsuppress (All_Checks);
+ -- To make T'Class'Input robust in the case of bad data
+ Res : Tag := null;
+
begin
+ -- Raise Tag_Error for empty strings, and for absurdly long strings.
+ -- This is to make T'Class'Input robust in the case of bad data, for
+ -- example a String(123456789..1234). The limit of 10,000 characters is
+ -- arbitrary, but is unlikely to be exceeded by legitimate external tag
+ -- names.
+
+ if External'Length not in 1 .. 10_000 then
+ raise Tag_Error;
+ end if;
+
-- Handle locally defined tagged types
if External'Length > Internal_Tag_Header'Length
@@ -731,9 +743,14 @@
else
-- Make NUL-terminated copy of external tag string
- Ext_Copy (External'Range) := External;
- Ext_Copy (Ext_Copy'Last) := ASCII.NUL;
- Res := External_Tag_HTable.Get (Ext_Copy'Address);
+ declare
+ Ext_Copy : aliased String (External'First .. External'Last + 1);
+ pragma Assert (Ext_Copy'Length > 1); -- See Length check at top
+ begin
+ Ext_Copy (External'Range) := External;
+ Ext_Copy (Ext_Copy'Last) := ASCII.NUL;
+ Res := External_Tag_HTable.Get (Ext_Copy'Address);
+ end;
end if;
if Res = null then
===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 2008-2017, 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- --
@@ -128,17 +128,20 @@
(Strm : access Root_Stream_Type'Class;
IO : IO_Kind) return Array_Type
is
+ pragma Unsuppress (All_Checks);
+ -- To make T'Class'Input robust in the case of bad data. The
+ -- declaration of Item below could raise Storage_Error if the length
+ -- is huge.
begin
if Strm = null then
raise Constraint_Error;
end if;
declare
- Low : Index_Type;
- High : Index_Type;
-
+ Low, High : Index_Type'Base;
begin
- -- Read the bounds of the string
+ -- Read the bounds of the string. Note that they could be out of
+ -- range of Index_Type in the case of empty arrays.
Index_Type'Read (Strm, Low);
Index_Type'Read (Strm, High);