FIX: Handle special shell characters when filtering TERM.

The double quotes used in the filter_command erroneously expand $VARIABLE, and due to missing quoting in the eval() of filter_command, multiple spaces are condensed into a single space.
Introduce a new function shellquote() to correctly quote each filter TERM.
This commit is contained in:
Ingo Karkat
2011-11-03 17:57:01 +01:00
parent d804a78fa1
commit a0f39480bf
2 changed files with 44 additions and 5 deletions

View File

@@ -94,6 +94,40 @@ TODO: 1 of 3 tasks shown
TODO: 1 of 3 tasks shown TODO: 1 of 3 tasks shown
EOF EOF
#
# check the filtering of TERM containing characters that are special to the
# shell, like variables, quotes, and multiple subsequent spaces.
#
cat > todo.txt <<'EOF'
earn some pennies
earn some $$
earn some "money"
get money from O'Brian
just get money!
EOF
test_todo_session 'checking filtering of special characters' <<'EOF'
>>> todo.sh ls '$$'
2 earn some $$
--
TODO: 1 of 5 tasks shown
>>> todo.sh ls '"money"'
3 earn some "money"
--
TODO: 1 of 5 tasks shown
>>> todo.sh ls "O'Brian"
4 get money from O'Brian
--
TODO: 1 of 5 tasks shown
>>> todo.sh ls "get money"
5 just get money!
--
TODO: 1 of 5 tasks shown
EOF
# #
# check the x command line option # check the x command line option
# #

15
todo.sh
View File

@@ -633,6 +633,11 @@ _addto() {
fi fi
} }
shellquote()
{
typeset -r qq=\'; printf %s\\n "'${1//\'/${qq}\\${qq}${qq}}'";
}
filtercommand() filtercommand()
{ {
filter=${1:-} filter=${1:-}
@@ -647,13 +652,13 @@ filtercommand()
then then
## First character isn't a dash: hide lines that don't match ## First character isn't a dash: hide lines that don't match
## this $search_term ## this $search_term
filter="${filter:-}${filter:+ | }grep -i \"$search_term\"" filter="${filter:-}${filter:+ | }grep -i $(shellquote "$search_term")"
else else
## First character is a dash: hide lines that match this ## First character is a dash: hide lines that match this
## $search_term ## $search_term
# #
## Remove the first character (-) before adding to our filter command ## Remove the first character (-) before adding to our filter command
filter="${filter:-}${filter:+ | }grep -v -i \"${search_term:1}\"" filter="${filter:-}${filter:+ | }grep -v -i '$(shellquote "${search_term:1}")'"
fi fi
done done
@@ -706,7 +711,7 @@ _list() {
| grep -v "^[ 0-9]\+ *$" | grep -v "^[ 0-9]\+ *$"
) )
if [ "${filter_command}" ]; then if [ "${filter_command}" ]; then
filtered_items=$(echo -n "$items" | eval ${filter_command}) filtered_items=$(echo -n "$items" | eval "${filter_command}")
else else
filtered_items=$items filtered_items=$items
fi fi
@@ -759,7 +764,7 @@ _list() {
fi fi
} }
export -f cleaninput filtercommand _list die export -f cleaninput shellquote filtercommand _list die
# == HANDLE ACTION == # == HANDLE ACTION ==
action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' ) action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
@@ -1015,7 +1020,7 @@ case $action in
"listproj" | "lsprj" ) "listproj" | "lsprj" )
shift shift
eval $(filtercommand 'cat "$TODO_FILE"' '' "$@") | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u eval "$(filtercommand 'cat "$TODO_FILE"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u
;; ;;
"listpri" | "lsp" ) "listpri" | "lsp" )