Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 85 additions & 15 deletions pkgs/by-name/ma/makeBinaryWrapper/make-binary-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,8 @@ makeCWrapper() {
addFlags() {
local n flag before after var

# Disable file globbing, since bash will otherwise try to find
# filenames matching the the value to be prefixed/suffixed if
# it contains characters considered wildcards, such as `?` and
# `*`. We want the value as is, except we also want to split
# it on on the separator; hence we can't quote it.
local reenableGlob=0
if [[ ! -o noglob ]]; then
reenableGlob=1
fi
set -o noglob
# shellcheck disable=SC2086
before=($1) after=($2)
if (( reenableGlob )); then
set +o noglob
fi
escapedArgsFromString before "$1"
escapedArgsFromString after "$2"

var="argv_tmp"
printf '%s\n' "char **$var = calloc(${#before[@]} + argc + ${#after[@]} + 1, sizeof(*$var));"
Expand All @@ -240,6 +227,89 @@ addFlags() {
printf '%s\n' "argv = $var;"
}

# escapedArgsFromString ARRAYNAME "$INPUT"
# escapedArgsFromString ARRAYNAME <<< "$INPUT"
escapedArgsFromString() {
local outvarname="$1"
local input="${2:-$(cat)}"
local char='' token='' escape=0 quote=''

local out=()

while IFS= read -r -n1 char || [[ -n "$char" ]]; do
# it gives empty char when you get a newline
[[ -z "$char" ]] && char=$'\n'

if (( escape )); then
token+="$char"
escape=0
continue
fi

case "$char" in
# in an argument list, \ within ' are ignored, but \ within " are not
\\)
if [[ $quote == "'" ]]; then
token+="$char"
else
escape=1
fi
;;

"'")
if [[ $quote == '' ]]; then
quote="'"
elif [[ $quote == "'" ]]; then
quote=''
else
token+="$char"
fi
;;

'"')
if [[ $quote == '' ]]; then
quote='"'
elif [[ $quote == '"' ]]; then
quote=''
else
token+="$char"
fi
;;

[[:space:]])
if [[ -n $quote ]]; then
token+="$char"
elif [[ -n $token ]]; then
out+=("$token")
token=''
fi
;;

$'\n')
if [[ -n $quote ]]; then
token+="$char"
elif [[ -n $token ]]; then
out+=("$token")
token=''
fi
;;

*)
token+="$char"
;;
esac
done <<< "$input"

# Add final token if needed
[[ -n $token ]] && out+=("$token")

# set variable name given to the new array
eval "$outvarname=()"
for (( i=0; i<${#out[@]}; i++ )); do
eval "$(printf "$outvarname+=(%q)" "${out[i]}")"
done
}

# chdir DIR
changeDir() {
local dir
Expand Down
31 changes: 26 additions & 5 deletions pkgs/test/make-binary-wrapper/add-flags/add-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <assert.h>

int main(int argc, char **argv) {
char **argv_tmp = calloc(6 + argc + 2 + 1, sizeof(*argv_tmp));
char **argv_tmp = calloc(27 + argc + 2 + 1, sizeof(*argv_tmp));
assert(argv_tmp != NULL);
argv_tmp[0] = argv[0];
argv_tmp[1] = "-x";
Expand All @@ -12,12 +12,33 @@ int main(int argc, char **argv) {
argv_tmp[4] = "-abc";
argv_tmp[5] = "-g";
argv_tmp[6] = "*.txt";
argv_tmp[7] = "some word";
argv_tmp[8] = "some word";
argv_tmp[9] = "-g";
argv_tmp[10] = "*.txt *.lua $HOME";
argv_tmp[11] = "$HOME";
argv_tmp[12] = "--cmd";
argv_tmp[13] = "lua testvar = true";
argv_tmp[14] = "--cmd";
argv_tmp[15] = "lua print(true)";
argv_tmp[16] = "--cmd";
argv_tmp[17] = "lua print(\"hello\")";
argv_tmp[18] = "--cmd";
argv_tmp[19] = "lua print('hello')";
argv_tmp[20] = "--cmd";
argv_tmp[21] = "lua print('$HOME')";
argv_tmp[22] = "-g";
argv_tmp[23] = "*.txt\n *.lua $HOME";
argv_tmp[24] = "$HOME";
argv_tmp[25] = "$word";
argv_tmp[26] = "$word";
argv_tmp[27] = "\\$word";
for (int i = 1; i < argc; ++i) {
argv_tmp[6 + i] = argv[i];
argv_tmp[27 + i] = argv[i];
}
argv_tmp[6 + argc + 0] = "-foo";
argv_tmp[6 + argc + 1] = "-bar";
argv_tmp[6 + argc + 2] = NULL;
argv_tmp[27 + argc + 0] = "-foo";
argv_tmp[27 + argc + 1] = "-bar";
argv_tmp[27 + argc + 2] = NULL;
argv = argv_tmp;

argv[0] = "/send/me/flags";
Expand Down
16 changes: 15 additions & 1 deletion pkgs/test/make-binary-wrapper/add-flags/add-flags.cmdline
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
--append-flags "-foo -bar" \
--add-flags "-x -y -z" \
--add-flags -abc \
--add-flags "-g *.txt"
--add-flags "-g *.txt" \
--add-flags 'some\ word' \
--add-flags some\\\ word \
--add-flags '-g "*.txt *.lua $HOME"
\$HOME' \
--add-flags "--cmd 'lua testvar = true'" \
--add-flags "--cmd 'lua print(true)'" \
--add-flags "--cmd 'lua print(\"hello\")'" \
--add-flags '--cmd "lua print('\''hello'\'')"' \
--add-flags '--cmd "lua print('\''$HOME'\'')"' \
--add-flags '-g "*.txt
*.lua $HOME"
$HOME' \
--add-flags '\$word "\$word"' \
--add-flags ''\''\$word'\'''
22 changes: 22 additions & 0 deletions pkgs/test/make-binary-wrapper/add-flags/add-flags.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,27 @@ SUBST_ARGV0
-abc
-g
*.txt
some word
some word
-g
*.txt *.lua $HOME
$HOME
--cmd
lua testvar = true
--cmd
lua print(true)
--cmd
lua print("hello")
--cmd
lua print('hello')
--cmd
lua print('$HOME')
-g
*.txt
*.lua $HOME
$HOME
$word
$word
\$word
-foo
-bar