bug-tar
[Top][All Lists]
Advanced

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

[Bug-tar] Additional info and possible patch for error in earlier report


From: Richard Nolde
Subject: [Bug-tar] Additional info and possible patch for error in earlier report from Richard Nolde
Date: Wed, 09 Feb 2011 18:19:11 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10

I compiled tar 1.25 locally with optimizations turned off.  The problem seems to be in the all_names_found function where the for loop incorrectly returns true after the first file within the directory has been read.  I'm not familar with the tar code so I cannot say how it should work, but I would think that there needs to be some way to track the fact that the requested item was a directory and this function should not return true until all the elements in the directory have been read. I've provided a suggested alternative test that works in my testing for listing and extracting the directory: eg  tar -[tx]v --strip-components=2 --occurrence=1 -f /tmp/nmon.tar archive/fedora/nmon.  I realize that the ISSLASH macro handles the two tests, but the slash in the file name may not be at the position tested in the original code. If the adjusted file name contains a slash at any point, I'm guessing that the current file is within a subdirectory that is being extracted.

Richard Nolde

names.c

bool
all_names_found (struct tar_stat_info *p)
{
  struct name const *cursor;
  size_t len;

  if (!p->file_name || occurrence_option == 0 || p->had_trailing_slash)
    return false;
  len = strlen (p->file_name);
  for (cursor = namelist; cursor; cursor = cursor->next)
    {
    if ((cursor->name[0] && !WASFOUND (cursor))
       || (len >= cursor->length &&
         ((strchr (p->file_name, '/'))|| (strchr(p->file_name, '\\')))))

/*  original code here that does not work
    || (len >= cursor->length && ISSLASH (p->file_name[cursor->length])))
 */
    return false;
    }
  return true;
}

  for (cursor = namelist; cursor; cursor = cursor->next)
    {
      if ((cursor->name[0] && !WASFOUND (cursor))
       || (len >= cursor->length && ((strchr (p->file_name, '/')) || (strchr(p->file_name, '\\')))))
    /*       || (len >= cursor->length && ISSLASH (p->file_name[cursor->length]))) */
    return false;
    }

(gdb) p *namelist
$18 = {next = 0x0, prev = 0x0, name = 0x808f950 "archive/fedora/nmon", length = 19,
matching_flags = 1073741832, cmdline = true, change_dir = 0, found_count = 1,
directory = 0x0, parent = 0x0, child = 0x0, sibling = 0x0, caname = 0x0}
...
(gdb) p *p
$20 = {orig_file_name = 0x8090508 "archive/fedora/nmon/nmon_x86_64_rhel4",
file_name = 0x808f968 "nmon/nmon_x86_64_rhel4", had_trailing_slash = false,
link_name = 0x808f9c8 "", uname = 0x808f9b8 "nolde",gname = 0x808f9a8 "nolde",
stat = {st_dev = 0, __pad1 = 0, __st_ino = 0, st_mode = 438, st_nlink = 0,
st_uid = 500, st_gid = 500, st_rdev = 0, __pad2 = 0, st_size = 217828,
st_blksize = 0, st_blocks = 0, st_atim = {tv_sec = 0, tv_nsec = 0},
st_mtim = {tv_sec = 0, tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0},
st_ino = 0}, atime = {tv_sec = 1297296281, tv_nsec = 763835143},
mtime = {tv_sec = 1290574642, tv_nsec = 0}, ctime = {tv_sec = 1297296281,
tv_nsec = 763835143}, archive_file_size = 217828, is_sparse = false,
sparse_major = 0, sparse_minor = 0, sparse_map_avail = 0, sparse_map_size = 0,
sparse_map = 0x0, xhdr = {stk = 0x0, size = 0, buffer = 0x0, string_length = 0},
is_dumpdir = false, skipped = false, dumpdir = 0x0, parent = 0x0,
dirstream = 0x0, fd = 0}



reply via email to

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