diff options
author | James Davidson <james.davidson@vyatta.com> | 2012-08-13 10:23:40 -0700 |
---|---|---|
committer | James Davidson <james.davidson@vyatta.com> | 2012-08-16 09:41:13 -0700 |
commit | aab0c46891649f9dc3c4be2d01c74e330c4f6917 (patch) | |
tree | d7f8100833c50a4c3e7d56df101ae5a4d23566c3 /functions/interpreter | |
parent | 5195f8e195e61a1317e0239029c807ddde0c056b (diff) | |
download | vyatta-op-aab0c46891649f9dc3c4be2d01c74e330c4f6917.tar.gz vyatta-op-aab0c46891649f9dc3c4be2d01c74e330c4f6917.zip |
Fix handling of single quote character (') when parsing command
The previous parsing logic worked on word boundries but did not handle
multiple single quote characters in the same word. This lead to the
misinterpretation of whether subsequent words being parsed were quoted
or not.
The new parsing code breaks the command line up into substrings at
single quote boundries so the relative location of sigle quote characters
is irrelevant.
Fixes bug 8210
Diffstat (limited to 'functions/interpreter')
-rw-r--r-- | functions/interpreter/vyatta-op-run | 70 |
1 files changed, 34 insertions, 36 deletions
diff --git a/functions/interpreter/vyatta-op-run b/functions/interpreter/vyatta-op-run index da16ae4..b0f72ae 100644 --- a/functions/interpreter/vyatta-op-run +++ b/functions/interpreter/vyatta-op-run @@ -106,53 +106,51 @@ _vyatta_op_conv_run_cmd () local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; ) shopt -s extglob shopt -u nullglob - local run_cmd - run_cmd=$1 + local run_cmd="$1" + local line outline + local -i inquote=0; + local outcmd=''; + local OIFS=$IFS + local re="([^']*')(.*)" + + toggle_inquote() + { + if [[ $inquote == 0 ]]; then + inquote=1 + else + inquote=0 + fi + } + + process_subline() + { + if [[ $inquote == 1 ]]; then + outline+="$1" + else + outline+=$(sed -e 's/\$\([0-9]\)/\$\{args\[\1\]\}/g' <<<"$1") + fi + } + run_cmd="${run_cmd/\"\$\@\"/${args[*]}}" run_cmd="${run_cmd/\$\*/${args[*]}}" run_cmd="${run_cmd//\\/\\\\}" - inquote=0; - outcmd=''; - OIFS=$IFS IFS=$'\n' - regex="'[^']+'" for line in ${run_cmd[@]}; do outline='' - if [[ "$line" =~ $regex ]]; then - IFS=$OIFS - for word in $line; do - if [[ $word =~ "'" ]]; then - if [[ $inquote == 0 ]]; then - inquote=1 - else - inquote=0 - outline+="$word " - continue - fi - fi - if [[ $inquote == 0 ]] && - [[ "$word" =~ \$[0-9] ]]; then - word=$( sed -e 's/\$\([0-9]\)/\$\{args\[\1\]\}/g' <<<"$word" ) - fi - if [[ "$word" != '\\' ]]; then - outline+="$word " + while [[ -n "$line" ]]; do + if [[ "$line" =~ $re ]]; then + process_subline "${BASH_REMATCH[1]}" + toggle_inquote else - outline+="$word" + process_subline "$line" fi - done - IFS=$'\n' - line=$outline - else - if [[ "$line" =~ \$[0-9] ]]; then - line=$( sed -e 's/\$\([0-9]\)/\$\{args\[\1\]\}/g' <<<"$line" ) - fi - fi - outcmd+="$line\n" + line="${BASH_REMATCH[2]}" + done + outcmd+="$outline\n" done - run_cmd=$outcmd IFS=$OIFS eval "$restore_shopts" - echo -ne "$run_cmd" + echo -ne "$outcmd" } _vyatta_op_run () |