Re: [Bug-tar] Symlink extraction broken w/recent CVS versions
Paul Eggert [EMAIL PROTECTED] ha escrit: I agree. It appears to be a bug introduced in this patch: Yes, indeed. I agree, too. As your example shows, it's not so simple as blindly applying --strip-components values to every link that comes in. Perhaps absolute links should be stripped, but certainly a relative symbolic link within the tree should not be stripped. In this particular case, yes, probably it should not. But the problem is more general than that. Consider, for example, running tar --transform='s,/subdir/,/sub-dir/,' -x -f archive.tar and suppose that archive.tar contains the following symlink: dir1/a - ../subdir/a The link target contains leading dots, but it is obviously subject to filename transformation, otherwise the extraction won't be correct. Regards, Sergey
Re: [Bug-tar] Symlink extraction broken w/recent CVS versions
Hello, In the absence of a better solution, I have applied the following patch: 2007-06-02 Sergey Poznyakoff [EMAIL PROTECTED] * src/common.h (xform_type): New data type (transform_member_name): Last argument is of xform_type type. All callers updated * src/extract.c: Update calls to transform_member_name * src/list.c (decode_xform): Symbolic links are exempt from component stripping and name suffix normalization but subject to file name transformation proper. This solution satisfies both the test case provided by MrC, and the one submitted by Morten Welinder (http://lists.gnu.org/archive/html/bug-tar/2007-03/msg00011.html). Regards, Sergey Index: src/common.h === RCS file: /cvsroot/tar/tar/src/common.h,v retrieving revision 1.97 diff -p -u -r1.97 common.h --- src/common.h19 May 2007 17:02:13 - 1.97 +++ src/common.h1 Jun 2007 21:21:33 - @@ -725,7 +725,14 @@ bool string_ascii_p (const char *str); bool utf8_convert (bool to_utf, char const *input, char **output); /* Module transform.c */ +typedef enum + { +xform_regfile, +xform_link, +xform_symlink + } xform_type; + void set_transform_expr (const char *expr); bool transform_name (char **pinput); -bool transform_member_name (char **pinput, bool lnk); +bool transform_member_name (char **pinput, xform_type type); bool transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *); Index: src/extract.c === RCS file: /cvsroot/tar/tar/src/extract.c,v retrieving revision 1.101 diff -p -u -r1.101 extract.c --- src/extract.c 30 Mar 2007 19:18:10 - 1.101 +++ src/extract.c 1 Jun 2007 21:21:33 - @@ -917,7 +917,7 @@ extract_link (char *file_name, int typef int interdir_made = 0; char const *link_name; - transform_member_name (current_stat_info.link_name, true); + transform_member_name (current_stat_info.link_name, xform_link); link_name = current_stat_info.link_name; if (! absolute_names_option contains_dot_dot (link_name)) @@ -974,7 +974,7 @@ extract_symlink (char *file_name, int ty int status; int interdir_made = 0; - transform_member_name (current_stat_info.link_name, true); + transform_member_name (current_stat_info.link_name, xform_symlink); if (! absolute_names_option (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name) Index: src/list.c === RCS file: /cvsroot/tar/tar/src/list.c,v retrieving revision 1.104 diff -p -u -r1.104 list.c --- src/list.c 19 May 2007 17:03:28 - 1.104 +++ src/list.c 1 Jun 2007 21:21:33 - @@ -472,9 +472,27 @@ read_header (bool raw_extended_headers) static char * decode_xform (char *file_name, void *data) { - bool link_target = *(bool*)data; - file_name = safer_name_suffix (file_name, link_target, -absolute_names_option); + xform_type type = *(xform_type*)data; + + switch (type) +{ +case xform_symlink: + /* FIXME: It is not quite clear how and to which extent are the symbolic +links subject to filename transformation. In the absence of another +solution, symbolic links are exempt from component stripping and +name suffix normalization, but subject to filename transformation +proper. */ + return file_name; + +case xform_link: + file_name = safer_name_suffix (file_name, true, absolute_names_option); + break; + +case xform_regfile: + file_name = safer_name_suffix (file_name, false, absolute_names_option); + break; +} + if (strip_name_components) { size_t prefix_len = stripped_prefix_len (file_name, @@ -487,9 +505,9 @@ decode_xform (char *file_name, void *dat } bool -transform_member_name (char **pinput, bool lnk) +transform_member_name (char **pinput, xform_type type) { - return transform_name_fp (pinput, decode_xform, lnk); + return transform_name_fp (pinput, decode_xform, type); } #define ISOCTAL(c) ((c)='0'(c)='7') @@ -610,7 +628,7 @@ decode_header (union block *header, stru stat_info-is_dumpdir = true; } - transform_member_name (stat_info-file_name, false); + transform_member_name (stat_info-file_name, xform_regfile); } /* Convert buffer at WHERE0 of size DIGS from external format to
[Bug-tar] Symlink extraction broken w/recent CVS versions
It appears that symlink extraction is broken in recent CVS versions of tar. Here's a directory tree, with two symlinks: # ls -lR /tmp/test /tmp/test: total 4 -rw--- 1 root root0 May 31 13:03 a -rw--- 1 root root0 May 31 13:03 b drwx-- 2 root root 4096 May 31 13:23 somedir/ /tmp/test/somedir: total 0 lrwxrwxrwx 1 root root 4 May 31 13:23 a - ../a lrwxrwxrwx 1 root root 4 May 31 13:23 b - ../b Tar archive is create just fine, and is shown to contain: # ~/build/tar-cvs/src/tar -tvf /tmp/test.tar drwx-- root/root 0 2007-05-31 13:03 test/ drwx-- root/root 0 2007-05-31 13:23 test/somedir/ lrwxrwxrwx root/root 0 2007-05-31 13:23 test/somedir/a - ../a lrwxrwxrwx root/root 0 2007-05-31 13:23 test/somedir/b - ../b -rw--- root/root 0 2007-05-31 13:03 test/a -rw--- root/root 0 2007-05-31 13:03 test/b However, upon extraction, symlinks a and b are not created correctly, and become dead links: # mkdir extract # cd extract # ~/build/tar-cvs/src/tar -tvf /tmp/test.tar # ls -lR .: total 4 drwx-- 3 root root 4096 May 31 13:03 test/ ./test: total 4 -rw--- 1 root root0 May 31 13:03 a -rw--- 1 root root0 May 31 13:03 b drwx-- 2 root root 4096 May 31 13:23 somedir/ ./test/somedir: total 0 lrwxrwxrwx 1 root root 1 May 31 13:25 a - a lrwxrwxrwx 1 root root 1 May 31 13:25 b - b Mike
Re: [Bug-tar] Symlink extraction broken w/recent CVS versions
MrC [EMAIL PROTECTED] ha escrit: However, upon extraction, symlinks a and b are not created correctly, and become dead links: When you run `tar vxf /tmp/test.tar' you get the following: test/ test/a test/b test/somedir/ test/somedir/a ../tar: Removing leading `../' from hard link targets If you wish to preserve relative paths to upper directories, use -P (--absolute-names) command line option: $ tar vvxfP /tmp/test.tar drwxr-xr-x gray/staff0 2007-06-01 00:24 test/ -rw-r--r-- gray/staff0 2007-06-01 00:24 test/a -rw-r--r-- gray/staff0 2007-06-01 00:24 test/b drwxr-xr-x gray/staff0 2007-06-01 00:24 test/somedir/ lrwxrwxrwx gray/staff0 2007-06-01 00:24 test/somedir/a - ../a lrwxrwxrwx gray/staff0 2007-06-01 00:24 test/somedir/b - ../b Regards, Sergey
RE: [Bug-tar] Symlink extraction broken w/recent CVS versions
MrC ha escrit: However, upon extraction, symlinks a and b are not created correctly, and become dead links: When you run `tar vxf /tmp/test.tar' you get the following: test/ test/a test/b test/somedir/ test/somedir/a ../tar: Removing leading `../' from hard link targets If you wish to preserve relative paths to upper directories, use -P (--absolute-names) command line option: $ tar vvxfP /tmp/test.tar drwxr-xr-x gray/staff0 2007-06-01 00:24 test/ -rw-r--r-- gray/staff0 2007-06-01 00:24 test/a -rw-r--r-- gray/staff0 2007-06-01 00:24 test/b drwxr-xr-x gray/staff0 2007-06-01 00:24 test/somedir/ lrwxrwxrwx gray/staff0 2007-06-01 00:24 test/somedir/a - ../a lrwxrwxrwx gray/staff0 2007-06-01 00:24 test/somedir/b - ../b Regards, Sergey This is a change in behavior from 1.16.1, which does not yet appear in the Changelog. I was bitten by this change during my attempt to rebuild some standard software from is distribution tar archive. I would *never* use -P when extracting someone else's tar archive into my file system, but this change seems to *require* that I do in order to correctly extract the archive (or, manually fix all broken symbolic links by hand). This doesn't seem appropriate, and is going to bite a lot of software distributors and builders. MrC
Re: [Bug-tar] Symlink extraction broken w/recent CVS versions
MrC [EMAIL PROTECTED] writes: This doesn't seem appropriate, and is going to bite a lot of software distributors and builders. I agree. It appears to be a bug introduced in this patch: 2007-03-30 Sergey Poznyakoff [EMAIL PROTECTED] * src/common.h (transform_name_fp): Change signature (transform_member_name): New function * src/extract.c (extract_link, extract_symlink): Use transform_member_name instead of safer_name_suffix so that --transform and --strip-components affect links as well. * src/list.c (transform_member_name): New function (decode_header): Use transform_member_name * src/names.c (all_names_found): Remove check for matching_flags. * NEWS: Update * TODO: Update * bootstrap (slurp): Remove any occurrences of $bt from the generated gnulib.mk * src/incremen.c: Do not include mkdtemp.h As your example shows, it's not so simple as blindly applying --strip-components values to every link that comes in. Perhaps absolute links should be stripped, but certainly a relative symbolic link within the tree should not be stripped.