Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Jul 2008 20:03:44 GMT
From:      Anselm Strauss <strauss@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 145998 for review
Message-ID:  <200807262003.m6QK3i6c044510@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145998

Change 145998 by strauss@strauss_marvelman on 2008/07/26 20:03:16

	- Fixed writing of signature in local file header
	- Fixed written byte counting and offsets (must recheck)
	- Fixed freeing of cloned archive entries

Affected files ...

.. //depot/projects/soc2008/strauss_libarchive/TODO#11 edit
.. //depot/projects/soc2008/strauss_libarchive/libarchive/archive_write_set_format_zip.c#19 edit

Differences ...

==== //depot/projects/soc2008/strauss_libarchive/TODO#11 (text+ko) ====

@@ -1,7 +1,8 @@
 To Be Done
 ==========
 
-- Exception handling in ZIP writer
+- Free archive entry clones in ZIP writer
+- Exception handling in ZIP writer, archive error setting
 - Update ZIP writer in docs
 - About the keywords: of course they always change when integrating ...
 - Not all P4 keywords do expand (tested on OS X and FreeBSD)

==== //depot/projects/soc2008/strauss_libarchive/libarchive/archive_write_set_format_zip.c#19 (text+ko) ====

@@ -98,6 +98,8 @@
 struct zip {
 	struct zip_data_descriptor data_descriptor;
 	struct zip_file_header_link *central_directory;
+	off_t offset;
+	size_t written_bytes;
 };
 
 struct zip_central_directory_end {
@@ -127,6 +129,8 @@
 		return (ARCHIVE_FATAL);
 	}
 	zip->central_directory = NULL;
+	zip->offset = 0;
+	zip->written_bytes = 0;
 	a->format_data = zip;
 
 	a->pad_uncompressed = 0; /* Actually not needed for now, since no compression support yet. */
@@ -178,7 +182,7 @@
 	zip->central_directory = l;
 	
 	/* Store the offset of this header for later use in central directory. */ 
-	l->offset = a->archive.raw_position;
+	l->offset = zip->written_bytes;
 
 	/* 
 	 * Formatting local file header.
@@ -192,7 +196,7 @@
 	 *   - extra_length: first used when
 	 */
 	memset(&h, 0, sizeof(h));
-	zip_encode(ZIP_SIGNATURE_LOCAL_FILE_HEADER, &h.version, sizeof(h.version));
+	zip_encode(ZIP_SIGNATURE_LOCAL_FILE_HEADER, &h.signature, sizeof(h.signature));
 	zip_encode(0x0200, &h.version, sizeof(h.version));
 	zip_encode(1 << 2, &h.flags, sizeof(h.flags)); /* Flagging bit 3 for using data descriptor. */
 	zip_encode(strlen(path), &h.filename_length, sizeof(h.filename_length));
@@ -204,9 +208,11 @@
 	
 	ret = (a->compressor.write)(a, &h, sizeof(h));
 	if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL);
+	zip->written_bytes += sizeof(h);
 	
 	ret = (a->compressor.write)(a, path, strlen(path));
 	if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL);
+	zip->written_bytes += strlen(path);
 
 	return (ARCHIVE_OK);
 }
@@ -215,12 +221,16 @@
 archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
 {
 	int ret;
+	struct zip *zip = a->format_data;
+	
 	ret = (a->compressor.write)(a, buff, s);
-	if (ret >= 0)
+	if (ret >= 0) {
+		zip->written_bytes += s;
 		return (s);
-	else
+	} else {
 		return (ret);
-	
+	}
+		
 	/* TODO: Compute data descriptor CRC. */
 }
 
@@ -237,6 +247,7 @@
 	if (ret != ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
 	
+	zip->written_bytes += sizeof(*d);
 	return (ret);
 }
 
@@ -248,7 +259,7 @@
 	struct zip_file_header h;
 	struct zip_central_directory_end end;
 	int64_t size;
-	off_t offset;
+	off_t offset_start, offset_end;
 	const char *path;
 	int entries;
 	int ret;
@@ -272,7 +283,7 @@
 	zip_encode(0x0200, &h.version_extract, sizeof(h.version_extract));
 	
 	entries = 0;
-	offset = a->archive.raw_position;
+	offset_start = zip->written_bytes;
 	while (l != NULL) {
 		
 		/* Formatting individual header fields per entry. */
@@ -286,26 +297,30 @@
 		/* Writing file header. */
 		ret = (a->compressor.write)(a, &h, sizeof(h));
 		if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL);
+		zip->written_bytes += sizeof(h);
 		
 		/* Writing filename. */
 		ret = (a->compressor.write)(a, path, strlen(path));
 		if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL);
-
+		zip->written_bytes += strlen(path);
+		
 		l = l->next;
-		++entries;
+		entries++;
 	}
+	offset_end = zip->written_bytes;
 	
 	/* Formatting end of central directory. */
 	memset(&end, 0, sizeof(end));
 	zip_encode(ZIP_SIGNATURE_CENTRAL_DIRECTORY_END, &end.signature, sizeof(end.signature));
 	zip_encode(entries, &end.entries, sizeof(end.entries));
 	zip_encode(entries, &end.entries_disk, sizeof(end.entries_disk));
-	zip_encode(entries * sizeof(h), &end.size, sizeof(end.size));
-	zip_encode(offset, &end.offset, sizeof(end.offset));
+	zip_encode(offset_end - offset_start, &end.size, sizeof(end.size));
+	zip_encode(offset_start, &end.offset, sizeof(end.offset));
 	
 	/* Writing end of central directory. */
 	ret = (a->compressor.write)(a, &end, sizeof(end));
 	if (ret != ARCHIVE_OK) return (ARCHIVE_FATAL);
+	zip->written_bytes += sizeof(end);
 	
 	return (ARCHIVE_OK);
 }
@@ -314,13 +329,15 @@
 archive_write_zip_destroy(struct archive_write *a)
 {	
 	struct zip *zip;
-	struct zip_file_header_link *l;
+	struct zip_file_header_link *l1, *l2;
 	
 	zip = a->format_data;
-	l = zip->central_directory;
-	while (l != NULL) {
-		l = l->next;
-		free(l);
+	l1 = l2 = zip->central_directory;
+	while (l2 != NULL) {
+		l2 = l1->next;
+		free(l1->entry);
+		free(l1);
+		l1 = l2;
 	}
 	free(zip);
 	a->format_data = NULL;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807262003.m6QK3i6c044510>