Package: zip Version: 3.0-12 Severity: normal Tags: patch upstream How to reproduce:
Prep phase: porridge@butla:~/tmp$ mkdir dir porridge@butla:~/tmp$ echo foo > dir/file porridge@butla:~/tmp$ ln -s file dir/link porridge@butla:~/tmp$ find dir -ls 50725398 4 drwxrwxr-x 2 porridge porridge 4096 lut 17 18:01 dir 50725399 4 -rw-rw-r-- 1 porridge porridge 4 lut 17 18:01 dir/file 50725400 0 lrwxrwxrwx 1 porridge porridge 4 lut 17 18:01 dir/link -> file porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir adding: dir/ (in=0) (out=0) (stored 0%) adding: dir/file (in=4) (out=4) (stored 0%) adding: dir/link (in=4) (out=4) (stored 0%) total bytes=8, compressed=8 -> 0% savings porridge@butla:~/tmp$ So far so good, now the unexpected part: porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir ok: dir/ ok: dir/file updating: dir/link (in=4) (out=4) (stored 0%) total bytes=8, compressed=8 -> 0% savings porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir ok: dir/ ok: dir/file updating: dir/link (in=4) (out=4) (stored 0%) total bytes=8, compressed=8 -> 0% savings porridge@butla:~/tmp$ As you can see, the symlink is always considered to be in need of update. While the expected behaviour would be: porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir Archive is current porridge@butla:~/tmp$ I managed to produce the following patch which seems to fix the issue. It basically changes the UNIX-specific implementation of the filetime() function to retrieve the size not just for regular files, but also for symlinks. This way the `current` flag is set to 1 in zip.c:6018 like for regular files. The above (expected) behaviour is for a zip package built with this patch. --- zip-3.0.orig/unix/unix.c +++ zip-3.0/unix/unix.c @@ -423,7 +423,7 @@ ulg filetime(f, a, n, t) } } if (n != NULL) - *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + *n = ((s.st_mode & S_IFMT) == S_IFREG || (s.st_mode & S_IFMT) == S_IFLNK) ? s.st_size : -1L; if (t != NULL) { t->atime = s.st_atime; t->mtime = s.st_mtime; -- System Information: Debian Release: 11.2 APT prefers stable-security APT policy: (500, 'stable-security'), (500, 'stable-debug'), (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 5.10.0-11-amd64 (SMP w/4 CPU threads) Locale: LANG=pl_PL.UTF-8, LC_CTYPE=pl_PL.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages zip depends on: ii libbz2-1.0 1.0.8-4 ii libc6 2.31-13+deb11u2 Versions of packages zip recommends: ii unzip 6.0-26 zip suggests no packages. -- no debconf information