diff --git a/git-proxy/parseargs.sh b/git-proxy/parseargs.sh new file mode 100644 index 0000000..60f1d20 --- /dev/null +++ b/git-proxy/parseargs.sh @@ -0,0 +1,71 @@ +set -u +set -e + +# ParseArgs will parse a string that contains quoted strings the same as bash does +# (same as most other *nix shells do). This is secure in the sense that it doesn't do any +# executing or interpeting. However, it also doesn't do any escaping, so you shouldn't pass +# these strings to shells without escaping them. +parseargs() { + notquote="-" + str=$1 + declare -a m=() + s="" + + # Strip leading space, then trailing space, then add a terminating space. + str="${str## }" + str="${str%% }" + str+=" " + + last_quote="${notquote}" + is_space="" + n=$(( ${#str} - 1 )) + i=-1 + for ((i=0;i<=$n;i+=1)); do + c="${str:$i:1}" + + # If we're ending a quote, break out and skip this character + if [ "$c" == "$last_quote" ]; then + last_quote=$notquote + continue + fi + + # If we're in a quote, count this character + if [ "$last_quote" != "$notquote" ]; then + s+=$c + continue + fi + + # If we encounter a quote, enter it and skip this character + if [ "$c" == "'" ] || [ "$c" == '"' ]; then + is_space="" + last_quote=$c + continue + fi + + # If it's a space, store the string + re="[[:space:]]+" # must be used as a var, not a literal + if [[ $c =~ $re ]]; then + if [ "0" == "$i" ] || [ -n "$is_space" ]; then + echo continue $i $is_space + continue + fi + is_space="true" + m+=("$s") + s="" + continue + fi + + is_space="" + s+="$c" + done + + if [ "$last_quote" != "$notquote" ]; then + >&2 echo "error" + return 1 + fi + + for arg in "${m[@]}"; do + echo "$arg" + done + return 0 +} diff --git a/git-proxy/parseargs_test.sh b/git-proxy/parseargs_test.sh new file mode 100644 index 0000000..7802b2c --- /dev/null +++ b/git-proxy/parseargs_test.sh @@ -0,0 +1,8 @@ +# usage +source ./parseargs.sh +export -f parseargs +IFS=$'\r\n' GLOBIGNORE='*' args=($(parseargs "foo 'bar baz' qux *")) +echo '$@': "${args[@]}" +for arg in "${args[@]}"; do + echo "$arg" +done