From 417e86ae7ad3fb15692d200b239b05a8e0e1f126 Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Thu, 3 Nov 2011 17:57:01 +0100 Subject: [PATCH] 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. --- tests/t1300-ls.sh | 34 ++++++++++++++++++++++++++++++++++ todo.sh | 15 ++++++++++----- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/tests/t1300-ls.sh b/tests/t1300-ls.sh index 7a18fde..1112047 100755 --- a/tests/t1300-ls.sh +++ b/tests/t1300-ls.sh @@ -94,6 +94,40 @@ TODO: 1 of 3 tasks shown TODO: 1 of 3 tasks shown 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 # diff --git a/todo.sh b/todo.sh index 92e4c01..c2fa85c 100755 --- a/todo.sh +++ b/todo.sh @@ -663,6 +663,11 @@ _addto() { fi } +shellquote() +{ + typeset -r qq=\'; printf %s\\n "'${1//\'/${qq}\\${qq}${qq}}'"; +} + filtercommand() { filter=${1:-} @@ -677,13 +682,13 @@ filtercommand() then ## First character isn't a dash: hide lines that don't match ## this $search_term - filter="${filter:-}${filter:+ | }grep -i \"$search_term\"" + filter="${filter:-}${filter:+ | }grep -i $(shellquote "$search_term")" else ## First character is a dash: hide lines that match this ## $search_term # ## 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 done @@ -736,7 +741,7 @@ _list() { | grep -v "^[ 0-9]\+ *$" ) if [ "${filter_command}" ]; then - filtered_items=$(echo -n "$items" | eval ${filter_command}) + filtered_items=$(echo -n "$items" | eval "${filter_command}") else filtered_items=$items fi @@ -790,7 +795,7 @@ _list() { fi } -export -f cleaninput filtercommand _list die +export -f cleaninput shellquote filtercommand _list die # == HANDLE ACTION == action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' ) @@ -1056,7 +1061,7 @@ case $action in "listproj" | "lsprj" ) shift - eval $(filtercommand 'cat "$TODO_FILE"' '' "$@") | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u + eval "$(filtercommand 'cat "$TODO_FILE"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u ;; "listpri" | "lsp" )