This change prevents a potential double free in Finalize, which
can cause gnatprfh to crash on some platforms.

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-08-03  Thomas Quinot  <qui...@adacore.com>

        * g-pehage.adb (Finalize): Avoid possible double-free.

Index: g-pehage.adb
===================================================================
--- g-pehage.adb        (revision 177040)
+++ g-pehage.adb        (working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                     Copyright (C) 2002-2010, AdaCore                     --
+--                     Copyright (C) 2002-2011, AdaCore                     --
 --                                                                          --
 -- 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- --
@@ -103,7 +103,7 @@
    No_Table  : constant Table_Id  := -1;
 
    type Word_Type is new String_Access;
-   procedure Free_Word (W : in out Word_Type);
+   procedure Free_Word (W : in out Word_Type) renames Free;
    function New_Word (S : String) return Word_Type;
 
    procedure Resize_Word (W : in out Word_Type; Len : Natural);
@@ -913,8 +913,14 @@
       --  ones) to avoid memory leaks.
 
       for W in 0 .. WT.Last loop
-         Free_Word (WT.Table (W));
+         --  Note: WT.Table (NK) is a temporary variable, do not free it since
+         --  this would cause a double free.
+
+         if W /= NK then
+            Free_Word (WT.Table (W));
+         end if;
       end loop;
+
       WT.Release;
       IT.Release;
 
@@ -948,17 +954,6 @@
       Min_Key_Len := 0;
    end Finalize;
 
-   ---------------
-   -- Free_Word --
-   ---------------
-
-   procedure Free_Word (W : in out Word_Type) is
-   begin
-      if W /= null then
-         Free (W);
-      end if;
-   end Free_Word;
-
    ----------------------------
    -- Generate_Mapping_Table --
    ----------------------------
@@ -1258,6 +1253,11 @@
       --  explicitly initialized to null.
 
       WT.Set_Last (Reduced (NK - 1));
+
+      --  Note: Reduced (0) = NK + 1
+
+      WT.Table (NK) := null;
+
       for W in 0 .. NK - 1 loop
          WT.Table (Reduced (W)) := null;
       end loop;

Reply via email to