zip/0002-unix-reproducible-directory-order-scandir.patch

98 lines
3.1 KiB
Diff

https://sourceforge.net/p/infozip/patches/25/
From 706b9fdc032582a258f0f8e5444fde4ee5bab220 Mon Sep 17 00:00:00 2001
From: Mingye Wang <arthur200126@gmail.com>
Date: Sat, 25 Jan 2020 23:07:03 +0800
Subject: [PATCH 2/2] unix: reproducible directory order (scandir)
This commit replaces the readdir() loop with scandir. This means a well-
defined, reproducible sort order, with the downside that we will need to
store ALL directory entries in memory to sort them.
I am too lazy to add a switch to change how it is supposed to work. This
is only a proof-of-concept.
Co-Authored-By: Bernhard M. Wiedemann <bwiedemann suse.de>
---
unix/unix.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
Index: zip30/unix/unix.c
===================================================================
--- zip30.orig/unix/unix.c
+++ zip30/unix/unix.c
@@ -92,6 +92,10 @@ DIR *dirp;
#define closedir(dirp) fclose(dirp)
#endif /* NO_DIR */
+#ifdef NO_SCANDIR
+/* TODO Port the FreeBSD libc version */
+#error "We need scandir now."
+#endif
local char *readd(d)
DIR *d; /* directory stream to read from */
@@ -111,12 +115,14 @@ int caseflag; /* true to force
an error code in the ZE_ class. */
{
char *a; /* path and name for recursion */
- DIR *d; /* directory stream from opendir() */
- char *e; /* pointer to name from readd() */
+ char *e; /* pointer to name from scandir() */
+ int c; /* number of entries from scandir() */
+ int i; /* entry index */
int m; /* matched flag */
char *p; /* path for recursion */
z_stat s; /* result of stat() */
struct zlist far *z; /* steps through zfiles list */
+ struct dirent **namelist;
if (strcmp(n, "-") == 0) /* if compressing stdin */
return newname(n, 0, caseflag);
@@ -176,14 +182,16 @@ int caseflag; /* true to force
}
}
/* recurse into directory */
- if (recurse && (d = opendir(n)) != NULL)
+ if (recurse && (c = scandir(n, &namelist, NULL, alphasort)) >= 0)
{
- while ((e = readd(d)) != NULL) {
+ for (i = 0; i < c; i++) {
+ e = namelist[i]->d_name;
if (strcmp(e, ".") && strcmp(e, ".."))
{
if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
{
- closedir(d);
+ for (; i < c; i++) free(namelist[i]);
+ free(namelist);
free((zvoid *)p);
return ZE_MEM;
}
@@ -197,8 +205,9 @@ int caseflag; /* true to force
}
free((zvoid *)a);
}
+ free(namelist[i]);
}
- closedir(d);
+ free(namelist);
}
free((zvoid *)p);
} /* (s.st_mode & S_IFDIR) */
Index: zip30/test.sh
===================================================================
--- /dev/null
+++ zip30/test.sh
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+mkdir -p test/{a,b,c}
+echo x > test/a/x
+echo y > test/a/y
+echo y > test/b/y
+export SOURCE_DATE_EPOCH=1
+./zip -X -r test.zip test
+md5sum test.zip
+echo "89057b9c9501ce122973d24b68a0522a test.zip" | md5sum -c
+