From 7a6955760ba950eb82f57929f8f6c9847c65f0af Mon Sep 17 00:00:00 2001 From: Mark Adler Date: Fri, 9 Sep 2011 23:23:45 -0700 Subject: zlib 1.2.1.2 --- contrib/README.contrib | 2 +- contrib/ada/buffer_demo.adb | 106 ++++++++++++++++ contrib/ada/mtest.adb | 11 +- contrib/ada/read.adb | 9 +- contrib/ada/readme.txt | 27 +++- contrib/ada/zlib-streams.adb | 14 +- contrib/ada/zlib-streams.ads | 6 +- contrib/ada/zlib-thin.adb | 70 ++-------- contrib/ada/zlib-thin.ads | 57 ++------- contrib/ada/zlib.adb | 143 ++++++++++++--------- contrib/ada/zlib.ads | 105 ++++++++------- contrib/ada/zlib.gpr | 42 +++--- contrib/delphi/ZLib.pas | 4 +- contrib/infback9/infback9.c | 3 + contrib/infback9/inftree9.c | 4 +- contrib/masmx86/mkasm.bat | 2 +- contrib/minizip/ChangeLogUnzip | 8 ++ contrib/minizip/crypt.h | 4 +- contrib/minizip/ioapi.c | 4 +- contrib/minizip/ioapi.h | 4 +- contrib/minizip/iowin32.c | 4 +- contrib/minizip/iowin32.h | 4 +- contrib/minizip/miniunz.c | 41 +++++- contrib/minizip/minizip.c | 37 +++++- contrib/minizip/mztools.c | 281 +++++++++++++++++++++++++++++++++++++++++ contrib/minizip/mztools.h | 31 +++++ contrib/minizip/unzip.c | 61 ++++++++- contrib/minizip/unzip.h | 14 +- contrib/minizip/zip.c | 26 +++- contrib/minizip/zip.h | 5 +- contrib/pascal/zlibpas.pas | 2 +- contrib/untgz/untgz.c | 135 +++++++++++++++++--- contrib/vstudio/vc7/zlib.rc | 6 +- 33 files changed, 965 insertions(+), 307 deletions(-) create mode 100644 contrib/ada/buffer_demo.adb create mode 100644 contrib/minizip/mztools.c create mode 100644 contrib/minizip/mztools.h (limited to 'contrib') diff --git a/contrib/README.contrib b/contrib/README.contrib index 8860f31..eae15aa 100644 --- a/contrib/README.contrib +++ b/contrib/README.contrib @@ -67,4 +67,4 @@ visual-basic.txt by Carlos Rios How to use compress(), uncompress() and the gz* functions from VB vstudio/ by Gilles Vollant - Building zlib with Visual Studio .NET + Building a minizip-enhanced zlib with Visual Studio .NET diff --git a/contrib/ada/buffer_demo.adb b/contrib/ada/buffer_demo.adb new file mode 100644 index 0000000..46b8638 --- /dev/null +++ b/contrib/ada/buffer_demo.adb @@ -0,0 +1,106 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- +-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $ + +-- This demo program provided by Dr Steve Sangwine +-- +-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer +-- of exactly the correct size is used for decompressed data, and the last +-- few bytes passed in to Zlib are checksum bytes. + +-- This program compresses a string of text, and then decompresses the +-- compressed text into a buffer of the same size as the original text. + +with Ada.Streams; use Ada.Streams; +with Ada.Text_IO; + +with ZLib; use ZLib; + +procedure Buffer_Demo is + EOL : Character renames ASCII.LF; + Text : constant String + := "Four score and seven years ago our fathers brought forth," & EOL & + "upon this continent, a new nation, conceived in liberty," & EOL & + "and dedicated to the proposition that `all men are created equal'."; + + Source : Stream_Element_Array (1 .. Text'Length); + for Source'Address use Text'Address; + +begin + Ada.Text_IO.Put (Text); + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes"); + + declare + Compressed_Data : Stream_Element_Array (1 .. Text'Length); + L : Stream_Element_Offset; + begin + Compress : declare + Compressor : Filter_Type; + I : Stream_Element_Offset; + begin + Deflate_Init (Compressor); + + -- Compress the whole of T at once. + + Translate (Compressor, Source, I, Compressed_Data, L, Finish); + pragma Assert (I = Source'Last); + + Close (Compressor); + + Ada.Text_IO.Put_Line + ("Compressed size : " + & Stream_Element_Offset'Image (L) & " bytes"); + end Compress; + + -- Now we decompress the data, passing short blocks of data to Zlib + -- (because this demonstrates the problem - the last block passed will + -- contain checksum information and there will be no output, only a + -- check inside Zlib that the checksum is correct). + + Decompress : declare + Decompressor : Filter_Type; + + Uncompressed_Data : Stream_Element_Array (1 .. Text'Length); + + Block_Size : constant := 4; + -- This makes sure that the last block contains + -- only Adler checksum data. + + P : Stream_Element_Offset := Compressed_Data'First - 1; + O : Stream_Element_Offset; + begin + Inflate_Init (Decompressor); + + loop + Translate + (Decompressor, + Compressed_Data + (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)), + P, + Uncompressed_Data + (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last), + O, + No_Flush); + + Ada.Text_IO.Put_Line + ("Total in : " & Count'Image (Total_In (Decompressor)) & + ", out : " & Count'Image (Total_Out (Decompressor))); + + exit when P = L; + end loop; + + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Decompressed text matches original text : " + & Boolean'Image (Uncompressed_Data = Source)); + end Decompress; + end; +end Buffer_Demo; diff --git a/contrib/ada/mtest.adb b/contrib/ada/mtest.adb index 91a96cd..c4dfd08 100644 --- a/contrib/ada/mtest.adb +++ b/contrib/ada/mtest.adb @@ -5,10 +5,10 @@ -- -- -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- Continuous test for ZLib multithreading. If the test is fail --- Wou should provide thread safe allocation routines for the Z_Stream. +-- Continuous test for ZLib multithreading. If the test would fail +-- we should provide thread safe allocation routines for the Z_Stream. -- --- $Id: mtest.adb,v 1.2 2003/08/12 12:11:05 vagul Exp $ +-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $ with ZLib; with Ada.Streams; @@ -148,6 +148,9 @@ procedure MTest is pragma Unreferenced (Test); + Dummy : Character; + begin - null; + Ada.Text_IO.Get_Immediate (Dummy); + Stop := True; end MTest; diff --git a/contrib/ada/read.adb b/contrib/ada/read.adb index 184ea00..1f2efbf 100644 --- a/contrib/ada/read.adb +++ b/contrib/ada/read.adb @@ -6,7 +6,7 @@ -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- $Id: read.adb,v 1.7 2003/08/12 12:12:35 vagul Exp $ +-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $ -- Test/demo program for the generic read interface. @@ -68,7 +68,11 @@ procedure Read is -- ZLib.Read -- reading data from the File_In. - procedure Read is new ZLib.Read (Read, Read_Buffer, Read_First, Read_Last); + procedure Read is new ZLib.Read + (Read, + Read_Buffer, + Rest_First => Read_First, + Rest_Last => Read_Last); ---------- -- Read -- @@ -103,6 +107,7 @@ procedure Read is Pack_Size := 0; Offset := 1; Read_First := Read_Buffer'Last + 1; + Read_Last := Read_Buffer'Last; end Reset; begin diff --git a/contrib/ada/readme.txt b/contrib/ada/readme.txt index ad02c22..dec7ef3 100644 --- a/contrib/ada/readme.txt +++ b/contrib/ada/readme.txt @@ -1,20 +1,31 @@ - ZLib for Ada thick binding (ZLib.Ada) - Release 1.2 + Release 1.3 ZLib.Ada is a thick binding interface to the popular ZLib data compression library, available at http://www.gzip.org/zlib/. It provides Ada-style access to the ZLib C library. - Here are the main changes since ZLib.Ada 1.1: + Here are the main changes since ZLib.Ada 1.2: + +- Attension: ZLib.Read generic routine have a initialization requirement + for Read_Last parameter now. It is a bit incompartible with previous version, + but extends functionality, we could use new parameters Allow_Read_Some and + Flush now. + +- Added Is_Open routines to ZLib and ZLib.Streams packages. -- The default header type has a name "Default" now. Auto is used only for - automatic GZip/ZLib header detection. +- Add pragma Assert to check Stream_Element is 8 bit. -- Added test for multitasking mtest.adb. +- Fix extraction to buffer with exact known decompressed size. Error reported by + Steve Sangwine. -- Added GNAT project file zlib.gpr. +- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits + computers. Patch provided by Pascal Obry. + +- Add Status_Error exception definition. + +- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit. How to build ZLib.Ada under GNAT @@ -50,3 +61,5 @@ The routines from the package specifications are commented. Homepage: http://zlib-ada.sourceforge.net/ Author: Dmitriy Anisimkov + +Contributors: Pascal Obry , Steve Sangwine diff --git a/contrib/ada/zlib-streams.adb b/contrib/ada/zlib-streams.adb index d213b5c..398664a 100644 --- a/contrib/ada/zlib-streams.adb +++ b/contrib/ada/zlib-streams.adb @@ -6,7 +6,7 @@ -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- $Id: zlib-streams.adb,v 1.9 2003/08/12 13:15:31 vagul Exp $ +-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $ with Ada.Unchecked_Deallocation; @@ -90,6 +90,7 @@ package body ZLib.Streams is Stream.Buffer := new Buffer_Subtype; Stream.Rest_First := Stream.Buffer'Last + 1; + Stream.Rest_Last := Stream.Buffer'Last; end if; end Create; @@ -113,6 +114,15 @@ package body ZLib.Streams is end loop; end Flush; + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Stream : Stream_Type) return Boolean is + begin + return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer); + end Is_Open; + ---------- -- Read -- ---------- @@ -212,4 +222,4 @@ package body ZLib.Streams is return Total_Out (Stream.Writer); end Write_Total_Out; -end ZLib.Streams; +end ZLib.Streams; \ No newline at end of file diff --git a/contrib/ada/zlib-streams.ads b/contrib/ada/zlib-streams.ads index 1d5e904..5c68667 100644 --- a/contrib/ada/zlib-streams.ads +++ b/contrib/ada/zlib-streams.ads @@ -6,7 +6,7 @@ -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- $Id: zlib-streams.ads,v 1.11 2003/08/12 13:15:31 vagul Exp $ +-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $ package ZLib.Streams is @@ -77,6 +77,8 @@ package ZLib.Streams is -- !!! When the Need_Header is False ZLib-Ada is using undocumented -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers. + function Is_Open (Stream : Stream_Type) return Boolean; + procedure Close (Stream : in out Stream_Type); private @@ -109,4 +111,4 @@ private Writer : Filter_Type; end record; -end ZLib.Streams; +end ZLib.Streams; \ No newline at end of file diff --git a/contrib/ada/zlib-thin.adb b/contrib/ada/zlib-thin.adb index 163bd5b..0ca4a71 100644 --- a/contrib/ada/zlib-thin.adb +++ b/contrib/ada/zlib-thin.adb @@ -6,12 +6,11 @@ -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- $Id: zlib-thin.adb,v 1.6 2003/01/21 15:26:37 vagul Exp $ +-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $ package body ZLib.Thin is - ZLIB_VERSION : constant Chars_Ptr := - Interfaces.C.Strings.New_String ("1.1.4"); + ZLIB_VERSION : constant Chars_Ptr := zlibVersion; Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit; @@ -37,14 +36,6 @@ package body ZLib.Thin is -- Deflate_Init -- ------------------ - function Deflate_Init - (strm : in Z_Streamp; - level : in Int := Z_DEFAULT_COMPRESSION) - return Int is - begin - return deflateInit (strm, level, ZLIB_VERSION, Z_Stream_Size); - end Deflate_Init; - function Deflate_Init (strm : Z_Streamp; level : Int; @@ -69,16 +60,15 @@ package body ZLib.Thin is -- Inflate_Init -- ------------------ - function Inflate_Init (strm : Z_Streamp) return Int is - begin - return inflateInit (strm, ZLIB_VERSION, Z_Stream_Size); - end Inflate_Init; - function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is begin return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size); end Inflate_Init; + ------------------------ + -- Last_Error_Message -- + ------------------------ + function Last_Error_Message (Strm : in Z_Stream) return String is use Interfaces.C.Strings; begin @@ -89,54 +79,28 @@ package body ZLib.Thin is end if; end Last_Error_Message; - ------------- - -- Need_In -- - ------------- - - function Need_In (strm : Z_Stream) return Boolean is - begin - return strm.Avail_In = 0; - end Need_In; - - -------------- - -- Need_Out -- - -------------- - - function Need_Out (strm : Z_Stream) return Boolean is - begin - return strm.Avail_Out = 0; - end Need_Out; - ------------ -- Set_In -- ------------ procedure Set_In (Strm : in out Z_Stream; - Buffer : in Byte_Access; - Size : in UInt) is + Buffer : in Voidp; + Size : in UInt) is begin Strm.Next_In := Buffer; Strm.Avail_In := Size; end Set_In; - procedure Set_In - (Strm : in out Z_Stream; - Buffer : in Voidp; - Size : in UInt) is - begin - Set_In (Strm, Bytes.To_Pointer (Buffer), Size); - end Set_In; - ------------------ -- Set_Mem_Func -- ------------------ procedure Set_Mem_Func (Strm : in out Z_Stream; - Opaque : in Voidp; - Alloc : in alloc_func; - Free : in free_func) is + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func) is begin Strm.opaque := Opaque; Strm.zalloc := Alloc; @@ -149,21 +113,13 @@ package body ZLib.Thin is procedure Set_Out (Strm : in out Z_Stream; - Buffer : in Byte_Access; - Size : in UInt) is + Buffer : in Voidp; + Size : in UInt) is begin Strm.Next_Out := Buffer; Strm.Avail_Out := Size; end Set_Out; - procedure Set_Out - (Strm : in out Z_Stream; - Buffer : in Voidp; - Size : in UInt) is - begin - Set_Out (Strm, Bytes.To_Pointer (Buffer), Size); - end Set_Out; - -------------- -- Total_In -- -------------- diff --git a/contrib/ada/zlib-thin.ads b/contrib/ada/zlib-thin.ads index c227374..d4407eb 100644 --- a/contrib/ada/zlib-thin.ads +++ b/contrib/ada/zlib-thin.ads @@ -6,10 +6,11 @@ -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- $Id: zlib-thin.ads,v 1.8 2003/08/12 13:16:51 vagul Exp $ +-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $ with Interfaces.C.Strings; -with System.Address_To_Access_Conversions; + +with System; private package ZLib.Thin is @@ -36,18 +37,18 @@ private package ZLib.Thin is -- zconf.h:216 type Int is new Interfaces.C.int; - type ULong is new Interfaces.C.unsigned; -- 32 bits or more - -- zconf.h:217 + type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more + -- zconf.h:217 subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr; type ULong_Access is access ULong; type Int_Access is access Int; - subtype Voidp is System.Address; -- zconf.h:232 - package Bytes is new System.Address_To_Access_Conversions (Byte); + subtype Voidp is System.Address; -- zconf.h:232 - subtype Byte_Access is Bytes.Object_Pointer; + subtype Byte_Access is Voidp; + Nul : constant Voidp := System.Null_Address; -- end from zconf Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125 @@ -251,12 +252,6 @@ private package ZLib.Thin is stream_size : Int) return Int; - function Deflate_Init - (strm : in Z_Streamp; - level : in Int := Z_DEFAULT_COMPRESSION) - return Int; - pragma Inline (Deflate_Init); - function deflateInit2 (strm : Z_Streamp; level : Int; @@ -284,9 +279,6 @@ private package ZLib.Thin is stream_size : Int) return Int; - function Inflate_Init (strm : Z_Streamp) return Int; - pragma Inline (Inflate_Init); - function inflateInit2 (strm : in Z_Streamp; windowBits : in Int; @@ -318,32 +310,12 @@ private package ZLib.Thin is -- has dropped to zero. The application must initialize zalloc, zfree and -- opaque before calling the init function. - function Need_In (strm : in Z_Stream) return Boolean; - -- return true when we do not need to setup Next_In and Avail_In fields. - pragma Inline (Need_In); - - function Need_Out (strm : in Z_Stream) return Boolean; - -- return true when we do not need to setup Next_Out and Avail_Out field. - pragma Inline (Need_Out); - - procedure Set_In - (Strm : in out Z_Stream; - Buffer : in Byte_Access; - Size : in UInt); - pragma Inline (Set_In); - procedure Set_In (Strm : in out Z_Stream; Buffer : in Voidp; Size : in UInt); pragma Inline (Set_In); - procedure Set_Out - (Strm : in out Z_Stream; - Buffer : in Byte_Access; - Size : in UInt); - pragma Inline (Set_Out); - procedure Set_Out (Strm : in out Z_Stream; Buffer : in Voidp; @@ -388,19 +360,13 @@ private package ZLib.Thin is function zlibCompileFlags return ULong; - function deflatePrime - (strm : Z_Streamp; - bits : Int; - value : Int) - return Int; - private type Z_Stream is record -- zlib.h:68 - Next_In : Byte_Access; -- next input byte + Next_In : Voidp := Nul; -- next input byte Avail_In : UInt := 0; -- number of bytes available at next_in Total_In : ULong := 0; -- total nb of input bytes read so far - Next_Out : Byte_Access; -- next output byte should be put there + Next_Out : Voidp := Nul; -- next output byte should be put there Avail_Out : UInt := 0; -- remaining free space at next_out Total_Out : ULong := 0; -- total nb of bytes output so far msg : Chars_Ptr; -- last error message, NULL if no error @@ -460,14 +426,13 @@ private pragma Import (C, inflateSyncPoint, "inflateSyncPoint"); pragma Import (C, get_crc_table, "get_crc_table"); - -- added in zlib 1.2.1: + -- since zlib 1.2.0: pragma Import (C, inflateCopy, "inflateCopy"); pragma Import (C, compressBound, "compressBound"); pragma Import (C, deflateBound, "deflateBound"); pragma Import (C, gzungetc, "gzungetc"); pragma Import (C, zlibCompileFlags, "zlibCompileFlags"); - pragma Import (C, deflatePrime, "deflatePrime"); pragma Import (C, inflateBackInit, "inflateBackInit_"); diff --git a/contrib/ada/zlib.adb b/contrib/ada/zlib.adb index 93bf885..8b6fd68 100644 --- a/contrib/ada/zlib.adb +++ b/contrib/ada/zlib.adb @@ -1,12 +1,12 @@ ---------------------------------------------------------------- -- ZLib for Ada thick binding. -- -- -- --- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- -- -- -- Open source license information is in the zlib.ads file. -- ---------------------------------------------------------------- --- $Id: zlib.adb,v 1.19 2003/07/13 16:02:19 vagul Exp $ +-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $ with Ada.Exceptions; with Ada.Unchecked_Conversion; @@ -34,7 +34,7 @@ package body ZLib is VERSION_ERROR); type Flate_Step_Function is access - function (Strm : Thin.Z_Streamp; flush : Thin.Int) return Thin.Int; + function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int; pragma Convention (C, Flate_Step_Function); type Flate_End_Function is access @@ -82,13 +82,13 @@ package body ZLib is Flush_Finish : constant array (Boolean) of Flush_Mode := (True => Finish, False => No_Flush); - procedure Raise_Error (Stream : Z_Stream); + procedure Raise_Error (Stream : in Z_Stream); pragma Inline (Raise_Error); - procedure Raise_Error (Message : String); + procedure Raise_Error (Message : in String); pragma Inline (Raise_Error); - procedure Check_Error (Stream : Z_Stream; Code : Thin.Int); + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int); procedure Free is new Ada.Unchecked_Deallocation (Z_Stream, Z_Stream_Access); @@ -118,7 +118,7 @@ package body ZLib is -- Check_Error -- ----------------- - procedure Check_Error (Stream : Z_Stream; Code : Thin.Int) is + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is use type Thin.Int; begin if Code /= Thin.Z_OK then @@ -138,10 +138,11 @@ package body ZLib is is Code : Thin.Int; begin - Code := Flate (Filter.Compression).Done - (To_Thin_Access (Filter.Strm)); + if not Ignore_Error and then not Is_Open (Filter) then + raise Status_Error; + end if; - Filter.Opened := False; + Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm)); if Ignore_Error or else Code = Thin.Z_OK then Free (Filter.Strm); @@ -154,7 +155,7 @@ package body ZLib is Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Return_Code_Enum'Image (Return_Code (Code)) - & ": " & Error_Message); + & ": " & Error_Message); end; end if; end Close; @@ -170,10 +171,9 @@ package body ZLib is is use Thin; begin - return Unsigned_32 (crc32 - (ULong (CRC), - Bytes.To_Pointer (Data'Address), - Data'Length)); + return Unsigned_32 (crc32 (ULong (CRC), + Data'Address, + Data'Length)); end CRC32; procedure CRC32 @@ -192,13 +192,17 @@ package body ZLib is Level : in Compression_Level := Default_Compression; Strategy : in Strategy_Type := Default_Strategy; Method : in Compression_Method := Deflated; - Window_Bits : in Window_Bits_Type := 15; - Memory_Level : in Memory_Level_Type := 8; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; Header : in Header_Type := Default) is use type Thin.Int; Win_Bits : Thin.Int := Thin.Int (Window_Bits); begin + if Is_Open (Filter) then + raise Status_Error; + end if; + -- We allow ZLib to make header only in case of default header type. -- Otherwise we would either do header by ourselfs, or do not do -- header at all. @@ -216,10 +220,9 @@ package body ZLib is Filter.Offset := Simple_GZip_Header'Last + 1; end if; - Filter.Strm := new Z_Stream; + Filter.Strm := new Z_Stream; Filter.Compression := True; Filter.Stream_End := False; - Filter.Opened := True; Filter.Header := Header; if Thin.Deflate_Init @@ -255,18 +258,18 @@ package body ZLib is ----------------------- procedure Generic_Translate - (Filter : in out ZLib.Filter_Type; - In_Buffer_Size : Integer := Default_Buffer_Size; - Out_Buffer_Size : Integer := Default_Buffer_Size) + (Filter : in out ZLib.Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size) is - In_Buffer : Stream_Element_Array - (1 .. Stream_Element_Offset (In_Buffer_Size)); + In_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (In_Buffer_Size)); Out_Buffer : Stream_Element_Array - (1 .. Stream_Element_Offset (Out_Buffer_Size)); - Last : Stream_Element_Offset; - In_Last : Stream_Element_Offset; - In_First : Stream_Element_Offset; - Out_Last : Stream_Element_Offset; + (1 .. Stream_Element_Offset (Out_Buffer_Size)); + Last : Stream_Element_Offset; + In_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; begin Main : loop Data_In (In_Buffer, Last); @@ -275,18 +278,21 @@ package body ZLib is loop Translate - (Filter, - In_Buffer (In_First .. Last), - In_Last, - Out_Buffer, - Out_Last, - Flush_Finish (Last < In_Buffer'First)); + (Filter => Filter, + In_Data => In_Buffer (In_First .. Last), + In_Last => In_Last, + Out_Data => Out_Buffer, + Out_Last => Out_Last, + Flush => Flush_Finish (Last < In_Buffer'First)); - Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); + if Out_Buffer'First <= Out_Last then + Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); + end if; exit Main when Stream_End (Filter); -- The end of in buffer. + exit when In_Last = Last; In_First := In_Last + 1; @@ -301,7 +307,7 @@ package body ZLib is procedure Inflate_Init (Filter : in out Filter_Type; - Window_Bits : in Window_Bits_Type := 15; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; Header : in Header_Type := Default) is use type Thin.Int; @@ -320,6 +326,10 @@ package body ZLib is end Check_Version; begin + if Is_Open (Filter) then + raise Status_Error; + end if; + case Header is when None => Check_Version; @@ -344,10 +354,9 @@ package body ZLib is when Default => null; end case; - Filter.Strm := new Z_Stream; + Filter.Strm := new Z_Stream; Filter.Compression := False; Filter.Stream_End := False; - Filter.Opened := True; Filter.Header := Header; if Thin.Inflate_Init @@ -357,16 +366,25 @@ package body ZLib is end if; end Inflate_Init; + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Filter : in Filter_Type) return Boolean is + begin + return Filter.Strm /= null; + end Is_Open; + ----------------- -- Raise_Error -- ----------------- - procedure Raise_Error (Message : String) is + procedure Raise_Error (Message : in String) is begin Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message); end Raise_Error; - procedure Raise_Error (Stream : Z_Stream) is + procedure Raise_Error (Stream : in Z_Stream) is begin Raise_Error (Last_Error_Message (Stream)); end Raise_Error; @@ -378,21 +396,29 @@ package body ZLib is procedure Read (Filter : in out Filter_Type; Item : out Ada.Streams.Stream_Element_Array; - Last : out Ada.Streams.Stream_Element_Offset) + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush) is In_Last : Stream_Element_Offset; Item_First : Ada.Streams.Stream_Element_Offset := Item'First; + V_Flush : Flush_Mode := Flush; begin pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1); + pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); loop - if Rest_First > Buffer'Last then + if Rest_Last = Buffer'First - 1 then + V_Flush := Finish; + + elsif Rest_First > Rest_Last then Read (Buffer, Rest_Last); Rest_First := Buffer'First; - end if; - pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); + if Rest_Last < Buffer'First then + V_Flush := Finish; + end if; + end if; Translate (Filter => Filter, @@ -400,11 +426,13 @@ package body ZLib is In_Last => In_Last, Out_Data => Item (Item_First .. Item'Last), Out_Last => Last, - Flush => Flush_Finish (Rest_Last < Rest_First)); + Flush => V_Flush); Rest_First := In_Last + 1; - exit when Last = Item'Last or else Stream_End (Filter); + exit when Stream_End (Filter) + or else Last = Item'Last + or else (Last >= Item'First and then Allow_Read_Some); Item_First := Last + 1; end loop; @@ -489,11 +517,11 @@ package body ZLib is Code : Thin.Int; begin - if Filter.Opened = False then - raise ZLib_Error; + if not Is_Open (Filter) then + raise Status_Error; end if; - if Out_Data'Length = 0 then + if Out_Data'Length = 0 and then In_Data'Length = 0 then raise Constraint_Error; end if; @@ -514,7 +542,6 @@ package body ZLib is - Stream_Element_Offset (Avail_In (Filter.Strm.all)); Out_Last := Out_Data'Last - Stream_Element_Offset (Avail_Out (Filter.Strm.all)); - end Translate_Auto; -------------------- @@ -529,7 +556,7 @@ package body ZLib is Out_Last : out Ada.Streams.Stream_Element_Offset; Flush : in Flush_Mode) is - Out_First : Stream_Element_Offset; + Out_First : Stream_Element_Offset; procedure Add_Data (Data : in Stream_Element_Array); -- Add data to stream from the Filter.Offset till necessary, @@ -596,7 +623,7 @@ package body ZLib is Add_Data (Simple_GZip_Header); Translate_Auto - (Filter => Filter, + (Filter => Filter, In_Data => In_Data, In_Last => In_Last, Out_Data => Out_Data (Out_First .. Out_Data'Last), @@ -604,7 +631,6 @@ package body ZLib is Flush => Flush); CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last)); - end if; if Filter.Stream_End and then Out_Last <= Out_Data'Last then @@ -642,10 +668,11 @@ package body ZLib is procedure Write (Filter : in out Filter_Type; Item : in Ada.Streams.Stream_Element_Array; - Flush : in Flush_Mode) + Flush : in Flush_Mode := No_Flush) is - Buffer : Stream_Element_Array (1 .. Buffer_Size); - In_Last, Out_Last : Stream_Element_Offset; + Buffer : Stream_Element_Array (1 .. Buffer_Size); + In_Last : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; In_First : Stream_Element_Offset := Item'First; begin if Item'Length = 0 and Flush = No_Flush then @@ -654,7 +681,7 @@ package body ZLib is loop Translate - (Filter => Filter, + (Filter => Filter, In_Data => Item (In_First .. Item'Last), In_Last => In_Last, Out_Data => Buffer, diff --git a/contrib/ada/zlib.ads b/contrib/ada/zlib.ads index b72e4d2..79ffc40 100644 --- a/contrib/ada/zlib.ads +++ b/contrib/ada/zlib.ads @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- ZLib for Ada thick binding. -- -- -- --- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- -- -- -- This library is free software; you can redistribute it and/or modify -- -- it under the terms of the GNU General Public License as published by -- @@ -25,7 +25,7 @@ -- covered by the GNU Public License. -- ------------------------------------------------------------------------------ --- $Id: zlib.ads,v 1.17 2003/08/12 13:19:07 vagul Exp $ +-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $ with Ada.Streams; @@ -33,7 +33,8 @@ with Interfaces; package ZLib is - ZLib_Error : exception; + ZLib_Error : exception; + Status_Error : exception; type Compression_Level is new Integer range -1 .. 9; @@ -55,12 +56,15 @@ package ZLib is subtype Count is Ada.Streams.Stream_Element_Count; + Default_Memory_Level : constant Memory_Level_Type := 8; + Default_Window_Bits : constant Window_Bits_Type := 15; + ---------------------------------- -- Compression method constants -- ---------------------------------- Deflated : constant Compression_Method; - -- Only one method allowed in this ZLib version. + -- Only one method allowed in this ZLib version --------------------------------- -- Compression level constants -- @@ -79,21 +83,29 @@ package ZLib is -- Regular way for compression, no flush Partial_Flush : constant Flush_Mode; - -- will be removed, use Z_SYNC_FLUSH instead + -- Will be removed, use Z_SYNC_FLUSH instead Sync_Flush : constant Flush_Mode; - -- all pending output is flushed to the output buffer and the output + -- All pending output is flushed to the output buffer and the output -- is aligned on a byte boundary, so that the decompressor can get all -- input data available so far. (In particular avail_in is zero after the -- call if enough output space has been provided before the call.) -- Flushing may degrade compression for some compression algorithms and so -- it should be used only when necessary. + Block_Flush : constant Flush_Mode; + -- Z_BLOCK requests that inflate() stop + -- if and when it get to the next deflate block boundary. When decoding the + -- zlib or gzip format, this will cause inflate() to return immediately + -- after the header and before the first block. When doing a raw inflate, + -- inflate() will go ahead and process the first block, and will return + -- when it gets to the end of that block, or when it runs out of data. + Full_Flush : constant Flush_Mode; - -- all output is flushed as with SYNC_FLUSH, and the compression state + -- All output is flushed as with SYNC_FLUSH, and the compression state -- is reset so that decompression can restart from this point if previous -- compressed data has been damaged or if random access is desired. Using - -- FULL_FLUSH too often can seriously degrade the compression. + -- Full_Flush too often can seriously degrade the compression. Finish : constant Flush_Mode; -- Just for tell the compressor that input data is complete. @@ -111,7 +123,7 @@ package ZLib is Default_Buffer_Size : constant := 4096; - type Filter_Type is limited private; + type Filter_Type is tagged limited private; -- The filter is for compression and for decompression. -- The usage of the type is depend of its initialization. @@ -124,8 +136,8 @@ package ZLib is Level : in Compression_Level := Default_Compression; Strategy : in Strategy_Type := Default_Strategy; Method : in Compression_Method := Deflated; - Window_Bits : in Window_Bits_Type := 15; - Memory_Level : in Memory_Level_Type := 8; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; Header : in Header_Type := Default); -- Compressor initialization. -- When Header parameter is Auto or Default, then default zlib header @@ -136,7 +148,7 @@ package ZLib is procedure Inflate_Init (Filter : in out Filter_Type; - Window_Bits : in Window_Bits_Type := 15; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; Header : in Header_Type := Default); -- Decompressor initialization. -- Default header type mean that ZLib default header is expecting in the @@ -146,10 +158,14 @@ package ZLib is -- input compressed stream. -- Auto header type mean that header type (GZip or Native) would be -- detected automatically in the input stream. - -- Note that header types parameter values None, GZip and Auto is - -- supporting for inflate routine only in ZLib versions 1.2.0.2 and later. + -- Note that header types parameter values None, GZip and Auto are + -- supported for inflate routine only in ZLib versions 1.2.0.2 and later. -- Deflate_Init is supporting all header types. + function Is_Open (Filter : in Filter_Type) return Boolean; + pragma Inline (Is_Open); + -- Is the filter opened for compression or decompression. + procedure Close (Filter : in out Filter_Type; Ignore_Error : in Boolean := False); @@ -167,31 +183,31 @@ package ZLib is (Filter : in out Filter_Type; In_Buffer_Size : in Integer := Default_Buffer_Size; Out_Buffer_Size : in Integer := Default_Buffer_Size); - -- Compressing/decompressing data arrived from Data_In routine + -- Compress/decompress data fetch from Data_In routine and pass the result -- to the Data_Out routine. User should provide Data_In and Data_Out -- for compression/decompression data flow. - -- Compression or decompression depend on initialization of Filter. + -- Compression or decompression depend on Filter initialization. function Total_In (Filter : in Filter_Type) return Count; pragma Inline (Total_In); - -- Return total number of input bytes read so far. + -- Returns total number of input bytes read so far function Total_Out (Filter : in Filter_Type) return Count; pragma Inline (Total_Out); - -- Return total number of bytes output so far. + -- Returns total number of bytes output so far function CRC32 (CRC : in Unsigned_32; Data : in Ada.Streams.Stream_Element_Array) return Unsigned_32; pragma Inline (CRC32); - -- Calculate CRC32, it could be necessary for make gzip format. + -- Compute CRC32, it could be necessary for make gzip format procedure CRC32 (CRC : in out Unsigned_32; Data : in Ada.Streams.Stream_Element_Array); pragma Inline (CRC32); - -- Calculate CRC32, it could be necessary for make gzip format. + -- Compute CRC32, it could be necessary for make gzip format ------------------------------------------------- -- Below is more complex low level routines. -- @@ -204,15 +220,11 @@ package ZLib is Out_Data : out Ada.Streams.Stream_Element_Array; Out_Last : out Ada.Streams.Stream_Element_Offset; Flush : in Flush_Mode); - -- Compressing/decompressing the datas from In_Data buffer to the - -- Out_Data buffer. - -- In_Data is incoming data portion, - -- In_Last is the index of last element from In_Data accepted by the - -- Filter. - -- Out_Data is the buffer for output data from the filter. - -- Out_Last is the last element of the received data from Filter. - -- To tell the filter that incoming data is complete put the - -- Flush parameter to FINISH. + -- Compress/decompress the In_Data buffer and place the result into + -- Out_Data. In_Last is the index of last element from In_Data accepted by + -- the Filter. Out_Last is the last element of the received data from + -- Filter. To tell the filter that incoming data are complete put the + -- Flush parameter to Finish. function Stream_End (Filter : in Filter_Type) return Boolean; pragma Inline (Stream_End); @@ -239,10 +251,9 @@ package ZLib is procedure Write (Filter : in out Filter_Type; Item : in Ada.Streams.Stream_Element_Array; - Flush : in Flush_Mode); - -- Compressing/Decompressing data from Item to the - -- generic parameter procedure Write. - -- Output buffer size could be set in Buffer_Size generic parameter. + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from Item to the generic parameter procedure + -- Write. Output buffer size could be set in Buffer_Size generic parameter. generic with procedure Read @@ -257,33 +268,41 @@ package ZLib is Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset; -- Rest_First have to be initialized to Buffer'Last + 1 + -- Rest_Last have to be initialized to Buffer'Last -- before usage. + Allow_Read_Some : in Boolean := False; + -- Is it allowed to return Last < Item'Last before end of data. + procedure Read (Filter : in out Filter_Type; Item : out Ada.Streams.Stream_Element_Array; - Last : out Ada.Streams.Stream_Element_Offset); - -- Compressing/Decompressing data from generic parameter - -- procedure Read to the Item. - -- User should provide Buffer for the operation - -- and Rest_First variable first time initialized to the Buffer'Last + 1. + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from generic parameter procedure Read to the + -- Item. User should provide Buffer and initialized Rest_First, Rest_Last + -- indicators. If Allow_Read_Some is True, Read routines could return + -- Last < Item'Last only at end of stream. private use Ada.Streams; - type Flush_Mode is new Integer range 0 .. 4; + pragma Assert (Ada.Streams.Stream_Element'Size = 8); + pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8); + + type Flush_Mode is new Integer range 0 .. 5; type Compression_Method is new Integer range 8 .. 8; type Strategy_Type is new Integer range 0 .. 3; No_Flush : constant Flush_Mode := 0; + Partial_Flush : constant Flush_Mode := 1; Sync_Flush : constant Flush_Mode := 2; Full_Flush : constant Flush_Mode := 3; Finish : constant Flush_Mode := 4; - Partial_Flush : constant Flush_Mode := 1; - -- will be removed, use Z_SYNC_FLUSH instead + Block_Flush : constant Flush_Mode := 5; Filtered : constant Strategy_Type := 1; Huffman_Only : constant Strategy_Type := 2; @@ -296,7 +315,7 @@ private type Z_Stream_Access is access all Z_Stream; - type Filter_Type is record + type Filter_Type is tagged limited record Strm : Z_Stream_Access; Compression : Boolean; Stream_End : Boolean; @@ -304,8 +323,6 @@ private CRC : Unsigned_32; Offset : Stream_Element_Offset; -- Offset for gzip header/footer output. - - Opened : Boolean := False; end record; end ZLib; diff --git a/contrib/ada/zlib.gpr b/contrib/ada/zlib.gpr index 0f58985..88f51cc 100644 --- a/contrib/ada/zlib.gpr +++ b/contrib/ada/zlib.gpr @@ -1,21 +1,21 @@ -project Zlib is - - for Languages use ("Ada"); - for Source_Dirs use ("."); - for Object_Dir use "."; - for Main use ("test.adb", "mtest.adb", "read.adb"); - - package Compiler is - for Default_Switches ("ada") use ("-gnatwbcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); - end Compiler; - - package Linker is - for Default_Switches ("ada") use ("-lz"); - end Linker; - - package Builder is - for Default_Switches ("ada") use ("-s", "-gnatQ"); - end Builder; - -end Zlib; - +project Zlib is + + for Languages use ("Ada"); + for Source_Dirs use ("."); + for Object_Dir use "."; + for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo"); + + package Compiler is + for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); + end Compiler; + + package Linker is + for Default_Switches ("ada") use ("-lz"); + end Linker; + + package Builder is + for Default_Switches ("ada") use ("-s", "-gnatQ"); + end Builder; + +end Zlib; + diff --git a/contrib/delphi/ZLib.pas b/contrib/delphi/ZLib.pas index 61ffd08..8853866 100644 --- a/contrib/delphi/ZLib.pas +++ b/contrib/delphi/ZLib.pas @@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; const OutBuf: Pointer; BufSize: Integer); const - zlib_version = '1.2.1'; + zlib_version = '1.2.2'; type EZlibError = class(Exception); @@ -510,7 +510,7 @@ begin Result := Count - FZRec.avail_out; Exit; end; - FZRec.next_in := FBuffer; + FZRec.next_in := FBuffer; FStrmPos := FStrm.Position; Progress(Self); end; diff --git a/contrib/infback9/infback9.c b/contrib/infback9/infback9.c index 34a95fc..103d901 100644 --- a/contrib/infback9/infback9.c +++ b/contrib/infback9/infback9.c @@ -430,6 +430,9 @@ void FAR *out_desc; } } + /* handle error breaks in while */ + if (mode == BAD) break; + /* build code tables */ state->next = state->codes; lencode = (code const FAR *)(state->next); diff --git a/contrib/infback9/inftree9.c b/contrib/infback9/inftree9.c index 337a277..5fd5b4a 100644 --- a/contrib/infback9/inftree9.c +++ b/contrib/infback9/inftree9.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate9_copyright[] = - " inflate9 1.2.1.1 Copyright 1995-2003 Mark Adler "; + " inflate9 1.2.1.2 Copyright 1995-2004 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -64,7 +64,7 @@ unsigned short FAR *work; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, - 133, 133, 133, 133, 144, 202, 196}; + 133, 133, 133, 133, 144, 77, 194}; static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, diff --git a/contrib/masmx86/mkasm.bat b/contrib/masmx86/mkasm.bat index f3fa0a0..70a51f8 100755 --- a/contrib/masmx86/mkasm.bat +++ b/contrib/masmx86/mkasm.bat @@ -1,3 +1,3 @@ -cl /I..\.. /O2 /c gvmat32c.c +cl /DASMV /I..\.. /O2 /c gvmat32c.c ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm ml /coff /Zi /c /Flinffas32.lst inffas32.asm diff --git a/contrib/minizip/ChangeLogUnzip b/contrib/minizip/ChangeLogUnzip index d7d4b6b..4be4d16 100644 --- a/contrib/minizip/ChangeLogUnzip +++ b/contrib/minizip/ChangeLogUnzip @@ -1,3 +1,11 @@ +Change in 1.01b (20 may 04) +- Integrate patch from Debian package (submited by Mark Brown) +- Add tools mztools from Xavier Roche + +Change in 1.01 (8 may 04) +- fix buffer overrun risk in unzip.c (Xavier Roche) +- fix a minor buffer insecurity in minizip.c (Mike Whittaker) + Change in 1.00: (10 sept 03) - rename to 1.00 - cosmetic code change diff --git a/contrib/minizip/crypt.h b/contrib/minizip/crypt.h index 9c7a89c..7f8a634 100644 --- a/contrib/minizip/crypt.h +++ b/contrib/minizip/crypt.h @@ -1,9 +1,9 @@ /* crypt.h -- base code for crypt/uncrypt ZIPfile - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant This code is a modified version of crypting code in Infozip distribution diff --git a/contrib/minizip/ioapi.c b/contrib/minizip/ioapi.c index 80443b7..6ddfd36 100644 --- a/contrib/minizip/ioapi.c +++ b/contrib/minizip/ioapi.c @@ -1,9 +1,9 @@ /* ioapi.c -- IO base function header for compress/uncompress .zip files using zlib + zip or unzip API - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant */ #include diff --git a/contrib/minizip/ioapi.h b/contrib/minizip/ioapi.h index 6bc2a2c..b761161 100644 --- a/contrib/minizip/ioapi.h +++ b/contrib/minizip/ioapi.h @@ -1,9 +1,9 @@ /* ioapi.h -- IO base function header for compress/uncompress .zip files using zlib + zip or unzip API - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant */ #ifndef _ZLIBIOAPI_H diff --git a/contrib/minizip/iowin32.c b/contrib/minizip/iowin32.c index 02b27cb..940dc0b 100644 --- a/contrib/minizip/iowin32.c +++ b/contrib/minizip/iowin32.c @@ -2,9 +2,9 @@ files using zlib + zip or unzip API This IO API version uses the Win32 API (for Microsoft Windows) - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant */ #include diff --git a/contrib/minizip/iowin32.h b/contrib/minizip/iowin32.h index c0ebd50..8774fe7 100644 --- a/contrib/minizip/iowin32.h +++ b/contrib/minizip/iowin32.h @@ -2,9 +2,9 @@ files using zlib + zip or unzip API This IO API version uses the Win32 API (for Microsoft Windows) - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant */ #include diff --git a/contrib/minizip/miniunz.c b/contrib/minizip/miniunz.c index c8cf81e..11b7260 100644 --- a/contrib/minizip/miniunz.c +++ b/contrib/minizip/miniunz.c @@ -1,3 +1,11 @@ +/* + miniunz.c + Version 1.01b, May 30th, 2004 + + Copyright (C) 1998-2004 Gilles Vollant +*/ + + #include #include #include @@ -27,7 +35,7 @@ mini unzip, demo of unzip package usage : - Usage : miniunz [-exvlo] file.zip [file_to_extract] + Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT if it exists @@ -140,17 +148,18 @@ int makedir (newdir) void do_banner() { - printf("MiniUnz 1.00, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); } void do_help() { - printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.]\n\n" \ + printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ " -e Extract without pathname (junk paths)\n" \ " -x Extract with pathname\n" \ " -v list files\n" \ " -l list files\n" \ + " -d directory to extract into\n" \ " -o overwrite files without prompting\n" \ " -p extract crypted file using password\n\n"); } @@ -304,8 +313,14 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password) do { char answer[128]; - printf("The file %s exist. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename); - scanf("%1s",answer); + int ret; + + printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename); + ret = scanf("%1s",answer); + if (ret != 1) + { + exit(EXIT_FAILURE); + } rep = answer[0] ; if ((rep>='a') && (rep<='z')) rep -= 0x20; @@ -459,6 +474,8 @@ int main(argc,argv) int opt_do_extract=1; int opt_do_extract_withoutpath=0; int opt_overwrite=0; + int opt_extractdir=0; + const char *dirname=NULL; unzFile uf=NULL; do_banner(); @@ -488,6 +505,12 @@ int main(argc,argv) opt_do_extract = opt_do_extract_withoutpath = 1; if ((c=='o') || (c=='O')) opt_overwrite=1; + if ((c=='d') || (c=='D')) + { + opt_extractdir=1; + dirname=argv[i+1]; + } + if (((c=='p') || (c=='P')) && (i+1 #include #include @@ -53,8 +60,8 @@ uLong filetime(f, tmzip, dt) #else #ifdef unix uLong filetime(f, tmzip, dt) - char *f; /* name of file to get info on */ - tm_zip *tmzip; /* return value: access, modific. and creation times */ + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ uLong *dt; /* dostime */ { int ret=0; @@ -66,6 +73,8 @@ uLong filetime(f, tmzip, dt) { char name[MAXFILENAME+1]; int len = strlen(f); + if (len > MAXFILENAME) + len = MAXFILENAME; strncpy(name, f,MAXFILENAME-1); /* strncpy doesnt append the trailing NULL, of the string is too long. */ @@ -120,7 +129,7 @@ int check_exist_file(filename) void do_banner() { - printf("MiniZip 1.00, demo of zLib + Zip package written by Gilles Vollant\n"); + printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n"); printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); } @@ -269,8 +278,13 @@ int main(argc,argv) do { char answer[128]; - printf("The file %s exist. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try); - scanf("%1s",answer); + int ret; + printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try); + ret = scanf("%1s",answer); + if (ret != 1) + { + exit(EXIT_FAILURE); + } rep = answer[0] ; if ((rep>='a') && (rep<='z')) rep -= 0x20; @@ -305,7 +319,12 @@ int main(argc,argv) for (i=zipfilenamearg+1;(i='0') || (argv[i][1]<='9'))) && + (strlen(argv[i]) == 2))) { FILE * fin; int size_read; @@ -390,7 +409,11 @@ int main(argc,argv) errclose = zipClose(zf,NULL); if (errclose != ZIP_OK) printf("error in closing %s\n",filename_try); - } + } + else + { + do_help(); + } free(buf); return 0; diff --git a/contrib/minizip/mztools.c b/contrib/minizip/mztools.c new file mode 100644 index 0000000..363ee13 --- /dev/null +++ b/contrib/minizip/mztools.c @@ -0,0 +1,281 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[256]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/contrib/minizip/mztools.h b/contrib/minizip/mztools.h new file mode 100644 index 0000000..eee78dc --- /dev/null +++ b/contrib/minizip/mztools.h @@ -0,0 +1,31 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +#ifndef _zip_tools_H +#define _zip_tools_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#include "unzip.h" + +/* Repair a ZIP file (missing central directory) + file: file to recover + fileOut: output file after recovery + fileOutTmp: temporary file name used for recovery +*/ +extern int ZEXPORT unzRepair(const char* file, + const char* fileOut, + const char* fileOutTmp, + uLong* nRecovered, + uLong* bytesRecovered); + +#endif diff --git a/contrib/minizip/unzip.c b/contrib/minizip/unzip.c index f08f624..e804a2a 100644 --- a/contrib/minizip/unzip.c +++ b/contrib/minizip/unzip.c @@ -1,7 +1,7 @@ /* unzip.c -- IO for uncompress .zip files using zlib - Version 1.00, September 10th, 2003 + Version 1.01c, August 23th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant Read unzip.h for more info */ @@ -88,7 +88,7 @@ woven in by Terry Thorsen 1/2003. const char unz_copyright[] = - " unzip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll"; + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info_internal_s @@ -798,7 +798,8 @@ extern int ZEXPORT unzGoToNextFile (file) s=(unz_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; - if (s->num_file+1==s->gi.number_entry) + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + @@ -1244,9 +1245,15 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len) pfile_in_zip_read_info->stream.avail_out = (uInt)len; - if (len>pfile_in_zip_read_info->rest_read_uncompressed) + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed; while (pfile_in_zip_read_info->stream.avail_out>0) { @@ -1339,6 +1346,9 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len) */ err=inflate(&pfile_in_zip_read_info->stream,flush); + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; uOutThis = uTotalOutAfter-uTotalOutBefore; @@ -1461,7 +1471,7 @@ extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, - buf,size_to_read)!=size_to_read) + buf,read_now)!=read_now) return UNZ_ERRNO; return (int)read_now; @@ -1544,3 +1554,40 @@ extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) *(szComment+s->gi.size_comment)='\0'; return (int)uReadThis; } + +/* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset (file) + unzFile file; +{ + unz_s* s; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT unzSetOffset (file, pos) + unzFile file; + uLong pos; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/contrib/minizip/unzip.h b/contrib/minizip/unzip.h index 4e50979..0c7c6f1 100644 --- a/contrib/minizip/unzip.h +++ b/contrib/minizip/unzip.h @@ -1,7 +1,7 @@ /* unzip.h -- IO for uncompress .zip files using zlib - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible. @@ -335,6 +335,16 @@ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, the error code */ +/***************************************************************************/ + +/* Get the current file offset */ +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + #ifdef __cplusplus } #endif diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c index 1a713e5..ce1444c 100644 --- a/contrib/minizip/zip.c +++ b/contrib/minizip/zip.c @@ -1,7 +1,7 @@ /* zip.c -- IO on .zip files using zlib - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant Read zip.h for more info */ @@ -77,7 +77,7 @@ #endif #endif const char zip_copyright[] = - " zip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll"; + " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; #define SIZEDATA_INDATABLOCK (4096-(4*4)) @@ -265,10 +265,19 @@ local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) { unsigned char buf[4]; int n; - for (n = 0; n < nbByte; n++) { + for (n = 0; n < nbByte; n++) + { buf[n] = (unsigned char)(x & 0xff); x >>= 8; } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) return ZIP_ERRNO; else @@ -287,7 +296,16 @@ local void ziplocal_putValue_inmemory (dest, x, nbByte) buf[n] = (unsigned char)(x & 0xff); x >>= 8; } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } } + /****************************************************************************/ diff --git a/contrib/minizip/zip.h b/contrib/minizip/zip.h index c37ea21..d5112c4 100644 --- a/contrib/minizip/zip.h +++ b/contrib/minizip/zip.h @@ -1,7 +1,7 @@ /* zip.h -- IO for compress .zip files using zlib - Version 1.00, September 10th, 2003 + Version 1.01, May 8th, 2004 - Copyright (C) 1998-2003 Gilles Vollant + Copyright (C) 1998-2004 Gilles Vollant This unzip package allow creates .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible. @@ -212,7 +212,6 @@ extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); Close the current file in the zipfile */ - extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32)); diff --git a/contrib/pascal/zlibpas.pas b/contrib/pascal/zlibpas.pas index 6d5ebe0..94103d2 100644 --- a/contrib/pascal/zlibpas.pas +++ b/contrib/pascal/zlibpas.pas @@ -10,7 +10,7 @@ unit zlibpas; interface const - ZLIB_VERSION = '1.2.1'; + ZLIB_VERSION = '1.2.2'; type alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; diff --git a/contrib/untgz/untgz.c b/contrib/untgz/untgz.c index d748b69..3a30768 100644 --- a/contrib/untgz/untgz.c +++ b/contrib/untgz/untgz.c @@ -1,7 +1,7 @@ /* * untgz.c -- Display contents and extract files from a gzip'd TAR file * - * written by "Pedro A. Aranda Guti\irrez" + * written by Pedro A. Aranda Gutierrez * adaptation to Unix by Jean-loup Gailly * various fixes by Cosmin Truta */ @@ -15,10 +15,10 @@ #include "zlib.h" #ifdef unix -# include +# include #else -# include -# include +# include +# include #endif #ifdef WIN32 @@ -28,8 +28,9 @@ # endif # define mkdir(dirname,mode) _mkdir(dirname) # ifdef _MSC_VER -# define strdup(str) _strdup(str) # define access(path,mode) _access(path,mode) +# define chmod(path,mode) _chmod(path,mode) +# define strdup(str) _strdup(str) # endif #else # include @@ -48,7 +49,21 @@ #define FIFOTYPE '6' /* FIFO special */ #define CONTTYPE '7' /* reserved */ -#define BLOCKSIZE 512 +/* GNU tar extensions */ + +#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */ +#define GNUTYPE_LONGLINK 'K' /* long link name */ +#define GNUTYPE_LONGNAME 'L' /* long file name */ +#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */ +#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */ +#define GNUTYPE_SPARSE 'S' /* sparse file */ +#define GNUTYPE_VOLHDR 'V' /* tape/volume header */ + + +/* tar header */ + +#define BLOCKSIZE 512 +#define SHORTNAMESIZE 100 struct tar_header { /* byte offset */ @@ -71,11 +86,20 @@ struct tar_header /* 500 */ }; -union tar_buffer { +union tar_buffer +{ char buffer[BLOCKSIZE]; struct tar_header header; }; +struct attr_item +{ + struct attr_item *next; + char *fname; + int mode; + time_t time; +}; + enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID }; char *TGZfname OF((const char *)); @@ -84,6 +108,9 @@ void TGZnotfound OF((const char *)); int getoct OF((char *, int)); char *strtime OF((time_t *)); int setfiletime OF((char *, time_t)); +void push_attr OF((struct attr_item **, char *, int, time_t)); +void restore_attr OF((struct attr_item **)); + int ExprMatch OF((char *, char *)); int makedir OF((char *)); @@ -221,7 +248,42 @@ int setfiletime (char *fname,time_t ftime) } -/* regular expression matching */ +/* push file attributes */ + +void push_attr(struct attr_item **list,char *fname,int mode,time_t time) +{ + struct attr_item *item; + + item = (struct attr_item *)malloc(sizeof(struct attr_item)); + if (item == NULL) + error("Out of memory"); + item->fname = strdup(fname); + item->mode = mode; + item->time = time; + item->next = *list; + *list = item; +} + + +/* restore file attributes */ + +void restore_attr(struct attr_item **list) +{ + struct attr_item *item, *prev; + + for (item = *list; item != NULL; ) + { + setfiletime(item->fname,item->time); + chmod(item->fname,item->mode); + prev = item; + item = item->next; + free(prev); + } + *list = NULL; +} + + +/* match regular expression */ #define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) @@ -332,6 +394,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) char fname[BLOCKSIZE]; int tarmode; time_t tartime; + struct attr_item *attributes = NULL; if (action == TGZ_LIST) printf(" date time size file\n" @@ -354,14 +417,15 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) /* * If we have to get a tar header */ - if (getheader == 1) + if (getheader >= 1) { /* * if we met the end of the tar * or the end-of-tar block, * we are done */ - if ((len == 0) || (buffer.header.name[0] == 0)) break; + if (len == 0 || buffer.header.name[0] == 0) + break; tarmode = getoct(buffer.header.mode,8); tartime = (time_t)getoct(buffer.header.mtime,12); @@ -371,8 +435,25 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) action = TGZ_INVALID; } - strcpy(fname,buffer.header.name); + if (getheader == 1) + { + strncpy(fname,buffer.header.name,SHORTNAMESIZE); + if (fname[SHORTNAMESIZE-1] != 0) + fname[SHORTNAMESIZE] = 0; + } + else + { + /* + * The file name is longer than SHORTNAMESIZE + */ + if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0) + error("bad long name"); + getheader = 1; + } + /* + * Act according to the type flag + */ switch (buffer.header.typeflag) { case DIRTYPE: @@ -381,7 +462,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) if (action == TGZ_EXTRACT) { makedir(fname); - setfiletime(fname,tartime); + push_attr(&attributes,fname,tarmode,tartime); } break; case REGTYPE: @@ -419,6 +500,24 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) } getheader = 0; break; + case GNUTYPE_LONGLINK: + case GNUTYPE_LONGNAME: + remaining = getoct(buffer.header.size,12); + if (remaining < 0 || remaining >= BLOCKSIZE) + { + action = TGZ_INVALID; + break; + } + len = gzread(in, fname, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining) + { + action = TGZ_INVALID; + break; + } + getheader = 2; + break; default: if (action == TGZ_LIST) printf(" %s <---> %s\n",strtime(&tartime),fname); @@ -433,7 +532,8 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) { if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) { - fprintf(stderr,"%s: Error writing %s -- skipping\n",prog,fname); + fprintf(stderr, + "%s: Error writing %s -- skipping\n",prog,fname); fclose(outfile); outfile = NULL; remove(fname); @@ -450,7 +550,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) fclose(outfile); outfile = NULL; if (action != TGZ_INVALID) - setfiletime(fname,tartime); + push_attr(&attributes,fname,tarmode,tartime); } } @@ -464,6 +564,11 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) } } + /* + * Restore file modes and time stamps + */ + restore_attr(&attributes); + if (gzclose(in) != Z_OK) error("failed gzclose"); @@ -475,7 +580,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv) void help(int exitval) { - printf("untgz version 0.2\n" + printf("untgz version 0.2.1\n" " using zlib version %s\n\n", zlibVersion()); printf("Usage: untgz file.tgz extract all files\n" diff --git a/contrib/vstudio/vc7/zlib.rc b/contrib/vstudio/vc7/zlib.rc index 6c51679..2eb7c6b 100644 --- a/contrib/vstudio/vc7/zlib.rc +++ b/contrib/vstudio/vc7/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1,2,1,0 - PRODUCTVERSION 1,2,1,0 + FILEVERSION 1,2,1,2 + PRODUCTVERSION 1,2,1,2 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression library\0" - VALUE "FileVersion", "1.2.1.0\0" + VALUE "FileVersion", "1.2.1.2\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlib.dll\0" VALUE "ProductName", "ZLib.DLL\0" -- cgit v1.2.3-55-g6feb