]> git.lizzy.rs Git - zlib.git/blobdiff - contrib/minizip/unzip.c
zlib 1.2.2
[zlib.git] / contrib / minizip / unzip.c
index 7244523cc4de415f819a348aba729af44f569dc7..e14de9e5ba4d5d3d979e285c05586396ffd40fb7 100644 (file)
@@ -1,7 +1,7 @@
 /* unzip.c -- IO for uncompress .zip files using zlib
-   Version 0.21 with encryption, March 10th, 2003
+   Version 1.01d, September 22th, 2004
 
-   Copyright (C) 1998-2003 Gilles Vollant
+   Copyright (C) 1998-2004 Gilles Vollant
 
    Read unzip.h for more info
 */
@@ -59,10 +59,10 @@ woven in by Terry Thorsen 1/2003.
 /* compile with -Dlocal if your debugger can't find static symbols */
 
 
-
-#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
-                      !defined(CASESENSITIVITYDEFAULT_NO)
-#define CASESENSITIVITYDEFAULT_NO
+#ifndef CASESENSITIVITYDEFAULT_NO
+#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+#    define CASESENSITIVITYDEFAULT_NO
+#  endif
 #endif
 
 
@@ -88,7 +88,7 @@ woven in by Terry Thorsen 1/2003.
 
 
 const char unz_copyright[] =
-   " unzip 0.21 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
@@ -145,14 +145,14 @@ typedef struct
     file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
                                         file if we are decompressing it */
     int encrypted;
-    #ifndef NOUNCRPYT
+#    ifndef NOUNCRYPT
     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
     const unsigned long* pcrc_32_tab;
-    #endif
+#    endif
 } unz_s;
 
 
-#ifndef NOUNCRPYT
+#ifndef NOUNCRYPT
 #include "crypt.h"
 #endif
 
@@ -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 +
@@ -828,7 +829,11 @@ extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
     unz_s* s;
     int err;
 
-
+    /* We remember the 'current' position in the file so that we can jump
+     * back there if we fail.
+     */
+    unz_file_info cur_file_infoSaved;
+    unz_file_info_internal cur_file_info_internalSaved;
     uLong num_fileSaved;
     uLong pos_in_central_dirSaved;
 
@@ -843,25 +848,36 @@ extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
     if (!s->current_file_ok)
         return UNZ_END_OF_LIST_OF_FILE;
 
+    /* Save the current state */
     num_fileSaved = s->num_file;
     pos_in_central_dirSaved = s->pos_in_central_dir;
+    cur_file_infoSaved = s->cur_file_info;
+    cur_file_info_internalSaved = s->cur_file_info_internal;
 
     err = unzGoToFirstFile(file);
 
     while (err == UNZ_OK)
     {
         char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
-        unzGetCurrentFileInfo(file,NULL,
-                                szCurrentFileName,sizeof(szCurrentFileName)-1,
-                                NULL,0,NULL,0);
-        if (unzStringFileNameCompare(szCurrentFileName,
-                                        szFileName,iCaseSensitivity)==0)
-            return UNZ_OK;
-        err = unzGoToNextFile(file);
+        err = unzGetCurrentFileInfo(file,NULL,
+                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
+                                    NULL,0,NULL,0);
+        if (err == UNZ_OK)
+        {
+            if (unzStringFileNameCompare(szCurrentFileName,
+                                            szFileName,iCaseSensitivity)==0)
+                return UNZ_OK;
+            err = unzGoToNextFile(file);
+        }
     }
 
+    /* We failed, so restore the state of the 'current file' to where we
+     * were.
+     */
     s->num_file = num_fileSaved ;
     s->pos_in_central_dir = pos_in_central_dirSaved ;
+    s->cur_file_info = cur_file_infoSaved;
+    s->cur_file_info_internal = cur_file_info_internalSaved;
     return err;
 }
 
@@ -1041,12 +1057,12 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
     file_in_zip_read_info_s* pfile_in_zip_read_info;
     uLong offset_local_extrafield;  /* offset of the local extra field */
     uInt  size_local_extrafield;    /* size of the local extra field */
-    #ifndef NOUNCRPYT
+#    ifndef NOUNCRYPT
     char source[12];
-    #else
+#    else
     if (password != NULL)
         return UNZ_PARAMERROR;
-    #endif
+#    endif
 
     if (file==NULL)
         return UNZ_PARAMERROR;
@@ -1114,6 +1130,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
       pfile_in_zip_read_info->stream.zfree = (free_func)0;
       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
 
       err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
       if (err == Z_OK)
@@ -1142,7 +1160,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
 
     s->pfile_in_zip_read = pfile_in_zip_read_info;
 
-    #ifndef NOUNCRPYT
+#    ifndef NOUNCRYPT
     if (password != NULL)
     {
         int i;
@@ -1162,7 +1180,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
         s->pfile_in_zip_read->pos_in_zipfile+=12;
         s->encrypted=1;
     }
-    #endif
+#    endif
 
 
     return UNZ_OK;
@@ -1227,9 +1245,17 @@ 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->stream.avail_in) &&
+         (pfile_in_zip_read_info->raw))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_compressed+
+            pfile_in_zip_read_info->stream.avail_in;
 
     while (pfile_in_zip_read_info->stream.avail_out>0)
     {
@@ -1254,7 +1280,7 @@ extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
                 return UNZ_ERRNO;
 
 
-            #ifndef NOUNCRPYT
+#            ifndef NOUNCRYPT
             if(s->encrypted)
             {
                 uInt i;
@@ -1263,7 +1289,7 @@ extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
                       zdecode(s->keys,s->pcrc_32_tab,
                               pfile_in_zip_read_info->read_buffer[i]);
             }
-            #endif
+#            endif
 
 
             pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
@@ -1322,6 +1348,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;
 
@@ -1444,7 +1473,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;
@@ -1527,3 +1556,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;
+}