Re: coreutils 5.3.0: cp --parents broken
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Jim Meyering on 1/25/2005 5:31 AM: > * path-concat.c: Don't include assert.h. > (path_concat): Remove assertion that would have triggered > for ABASE starting with more than one slash. > Reported by Andreas Schwab. > > Index: path-concat.c > - concatenation. > + concatenation. However, if ABASE begins with more than one slash, > + set *BASE_IN_RESULT to point to the sole corresponding slash that > + is copied into the result buffer. Collapsing //file/name to /file/name violates POSIX (some systems use that notation for remote machine shared drive access). XBD 3.2 defines absolute path as "A pathname beginning with a single or more than two slashes", and XBD 4.11 agrees, so you are only allowed to collapse 3 or more leading slashes. - -- Life is short - so eat dessert first! Eric Blake [EMAIL PROTECTED] -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.0 (Cygwin) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFB9kVV84KuGfSFAYARAji9AKDLesm9Z2W/GsUVDiLN3o8ByGmXBQCghxUe 58QaeshhPcay8SfXWqR2rls= =ygbP -END PGP SIGNATURE- ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: coreutils 5.3.0: cp --parents broken
Eric Blake <[EMAIL PROTECTED]> wrote: > According to Jim Meyering on 1/25/2005 5:31 AM: >> * path-concat.c: Don't include assert.h. >> (path_concat): Remove assertion that would have triggered >> for ABASE starting with more than one slash. >> Reported by Andreas Schwab. >> >> Index: path-concat.c >> - concatenation. >> + concatenation. However, if ABASE begins with more than one slash, >> + set *BASE_IN_RESULT to point to the sole corresponding slash that >> + is copied into the result buffer. > > Collapsing //file/name to /file/name violates POSIX (some systems use that > notation for remote machine shared drive access). XBD 3.2 defines > absolute path as "A pathname beginning with a single or more than two > slashes", and XBD 4.11 agrees, so you are only allowed to collapse 3 or > more leading slashes. I am well aware of that part of POSIX. But it doesn't apply here, since we're not talking about a prefix of the result. This function concatenates two names, usually a directory and some other thing (file or directory) and the above ABASE refers to the latter part. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: coreutils 5.3.0: cp --parents broken
Andreas Schwab <[EMAIL PROTECTED]> wrote: > Jim Meyering <[EMAIL PROTECTED]> writes: > >> @@ -78,10 +79,49 @@ path_concat (char const *dir, char const >>p += needs_separator; >> >>if (base_in_result) >> -*base_in_result = p; >> +*base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase); >> >>p = mempcpy (p, base, baselen); >>*p = '\0'; >> >> + assert (!base_in_result >> + || strcmp (*base_in_result, abase) == 0); >> + > > I think this assertion will trigger if abase starts with multiple slashes, > which are all stripped by longest_relative_suffix. You're right. Here's the fix: * path-concat.c: Don't include assert.h. (path_concat): Remove assertion that would have triggered for ABASE starting with more than one slash. Reported by Andreas Schwab. Index: path-concat.c === RCS file: /fetish/cu/lib/path-concat.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -p -u -r1.22 -r1.23 --- path-concat.c 25 Jan 2005 09:07:49 - 1.22 +++ path-concat.c 25 Jan 2005 12:30:01 - 1.23 @@ -22,7 +22,6 @@ #if HAVE_CONFIG_H # include #endif -# include /* Specification. */ #include "path-concat.h" @@ -56,7 +55,9 @@ longest_relative_suffix (char const *f) in the result, removing any redundant separators. In any case, if BASE_IN_RESULT is non-NULL, set *BASE_IN_RESULT to point to the copy of ABASE in the returned - concatenation. + concatenation. However, if ABASE begins with more than one slash, + set *BASE_IN_RESULT to point to the sole corresponding slash that + is copied into the result buffer. Report an error if memory is exhausted. */ @@ -84,9 +85,6 @@ path_concat (char const *dir, char const p = mempcpy (p, base, baselen); *p = '\0'; - assert (!base_in_result - || strcmp (*base_in_result, abase) == 0); - return p_concat; } @@ -108,6 +106,7 @@ main () {"/", "/", "/"}, {"a", "/", "a/"}, /* this might deserve a diagnostic */ {"/a", "/", "/a/"}, /* this might deserve a diagnostic */ + {"a", "//b", "a/b"}, }; size_t i; bool fail = false; ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: coreutils 5.3.0: cp --parents broken
Jim Meyering <[EMAIL PROTECTED]> writes: > @@ -78,10 +79,49 @@ path_concat (char const *dir, char const >p += needs_separator; > >if (base_in_result) > -*base_in_result = p; > +*base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase); > >p = mempcpy (p, base, baselen); >*p = '\0'; > > + assert (!base_in_result > + || strcmp (*base_in_result, abase) == 0); > + I think this assertion will trigger if abase starts with multiple slashes, which are all stripped by longest_relative_suffix. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: coreutils 5.3.0: cp --parents broken
Andreas Schwab <[EMAIL PROTECTED]> wrote: > Jim Meyering <[EMAIL PROTECTED]> writes: >> Andreas Schwab <[EMAIL PROTECTED]> wrote: >>> $ ./cp --parents /bin/cp /tmp >>> ./cp: failed to get attributes of `bin': No such file or directory >> >> Thanks for the report. >> I can't reproduce that: > > Please make sure that /tmp/bin does not exist. Ahh... I should have known better. I *can* reproduce it. Here's the fix. Thanks again for reporting that! I'll add a test of `cp --parents' to exercise this. 2005-01-25 Jim Meyering <[EMAIL PROTECTED]> * path-concat.c (path_concat): Set *BASE_IN_RESULT properly when ABASE is an absolute file name. Correct the description of this function. Include . Add an assertion and a test driver. This fixes a bug introduced on 2004-07-02. Andreas Schwab reported the resulting failure in cp --parents: http://lists.gnu.org/archive/html/bug-coreutils/2005-01/msg00130.html Index: lib/path-concat.c === RCS file: /fetish/cu/lib/path-concat.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -p -u -r1.21 -r1.22 --- path-concat.c 5 Jul 2004 08:41:13 - 1.21 +++ path-concat.c 25 Jan 2005 09:07:49 - 1.22 @@ -1,6 +1,6 @@ /* path-concat.c -- concatenate two arbitrary pathnames - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -22,6 +22,7 @@ #if HAVE_CONFIG_H # include #endif +# include /* Specification. */ #include "path-concat.h" @@ -54,7 +55,7 @@ longest_relative_suffix (char const *f) Arrange for a directory separator if necessary between DIR and BASE in the result, removing any redundant separators. In any case, if BASE_IN_RESULT is non-NULL, set - *BASE_IN_RESULT to point to the copy of BASE in the returned + *BASE_IN_RESULT to point to the copy of ABASE in the returned concatenation. Report an error if memory is exhausted. */ @@ -78,10 +79,49 @@ path_concat (char const *dir, char const p += needs_separator; if (base_in_result) -*base_in_result = p; +*base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase); p = mempcpy (p, base, baselen); *p = '\0'; + assert (!base_in_result + || strcmp (*base_in_result, abase) == 0); + return p_concat; } + +#ifdef TEST_PATH_CONCAT +#include +#include +int +main () +{ + static char const *const tests[][3] = +{ + {"a", "b", "a/b"}, + {"a/", "b", "a/b"}, + {"a/", "/b", "a/b"}, + {"a", "/b", "a/b"}, + + {"/", "b", "/b"}, + {"/", "/b", "/b"}, + {"/", "/", "/"}, + {"a", "/", "a/"}, /* this might deserve a diagnostic */ + {"/a", "/", "/a/"}, /* this might deserve a diagnostic */ +}; + size_t i; + bool fail = false; + for (i = 0; i < sizeof tests / sizeof tests[0]; i++) +{ + char *base_in_result; + char const *const *t = tests[i]; + char *res = path_concat (t[0], t[1], &base_in_result); + if (strcmp (res, t[2]) != 0) + { + printf ("got %s, expected %s\n", res, t[2]); + fail = true; + } +} + exit (fail ? EXIT_FAILURE : EXIT_SUCCESS); +} +#endif ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: coreutils 5.3.0: cp --parents broken
Jim Meyering <[EMAIL PROTECTED]> writes: > Andreas Schwab <[EMAIL PROTECTED]> wrote: >> $ ./cp --parents /bin/cp /tmp >> ./cp: failed to get attributes of `bin': No such file or directory > > Thanks for the report. > I can't reproduce that: Please make sure that /tmp/bin does not exist. > Does your /bin have unusual permissions or attributes (a la lsattr or ACLs)? Just the normal 755. > For example, what does > > strace -o log ./cp --parents /bin/cp /tmp > > put into the `log' file? It's attached. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." execve("./cp", ["./cp", "--parents", "/bin/cp", "/tmp"], [/* 110 vars */]) = 0 uname({sys="Linux", node="sykes", ...}) = 0 brk(0) = 0x6000c000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=143092, ...}) = 0 mmap(NULL, 143092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x20044000 close(3)= 0 open("/lib/tls/libc.so.6.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0002\0\1\0\0\0\240\232"..., 640) = 640 fstat(3, {st_mode=S_IFREG|0755, st_size=2420535, ...}) = 0 mmap(NULL, 2253856, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x20068000 madvise(0x20068000, 2253856, MADV_SEQUENTIAL|0x1) = 0 mmap(0x20278000, 81920, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x20) = 0x20278000 mmap(0x2028c000, 9248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2028c000 close(3)= 0 mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2029 munmap(0x20044000, 143092) = 0 brk(0) = 0x6000c000 brk(0x6003) = 0x6003 open("/usr/lib/locale/locale-archive", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/locale.alias", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=2528, ...}) = 0 mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x20044000 read(3, "# Locale name alias data base.\n#"..., 16384) = 2528 read(3, "", 16384) = 0 close(3)= 0 munmap(0x20044000, 65536) = 0 open("/usr/lib/locale/de_DE.UTF-8/LC_IDENTIFICATION", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/de_DE.utf8/LC_IDENTIFICATION", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=375, ...}) = 0 mmap(NULL, 375, PROT_READ, MAP_PRIVATE, 3, 0) = 0x20044000 close(3)= 0 open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=21544, ...}) = 0 mmap(NULL, 21544, PROT_READ, MAP_SHARED, 3, 0) = 0x2030 close(3)= 0 open("/usr/lib/locale/de_DE.UTF-8/LC_MEASUREMENT", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/de_DE.utf8/LC_MEASUREMENT", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=23, ...}) = 0 mmap(NULL, 23, PROT_READ, MAP_PRIVATE, 3, 0) = 0x20308000 close(3)= 0 open("/usr/lib/locale/de_DE.UTF-8/LC_TELEPHONE", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/de_DE.utf8/LC_TELEPHONE", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=56, ...}) = 0 mmap(NULL, 56, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2030c000 close(3)= 0 open("/usr/lib/locale/de_DE.UTF-8/LC_ADDRESS", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/de_DE.utf8/LC_ADDRESS", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=159, ...}) = 0 mmap(NULL, 159, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2031 close(3)= 0 open("/usr/lib/locale/de_DE.UTF-8/LC_NAME", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/de_DE.utf8/LC_NAME", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=83, ...}) = 0 mmap(NULL, 83, PROT_READ, MAP_PRIVATE, 3, 0) = 0x20314000 close(3)= 0 open("/usr/lib/locale/de_DE.UTF-8/LC_PAPER", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/de_DE.utf8/LC_PAPER", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=34, ...}) = 0 mmap(NULL, 34, PROT_READ, MAP_PRIVATE, 3, 0) = 0x20318000 close(3)= 0 open("/usr/lib/locale/en_US.UTF-8/LC_MESSAGES", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/en_US.utf8/LC_MESSAGES", O_RDONLY) = 3 fstat(3, {st_mode=S_IFDIR|0755, st_size=80,
Re: coreutils 5.3.0: cp --parents broken
Andreas Schwab <[EMAIL PROTECTED]> wrote: > $ ./cp --parents /bin/cp /tmp > ./cp: failed to get attributes of `bin': No such file or directory Thanks for the report. I can't reproduce that: $ ./cp --parents /bin/cp /tmp $ find /tmp/bin /tmp/bin /tmp/bin/cp $ Would you please investigate it? Does your /bin have unusual permissions or attributes (a la lsattr or ACLs)? For example, what does strace -o log ./cp --parents /bin/cp /tmp put into the `log' file? ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
coreutils 5.3.0: cp --parents broken
$ ./cp --parents /bin/cp /tmp ./cp: failed to get attributes of `bin': No such file or directory Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils