From 8286513838beaf9ccaab15bb5905248c3b7b8a69 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 29 Sep 2016 16:59:06 +0200 Subject: [PATCH] hush: rework input char buffering to allow more than one-deep peek This fixes backslash+newline continuation in $VAR\ NAME construct. (ash has a bug there as well). function old new delta file_peek2 - 74 +74 parse_dollar 746 773 +27 expand_vars_to_list 1143 1167 +24 setup_string_in_str 32 46 +14 setup_file_in_str 33 47 +14 file_get 264 278 +14 static_peek2 - 7 +7 file_peek 91 72 -19 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 5/1 up/down: 174/-19) Total: 155 bytes Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-vars/var_serial.right | 5 +++ shell/ash_test/ash-vars/var_serial.tests | 22 ++++++++++ .../ash_test/ash-vars/var_subst_in_for.right | 40 +++++++++++++++++++ .../ash_test/ash-vars/var_subst_in_for.tests | 40 +++++++++++++++++++ shell/ash_test/ash-vars/var_unbackslash.right | 11 +++++ shell/ash_test/ash-vars/var_unbackslash.tests | 23 +++++++++++ .../ash_test/ash-vars/var_unbackslash1.right | 3 ++ .../ash_test/ash-vars/var_unbackslash1.tests | 15 +++++++ .../hush-vars/var_unbackslash1.right | 3 ++ .../hush-vars/var_unbackslash1.tests | 15 +++++++ 10 files changed, 177 insertions(+) create mode 100644 shell/ash_test/ash-vars/var_serial.right create mode 100755 shell/ash_test/ash-vars/var_serial.tests create mode 100644 shell/ash_test/ash-vars/var_subst_in_for.right create mode 100755 shell/ash_test/ash-vars/var_subst_in_for.tests create mode 100644 shell/ash_test/ash-vars/var_unbackslash.right create mode 100755 shell/ash_test/ash-vars/var_unbackslash.tests create mode 100644 shell/ash_test/ash-vars/var_unbackslash1.right create mode 100755 shell/ash_test/ash-vars/var_unbackslash1.tests create mode 100644 shell/hush_test/hush-vars/var_unbackslash1.right create mode 100755 shell/hush_test/hush-vars/var_unbackslash1.tests diff --git a/shell/ash_test/ash-vars/var_serial.right b/shell/ash_test/ash-vars/var_serial.right new file mode 100644 index 000000000..42aa33057 --- /dev/null +++ b/shell/ash_test/ash-vars/var_serial.right @@ -0,0 +1,5 @@ +Assignments only: c=a +Assignments and a command: c=a +Assignments and a builtin: c=a +Assignments and a function: c=a +Done diff --git a/shell/ash_test/ash-vars/var_serial.tests b/shell/ash_test/ash-vars/var_serial.tests new file mode 100755 index 000000000..6b4a4cdf7 --- /dev/null +++ b/shell/ash_test/ash-vars/var_serial.tests @@ -0,0 +1,22 @@ +a=a + +b=b +c=c +# Second assignment depends on the first: +b=$a c=$b +echo Assignments only: c=$c + +b=b +c=c +b=$a c=$b "$THIS_SH" -c 'echo Assignments and a command: c=$c' + +b=b +c=c +b=$a c=$b eval 'echo Assignments and a builtin: c=$c' + +b=b +c=c +f() { echo Assignments and a function: c=$c; } +b=$a c=$b f + +echo Done diff --git a/shell/ash_test/ash-vars/var_subst_in_for.right b/shell/ash_test/ash-vars/var_subst_in_for.right new file mode 100644 index 000000000..c8aca1c12 --- /dev/null +++ b/shell/ash_test/ash-vars/var_subst_in_for.right @@ -0,0 +1,40 @@ +Testing: in x y z +.x. +.y. +.z. +Testing: in u $empty v +.u. +.v. +Testing: in u " $empty" v +.u. +. . +.v. +Testing: in u $empty $empty$a v +.u. +.a. +.v. +Testing: in $a_b +.a. +.b. +Testing: in $* +.abc. +.d. +.e. +Testing: in $@ +.abc. +.d. +.e. +Testing: in -$*- +.-abc. +.d. +.e-. +Testing: in -$@- +.-abc. +.d. +.e-. +Testing: in $a_b -$a_b- +.a. +.b. +.-a. +.b-. +Finished diff --git a/shell/ash_test/ash-vars/var_subst_in_for.tests b/shell/ash_test/ash-vars/var_subst_in_for.tests new file mode 100755 index 000000000..433c60627 --- /dev/null +++ b/shell/ash_test/ash-vars/var_subst_in_for.tests @@ -0,0 +1,40 @@ +if test $# = 0; then + exec "$THIS_SH" "$0" abc "d e" +fi + +echo 'Testing: in x y z' +for a in x y z; do echo ".$a."; done + +echo 'Testing: in u $empty v' +empty='' +for a in u $empty v; do echo ".$a."; done + +echo 'Testing: in u " $empty" v' +empty='' +for a in u " $empty" v; do echo ".$a."; done + +echo 'Testing: in u $empty $empty$a v' +a='a' +for a in u $empty $empty$a v; do echo ".$a."; done + +echo 'Testing: in $a_b' +a_b='a b' +for a in $a_b; do echo ".$a."; done + +echo 'Testing: in $*' +for a in $*; do echo ".$a."; done + +echo 'Testing: in $@' +for a in $@; do echo ".$a."; done + +echo 'Testing: in -$*-' +for a in -$*-; do echo ".$a."; done + +echo 'Testing: in -$@-' +for a in -$@-; do echo ".$a."; done + +echo 'Testing: in $a_b -$a_b-' +a_b='a b' +for a in $a_b -$a_b-; do echo ".$a."; done + +echo Finished diff --git a/shell/ash_test/ash-vars/var_unbackslash.right b/shell/ash_test/ash-vars/var_unbackslash.right new file mode 100644 index 000000000..8bc834711 --- /dev/null +++ b/shell/ash_test/ash-vars/var_unbackslash.right @@ -0,0 +1,11 @@ +b1=-qwerty-t-\-"-`---z-*-?- +b1=-qwerty-t-\-"-`---z-*-?- +b2=-qwerty-\t-\-"-`-\--\z-\*-\?- +b2=-qwerty-\t-\-"-`-\--\z-\*-\?- +b3=-$a-\t-\\-\"-\`-\--\z-\*-\?- +b3=-$a-\t-\\-\"-\`-\--\z-\*-\?- +c=-$a-\t-\\-\"-\`-\--\z-\*-\?- +c=-$a-\t-\\-\"-\`-\--\z-\*-\?- +c=-$a-\t-\\-\"-\`-\--\z-\*-\?- +c=-$a-\t-\\-\"-\`-\--\z-\*-\?- +Done: 0 diff --git a/shell/ash_test/ash-vars/var_unbackslash.tests b/shell/ash_test/ash-vars/var_unbackslash.tests new file mode 100755 index 000000000..bb52af3d0 --- /dev/null +++ b/shell/ash_test/ash-vars/var_unbackslash.tests @@ -0,0 +1,23 @@ +# Test for correct handling of backslashes +a=qwerty + +b=-$a-\t-\\-\"-\`-\--\z-\*-\?- +echo b1=$b +echo "b1=$b" +b="-$a-\t-\\-\"-\`-\--\z-\*-\?-" +echo b2=$b +echo "b2=$b" +b='-$a-\t-\\-\"-\`-\--\z-\*-\?-' +echo b3=$b +echo "b3=$b" + +c=$b +echo "c=$c" +c=${b} +echo "c=$c" +c="$b" +echo "c=$c" +c="${b}" +echo "c=$c" + +echo "Done: $?" diff --git a/shell/ash_test/ash-vars/var_unbackslash1.right b/shell/ash_test/ash-vars/var_unbackslash1.right new file mode 100644 index 000000000..8d4eca34e --- /dev/null +++ b/shell/ash_test/ash-vars/var_unbackslash1.right @@ -0,0 +1,3 @@ +Ok +Ba d +Ok diff --git a/shell/ash_test/ash-vars/var_unbackslash1.tests b/shell/ash_test/ash-vars/var_unbackslash1.tests new file mode 100755 index 000000000..8a9f2e249 --- /dev/null +++ b/shell/ash_test/ash-vars/var_unbackslash1.tests @@ -0,0 +1,15 @@ +ad="Ok" +a="Ba" + +# "Ok" +echo $a\ +d + +# This variable contains backslash+newline! +e='echo $a\ +d' + +# "Ba d" +eval $e +# "Ok" +eval "$e" diff --git a/shell/hush_test/hush-vars/var_unbackslash1.right b/shell/hush_test/hush-vars/var_unbackslash1.right new file mode 100644 index 000000000..8d4eca34e --- /dev/null +++ b/shell/hush_test/hush-vars/var_unbackslash1.right @@ -0,0 +1,3 @@ +Ok +Ba d +Ok diff --git a/shell/hush_test/hush-vars/var_unbackslash1.tests b/shell/hush_test/hush-vars/var_unbackslash1.tests new file mode 100755 index 000000000..8a9f2e249 --- /dev/null +++ b/shell/hush_test/hush-vars/var_unbackslash1.tests @@ -0,0 +1,15 @@ +ad="Ok" +a="Ba" + +# "Ok" +echo $a\ +d + +# This variable contains backslash+newline! +e='echo $a\ +d' + +# "Ba d" +eval $e +# "Ok" +eval "$e"