Source-Changes-HG archive

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

[src/trunk]: src Allow quoting of embedded shell metacharacters in locate.con...



details:   https://anonhg.NetBSD.org/src/rev/e35aee5db44d
branches:  trunk
changeset: 767178:e35aee5db44d
user:      apb <apb%NetBSD.org@localhost>
date:      Sun Jul 10 13:42:49 2011 +0000

description:
Allow quoting of embedded shell metacharacters in locate.conf(5).

The shell_quote function here is identical to that in postinstall
and etcupdate.

This should fix PR 45130 from Greg Woods.

diffstat:

 share/man/man5/locate.conf.5      |   9 ++-
 usr.bin/locate/locate/updatedb.sh |  92 ++++++++++++++++++++++++++------------
 2 files changed, 68 insertions(+), 33 deletions(-)

diffs (185 lines):

diff -r 854adfcda27c -r e35aee5db44d share/man/man5/locate.conf.5
--- a/share/man/man5/locate.conf.5      Sun Jul 10 12:14:01 2011 +0000
+++ b/share/man/man5/locate.conf.5      Sun Jul 10 13:42:49 2011 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: locate.conf.5,v 1.8 2011/02/21 02:31:57 itohy Exp $
+.\"    $NetBSD: locate.conf.5,v 1.9 2011/07/10 13:42:49 apb Exp $
 .\"
 .\" Copyright (c) 2004 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 1, 2005
+.Dd July 10, 2011
 .Dt LOCATE.CONF 5
 .Os
 .Sh NAME
@@ -47,12 +47,15 @@
 file contains a list of newline separated records,
 each of which is composed of a keyword and arguments,
 which are separated by white space.
+Arguments with embedded shell metacharacters must be quoted in
+.Xr sh 1
+style.
 Lines beginning with
 .Dq #
 are treated as comments and ignored.
 However, a
 .Dq #
-in the middle of a line does not start comment.
+in the middle of a line does not start a comment.
 .Pp
 The configuration options are as follows:
 .Bl -tag -width XXXXXX
diff -r 854adfcda27c -r e35aee5db44d usr.bin/locate/locate/updatedb.sh
--- a/usr.bin/locate/locate/updatedb.sh Sun Jul 10 12:14:01 2011 +0000
+++ b/usr.bin/locate/locate/updatedb.sh Sun Jul 10 13:42:49 2011 +0000
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-#      $NetBSD: updatedb.sh,v 1.11 2006/04/23 03:04:08 christos Exp $
+#      $NetBSD: updatedb.sh,v 1.12 2011/07/10 13:42:49 apb Exp $
 #
 # Copyright (c) 1989, 1993
 #      The Regents of the University of California.  All rights reserved.
@@ -51,47 +51,78 @@
 ignore=
 SRCHPATHS=
 
+# Quote args to make them safe in the shell.
+# Usage: quotedlist="$(shell_quote args...)"
+#
+# After building up a quoted list, use it by evaling it inside
+# double quotes, like this:
+#    eval "set -- $quotedlist"
+# or like this:
+#    eval "\$command $quotedlist \$filename"
+#
+shell_quote()
+{
+       local result=''
+       local arg
+       for arg in "$@" ; do
+               # Append a space if necessary
+               result="${result}${result:+ }"
+               # Convert each embedded ' to '\'',
+               # then insert ' at the beginning of the first line,
+               # and append ' at the end of the last line.
+               result="${result}$(printf "%s\n" "$arg" | \
+                       sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/")"
+       done
+       printf "%s\n" "$result"
+}
+
 # read configuration file
 if [ -f "$CONF" ]; then
-       exec 5<&0 < "$CONF"
-       while read com args; do
-               case "$com/$args" in /) continue;; esac # skip blank lines
+       while read -r com args; do
                case "$com" in
-               '#'*)   ;;                      # lines start with # is comment
+               ''|'#'*)
+                       continue ;;     # skip blank lines and comment lines
+               esac
+               eval "set -- $args"
+               case "$com" in
                searchpath)
-                       SRCHPATHS="$SRCHPATHS $args";;
+                       SRCHPATHS="${SRCHPATHS}${SRCHPATHS:+ }$(shell_quote "$@")";;
                ignorefs)
-                       for i in $args; do
+                       for i in "$@"; do
+                               fs=
                                case "$i" in
                                none)   ignorefs=;;
-                               *)      fs=`echo "$i" | sed -e 's/^!/! -fstype /' -e t -e 's/^/-fstype /'`
-                                       ignorefs="${ignorefs:+${ignorefs} -o }${fs}"
+                               \!*)    fs="! -fstype $(shell_quote "$i")";;
+                               *)      fs="-fstype $(shell_quote "${i#?}")";;
+                               esac
+                               case "$fs" in
+                               '')     ;;
+                               *)      ignorefs="${ignorefs:+${ignorefs} -o }${fs}";;
                                esac
                        done;;
                ignore)
-                       set -f
-                       for i in $args; do
-                               ignore="${ignore:+${ignore} -o }-path ${i}"
-                       done
-                       set +f;;
+                       for i in "$@"; do
+                               q="$(shell_quote "$i")"
+                               ignore="${ignore:+${ignore} -o }-path ${q}"
+                       done;;
                ignorecontents)
-                       set -f
-                       for i in $args; do
-                               ignore="${ignore:+${ignore} -o }-path ${i} -print"
-                       done
-                       set +f;;
+                       for i in "$@"; do
+                               q="$(shell_quote "$i")"
+                               ignore="${ignore:+${ignore} -o }-path ${q} -print"
+                       done;;
                workdir)
-                       if [ -d "$args" ]; then
-                               TMPDIR="$args"
+                       if [ $# -ne 1 ]; then
+                               echo "$CONF: workdir takes exactly one argument" >&2
+                       elif [ -d "$1" ]; then
+                               TMPDIR="$1"
                        else
-                               echo "$CONF: workdir: $args nonexistent" >&2
+                               echo "$CONF: workdir: $1 nonexistent" >&2
                        fi;;
                *)
-                       echo "$CONF: $com: unknown config command"      >&2
+                       echo "$CONF: $com: unknown config command" >&2
                        exit 1;;
                esac
-       done
-       exec <&5 5>&-
+       done < "$CONF"
 fi
 
 : ${SRCHPATHS:=/}                      # directories to be put in the database
@@ -99,7 +130,7 @@
 
 case "$ignorefs/$ignore" in
 /)     lp= ;   rp= ;;
-*)     lp='('; rp=') -prune -o' ;;
+*)     lp='\('; rp='\) -prune -o' ;;
 esac
 
 # insert '-o' if neither $ignorefs or $ignore are empty
@@ -109,14 +140,14 @@
 esac
 
 FILELIST=$(mktemp -t locate.list) || exit 1
-trap "rm -f '$FILELIST'" EXIT
-trap "rm -f '$FILELIST'; exit 1" INT QUIT TERM
+trap 'rm -f "$FILELIST"' EXIT
+trap 'rm -f "$FILELIST"; exit 1' INT QUIT TERM
 
 # Make a file list and compute common bigrams.
 # Entries of each directory shall be sorted (find -s).
 
-set -f
-(find -s ${SRCHPATHS} $lp $ignorefs $ignore $rp -print; true) | cat  >> "$FILELIST"
+(eval "find -s ${SRCHPATHS} $lp $ignorefs $ignore $rp -print"; true) \
+       | cat >> "$FILELIST"
 if [ $? != 0 ]
 then
        exit 1
@@ -127,6 +158,7 @@
 # code the file list
 if [ -z "$BIGRAMS" ]; then
        echo 'locate: updatedb failed' >&2
+       exit 1
 else
        $LIBDIR/locate.code "$BIGRAMS" <"$FILELIST" >"$FCODES"
        chmod 644 "$FCODES"



Home | Main Index | Thread Index | Old Index