Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package tarix for openSUSE:Factory checked 
in at 2026-10-13 17:43:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tarix (Old)
 and      /work/SRC/openSUSE:Factory/.tarix.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tarix"

Tue Oct 13 17:43:46 2026 rev:3 rq:1384435 version:1.0.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/tarix/tarix.changes      2026-06-22 
17:45:06.630714152 +0200
+++ /work/SRC/openSUSE:Factory/.tarix.new.3698736/tarix.changes 2026-10-13 
17:44:27.307076902 +0200
@@ -1,0 +2,15 @@
+Mon Oct 12 18:33:13 UTC 2026 - Tomáš Chvátal <[email protected]>
+
+- Extend tarix-fuse3.patch with -D_FILE_OFFSET_BITS=64 for the
+  fuse_tarix build: libfuse3 requires a 64-bit off_t, so the
+  build failed on 32-bit targets (i586, armv7l)
+- Add tarix-pax-headers.patch: keep POSIX pax extended headers
+  attached to the archive member they describe when extracting.
+  They were matched against the file list on their own before,
+  so filtered extractions leaked the headers of excluded
+  members and tar applied them to the wrong member
+- Run the full upstream testsuite in %check: the pax header fix
+  makes 08-exclude pass with the POSIX tar format that openSUSE
+  uses by default, so failures are no longer ignored there
+
+-------------------------------------------------------------------

New:
----
  tarix-pax-headers.patch

----------(New B)----------
  New:  build failed on 32-bit targets (i586, armv7l)
- Add tarix-pax-headers.patch: keep POSIX pax extended headers
  attached to the archive member they describe when extracting.
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tarix.spec ++++++
--- /var/tmp/diff_new_pack.Czk6Ql/_old  2026-10-13 17:44:28.039107581 +0200
+++ /var/tmp/diff_new_pack.Czk6Ql/_new  2026-10-13 17:44:28.041107665 +0200
@@ -21,11 +21,12 @@
 Release:        0
 Summary:        Simple Indexer for GNU and POSIX Tar Files
 License:        GPL-2.0-only
-Group:          Productivity/Archiving/Backup
 URL:            https://github.com/fastcat/tarix
 Source:         
https://github.com/fastcat/tarix/archive/tarix-%{version}.tar.gz
 # PATCH-FIX-UPSTREAM tarix-fuse3.patch boo#1242192 -- port the FUSE filesystem 
from libfuse2 to libfuse3
 Patch0:         tarix-fuse3.patch
+# PATCH-FIX-UPSTREAM tarix-pax-headers.patch -- keep POSIX pax headers 
attached to the archive member they describe during extraction
+Patch1:         tarix-pax-headers.patch
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(fuse3)
 BuildRequires:  pkgconfig(glib-2.0)
@@ -51,8 +52,7 @@
   %{buildroot}%{_bindir}/fuse_tarix
 
 %check
-# Test: 08-exclude                     ...FAILED
-make %{?_smp_mflags} CC="cc %{optflags} -std=c99" test ||:
+%make_build CC="cc %{optflags} -std=c99" test
 
 %files
 %license LICENSE

++++++ tarix-fuse3.patch ++++++
--- /var/tmp/diff_new_pack.Czk6Ql/_old  2026-10-13 17:44:28.064108629 +0200
+++ /var/tmp/diff_new_pack.Czk6Ql/_new  2026-10-13 17:44:28.067108754 +0200
@@ -1,5 +1,5 @@
---- a/Makefile 2026-06-22 13:13:42.245101145 +0200
-+++ b/Makefile 2026-06-22 13:13:42.313108724 +0200
+--- a/Makefile
++++ b/Makefile
 @@ -8,9 +8,9 @@
  
  # silence-errors doesn't completely silence them
@@ -12,8 +12,17 @@
  LDFLAGS_GLIB:=$(strip $(shell pkg-config glib-2.0 --libs --silence-errors))
  
  # disable fuse if it's not available
---- a/src/fuse_tarix.c 2026-06-22 13:13:42.257102483 +0200
-+++ b/src/fuse_tarix.c 2026-06-22 13:13:42.313108724 +0200
+@@ -67,7 +67,7 @@
+ endif
+ OPTCFLAGS?=
+ CFLAGS=-Wall -Werror -std=gnu99 $(CFLAGS_O) $(OPTCFLAGS)
+-CPPFLAGS_fuse_tarix:= ${CPPFLAGS_FUSE} ${CPPFLAGS_GLIB}
++CPPFLAGS_fuse_tarix:= ${CPPFLAGS_FUSE} ${CPPFLAGS_GLIB} -D_FILE_OFFSET_BITS=64
+ LDFLAGS+=-lz
+ LDFLAGS_fuse_tarix:=${LDFLAGS_FUSE} ${LDFLAGS_GLIB}
+ CC?=gcc
+--- a/src/fuse_tarix.c
++++ b/src/fuse_tarix.c
 @@ -19,7 +19,7 @@
  
  #include "config.h"
@@ -83,8 +92,8 @@
    .utimens = tarix_utimens,
  };
  
---- a/src/fuse_rofs.c  2026-06-22 13:13:42.273104266 +0200
-+++ b/src/fuse_rofs.c  2026-06-22 13:13:42.317109170 +0200
+--- a/src/fuse_rofs.c
++++ b/src/fuse_rofs.c
 @@ -25,26 +25,40 @@
    return -EROFS;
  }

++++++ tarix-pax-headers.patch ++++++
--- a/src/extract_files.c
+++ b/src/extract_files.c
@@ -46,6 +46,13 @@
   int zlib_level;
   t_streamp tsp;
   int outfd;
+  /* POSIX pax header entries ('x'/'g') held back until the archive
+     member they belong to is decided on; they immediately precede
+     their member and are contiguous, so a range is enough */
+  int have_pending;
+  unsigned long pending_blocknum;
+  off64_t pending_offset;
+  unsigned long pending_blocklength;
   /* flags to pass to fnmatch, if 0, don't use fnmatch */
   int glob_flags;
   /* if set, then matched items are excluded */
@@ -54,6 +61,55 @@
   const struct files_list_state *files_list;
 };
 
+/* seek (if needed) to the given record and pass it through to the
+   output; returns 0 on success, nonzero on error like the caller */
+static int copy_blocks(struct extract_files_state *state,
+  unsigned long blocknum, off64_t offset, unsigned long blocklength)
+{
+  /* for the DMSG macro */
+  int debug_messages = state->debug_messages;
+  off64_t destoff;
+  char passbuf[TARBLKSZ];
+
+  /* seek to the record start and then pass the record through */
+  /* don't actually seek if we're already there */
+  if (state->curpos != blocknum)
+  {
+    destoff = state->zlib_level ? offset : blocknum * TARBLKSZ;
+    DMSG("seeking to %lld\n", (long long)destoff);
+    if (ts_seek(state->tsp, destoff) != 0)
+    {
+      fprintf(stderr, "seek error\n");
+      return 1;
+    }
+    state->curpos = blocknum;
+  }
+  DMSG("reading %ld records\n", blocklength);
+  for (unsigned long bnum = 0; bnum < blocklength; ++bnum)
+  {
+    int n;
+    if ((n = ts_read(state->tsp, passbuf, TARBLKSZ)) < TARBLKSZ)
+    {
+      if (n >= 0)
+        perror("partial tarfile read");
+      else
+        ptserror("read tarfile", n, state->tsp);
+      return 2;
+    }
+    DMSG("read a rec, now at %lld, %ld left\n",
+      (long long)state->curpos, blocklength - bnum - 1);
+    ++state->curpos;
+    if ((n = write(state->outfd, passbuf, TARBLKSZ)) < TARBLKSZ)
+    {
+      perror((n > 0) ? "partial tarfile write" : "write tarfile");
+      return 2;
+    }
+    DMSG("wrote rec\n");
+  }
+
+  return 0;
+}
+
 int extract_files_lineloop_processor(char *line, void *data)
 {
   struct extract_files_state *state = (struct extract_files_state*)data;
@@ -62,8 +118,7 @@
   size_t i;
   /* for the DMSG macro */
   int debug_messages = state->debug_messages;
-  off64_t destoff;
-  
+
   if (!state->gotheader)
   {
     if (init_index_parser(&state->ipstate, line) != 0)
@@ -86,6 +141,26 @@
     /* comment line */
     return 0;
 
+  if (entry.recordtype == 'x' || entry.recordtype == 'g')
+  {
+    /* a pax header describes the member that follows it, it is not a
+       member of its own: never match it against the file list, hold it
+       until that member's extract decision is made so the two are
+       copied (or dropped) together */
+    if (state->have_pending &&
+        entry.blocknum ==
+          state->pending_blocknum + state->pending_blocklength)
+      state->pending_blocklength += entry.blocklength;
+    else
+    {
+      state->have_pending = 1;
+      state->pending_blocknum = entry.blocknum;
+      state->pending_offset = entry.offset;
+      state->pending_blocklength = entry.blocklength;
+    }
+    return 0;
+  }
+
   /* take action on the line */
   for (i = 0; i < files_list->argc; ++i)
   {
@@ -124,50 +199,28 @@
   
   if (state->exclude_mode)
     extract = !extract;
-  
+
   if (!extract)
-    return 0;
-    
-  char passbuf[TARBLKSZ];
-  
-  DMSG("extracting %s\n", entry.filename);
-  /* seek to the record start and then pass the record through */
-  /* don't actually seek if we're already there */
-  if (state->curpos != entry.blocknum)
   {
-    destoff = state->zlib_level ? entry.offset : entry.blocknum * TARBLKSZ;
-    DMSG("seeking to %lld\n", (long long)destoff);
-    if (ts_seek(state->tsp, destoff) != 0)
-    {
-      fprintf(stderr, "seek error\n");
-      return 1;
-    }
-    state->curpos = entry.blocknum;
+    /* the member is skipped, so are its held pax headers */
+    state->have_pending = 0;
+    return 0;
   }
-  DMSG("reading %ld records\n", entry.blocklength);
-  for (unsigned long bnum = 0; bnum < entry.blocklength; ++bnum)
+
+  if (state->have_pending)
   {
-    int n;
-    if ((n = ts_read(state->tsp, passbuf, TARBLKSZ)) < TARBLKSZ)
-    {
-      if (n >= 0)
-        perror("partial tarfile read");
-      else
-        ptserror("read tarfile", n, state->tsp);
-      return 2;
-    }
-    DMSG("read a rec, now at %lld, %ld left\n",
-      (long long)state->curpos, entry.blocklength - bnum - 1);
-    ++state->curpos;
-    if ((n = write(state->outfd, passbuf, TARBLKSZ)) < TARBLKSZ)
-    {
-      perror((n > 0) ? "partial tarfile write" : "write tarfile");
-      return 2;
-    }
-    DMSG("wrote rec\n");
+    /* the member is extracted: its pax headers go first so they stay
+       attached to it */
+    int ret = copy_blocks(state, state->pending_blocknum,
+      state->pending_offset, state->pending_blocklength);
+    state->have_pending = 0;
+    if (ret != 0)
+      return ret;
   }
-  
-  return 0;
+
+  DMSG("extracting %s\n", entry.filename);
+  return copy_blocks(state, entry.blocknum, entry.offset,
+    entry.blocklength);
 }
 
 int extract_files(const char *indexfile, const char *tarfile,

Reply via email to