diff options
author | Eric Blake <ebb9@byu.net> | 2007-08-05 12:22:14 +0000 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2007-08-05 12:22:14 +0000 |
commit | 4859cfca404f2e51b53f5696b70f7b845a69af69 (patch) | |
tree | 4bb3b69c0371902f66fb0fbdf89f631a8276caf4 | |
parent | 756cecd45b0545ad52345507592cfa3c9f97a0ad (diff) | |
download | findutils-4859cfca404f2e51b53f5696b70f7b845a69af69.tar.gz |
Fix Savannah bugs #20662, 20688.
* find/find.c (at_top): Avoid memory leak.
* find/pred.c (do_fprintf, pred_iname, pred_name): Likewise.
(pred_name_common): New function, factored from pred_iname and
pred_name.
* find/parser.c (check_name_arg): Let -nowarn silence -name /.
* locate/locate.c (visit_basename): Avoid memory leak.
* NEWS: Document the changes.
* doc/find.texi (Warning Messages): Document -nowarn's effect on
-name and -iname.
* find/testsuite/find.gnu/name-slash.exp: New test, to ensure
20662 doesn't regress on '-name /', and that 20688 silences the
warning.
* find/testsuite/find.gnu/printf-slash.exp: Likewise.
* find/testsuite/find.gnu/name-slash.xo: Expected results.
* find/testsuite/find.gnu/printf-slash.xo: Likewise.
* find/testsuite/Makefile.am (EXTRA_DIST_XO, EXTRA_DIST_EXP):
Distribute new tests.
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | doc/find.texi | 9 | ||||
-rw-r--r-- | find/find.c | 10 | ||||
-rw-r--r-- | find/parser.c | 4 | ||||
-rw-r--r-- | find/pred.c | 53 | ||||
-rw-r--r-- | find/testsuite/Makefile.am | 4 | ||||
-rw-r--r-- | find/testsuite/find.gnu/name-slash.exp | 2 | ||||
-rw-r--r-- | find/testsuite/find.gnu/name-slash.xo | 2 | ||||
-rw-r--r-- | find/testsuite/find.gnu/printf-slash.exp | 1 | ||||
-rw-r--r-- | find/testsuite/find.gnu/printf-slash.xo | 2 | ||||
-rw-r--r-- | locate/locate.c | 5 |
12 files changed, 88 insertions, 32 deletions
@@ -1,3 +1,24 @@ +2007-08-05 Eric Blake <ebb9@byu.net> + + Fix Savannah bugs #20662, #20688. + * find/find.c (at_top): Avoid memory leak. + * find/pred.c (do_fprintf, pred_iname, pred_name): Likewise. + (pred_name_common): New function, factored from pred_iname and + pred_name. + * find/parser.c (check_name_arg): Let -nowarn silence -name /. + * locate/locate.c (visit_basename): Avoid memory leak. + * NEWS: Document the changes. + * doc/find.texi (Warning Messages): Document -nowarn's effect on + -name and -iname. + * find/testsuite/find.gnu/name-slash.exp: New test, to ensure + 20662 doesn't regress on '-name /', and that 20688 silences the + warning. + * find/testsuite/find.gnu/printf-slash.exp: Likewise. + * find/testsuite/find.gnu/name-slash.xo: Expected results. + * find/testsuite/find.gnu/printf-slash.xo: Likewise. + * find/testsuite/Makefile.am (EXTRA_DIST_XO, EXTRA_DIST_EXP): + Distribute new tests. + 2007-07-31 Eric Blake <ebb9@byu.net> Allow choice of default arg size, Savannah bug #20594. @@ -27,11 +27,18 @@ does not follow the POSIX rules of doing likewise. updatedb, frcode and code now complies with the GNU Project's coding standards. +#20662: Avoid memory leak in find -name and other places affected by +gnulib dirname module. The leak had been present since 4.3.1. + ** Enhancements #20594: Allow fine-tuning of the default argument size used by xargs and find at ./configure time. +#20688: The warning printed by -name or -iname when the pattern to + match contains a slash can now be silenced by -nowarn. This warning + was originally introduced unconditionally in 4.2.21. + ** Documentation Fixes Point out more explicitly that the subsecond timestamp support diff --git a/doc/find.texi b/doc/find.texi index d6e9c64b..3c3e11b9 100644 --- a/doc/find.texi +++ b/doc/find.texi @@ -31,8 +31,8 @@ This file documents the GNU utilities for finding files that match certain criteria and performing various operations on them. -Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003, 2004, 2005 Free -Software Foundation, Inc. +Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003, 2004, 2005, 2006, +2007 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -2972,6 +2972,11 @@ Use of the @samp{-ipath} option which is deprecated; please use @item Specifying an option (for example @samp{-mindepth}) after a non-option (for example @samp{-type} or @samp{-print}) on the command line. +@item +Use of the @samp{-name} or @samp{-iname} option with a slash character +in the pattern. Since the name predicates only compare against the +basename of the visited files, the only file that can match a slash is +the root directory itself. @end itemize The default behaviour above is designed to work in that way so that diff --git a/find/find.c b/find/find.c index 8dcf0012..72f555ae 100644 --- a/find/find.c +++ b/find/find.c @@ -1,6 +1,6 @@ /* find -- search for files in a directory hierarchy Copyright (C) 1990, 91, 92, 93, 94, 2000, - 2003, 2004, 2005 Free Software Foundation, Inc. + 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -947,13 +947,13 @@ at_top (char *pathname, struct stat *pstat)) { int dirchange; - char *parent_dir = dir_name(pathname); - char *base = base_name(pathname); - + char *parent_dir = dir_name (pathname); + char *base = last_component (pathname); + state.curdepth = 0; state.starting_path_length = strlen (pathname); - if (0 == strcmp(pathname, parent_dir) + if (0 == *base || 0 == strcmp(parent_dir, ".")) { dirchange = 0; diff --git a/find/parser.c b/find/parser.c index 6c078aa1..2a5b19e2 100644 --- a/find/parser.c +++ b/find/parser.c @@ -1124,10 +1124,10 @@ fnmatch_sanitycheck(void) } -static boolean +static boolean check_name_arg(const char *pred, const char *arg) { - if (strchr(arg, '/')) + if (options.warnings && strchr(arg, '/')) { error(0, 0,_("warning: Unix filenames usually don't contain slashes (though pathnames do). That means that '%s %s' will probably evaluate to false all the time on this system. You might find the '-wholename' test more useful, or perhaps '-samefile'. Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ %s'."), pred, diff --git a/find/pred.c b/find/pred.c index 5e3adb70..730a8765 100644 --- a/find/pred.c +++ b/find/pred.c @@ -741,7 +741,11 @@ do_fprintf(struct format_val *dest, break; case 'f': /* base name of path */ /* sanitised */ - checked_print_quoted (dest, segment->text, base_name (pathname)); + { + char *base = base_name (pathname); + checked_print_quoted (dest, segment->text, base); + free (base); + } break; case 'F': /* file system type */ /* trusted */ @@ -1150,20 +1154,38 @@ pred_ilname (const char *pathname, struct stat *stat_buf, struct predicate *pred return match_lname (pathname, stat_buf, pred_ptr, true); } -boolean -pred_iname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) +/* Common code between -name, -iname. PATHNAME is being visited, STR + is name to compare basename against, and FLAGS are passed to + fnmatch. */ +static boolean +pred_name_common (const char *pathname, const char *str, int flags) { - const char *base; - - (void) stat_buf; + /* Prefer last_component over base_name, to avoid malloc when + possible. */ + char *base = last_component (pathname); + /* base is empty only if pathname is a file system root. But recall + that 'find / -name /' is one of the few times where a '/' in the + -name must actually find something. */ + if (!*base) + { + boolean b; + base = base_name (pathname); + b = fnmatch (str, base, flags) == 0; + free (base); + return b; + } /* FNM_PERIOD is not used here because POSIX requires that it not be. * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html */ - base = base_name (pathname); - if (fnmatch (pred_ptr->args.str, base, FNM_CASEFOLD) == 0) - return (true); - return (false); + return fnmatch (str, base, flags) == 0; +} + +boolean +pred_iname (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) +{ + (void) stat_buf; + return pred_name_common (pathname, pred_ptr->args.str, FNM_CASEFOLD); } boolean @@ -1271,17 +1293,8 @@ pred_mtime (const char *pathname, struct stat *stat_buf, struct predicate *pred_ boolean pred_name (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) { - const char *base; - (void) stat_buf; - base = base_name (pathname); - - /* FNM_PERIOD is not used here because POSIX requires that it not be. - * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html - */ - if (fnmatch (pred_ptr->args.str, base, 0) == 0) - return (true); - return (false); + return pred_name_common (pathname, pred_ptr->args.str, 0); } boolean diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am index 02d4c751..c1033d43 100644 --- a/find/testsuite/Makefile.am +++ b/find/testsuite/Makefile.am @@ -37,6 +37,7 @@ find.gnu/lname.xo \ find.gnu/mindepth-arg.xo \ find.gnu/name-opt.xo \ find.gnu/name-period.xo \ +find.gnu/name-slash.xo \ find.gnu/path.xo \ find.gnu/print_stdout.xo \ find.gnu/perm.xo \ @@ -46,6 +47,7 @@ find.gnu/posix-dflt.xo \ find.gnu/posix-h.xo \ find.gnu/posix-l.xo \ find.gnu/printfHdfl.xo \ +find.gnu/printf-slash.xo \ find.gnu/printf-symlink.xo \ find.gnu/printf-h.xo \ find.gnu/printf.xo \ @@ -133,6 +135,7 @@ find.gnu/mindepth-arg.exp \ find.gnu/mindepth-badarg.exp \ find.gnu/name-opt.exp \ find.gnu/name-period.exp \ +find.gnu/name-slash.exp \ find.gnu/path.exp \ find.gnu/print_stdout.exp \ find.gnu/print0.exp \ @@ -145,6 +148,7 @@ find.gnu/posix-l.exp \ find.gnu/printfHdfl.exp \ find.gnu/printf.exp \ find.gnu/printf.exp \ +find.gnu/printf-slash.exp \ find.gnu/printf-symlink.exp \ find.gnu/printf-h.exp \ find.gnu/prune-default-print.exp \ diff --git a/find/testsuite/find.gnu/name-slash.exp b/find/testsuite/find.gnu/name-slash.exp new file mode 100644 index 00000000..bd9a187b --- /dev/null +++ b/find/testsuite/find.gnu/name-slash.exp @@ -0,0 +1,2 @@ +# tests for '-name /' +find_start p {/ /// -maxdepth 0 -name /} diff --git a/find/testsuite/find.gnu/name-slash.xo b/find/testsuite/find.gnu/name-slash.xo new file mode 100644 index 00000000..6c241446 --- /dev/null +++ b/find/testsuite/find.gnu/name-slash.xo @@ -0,0 +1,2 @@ +/ +/// diff --git a/find/testsuite/find.gnu/printf-slash.exp b/find/testsuite/find.gnu/printf-slash.exp new file mode 100644 index 00000000..3f460238 --- /dev/null +++ b/find/testsuite/find.gnu/printf-slash.exp @@ -0,0 +1 @@ +find_start p {/ /// -maxdepth 0 -printf "%p %f\\n"} diff --git a/find/testsuite/find.gnu/printf-slash.xo b/find/testsuite/find.gnu/printf-slash.xo new file mode 100644 index 00000000..50f8192f --- /dev/null +++ b/find/testsuite/find.gnu/printf-slash.xo @@ -0,0 +1,2 @@ +/ / +/// / diff --git a/locate/locate.c b/locate/locate.c index b02f227d..1595075a 100644 --- a/locate/locate.c +++ b/locate/locate.c @@ -337,7 +337,7 @@ struct process_data int len; char *original_filename; /* The current input database entry. */ size_t pathsize; /* Amount allocated for it. */ - char *munged_filename; /* path or base_name(path) */ + char *munged_filename; /* path or basename(path) */ FILE *fp; /* The pathname database. */ const char *dbfile; /* Its name, or "<stdin>" */ int slocatedb_format; /* Allows us to cope with slocate's format variant */ @@ -641,7 +641,7 @@ static int visit_basename(struct process_data *procdata, void *context) { (void) context; - procdata->munged_filename = base_name(procdata->original_filename); + procdata->munged_filename = last_component (procdata->original_filename); return VISIT_CONTINUE; } @@ -1929,4 +1929,3 @@ main (int argc, char **argv) return dolocate(argc, argv, dbfd); } - |