about summary refs log tree commit diff
path: root/third_party/git/archive-zip.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/git/archive-zip.c')
-rw-r--r--third_party/git/archive-zip.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/third_party/git/archive-zip.c b/third_party/git/archive-zip.c
index 4d66b5be6e..2961e01c75 100644
--- a/third_party/git/archive-zip.c
+++ b/third_party/git/archive-zip.c
@@ -24,6 +24,11 @@ static unsigned int max_creator_version;
 #define ZIP_STREAM	(1 <<  3)
 #define ZIP_UTF8	(1 << 11)
 
+enum zip_method {
+	ZIP_METHOD_STORE = 0,
+	ZIP_METHOD_DEFLATE = 8
+};
+
 struct zip_local_header {
 	unsigned char magic[4];
 	unsigned char version[2];
@@ -280,7 +285,8 @@ static int entry_is_binary(struct index_state *istate, const char *path,
 static int write_zip_entry(struct archiver_args *args,
 			   const struct object_id *oid,
 			   const char *path, size_t pathlen,
-			   unsigned int mode)
+			   unsigned int mode,
+			   void *buffer, unsigned long size)
 {
 	struct zip_local_header header;
 	uintmax_t offset = zip_offset;
@@ -291,13 +297,11 @@ static int write_zip_entry(struct archiver_args *args,
 	unsigned long attr2;
 	unsigned long compressed_size;
 	unsigned long crc;
-	int method;
+	enum zip_method method;
 	unsigned char *out;
 	void *deflated = NULL;
-	void *buffer;
 	struct git_istream *stream = NULL;
 	unsigned long flags = 0;
-	unsigned long size;
 	int is_binary = -1;
 	const char *path_without_prefix = path + args->baselen;
 	unsigned int creator_version = 0;
@@ -320,45 +324,36 @@ static int write_zip_entry(struct archiver_args *args,
 	}
 
 	if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
-		method = 0;
+		method = ZIP_METHOD_STORE;
 		attr2 = 16;
 		out = NULL;
-		size = 0;
 		compressed_size = 0;
-		buffer = NULL;
 	} else if (S_ISREG(mode) || S_ISLNK(mode)) {
-		enum object_type type = oid_object_info(args->repo, oid,
-							&size);
-
-		method = 0;
+		method = ZIP_METHOD_STORE;
 		attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
 			(mode & 0111) ? ((mode) << 16) : 0;
 		if (S_ISLNK(mode) || (mode & 0111))
 			creator_version = 0x0317;
 		if (S_ISREG(mode) && args->compression_level != 0 && size > 0)
-			method = 8;
+			method = ZIP_METHOD_DEFLATE;
 
-		if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
-		    size > big_file_threshold) {
-			stream = open_istream(oid, &type, &size, NULL);
+		if (!buffer) {
+			enum object_type type;
+			stream = open_istream(args->repo, oid, &type, &size,
+					      NULL);
 			if (!stream)
 				return error(_("cannot stream blob %s"),
 					     oid_to_hex(oid));
 			flags |= ZIP_STREAM;
-			out = buffer = NULL;
+			out = NULL;
 		} else {
-			buffer = object_file_to_archive(args, path, oid, mode,
-							&type, &size);
-			if (!buffer)
-				return error(_("cannot read %s"),
-					     oid_to_hex(oid));
 			crc = crc32(crc, buffer, size);
 			is_binary = entry_is_binary(args->repo->index,
 						    path_without_prefix,
 						    buffer, size);
 			out = buffer;
 		}
-		compressed_size = (method == 0) ? size : 0;
+		compressed_size = (method == ZIP_METHOD_STORE) ? size : 0;
 	} else {
 		return error(_("unsupported file mode: 0%o (SHA1: %s)"), mode,
 				oid_to_hex(oid));
@@ -367,13 +362,13 @@ static int write_zip_entry(struct archiver_args *args,
 	if (creator_version > max_creator_version)
 		max_creator_version = creator_version;
 
-	if (buffer && method == 8) {
+	if (buffer && method == ZIP_METHOD_DEFLATE) {
 		out = deflated = zlib_deflate_raw(buffer, size,
 						  args->compression_level,
 						  &compressed_size);
 		if (!out || compressed_size >= size) {
 			out = buffer;
-			method = 0;
+			method = ZIP_METHOD_STORE;
 			compressed_size = size;
 		}
 	}
@@ -420,7 +415,7 @@ static int write_zip_entry(struct archiver_args *args,
 		zip_offset += ZIP64_EXTRA_SIZE;
 	}
 
-	if (stream && method == 0) {
+	if (stream && method == ZIP_METHOD_STORE) {
 		unsigned char buf[STREAM_BUFFER_SIZE];
 		ssize_t readlen;
 
@@ -443,7 +438,7 @@ static int write_zip_entry(struct archiver_args *args,
 		zip_offset += compressed_size;
 
 		write_zip_data_desc(size, compressed_size, crc);
-	} else if (stream && method == 8) {
+	} else if (stream && method == ZIP_METHOD_DEFLATE) {
 		unsigned char buf[STREAM_BUFFER_SIZE];
 		ssize_t readlen;
 		git_zstream zstream;
@@ -505,7 +500,6 @@ static int write_zip_entry(struct archiver_args *args,
 	}
 
 	free(deflated);
-	free(buffer);
 
 	if (compressed_size > 0xffffffff || size > 0xffffffff ||
 	    offset > 0xffffffff) {
@@ -603,18 +597,18 @@ static void write_zip_trailer(const struct object_id *oid)
 static void dos_time(timestamp_t *timestamp, int *dos_date, int *dos_time)
 {
 	time_t time;
-	struct tm *t;
+	struct tm tm;
 
 	if (date_overflows(*timestamp))
 		die(_("timestamp too large for this system: %"PRItime),
 		    *timestamp);
 	time = (time_t)*timestamp;
-	t = localtime(&time);
+	localtime_r(&time, &tm);
 	*timestamp = time;
 
-	*dos_date = t->tm_mday + (t->tm_mon + 1) * 32 +
-	            (t->tm_year + 1900 - 1980) * 512;
-	*dos_time = t->tm_sec / 2 + t->tm_min * 32 + t->tm_hour * 2048;
+	*dos_date = tm.tm_mday + (tm.tm_mon + 1) * 32 +
+		    (tm.tm_year + 1900 - 1980) * 512;
+	*dos_time = tm.tm_sec / 2 + tm.tm_min * 32 + tm.tm_hour * 2048;
 }
 
 static int archive_zip_config(const char *var, const char *value, void *data)