bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-tar] oldgnu file format changes (file permissions field).


From: Igor Zhbanov
Subject: [Bug-tar] oldgnu file format changes (file permissions field).
Date: Fri, 2 Oct 2009 14:35:19 +0400

Hello!

I have found that tarĀ“s after 1.16 creates binary different archives
in oldgnu format.
The difference is in file mode field.

To test this I use the command: tar cvf test.tar -H oldgnu tar.c

tar-1.15.91 sets mode field to 0100644 (as all previous versions),
but tar-1.16 (and all later versions) sets the mode field to 0000644
in the same oldgnu file format.

So different versions of tar create binary different files with
different checksums. That's sad. :-(

That difference is because of changes to function mode_to_chars in src/create.c.

Old version was:

bool
mode_to_chars (mode_t v, char *p, size_t s)
{
  /* In the common case where the internal and external mode bits are the same,
     and we are not using POSIX or GNU format,
     propagate all unknown bits to the external mode.
     This matches historical practice.
     Otherwise, just copy the bits we know about.  */
  int negative;
  uintmax_t u;
  if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
      && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
      && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
      && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC
      && archive_format != POSIX_FORMAT
      && archive_format != USTAR_FORMAT
      && archive_format != GNU_FORMAT)
    {
      negative = v < 0;
      u = v;
    }
  else
    {
      negative = 0;
      u = ((v & S_ISUID ? TSUID : 0)
           | (v & S_ISGID ? TSGID : 0)
           | (v & S_ISVTX ? TSVTX : 0)
           | (v & S_IRUSR ? TUREAD : 0)
           | (v & S_IWUSR ? TUWRITE : 0)
           | (v & S_IXUSR ? TUEXEC : 0)
           | (v & S_IRGRP ? TGREAD : 0)
           | (v & S_IWGRP ? TGWRITE : 0)
           | (v & S_IXGRP ? TGEXEC : 0)
           | (v & S_IROTH ? TOREAD : 0)
           | (v & S_IWOTH ? TOWRITE : 0)
           | (v & S_IXOTH ? TOEXEC : 0));
    }
  return to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
}

And the new is:

bool
mode_to_chars (mode_t v, char *p, size_t s)
{
  /* In the common case where the internal and external mode bits are the same,
     and we are not using POSIX or GNU format,
     propagate all unknown bits to the external mode.
     This matches historical practice.
     Otherwise, just copy the bits we know about.  */
  int negative;
  uintmax_t u;
  if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
      && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
      && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
      && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC
      && archive_format != POSIX_FORMAT
      && archive_format != USTAR_FORMAT
      && archive_format != GNU_FORMAT
      && archive_format != OLDGNU_FORMAT)
    {
      negative = v < 0;
      u = v;
    }
  else
    {
      negative = 0;
      u = ((v & S_ISUID ? TSUID : 0)
           | (v & S_ISGID ? TSGID : 0)
           | (v & S_ISVTX ? TSVTX : 0)
           | (v & S_IRUSR ? TUREAD : 0)
           | (v & S_IWUSR ? TUWRITE : 0)
           | (v & S_IXUSR ? TUEXEC : 0)
           | (v & S_IRGRP ? TGREAD : 0)
           | (v & S_IWGRP ? TGWRITE : 0)
           | (v & S_IXGRP ? TGEXEC : 0)
           | (v & S_IROTH ? TOREAD : 0)
           | (v & S_IWOTH ? TOWRITE : 0)
           | (v & S_IXOTH ? TOEXEC : 0));
    }
  return to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
}

The difference is in IF statement:
...
      && archive_format != POSIX_FORMAT
      && archive_format != USTAR_FORMAT
      && archive_format != GNU_FORMAT)
vs.
...
      && archive_format != POSIX_FORMAT
      && archive_format != USTAR_FORMAT
      && archive_format != GNU_FORMAT
      && archive_format != OLDGNU_FORMAT)

So when different versions of tar create archive in oldgnu format,
different statements will be executed.

What do you think?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]