Commit 677d7278 by Bob Duff Committed by Pierre-Marie de Rodat

Alternate fix for PR ada/71358

2017-09-18  Bob Duff  <duff@adacore.com>

	Alternate fix for PR ada/71358
	* libgnat/g-comlin.adb (Getopt): Remove manual null access checks.
	Instead, make a local copy of Config, and if it's null, allocate an
	empty Command_Line_Configuration_Record, so we won't crash on null
	pointer dereference.

From-SVN: r252909
parent 2a63b04e
2017-09-18 Bob Duff <duff@adacore.com>
Alternate fix for PR ada/71358
* libgnat/g-comlin.adb (Getopt): Remove manual null access checks.
Instead, make a local copy of Config, and if it's null, allocate an
empty Command_Line_Configuration_Record, so we won't crash on null
pointer dereference.
2017-09-16 Eric Botcazou <ebotcazou@adacore.com> 2017-09-16 Eric Botcazou <ebotcazou@adacore.com>
* libgnarl/a-intnam__rtems.ads: Update copyright date. * libgnarl/a-intnam__rtems.ads: Update copyright date.
......
...@@ -3153,18 +3153,16 @@ package body GNAT.Command_Line is ...@@ -3153,18 +3153,16 @@ package body GNAT.Command_Line is
New_Line; New_Line;
if Section /= "" and then Config.Switches /= null then if Section /= "" then
Put_Line ("Switches after " & Section); Put_Line ("Switches after " & Section);
end if; end if;
-- Compute size of the switches column -- Compute size of the switches column
if Config.Switches /= null then for S in Config.Switches'Range loop
for S in Config.Switches'Range loop Max_Len := Natural'Max
Max_Len := Natural'Max (Max_Len, Switch_Name (Config.Switches (S), Section)'Length);
(Max_Len, Switch_Name (Config.Switches (S), Section)'Length); end loop;
end loop;
end if;
if Config.Aliases /= null then if Config.Aliases /= null then
for A in Config.Aliases'Range loop for A in Config.Aliases'Range loop
...@@ -3177,27 +3175,25 @@ package body GNAT.Command_Line is ...@@ -3177,27 +3175,25 @@ package body GNAT.Command_Line is
-- Display the switches -- Display the switches
if Config.Switches /= null then for S in Config.Switches'Range loop
for S in Config.Switches'Range loop declare
declare N : constant String :=
N : constant String := Switch_Name (Config.Switches (S), Section);
Switch_Name (Config.Switches (S), Section);
begin
if N /= "" then
Put (" ");
Put (N);
Put ((1 .. Max_Len - N'Length + 1 => ' '));
if Config.Switches (S).Help /= null then begin
Put (Config.Switches (S).Help.all); if N /= "" then
end if; Put (" ");
Put (N);
Put ((1 .. Max_Len - N'Length + 1 => ' '));
New_Line; if Config.Switches (S).Help /= null then
Put (Config.Switches (S).Help.all);
end if; end if;
end;
end loop; New_Line;
end if; end if;
end;
end loop;
-- Display the aliases -- Display the aliases
...@@ -3348,6 +3344,7 @@ package body GNAT.Command_Line is ...@@ -3348,6 +3344,7 @@ package body GNAT.Command_Line is
Parser : Opt_Parser := Command_Line_Parser; Parser : Opt_Parser := Command_Line_Parser;
Concatenate : Boolean := True) Concatenate : Boolean := True)
is is
Local_Config : Command_Line_Configuration := Config;
Getopt_Switches : String_Access; Getopt_Switches : String_Access;
C : Character := ASCII.NUL; C : Character := ASCII.NUL;
...@@ -3373,22 +3370,22 @@ package body GNAT.Command_Line is ...@@ -3373,22 +3370,22 @@ package body GNAT.Command_Line is
-- Do automatic handling when possible -- Do automatic handling when possible
if Index /= -1 then if Index /= -1 then
case Config.Switches (Index).Typ is case Local_Config.Switches (Index).Typ is
when Switch_Untyped => when Switch_Untyped =>
null; -- no automatic handling null; -- no automatic handling
when Switch_Boolean => when Switch_Boolean =>
Config.Switches (Index).Boolean_Output.all := Local_Config.Switches (Index).Boolean_Output.all :=
Config.Switches (Index).Boolean_Value; Local_Config.Switches (Index).Boolean_Value;
return; return;
when Switch_Integer => when Switch_Integer =>
begin begin
if Parameter = "" then if Parameter = "" then
Config.Switches (Index).Integer_Output.all := Local_Config.Switches (Index).Integer_Output.all :=
Config.Switches (Index).Integer_Default; Local_Config.Switches (Index).Integer_Default;
else else
Config.Switches (Index).Integer_Output.all := Local_Config.Switches (Index).Integer_Output.all :=
Integer'Value (Parameter); Integer'Value (Parameter);
end if; end if;
...@@ -3402,8 +3399,8 @@ package body GNAT.Command_Line is ...@@ -3402,8 +3399,8 @@ package body GNAT.Command_Line is
return; return;
when Switch_String => when Switch_String =>
Free (Config.Switches (Index).String_Output.all); Free (Local_Config.Switches (Index).String_Output.all);
Config.Switches (Index).String_Output.all := Local_Config.Switches (Index).String_Output.all :=
new String'(Parameter); new String'(Parameter);
return; return;
end case; end case;
...@@ -3441,45 +3438,57 @@ package body GNAT.Command_Line is ...@@ -3441,45 +3438,57 @@ package body GNAT.Command_Line is
-- Start of processing for Getopt -- Start of processing for Getopt
begin begin
-- We work with a local copy of Config, because Config can be null, for
-- example if Define_Switch was never called. We could modify Config
-- itself, but then we would have to make it into an 'in out' parameter,
-- which would be incompatible.
if Local_Config = null then
Local_Config := new Command_Line_Configuration_Record;
end if;
if Local_Config.Switches = null then
Local_Config.Switches := new Switch_Definitions (1 .. 0);
end if;
-- Initialize sections -- Initialize sections
if Config.Sections = null then if Local_Config.Sections = null then
Config.Sections := new Argument_List'(1 .. 0 => null); Local_Config.Sections := new Argument_List'(1 .. 0 => null);
end if; end if;
Internal_Initialize_Option_Scan Internal_Initialize_Option_Scan
(Parser => Parser, (Parser => Parser,
Switch_Char => Parser.Switch_Character, Switch_Char => Parser.Switch_Character,
Stop_At_First_Non_Switch => Parser.Stop_At_First, Stop_At_First_Non_Switch => Parser.Stop_At_First,
Section_Delimiters => Section_Delimiters (Config)); Section_Delimiters => Section_Delimiters (Local_Config));
Getopt_Switches := new String' Getopt_Switches := new String'
(Get_Switches (Config, Parser.Switch_Character, Section_Name.all) (Get_Switches (Local_Config, Parser.Switch_Character, Section_Name.all)
& " h -help"); & " h -help");
-- Initialize output values for automatically handled switches -- Initialize output values for automatically handled switches
if Config.Switches /= null then for S in Local_Config.Switches'Range loop
for S in Config.Switches'Range loop case Local_Config.Switches (S).Typ is
case Config.Switches (S).Typ is when Switch_Untyped =>
when Switch_Untyped => null; -- Nothing to do
null; -- Nothing to do
when Switch_Boolean => when Switch_Boolean =>
Config.Switches (S).Boolean_Output.all := Local_Config.Switches (S).Boolean_Output.all :=
not Config.Switches (S).Boolean_Value; not Local_Config.Switches (S).Boolean_Value;
when Switch_Integer => when Switch_Integer =>
Config.Switches (S).Integer_Output.all := Local_Config.Switches (S).Integer_Output.all :=
Config.Switches (S).Integer_Initial; Local_Config.Switches (S).Integer_Initial;
when Switch_String => when Switch_String =>
if Config.Switches (S).String_Output.all = null then if Local_Config.Switches (S).String_Output.all = null then
Config.Switches (S).String_Output.all := new String'(""); Local_Config.Switches (S).String_Output.all :=
end if; new String'("");
end case; end if;
end loop; end case;
end if; end loop;
-- For all sections, and all switches within those sections -- For all sections, and all switches within those sections
...@@ -3500,34 +3509,34 @@ package body GNAT.Command_Line is ...@@ -3500,34 +3509,34 @@ package body GNAT.Command_Line is
or else or else
Full_Switch (Parser) = "-help" Full_Switch (Parser) = "-help"
then then
Display_Help (Config); Display_Help (Local_Config);
raise Exit_From_Command_Line; raise Exit_From_Command_Line;
end if; end if;
-- Do switch expansion if needed -- Do switch expansion if needed
For_Each_Simple For_Each_Simple
(Config, (Local_Config,
Section => Section_Name.all, Section => Section_Name.all,
Switch => Parser.Switch_Character & Full_Switch (Parser), Switch => Parser.Switch_Character & Full_Switch (Parser),
Parameter => Parameter (Parser)); Parameter => Parameter (Parser));
else else
if Current_Section = -1 then if Current_Section = -1 then
Current_Section := Config.Sections'First; Current_Section := Local_Config.Sections'First;
else else
Current_Section := Current_Section + 1; Current_Section := Current_Section + 1;
end if; end if;
exit when Current_Section > Config.Sections'Last; exit when Current_Section > Local_Config.Sections'Last;
Section_Name := Config.Sections (Current_Section); Section_Name := Local_Config.Sections (Current_Section);
Goto_Section (Section_Name.all, Parser); Goto_Section (Section_Name.all, Parser);
Free (Getopt_Switches); Free (Getopt_Switches);
Getopt_Switches := new String' Getopt_Switches := new String'
(Get_Switches (Get_Switches
(Config, Parser.Switch_Character, Section_Name.all)); (Local_Config, Parser.Switch_Character, Section_Name.all));
end if; end if;
end loop; end loop;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment