Thread (10 messages) flat view 10 messages, 4 authors, 2016-08-11

sizeof(struct ...)

From: Gerrit Pape <hidden>
Date: 2016-08-11 20:14:50
Subsystem: the rest · Maintainer: Linus Torvalds

Hi, I don't think we can rely on sizeof(struct ...) to be the exact size
of the struct as defined.  As the selftests show, archive-zip doesn't
work correctly on Debian/arm

 http://buildd.debian.org/fetch.cgi?&pkg=git-core&ver=1%3A1.4.4-1&arch=arm&stamp=1164122355&file=log

It's because sizeof(struct zip_local_header) is 32, zip_dir_header 48,
and zip_dir_trailer 24, breaking the zip files.  Compiling with
-fpack-struct seemed to break other things, so I for now I ended up with
this (not so nice) workaround.

Regards, Gerrit.

diff --git a/archive-zip.c b/archive-zip.c
index ae5572a..4fcda44 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -211,7 +211,7 @@ static int write_zip_entry(const unsigne
 	}
 
 	/* make sure we have enough free space in the dictionary */
-	direntsize = sizeof(struct zip_dir_header) + pathlen;
+	direntsize = 46 + pathlen;
 	while (zip_dir_size < zip_dir_offset + direntsize) {
 		zip_dir_size += ZIP_DIRECTORY_MIN_SIZE;
 		zip_dir = xrealloc(zip_dir, zip_dir_size);
@@ -234,8 +234,8 @@ static int write_zip_entry(const unsigne
 	copy_le16(dirent.attr1, 0);
 	copy_le32(dirent.attr2, attr2);
 	copy_le32(dirent.offset, zip_offset);
-	memcpy(zip_dir + zip_dir_offset, &dirent, sizeof(struct zip_dir_header));
-	zip_dir_offset += sizeof(struct zip_dir_header);
+	memcpy(zip_dir + zip_dir_offset, &dirent, 46);
+	zip_dir_offset += 46;
 	memcpy(zip_dir + zip_dir_offset, path, pathlen);
 	zip_dir_offset += pathlen;
 	zip_dir_entries++;
@@ -251,8 +251,8 @@ static int write_zip_entry(const unsigne
 	copy_le32(header.size, uncompressed_size);
 	copy_le16(header.filename_length, pathlen);
 	copy_le16(header.extra_length, 0);
-	write_or_die(1, &header, sizeof(struct zip_local_header));
-	zip_offset += sizeof(struct zip_local_header);
+	write_or_die(1, &header, 30);
+	zip_offset += 30;
 	write_or_die(1, path, pathlen);
 	zip_offset += pathlen;
 	if (compressed_size > 0) {
@@ -282,7 +282,7 @@ static void write_zip_trailer(const unsi
 	copy_le16(trailer.comment_length, sha1 ? 40 : 0);
 
 	write_or_die(1, zip_dir, zip_dir_offset);
-	write_or_die(1, &trailer, sizeof(struct zip_dir_trailer));
+	write_or_die(1, &trailer, 22);
 	if (sha1)
 		write_or_die(1, sha1_to_hex(sha1), 40);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help