@@ -601,6 +601,337 @@ else |
| 601 | 601 | fail "Quoted assignment used in arithmetic" "8" "$result" |
| 602 | 602 | fi |
| 603 | 603 | |
| 604 | +# ===================================== |
| 605 | +section "465. ESCAPE SEQUENCES" |
| 606 | +# ===================================== |
| 607 | + |
| 608 | +result=$("$FORTSH_BIN" -c 'echo "hello\tworld"' 2>&1) |
| 609 | +if echo "$result" | grep -q "hello"; then |
| 610 | + pass "Backslash-t in double quotes" |
| 611 | +else |
| 612 | + fail "Backslash-t in double quotes" |
| 613 | +fi |
| 614 | + |
| 615 | +result=$("$FORTSH_BIN" -c "echo 'hello\nworld'" 2>&1) |
| 616 | +if echo "$result" | grep -q 'hello\\nworld'; then |
| 617 | + pass "Backslash-n literal in single quotes" |
| 618 | +else |
| 619 | + fail "Backslash-n literal in single quotes" |
| 620 | +fi |
| 621 | + |
| 622 | +# ===================================== |
| 623 | +section "466. QUOTING AND WORD SPLITTING" |
| 624 | +# ===================================== |
| 625 | + |
| 626 | +result=$("$FORTSH_BIN" -c 'x="a b c"; set -- $x; echo $#' 2>&1) |
| 627 | +if [ "$result" = "3" ]; then |
| 628 | + pass "Unquoted var splits on spaces" |
| 629 | +else |
| 630 | + fail "Unquoted var splits on spaces" "3" "$result" |
| 631 | +fi |
| 632 | + |
| 633 | +result=$("$FORTSH_BIN" -c 'x="a b c"; set -- "$x"; echo $#' 2>&1) |
| 634 | +if [ "$result" = "1" ]; then |
| 635 | + pass "Quoted var prevents splitting" |
| 636 | +else |
| 637 | + fail "Quoted var prevents splitting" "1" "$result" |
| 638 | +fi |
| 639 | + |
| 640 | +result=$("$FORTSH_BIN" -c 'x=""; set -- $x; echo $#' 2>&1) |
| 641 | +if [ "$result" = "0" ]; then |
| 642 | + pass "Empty unquoted var produces no args" |
| 643 | +else |
| 644 | + fail "Empty unquoted var produces no args" "0" "$result" |
| 645 | +fi |
| 646 | + |
| 647 | +result=$("$FORTSH_BIN" -c 'x=""; set -- "$x"; echo $#' 2>&1) |
| 648 | +if [ "$result" = "1" ]; then |
| 649 | + pass "Empty quoted var produces one empty arg" |
| 650 | +else |
| 651 | + fail "Empty quoted var produces one empty arg" "1" "$result" |
| 652 | +fi |
| 653 | + |
| 654 | +# ===================================== |
| 655 | +section "467. QUOTING SPECIAL PARAMETERS" |
| 656 | +# ===================================== |
| 657 | + |
| 658 | +result=$("$FORTSH_BIN" -c 'set -- a b c; echo "$@" | wc -w' 2>&1) |
| 659 | +if [ "$result" = "3" ]; then |
| 660 | + pass 'Quoted $@ preserves args' |
| 661 | +else |
| 662 | + fail 'Quoted $@ preserves args' "3" "$result" |
| 663 | +fi |
| 664 | + |
| 665 | +result=$("$FORTSH_BIN" -c 'set -- a b c; echo "$*"' 2>&1) |
| 666 | +if [ "$result" = "a b c" ]; then |
| 667 | + pass 'Quoted $* joins args' |
| 668 | +else |
| 669 | + fail 'Quoted $* joins args' "a b c" "$result" |
| 670 | +fi |
| 671 | + |
| 672 | +result=$("$FORTSH_BIN" -c 'set -- a "b c" d; for x in "$@"; do echo "[$x]"; done' 2>&1) |
| 673 | +expected=$(printf "[a]\n[b c]\n[d]") |
| 674 | +if [ "$result" = "$expected" ]; then |
| 675 | + pass 'Quoted $@ preserves quoting in original args' |
| 676 | +else |
| 677 | + fail 'Quoted $@ preserves quoting in original args' |
| 678 | +fi |
| 679 | + |
| 680 | +# ===================================== |
| 681 | +section "468. NESTED QUOTING" |
| 682 | +# ===================================== |
| 683 | + |
| 684 | +result=$("$FORTSH_BIN" -c "echo 'single \"with\" double'" 2>&1) |
| 685 | +if [ "$result" = 'single "with" double' ]; then |
| 686 | + pass "Double quotes inside single quotes" |
| 687 | +else |
| 688 | + fail "Double quotes inside single quotes" |
| 689 | +fi |
| 690 | + |
| 691 | +result=$("$FORTSH_BIN" -c 'echo "double '\''with'\'' single"' 2>&1) |
| 692 | +if [ "$result" = "double 'with' single" ]; then |
| 693 | + pass "Single quotes inside double quotes (escaped)" |
| 694 | +else |
| 695 | + fail "Single quotes inside double quotes (escaped)" |
| 696 | +fi |
| 697 | + |
| 698 | +# ===================================== |
| 699 | +section "469. QUOTING IN ASSIGNMENTS" |
| 700 | +# ===================================== |
| 701 | + |
| 702 | +result=$("$FORTSH_BIN" -c 'x="hello world"; echo $x' 2>&1) |
| 703 | +if [ "$result" = "hello world" ]; then |
| 704 | + pass "Quoted assignment with spaces" |
| 705 | +else |
| 706 | + fail "Quoted assignment with spaces" "hello world" "$result" |
| 707 | +fi |
| 708 | + |
| 709 | +result=$("$FORTSH_BIN" -c "x='hello world'; echo \$x" 2>&1) |
| 710 | +if [ "$result" = "hello world" ]; then |
| 711 | + pass "Single-quoted assignment with spaces" |
| 712 | +else |
| 713 | + fail "Single-quoted assignment with spaces" "hello world" "$result" |
| 714 | +fi |
| 715 | + |
| 716 | +result=$("$FORTSH_BIN" -c 'x=hello\ world; echo $x' 2>&1) |
| 717 | +if [ "$result" = "hello world" ]; then |
| 718 | + pass "Escaped space in assignment" |
| 719 | +else |
| 720 | + fail "Escaped space in assignment" "hello world" "$result" |
| 721 | +fi |
| 722 | + |
| 723 | +# ===================================== |
| 724 | +section "470. QUOTING IN COMMAND SUBSTITUTION" |
| 725 | +# ===================================== |
| 726 | + |
| 727 | +result=$("$FORTSH_BIN" -c 'x=$(echo "hello world"); echo "$x"' 2>&1) |
| 728 | +if [ "$result" = "hello world" ]; then |
| 729 | + pass "Quoted string in command substitution" |
| 730 | +else |
| 731 | + fail "Quoted string in command substitution" "hello world" "$result" |
| 732 | +fi |
| 733 | + |
| 734 | +result=$("$FORTSH_BIN" -c 'x=`echo "hello world"`; echo "$x"' 2>&1) |
| 735 | +if [ "$result" = "hello world" ]; then |
| 736 | + pass "Quoted string in backtick substitution" |
| 737 | +else |
| 738 | + fail "Quoted string in backtick substitution" "hello world" "$result" |
| 739 | +fi |
| 740 | + |
| 741 | +# ===================================== |
| 742 | +section "471. QUOTING AND GLOB PREVENTION" |
| 743 | +# ===================================== |
| 744 | + |
| 745 | +result=$("$FORTSH_BIN" -c 'echo "*"' 2>&1) |
| 746 | +if [ "$result" = "*" ]; then |
| 747 | + pass "Quoted asterisk is literal" |
| 748 | +else |
| 749 | + fail "Quoted asterisk is literal" "*" "$result" |
| 750 | +fi |
| 751 | + |
| 752 | +result=$("$FORTSH_BIN" -c 'echo "?"' 2>&1) |
| 753 | +if [ "$result" = "?" ]; then |
| 754 | + pass "Quoted question mark is literal" |
| 755 | +else |
| 756 | + fail "Quoted question mark is literal" "?" "$result" |
| 757 | +fi |
| 758 | + |
| 759 | +result=$("$FORTSH_BIN" -c 'echo "[abc]"' 2>&1) |
| 760 | +if [ "$result" = "[abc]" ]; then |
| 761 | + pass "Quoted brackets are literal" |
| 762 | +else |
| 763 | + fail "Quoted brackets are literal" "[abc]" "$result" |
| 764 | +fi |
| 765 | + |
| 766 | +# ===================================== |
| 767 | +section "472. QUOTING IN TESTS" |
| 768 | +# ===================================== |
| 769 | + |
| 770 | +result=$("$FORTSH_BIN" -c 'x=""; [ -z "$x" ] && echo empty' 2>&1) |
| 771 | +if [ "$result" = "empty" ]; then |
| 772 | + pass "Quoted empty var in test -z" |
| 773 | +else |
| 774 | + fail "Quoted empty var in test -z" "empty" "$result" |
| 775 | +fi |
| 776 | + |
| 777 | +result=$("$FORTSH_BIN" -c 'x="hello"; [ -n "$x" ] && echo nonempty' 2>&1) |
| 778 | +if [ "$result" = "nonempty" ]; then |
| 779 | + pass "Quoted var in test -n" |
| 780 | +else |
| 781 | + fail "Quoted var in test -n" "nonempty" "$result" |
| 782 | +fi |
| 783 | + |
| 784 | +result=$("$FORTSH_BIN" -c 'x="a b"; [ "$x" = "a b" ] && echo match' 2>&1) |
| 785 | +if [ "$result" = "match" ]; then |
| 786 | + pass "Quoted var with spaces in test =" |
| 787 | +else |
| 788 | + fail "Quoted var with spaces in test =" "match" "$result" |
| 789 | +fi |
| 790 | + |
| 791 | +# ===================================== |
| 792 | +section "473. QUOTING IN CASE PATTERNS" |
| 793 | +# ===================================== |
| 794 | + |
| 795 | +result=$("$FORTSH_BIN" -c 'x="*"; case "$x" in "*") echo literal;; esac' 2>&1) |
| 796 | +if [ "$result" = "literal" ]; then |
| 797 | + pass "Quoted asterisk matches literally in case" |
| 798 | +else |
| 799 | + fail "Quoted asterisk matches literally in case" "literal" "$result" |
| 800 | +fi |
| 801 | + |
| 802 | +result=$("$FORTSH_BIN" -c 'x="a b"; case "$x" in "a b") echo match;; esac' 2>&1) |
| 803 | +if [ "$result" = "match" ]; then |
| 804 | + pass "Quoted pattern with space in case" |
| 805 | +else |
| 806 | + fail "Quoted pattern with space in case" "match" "$result" |
| 807 | +fi |
| 808 | + |
| 809 | +# ===================================== |
| 810 | +section "474. QUOTING IN FUNCTION ARGS" |
| 811 | +# ===================================== |
| 812 | + |
| 813 | +result=$("$FORTSH_BIN" -c 'f() { echo "[$1]"; }; f "hello world"' 2>&1) |
| 814 | +if [ "$result" = "[hello world]" ]; then |
| 815 | + pass "Quoted arg to function" |
| 816 | +else |
| 817 | + fail "Quoted arg to function" "[hello world]" "$result" |
| 818 | +fi |
| 819 | + |
| 820 | +result=$("$FORTSH_BIN" -c 'f() { echo $#; }; f "a b" "c d"' 2>&1) |
| 821 | +if [ "$result" = "2" ]; then |
| 822 | + pass "Quoted args count in function" |
| 823 | +else |
| 824 | + fail "Quoted args count in function" "2" "$result" |
| 825 | +fi |
| 826 | + |
| 827 | +# ===================================== |
| 828 | +section "475. DOLLAR IN QUOTES" |
| 829 | +# ===================================== |
| 830 | + |
| 831 | +result=$("$FORTSH_BIN" -c 'echo "\$HOME"' 2>&1) |
| 832 | +if [ "$result" = '$HOME' ]; then |
| 833 | + pass "Escaped dollar in double quotes" |
| 834 | +else |
| 835 | + fail "Escaped dollar in double quotes" "\$HOME" "$result" |
| 836 | +fi |
| 837 | + |
| 838 | +result=$("$FORTSH_BIN" -c "echo '\$HOME'" 2>&1) |
| 839 | +if [ "$result" = '$HOME' ]; then |
| 840 | + pass "Dollar in single quotes" |
| 841 | +else |
| 842 | + fail "Dollar in single quotes" "\$HOME" "$result" |
| 843 | +fi |
| 844 | + |
| 845 | +# ===================================== |
| 846 | +section "476. BACKSLASH IN QUOTES" |
| 847 | +# ===================================== |
| 848 | + |
| 849 | +result=$("$FORTSH_BIN" -c 'echo "\\"' 2>&1) |
| 850 | +if [ "$result" = '\' ]; then |
| 851 | + pass "Escaped backslash in double quotes" |
| 852 | +else |
| 853 | + fail "Escaped backslash in double quotes" "\\" "$result" |
| 854 | +fi |
| 855 | + |
| 856 | +result=$("$FORTSH_BIN" -c "echo '\\'" 2>&1) |
| 857 | +if [ "$result" = '\' ]; then |
| 858 | + pass "Backslash in single quotes" |
| 859 | +else |
| 860 | + fail "Backslash in single quotes" "\\" "$result" |
| 861 | +fi |
| 862 | + |
| 863 | +# ===================================== |
| 864 | +section "477. QUOTE REMOVAL" |
| 865 | +# ===================================== |
| 866 | + |
| 867 | +result=$("$FORTSH_BIN" -c 'echo ""hello""' 2>&1) |
| 868 | +if [ "$result" = "hello" ]; then |
| 869 | + pass "Empty quotes around word" |
| 870 | +else |
| 871 | + fail "Empty quotes around word" "hello" "$result" |
| 872 | +fi |
| 873 | + |
| 874 | +result=$("$FORTSH_BIN" -c 'echo "a""b""c"' 2>&1) |
| 875 | +if [ "$result" = "abc" ]; then |
| 876 | + pass "Adjacent quoted strings concatenate" |
| 877 | +else |
| 878 | + fail "Adjacent quoted strings concatenate" "abc" "$result" |
| 879 | +fi |
| 880 | + |
| 881 | +# ===================================== |
| 882 | +section "478. MIXED QUOTE STYLES" |
| 883 | +# ===================================== |
| 884 | + |
| 885 | +result=$("$FORTSH_BIN" -c "x=val; echo 'a'\"\$x\"'b'" 2>&1) |
| 886 | +if [ "$result" = "avalb" ]; then |
| 887 | + pass "Mixed single and double quotes" |
| 888 | +else |
| 889 | + fail "Mixed single and double quotes" "avalb" "$result" |
| 890 | +fi |
| 891 | + |
| 892 | +result=$("$FORTSH_BIN" -c "echo 'single'\"double\"'single'" 2>&1) |
| 893 | +if [ "$result" = "singledoublesingle" ]; then |
| 894 | + pass "Alternating quote styles" |
| 895 | +else |
| 896 | + fail "Alternating quote styles" "singledoublesingle" "$result" |
| 897 | +fi |
| 898 | + |
| 899 | +# ===================================== |
| 900 | +section "479. QUOTING IN REDIRECTIONS" |
| 901 | +# ===================================== |
| 902 | + |
| 903 | +result=$("$FORTSH_BIN" -c 'echo test > "/tmp/quote space test.txt"; cat "/tmp/quote space test.txt"; rm "/tmp/quote space test.txt"' 2>&1) |
| 904 | +if [ "$result" = "test" ]; then |
| 905 | + pass "Quoted filename with space in redirect" |
| 906 | +else |
| 907 | + fail "Quoted filename with space in redirect" "test" "$result" |
| 908 | +fi |
| 909 | + |
| 910 | +# ===================================== |
| 911 | +section "480. EMPTY QUOTES" |
| 912 | +# ===================================== |
| 913 | + |
| 914 | +result=$("$FORTSH_BIN" -c 'echo ""' 2>&1) |
| 915 | +if [ -z "$result" ]; then |
| 916 | + pass "Empty double quotes produce empty output" |
| 917 | +else |
| 918 | + fail "Empty double quotes produce empty output" "empty" "$result" |
| 919 | +fi |
| 920 | + |
| 921 | +result=$("$FORTSH_BIN" -c "echo ''" 2>&1) |
| 922 | +if [ -z "$result" ]; then |
| 923 | + pass "Empty single quotes produce empty output" |
| 924 | +else |
| 925 | + fail "Empty single quotes produce empty output" "empty" "$result" |
| 926 | +fi |
| 927 | + |
| 928 | +result=$("$FORTSH_BIN" -c 'x=""; echo "[$x]"' 2>&1) |
| 929 | +if [ "$result" = "[]" ]; then |
| 930 | + pass "Empty var in quotes" |
| 931 | +else |
| 932 | + fail "Empty var in quotes" "[]" "$result" |
| 933 | +fi |
| 934 | + |
| 604 | 935 | # ===================================== |
| 605 | 936 | # Summary |
| 606 | 937 | # ===================================== |