git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/2] archive-zip: declare creator to be Unix for UTF-8 paths

From
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Date
Sep 18, 2012, 19:53 UTC
Message-ID
<5058D13C.8050203@lsrfire.ath.cx>
In-Reply-To
<5058CE49.3070108@lsrfire.ath.cx>

The UTF-8 flag seems to be ignored by unzip unless we also mark the archive entry as coming from a Unix system. This is done by setting the field creator_version ("version made by" in the standard[1]) to 0x03NN.

The NN part represents the version of the standard supported by us, and this patch sets it to 3f (for version 6.3) for Unix paths. We keep creator_version set to 0 (FAT filesystem, standard version 0) in the non-special cases, as before.

But when we declare a file to have a Unix path, then we have to set the file mode as well, or unzip will extract the files with the permission set 0000, i.e. inaccessible by all.

[1] http://www.pkware.com/documents/casestudies/APPNOTE.TXT --- No sign-off for this, yet. Perhaps there is a better way to convince unzip to respect the flag? And if not, do we need to offer umask settings for ZIP as well as we have for tar? And perhaps declare all files as being from a Unix filesystem, for consistency?

 archive-zip.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/archive-zip.c b/archive-zip.c
index 0f763e8..e9b3dc9 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -186,7 +186,8 @@ static int write_zip_entry(struct archiver_args *args,
 {
 	struct zip_local_header header;
 	struct zip_dir_header dirent;
-	unsigned long attr2;
+	unsigned int creator_version = 0;
+	unsigned long attr2 = 0;
 	unsigned long compressed_size;
 	unsigned long crc;
 	unsigned long direntsize;
@@ -224,10 +225,15 @@ static int write_zip_entry(struct archiver_args *args,
 		enum object_type type = sha1_object_info(sha1, &size);
 
 		method = 0;
-		attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
-			(mode & 0111) ? ((mode) << 16) : 0;
 		if (S_ISREG(mode) && args->compression_level != 0 && size > 0)
 			method = 8;
+		if (S_ISLNK(mode) || (mode & 0111) || (flags & ZIP_UTF8)) {
+			creator_version = 0x033f;
+			attr2 = mode;
+			if (S_ISLNK(mode))
+				attr2 |= 0777;
+			attr2 <<= 16;
+		}
 		compressed_size = size;
 
 		if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
@@ -274,8 +280,7 @@ static int write_zip_entry(struct archiver_args *args,
 	}
 
 	copy_le32(dirent.magic, 0x02014b50);
-	copy_le16(dirent.creator_version,
-		S_ISLNK(mode) || (S_ISREG(mode) && (mode & 0111)) ? 0x0317 : 0);
+	copy_le16(dirent.creator_version, creator_version);
 	copy_le16(dirent.version, 10);
 	copy_le16(dirent.flags, flags);
 	copy_le16(dirent.compression_method, method);
-- 
1.7.12
Previous: René ScharfeNext: René Scharfe
Message 14 of 21 in “git archive --format zip utf-8 issues”
  1. Sven StrickrothAug 10, 2012
  2. Junio C HamanoAug 10, 2012
  3. Sven StrickrothAug 10, 2012
  4. René ScharfeAug 11, 2012
  5. Junio C HamanoAug 12, 2012
  6. René ScharfeAug 11, 2012
  7. Sven StrickrothAug 11, 2012
  8. Jeff KingAug 30, 2012
  9. René ScharfeSep 4, 2012
  10. Junio C HamanoSep 4, 2012
  11. René ScharfeSep 5, 2012
  12. René ScharfeSep 18, 2012
  13. 1/2 archive-zip: support UTF-8 pathsRené Scharfe, Sep 18, 2012
  14. 2/2 archive-zip: declare creator to be Unix for UTF-8 pathsRené Scharfe, Sep 18, 2012
  15. René ScharfeSep 18, 2012
  16. Junio C HamanoSep 18, 2012
  17. René ScharfeSep 20, 2012
  18. René ScharfeSep 24, 2012
  19. Junio C HamanoSep 24, 2012
  20. 3/2 archive-zip: write extended timestampRené Scharfe, Sep 24, 2012
  21. Junio C HamanoAug 12, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.