OSDN Git Service

PR 33870
[pf3gnuchains/gcc-fork.git] / gcc / ada / g-md5.adb
index e126b8f..158c9c7 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                B o d y                                   --
 --                                                                          --
---              Copyright (C) 2002 Ada Core Technologies, Inc.              --
+--                     Copyright (C) 2002-2006, 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- --
@@ -16,8 +16,8 @@
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
+-- Boston, MA 02110-1301, USA.                                              --
 --                                                                          --
 -- As a special exception,  if other files  instantiate  generics from this --
 -- unit, or you link  this unit with other files  to produce an executable, --
@@ -138,7 +138,7 @@ package body GNAT.MD5 is
    procedure Transform
      (C     : in out Context;
       Block : String);
-   --  Process one block of 64 characters.
+   --  Process one block of 64 characters
 
    ------------
    -- Decode --
@@ -148,7 +148,7 @@ package body GNAT.MD5 is
      (Block : String;
       X     : out Sixteen_Words)
    is
-      Cur   : Positive := Block'First;
+      Cur : Positive := Block'First;
 
    begin
       pragma Assert (Block'Length = 64);
@@ -171,7 +171,11 @@ package body GNAT.MD5 is
       Result : Message_Digest;
 
       Cur : Natural := 1;
-      --  Index in Result where the next character will be placed.
+      --  Index in Result where the next character will be placed
+
+      Last_Block : String (1 .. 64);
+
+      C1 : Context := C;
 
       procedure Convert (X : Unsigned_32);
       --  Put the contribution of one of the four words (A, B, C, D) of the
@@ -183,7 +187,6 @@ package body GNAT.MD5 is
 
       procedure Convert (X : Unsigned_32) is
          Y : Unsigned_32 := X;
-
       begin
          for J in 1 .. 4 loop
             Result (Cur + 1) := Hex_Digit (Y and Unsigned_32'(16#0F#));
@@ -197,27 +200,57 @@ package body GNAT.MD5 is
    --  Start of processing for Digest
 
    begin
-      Convert (C.A);
-      Convert (C.B);
-      Convert (C.C);
-      Convert (C.D);
+      --  Process characters in the context buffer, if any
+
+      Last_Block (1 .. C.Last) := C.Buffer (1 .. C.Last);
+
+      --  Too many magic literals below, should be defined as constants ???
+
+      if C.Last > 55 then
+         Last_Block (C.Last + 1 .. 64) := Padding (1 .. 64 - C.Last);
+         Transform (C1, Last_Block);
+         Last_Block := (others => ASCII.NUL);
+
+      else
+         Last_Block (C.Last + 1 .. 56) := Padding (1 .. 56 - C.Last);
+      end if;
+
+      --  Add the input length (as stored in the context) as 8 characters
+
+      Last_Block (57 .. 64) := (others => ASCII.NUL);
+
+      declare
+         L : Unsigned_64 := Unsigned_64 (C.Length) * 8;
+         Idx : Positive := 57;
+
+      begin
+         while L > 0 loop
+            Last_Block (Idx) := Character'Val (L and 16#Ff#);
+            L := Shift_Right (L, 8);
+            Idx := Idx + 1;
+         end loop;
+      end;
+
+      Transform (C1, Last_Block);
+
+      Convert (C1.A);
+      Convert (C1.B);
+      Convert (C1.C);
+      Convert (C1.D);
       return Result;
    end Digest;
 
    function Digest (S : String) return Message_Digest is
       C : Context;
-
    begin
       Update (C, S);
       return Digest (C);
    end Digest;
 
    function Digest
-     (A    : Ada.Streams.Stream_Element_Array)
-      return Message_Digest
+     (A : Ada.Streams.Stream_Element_Array) return Message_Digest
    is
       C : Context;
-
    begin
       Update (C, A);
       return Digest (C);
@@ -450,45 +483,19 @@ package body GNAT.MD5 is
      (C     : in out Context;
       Input : String)
    is
-      Cur        : Positive := Input'First;
-      Last_Block : String (1 .. 64);
+      Inp : constant String := C.Buffer (1 .. C.Last) & Input;
+      Cur        : Positive := Inp'First;
 
    begin
-      while Cur + 63 <= Input'Last loop
-         Transform (C, Input (Cur .. Cur + 63));
+      C.Length := C.Length + Input'Length;
+
+      while Cur + 63 <= Inp'Last loop
+         Transform (C, Inp (Cur .. Cur + 63));
          Cur := Cur + 64;
       end loop;
 
-      Last_Block (1 .. Input'Last - Cur + 1) := Input (Cur .. Input'Last);
-
-      if Input'Last - Cur + 1 > 56 then
-         Cur := Input'Last - Cur + 2;
-         Last_Block (Cur .. 64) := Padding (1 .. 64 - Cur + 1);
-         Transform (C, Last_Block);
-         Last_Block := (others => ASCII.NUL);
-
-      else
-         Cur := Input'Last - Cur + 2;
-         Last_Block (Cur .. 56) := Padding (1 .. 56 - Cur + 1);
-      end if;
-
-      --  Add the input length as 8 characters
-
-      Last_Block (57 .. 64) := (others => ASCII.NUL);
-
-      declare
-         L : Unsigned_64 := Unsigned_64 (Input'Length) * 8;
-
-      begin
-         Cur := 57;
-         while L > 0 loop
-            Last_Block (Cur) := Character'Val (L and 16#Ff#);
-            L := Shift_Right (L, 8);
-            Cur := Cur + 1;
-         end loop;
-      end;
-
-      Transform (C, Last_Block);
+      C.Last := Inp'Last - Cur + 1;
+      C.Buffer (1 .. C.Last) := Inp (Cur .. Inp'Last);
    end Update;
 
    procedure Update
@@ -513,7 +520,6 @@ package body GNAT.MD5 is
 
    function Wide_Digest (W : Wide_String) return Message_Digest is
       C : Context;
-
    begin
       Wide_Update (C, W);
       return Digest (C);
@@ -527,7 +533,6 @@ package body GNAT.MD5 is
      (C     : in out Context;
       Input : Wide_String)
    is
-
       String_Input : String (1 .. 2 * Input'Length);
       Cur          : Positive := 1;