2009-06-22 guidod <guidod@gmx.de>
+ * zzip/zip.c (__zzip_parse_root_directory): rework parse_directory
+ to allow for ZZIP_ALLOW_MODULO_ENTRIES version as required for
+ some cases where more than 65535 entries are packed into a
+ non-ZIP64 archive. The modulo_entries variant is disabled by
+ default but the know for the problem space was put into code to
+ check for two more error conditions and report them in debug mode.
+ (problem space was described carefully by Tulipánt Gergely and
+ the provided patch was a good foundation for the ifdef code)
* configure.ac: use $can_build_shared from linker-config to allow
build on platforms that do not support a shared library concept
or where it is disabled (the commandline switch overrides it?)
}
}
- for (entries = zz_entries, zz_offset = 0; entries; entries--)
+ for (entries=0, zz_offset=0; ; entries++)
{
register struct zzip_disk_entry *d;
uint16_t u_extras, u_comment, u_namlen;
+# ifndef ZZIP_ALLOW_MODULO_ENTRIES
+ if (entries >= zz_entries) {
+ if (zz_offset + 256 < zz_rootsize) {
+ FAIL4("%li's entry is long before the end of directory - enable modulo_entries? (O:%li R:%li)",
+ (long) entries, (long) (zz_offset), (long) zz_rootsize);
+ }
+ break;
+ }
+# endif
+
if (fd_map)
{ d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
else
d = &dirent;
}
+ if (! zzip_disk_entry_check_magic(d)) {
+# ifndef ZZIP_ALLOW_MODULO_ENTRIES
+ FAIL4("%li's entry has no disk_entry magic indicator (O:%li R:%li)",
+ (long) entries, (long) (zz_offset), (long) zz_rootsize);
+# endif
+ break;
+ }
+
if ((zzip_off64_t) (zz_offset + sizeof(*d)) > zz_rootsize ||
(zzip_off64_t) (zz_offset + sizeof(*d)) < 0)
{
{
FAIL3("%li's entry stretches beyond root directory (O:%li)",
(long) entries, (long) (zz_offset));
- entries--;
+ entries ++;
break;
}
if (hdr_return)
*hdr_return = hdr0;
} /* else zero (sane) entries */
- return (entries ? ZZIP_CORRUPTED : 0);
+# ifndef ZZIP_ALLOW_MODULO_ENTRIES
+ return (entries != zz_entries ? ZZIP_CORRUPTED : 0);
+# else
+ return (entries & (unsigned)0xFFFF) != zz_entries ? ZZIP_CORRUPTED : 0);
+# endif
}
/* ------------------------- high-level interface ------------------------- */