-/* Read a central directory header from ZR and initializes ZE with it.
- Returns true if successful, false otherwise. */
-static bool
-zip_header_read_next (struct zip_reader *zr, struct zip_entry *ze)
-{
- uint16_t v, nlen, extralen;
- uint16_t gp, time, date;
- uint32_t expected_crc;
-
- uint16_t clen, diskstart, iattr;
- uint32_t eattr;
- uint16_t comp_type;
-
- if ( ! check_magic (zr->fr, MAGIC_SOCD, zr->errs))
- return false;
-
- if (! get_u16 (zr->fr, &v)) return false;
- if (! get_u16 (zr->fr, &v)) return false;
- if (! get_u16 (zr->fr, &gp)) return false;
- if (! get_u16 (zr->fr, &comp_type)) return false;
- if (! get_u16 (zr->fr, &time)) return false;
- if (! get_u16 (zr->fr, &date)) return false;
- if (! get_u32 (zr->fr, &expected_crc)) return false;
- if (! get_u32 (zr->fr, &ze->comp_size)) return false;
- if (! get_u32 (zr->fr, &ze->ucomp_size)) return false;
- if (! get_u16 (zr->fr, &nlen)) return false;
- if (! get_u16 (zr->fr, &extralen)) return false;
- if (! get_u16 (zr->fr, &clen)) return false;
- if (! get_u16 (zr->fr, &diskstart)) return false;
- if (! get_u16 (zr->fr, &iattr)) return false;
- if (! get_u32 (zr->fr, &eattr)) return false;
- if (! get_u32 (zr->fr, &ze->offset)) return false;
+ *datap = xmalloc (zm->ucomp_size);
+ *np = zm->ucomp_size;
+
+ uint8_t *data = *datap;
+ while (zm->bytes_unread)
+ if (zip_member_read (zm, data + (zm->ucomp_size - zm->bytes_unread),
+ zm->bytes_unread) == -1)
+ {
+ char *error = zip_member_steal_error (zm);
+ zip_member_finish (zm);
+ free (*datap);
+ *datap = NULL;
+ *np = 0;
+ return error;
+ }
+
+ zip_member_finish (zm);
+ return NULL;
+}
+
+/* Read a central directory header from FILE and initializes ZE with it.
+ Returns true if successful, false otherwise. On error, appends error
+ messages to ERRS. */
+static char * WARN_UNUSED_RESULT
+zip_header_read_next (FILE *file, const char *file_name,
+ struct zip_entry *ze)
+{
+ char *error = check_magic (file, file_name, MAGIC_SOCD);
+ if (error)
+ return error;
+
+ get_u16 (file); /* v */
+ get_u16 (file); /* v */
+ get_u16 (file); /* gp */
+ get_u16 (file); /* comp_type */
+ get_u16 (file); /* time */
+ get_u16 (file); /* date */
+ get_u32 (file); /* expected_crc */
+ ze->comp_size = get_u32 (file);
+ ze->ucomp_size = get_u32 (file);
+ uint16_t nlen = get_u16 (file);
+ uint16_t extralen = get_u16 (file);
+ get_u16 (file); /* clen */
+ get_u16 (file); /* diskstart */
+ get_u16 (file); /* iattr */
+ get_u32 (file); /* eattr */
+ ze->offset = get_u32 (file);
+
+ error = get_stream_error (file, file_name);
+ if (error)
+ return error;