#define zzip_extra_block_get_datasize(__p) ZZIP_GET16((zzip_byte_t*)(__p)+2)
#define zzip_extra_block_set_datasize(__p,__x) ZZIP_SET16((zzip_byte_t*)(__p)+2,__x)
+#define zzip_extra_zip64_get_datatype(__p) ZZIP_GET16((__p)->z_datatype)
+#define zzip_extra_zip64_set_datatype(__p,__x) ZZIP_SET16((__p)->z_datatype,(__x))
+#define zzip_extra_zip64_get_datasize(__p) ZZIP_GET16((__p)->z_datasize)
+#define zzip_extra_zip64_set_datasize(__p,__x) ZZIP_SET16((__p)->z_datasize,(__x))
+#define zzip_extra_zip64_get_usize(__p) ZZIP_GET64((__p)->z_usize)
+#define zzip_extra_zip64_set_usize(__p,__x ) ZZIP_SET64((__p)->z_usize,(__x))
+#define zzip_extra_zip64_get_csize(__p) ZZIP_GET64((__p)->z_csize)
+#define zzip_extra_zip64_set_csize(__p,__x ) ZZIP_SET64((__p)->z_csize,(__x))
+#define zzip_extra_zip64_get_offset(__p) ZZIP_GET64((__p)->z_offset)
+#define zzip_extra_zip64_set_offset(__p,__x) ZZIP_SET64((__p)->z_offset,(__x))
+#define zzip_extra_zip64_get_diskstart(__p) ZZIP_GET32((__p)->z_diskstart)
+#define zzip_extra_zip64_set_diskstart(__p,__x) ZZIP_SET32((__p)->z_diskstart,(__x))
+
/* zzip64_disk_trailer - the zip64 archive entry point */
#define zzip_disk64_trailer_get_magic(__p) ZZIP_GET32((__p)->z_magic)
#define zzip_disk64_trailer_set_magic(__p,__x) ZZIP_SET32((__p)->z_magic,(__x))
#define zzip_disk_trailer_to_endoffile(__p) ((void*) \
(zzip_disk_trailer_to_comment(__p) + zzip_disk_trailer_comment(__p)))
+#define zzip_extra_zip64_csize(__p) ((zzip_size_t) \
+ zzip_extra_zip64_get_csize(__p))
+#define zzip_extra_zip64_usize(__p) ((zzip_size_t) \
+ zzip_extra_zip64_get_usize(__p))
+#define zzip_extra_zip64_offset(__p) ((zzip_off_t) \
+ zzip_extra_zip64_get_offset(__p))
+#define zzip_extra_zip64_diskstart(__p) ((zzip_size_t) \
+ zzip_extra_zip64_get_diskstart(__p))
+
/* zzip_disk64_trailer - the zip archive entry point */
#define zzip_disk64_trailer_localdisk(__p) ((int) \
zzip_disk64_trailer_get_disk(__p))
(((zzip_byte_t*)(__p))[1]==(__B)) && \
(((zzip_byte_t*)(__p))[2]==(__C)) && \
(((zzip_byte_t*)(__p))[3]==(__D)) )
+#define ZZIP_CHECK(__p,__A,__B) \
+ ( (((zzip_byte_t*)(__p))[0]==(__A)) && \
+ (((zzip_byte_t*)(__p))[1]==(__B)) )
/* A. Local file header */
struct zzip_file_header
} ZZIP_GNUC_PACKED;
#define zzip_extra_block_headerlength (2U+2U)
+/* Zip64 extras block */
+struct zzip_extra_zip64
+{
+# define ZZIP_EXTRA_ZIP64_MAGIC 0x0001
+# define ZZIP_EXTRA_ZIP64_CHECK(__p) ZZIP_CHECK(__p,'\0','\1')
+ zzip_byte_t z_datatype[2]; /* extras signature 0x0001 */
+ zzip_byte_t z_datasize[2]; /* structure length 0x0010 */
+ zzip_byte_t z_usize[8]; /* original size */
+ zzip_byte_t z_csize[8]; /* compressed size */
+ zzip_byte_t z_offset[8]; /* offset from file header */
+ zzip_byte_t z_diskstart[4]; /* disk where the file starts */
+} ZZIP_GNUC_PACKED;
+
/* Zip64 end of central dir record */
struct zzip_disk64_trailer
{
-
/*
* NOTE: this is part of libzzipmmapped (i.e. it is not libzzip).
* ==================
#endif
#define ZZIP_EXTRA_zip64 0x0001
-typedef struct _zzip_extra_zip64
-{ /* ZIP64 extended information extra field */
- zzip_byte_t z_datatype[2]; /* Tag for this "extra" block type */
- zzip_byte_t z_datasize[2]; /* Size of this "extra" block */
- zzip_byte_t z_usize[8]; /* Original uncompressed file size */
- zzip_byte_t z_csize[8]; /* Size of compressed data */
- zzip_byte_t z_offset[8]; /* Offset of local header record */
- zzip_byte_t z_diskstart[4]; /* Number of the disk for file start */
-} zzip_extra_zip64;
+typedef struct zzip_extra_zip64 zzip_extra_zip64;
/*forward*/
}
{
/* override sizes/offsets with zip64 values for largefile support */
- zzip_extra_zip64 *block = (zzip_extra_zip64 *)
- zzip_mem_entry_find_extra_block(item, ZZIP_EXTRA_zip64, sizeof(zzip_extra_zip64));
+ struct zzip_extra_zip64 *block = (struct zzip_extra_zip64 *)
+ zzip_mem_entry_find_extra_block(item, ZZIP_EXTRA_ZIP64_MAGIC, sizeof(struct zzip_extra_zip64));
if (block)
{
- item->zz_usize = ZZIP_GET64(block->z_usize);
- item->zz_csize = ZZIP_GET64(block->z_csize);
- item->zz_offset = ZZIP_GET64(block->z_offset);
- item->zz_diskstart = ZZIP_GET32(block->z_diskstart);
+ item->zz_usize = zzip_extra_zip64_usize(block);
+ item->zz_csize = zzip_extra_zip64_csize(block);
+ item->zz_offset = zzip_extra_zip64_offset(block);
+ item->zz_diskstart = zzip_extra_zip64_diskstart(block);
}
}
/* NOTE:
#define ____ }
#endif
+#define DEBUG 1
+#ifdef DEBUG
+#define debug1(msg) do { fprintf(stderr, "DEBUG: %s : " msg "\n", __func__); } while(0)
+#define debug2(msg, arg1) do { fprintf(stderr, "DEBUG: %s : " msg "\n", __func__, arg1); } while(0)
+#define debug3(msg, arg1, arg2) do { fprintf(stderr, "DEBUG: %s : " msg "\n", __func__, arg1, arg2); } while(0)
+#define debug4(msg, arg1, arg2, arg3) do { fprintf(stderr, "DEBUG: %s : " msg "\n", __func__, arg1, arg2, arg3); } while(0)
+#else
+#define debug1(msg)
+#define debug2(msg, arg1)
+#define debug3(msg, arg1, arg2)
+#define debug4(msg, arg1, arg2, arg3)
+#endif
+
/** => zzip_disk_mmap
* This function does primary initialization of a disk-buffer struct.
*
zzip_byte_t *const ptr = disk->buffer + zzip_disk_entry_fileoffset(entry);
if (disk->buffer > ptr || ptr >= disk->endbuf)
{
+ debug2("file header: offset out of bounds (0x%llx)", (long long unsigned)(disk->buffer));
errno = EBADMSG;
return 0;
}
___ struct zzip_file_header *file_header = (void *) ptr;
if (zzip_file_header_get_magic(file_header) != ZZIP_FILE_HEADER_MAGIC)
{
+ debug1("file header: bad magic");
errno = EBADMSG;
return 0;
}
return file;
}
+ ___ /* a ZIP64 extended block may follow. */
+ size_t csize = zzip_file_header_csize(header);
+ off_t offset = zzip_file_header_to_data(header);
+ if (csize == 0xFFFFu) {
+ struct zzip_extra_zip64* zip64 =
+ zzip_file_header_to_extras(header);
+ if (ZZIP_EXTRA_ZIP64_CHECK(zip64)) {
+ csize = zzip_extra_zip64_csize(zip64);
+ }
+ }
+ if (offset == 0xFFFFu) {
+ struct zzip_extra_zip64* zip64 =
+ zzip_file_header_to_extras(header);
+ if (ZZIP_EXTRA_ZIP64_CHECK(zip64)) {
+ offset = zzip_extra_zip64_offset(zip64);
+ }
+ }
+
file->stored = 0;
file->zlib.opaque = 0;
file->zlib.zalloc = Z_NULL;
file->zlib.zfree = Z_NULL;
- file->zlib.avail_in = zzip_file_header_csize(header);
- file->zlib.next_in = zzip_file_header_to_data(header);
+ file->zlib.avail_in = csize;
+ file->zlib.next_in = offset;
+ ____;
DBG2("compressed size %i", (int) file->zlib.avail_in);
if (file->zlib.next_in + file->zlib.avail_in >= disk->endbuf)