Hi,

I believe that this is bug in diffutils, but I am not entirely sure. The
problem manifested itself while testing patchutils on Solaris. One of
the tests was failing. Upon closer inspection the filterdiff (aka
lsdiff) decides whether a give chunk is creating (or deleting) a file
based on timestamp the chunk is having. It compares whether the timezone
recorded equals to current timezone.

https://github.com/twaugh/patchutils/blob/master/src/filterdiff.c#L156

On Solaris patchutils correctly detect that there is no
struct tm ->  tm_gmtoff (HAVE_TM_GMTOFF). On line 1417 of nstrftime.c

 1415 #if HAVE_TM_GMTOFF
 1416             diff = tp->tm_gmtoff;
 1417 #else
 1418             if (!tz)
 1419               diff = 0;
 1420             else

And since there is zero tz specified in context.c

if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec)))
                                                         ^^^

The resulting chunk has zero timezone offset (on Solaris). Like here:

$ TZ=EST+5 gdiff -urN dir.orig dir
diff -urN dir.orig/a dir/a
--- dir.orig/a  1969-12-31 19:00:00.000000000 +0000  <------ this file is 
missing
+++ dir/a       2021-10-14 12:24:20.785102347 +0000

On Linux and after my fix on Solaris the result is

--- dir.orig/a  1969-12-31 19:00:00.000000000 -0500

I am not entirely sure where is nstrftime.c coming from, so I'm
reporting the issue here. I am also attaching patch I plan to use on
Solaris. The patch and additional test works for me on diffutils 3.8 on
both Linux and Solaris.

Thanks for diffutils, I believe it's the most important tool for release
engineer :)

Cheers
-- 
        Vlad
Solaris does not support tm_gmtoff and diffutils in such case defaults to zero
time offset no matter what timezone is being currently used. That manifests
when creating patch with new and/or deleted files.

 $ TZ=EST+5 gdiff -urN dir.orig dir
 diff -urN dir.orig/a dir/a
 --- dir.orig/a  1969-12-31 19:00:00.000000000 +0000  <------ this file is 
missing
 +++ dir/a       2021-10-14 12:24:20.785102347 +0000

The correct line should be
 --- dir.orig/a  1969-12-31 19:00:00.000000000 -0500


This issue was found by failing patchutils test case. Patchutils detect new
and/or deleted file by looking at the timestamp. It incorrectly assumes that
this is not new file creation but rather modification of existing file. And
it's test 'lsdiff2' fails.


--- diffutils-3.8/lib/nstrftime.c
+++ diffutils-3.8/lib/nstrftime.c
@@ -1416,7 +1416,10 @@ #if HAVE_TM_GMTOFF
             diff = tp->tm_gmtoff;
 #else
             if (!tz)
-              diff = 0;
+              {
+                time_t now = time(0);
+                diff = timegm(localtime(&now)) - now;
+              }
             else
               {
                 struct tm gtm;
--- diffutils-3.8/tests/Makefile.am
+++ diffutils-3.8/tests/Makefile.am
@@ -22,7 +22,8 @@ stdin \
   strcoll-0-names \
   filename-quoting \
   strip-trailing-cr \
-  colors
+  colors \
+  timezone
 
 XFAIL_TESTS = large-subopt
 
--- diffutils-3.6/tests/timezone
+++ diffutils-3.6/tests/timezone
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+TZ=EST+5
+export TZ
+
+TZ_OFFSET=-0500
+
+mkdir -p dir-empty dir
+echo a > dir/a
+
+returns_ 0 diff -urN dir-empty dir > out || fail=1
+STRING=$( grep ^--- out )
+if [[ $STRING == *$TZ_OFFSET ]]; then
+  exit 0
+else
+  fail_ "The timezone should be $TZ_OFFSET, but it is $STRING" 
+  exit 1
+fi

Reply via email to