From e5cfdb4ad2c593bdabfef586b9e29e40fd1bf1de Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Wed, 17 Mar 2021 11:21:02 +0100 Subject: [PATCH] Bash: Fixed single-quoted strings (#2792) --- components/prism-bash.js | 17 +++- components/prism-bash.min.js | 2 +- components/prism-shell-session.js | 9 +- components/prism-shell-session.min.js | 2 +- tests/languages/bash/assign-left_feature.test | 6 +- .../bash/entities_in_strings_feature.test | 65 ++++++++++--- tests/languages/bash/issue2436.test | 24 +++++ tests/languages/bash/string_feature.test | 93 ++++--------------- .../shell-session/command_string_feature.test | 33 ++----- 9 files changed, 132 insertions(+), 119 deletions(-) create mode 100644 tests/languages/bash/issue2436.test diff --git a/components/prism-bash.js b/components/prism-bash.js index fc34d92633..a48b864014 100644 --- a/components/prism-bash.js +++ b/components/prism-bash.js @@ -133,10 +133,25 @@ }, // “Normal” string { - pattern: /(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|(?!\2)[^\\`$])*\2/, + // https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html + pattern: /(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/, lookbehind: true, greedy: true, inside: insideString + }, + { + // https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html + pattern: /(^|[^$\\])'[^']*'/, + lookbehind: true, + greedy: true + }, + { + // https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html + pattern: /\$'(?:[^'\\]|\\[\s\S])*'/, + greedy: true, + inside: { + 'entity': insideString.entity + } } ], 'environment': { diff --git a/components/prism-bash.min.js b/components/prism-bash.min.js index dd4d97ff3b..81650901e6 100644 --- a/components/prism-bash.min.js +++ b/components/prism-bash.min.js @@ -1 +1 @@ -!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},a={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b\w+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+?)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:a},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|(?!\2)[^\\`$])*\2/,lookbehind:!0,greedy:!0,inside:a}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:a.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],i=a.variable[1].inside,o=0;o>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b\w+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+?)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:a},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:a},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:a.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:a.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],i=a.variable[1].inside,o=0;o:;|]+)?|[^\0-\x1F$#*?"<>:;|]+)?[$#](?:[^\\\r\n'"<]|\\.|<>)+/.source.replace(/<>/g, function () { return strings; }), 'm'), + pattern: RegExp(/^(?:[^\s@:$#*!/\\]+@[^\s@:$#*!/\\]+(?::[^\0-\x1F$#*?"<>:;|]+)?|[^\0-\x1F$#*?"<>:;|]+)?[$#](?:[^\\\r\n'"<$]|\\.|\$(?!')|<>)+/.source.replace(/<>/g, function () { return strings; }), 'm'), greedy: true, inside: { 'info': { diff --git a/components/prism-shell-session.min.js b/components/prism-shell-session.min.js index b21959cd63..d0ca81759f 100644 --- a/components/prism-shell-session.min.js +++ b/components/prism-shell-session.min.js @@ -1 +1 @@ -!function(s){var n=["([\"'])(?:\\\\[^]|\\$\\([^)]+\\)|\\$(?!\\()|`[^`]+`|(?!\\1)[^\\\\`$])*\\1","<<-?\\s*([\"']?)(\\w+)\\2\\s[^]*?[\r\n]\\3"].join("|");s.languages["shell-session"]={command:{pattern:RegExp('^(?:[^\\s@:$#*!/\\\\]+@[^\\s@:$#*!/\\\\]+(?::[^\0-\\x1F$#*?"<>:;|]+)?|[^\0-\\x1F$#*?"<>:;|]+)?[$#](?:[^\\\\\r\n\'"<]|\\\\.|<>)+'.replace(/<>/g,function(){return n}),"m"),greedy:!0,inside:{info:{pattern:/^[^#$]+/,alias:"punctuation",inside:{user:/^[^\s@:$#*!/\\]+@[^\s@:$#*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:s.languages.bash},"shell-symbol":{pattern:/^[$#]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},s.languages["sh-session"]=s.languages.shellsession=s.languages["shell-session"]}(Prism); \ No newline at end of file +!function(s){var n=['"(?:\\\\[^]|\\$\\([^)]+\\)|\\$(?!\\()|`[^`]+`|[^"\\\\`$])*"',"'[^']*'","\\$'(?:[^'\\\\]|\\\\[^])*'","<<-?\\s*([\"']?)(\\w+)\\1\\s[^]*?[\r\n]\\2"].join("|");s.languages["shell-session"]={command:{pattern:RegExp('^(?:[^\\s@:$#*!/\\\\]+@[^\\s@:$#*!/\\\\]+(?::[^\0-\\x1F$#*?"<>:;|]+)?|[^\0-\\x1F$#*?"<>:;|]+)?[$#](?:[^\\\\\r\n\'"<$]|\\\\.|\\$(?!\')|<>)+'.replace(/<>/g,function(){return n}),"m"),greedy:!0,inside:{info:{pattern:/^[^#$]+/,alias:"punctuation",inside:{user:/^[^\s@:$#*!/\\]+@[^\s@:$#*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:s.languages.bash},"shell-symbol":{pattern:/^[$#]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},s.languages["sh-session"]=s.languages.shellsession=s.languages["shell-session"]}(Prism); \ No newline at end of file diff --git a/tests/languages/bash/assign-left_feature.test b/tests/languages/bash/assign-left_feature.test index e21364696e..54b64a5ba9 100644 --- a/tests/languages/bash/assign-left_feature.test +++ b/tests/languages/bash/assign-left_feature.test @@ -8,13 +8,15 @@ foo+=('xyz') ["assign-left", ["foo"]], ["operator", ["="]], ["number", "12"], + ["assign-left", ["bar"]], ["operator", ["+="]], - ["string", ["'xyz'"]], + ["string", "'xyz'"], + ["assign-left", ["foo"]], ["operator", ["+="]], ["punctuation", "("], - ["string", ["'xyz'"]], + ["string", "'xyz'"], ["punctuation", ")"] ] diff --git a/tests/languages/bash/entities_in_strings_feature.test b/tests/languages/bash/entities_in_strings_feature.test index be4a544275..f4d7dcb911 100644 --- a/tests/languages/bash/entities_in_strings_feature.test +++ b/tests/languages/bash/entities_in_strings_feature.test @@ -1,24 +1,63 @@ -'1\a2\b3\c4\e5\f6\n7\r8\t9\v' -'1234\056789' -'abc\xdef' -'123\456789' -'\uABCDEFG' +$'1\a2\b3\c4\e5\f6\n7\r8\t9\v' +$'1234\056789' +$'123\456789' +"abc\xdef" +"\uABCDEFG" "a\"b" +'1\a2\b3\c4\e5\f6\n7\r8\t9\v' + ---------------------------------------------------- [ ["string", [ - "'1", ["entity", "\\a"], "2", ["entity", "\\b"], "3", ["entity", "\\c"], - "4", ["entity", "\\e"], "5", ["entity", "\\f"], "6", ["entity", "\\n"], - "7", ["entity", "\\r"], "8", ["entity", "\\t"], "9", ["entity", "\\v"], + "$'1", + ["entity", "\\a"], + "2", + ["entity", "\\b"], + "3", + ["entity", "\\c"], + "4", + ["entity", "\\e"], + "5", + ["entity", "\\f"], + "6", + ["entity", "\\n"], + "7", + ["entity", "\\r"], + "8", + ["entity", "\\t"], + "9", + ["entity", "\\v"], "'" ]], - ["string", ["'1234", ["entity", "\\056"], "789'"]], - ["string", ["'abc", ["entity", "\\xde"], "f'"]], - ["string", ["'123", ["entity", "\\456"], "789'"]], - ["string", ["'", ["entity", "\\uABCD"], "EFG'"]], - ["string", ["\"a", ["entity", "\\\""], "b\""]] + ["string", [ + "$'1234", + ["entity", "\\056"], + "789'" + ]], + ["string", [ + "$'123", + ["entity", "\\456"], + "789'" + ]], + ["string", [ + "\"abc", + ["entity", "\\xde"], + "f\"" + ]], + ["string", [ + "\"", + ["entity", "\\uABCD"], + "EFG\"" + ]], + ["string", [ + "\"a", + ["entity", "\\\""], + "b\"" + ]], + + ["string", "'1\\a2\\b3\\c4\\e5\\f6\\n7\\r8\\t9\\v'"] ] ---------------------------------------------------- diff --git a/tests/languages/bash/issue2436.test b/tests/languages/bash/issue2436.test new file mode 100644 index 0000000000..76568aac62 --- /dev/null +++ b/tests/languages/bash/issue2436.test @@ -0,0 +1,24 @@ +echo $'module.exports = {\n extends: [\n // add more generic rulesets here, such as:\n // 'eslint:recommended',\n "plugin:vue/vue3-recommended",\n "prettier",\n "prettier/vue",\n ],\n rules: {\n // override/add rules settings here, such as:\n // 'vue/no-unused-vars': 'error'\n },\n};' > .eslintrc.js + +---------------------------------------------------- + +[ + ["builtin", "echo"], + ["string", [ + "$'module.exports = {", + ["entity", "\\n"], + " extends: [", + ["entity", "\\n"], + " // add more generic rulesets here, such as:", + ["entity", "\\n"], + " // '" + ]], + "eslint:recommended", + ["string", "',\\n \"plugin:vue/vue3-recommended\",\\n \"prettier\",\\n \"prettier/vue\",\\n ],\\n rules: {\\n // override/add rules settings here, such as:\\n // '"], + "vue/no-unused-vars", + ["string", "': '"], + "error", + ["string", "'\\n },\\n};'"], + ["operator", [">"]], + " .eslintrc.js" +] \ No newline at end of file diff --git a/tests/languages/bash/string_feature.test b/tests/languages/bash/string_feature.test index b82afd001d..bdcfc762fe 100644 --- a/tests/languages/bash/string_feature.test +++ b/tests/languages/bash/string_feature.test @@ -47,30 +47,14 @@ STRING_END ---------------------------------------------------- [ - ["string", [ - "\"\"" - ]], - ["string", [ - "''" - ]], - ["string", [ - "\"foo\"" - ]], - ["string", [ - "'foo'" - ]], - ["string", [ - "\"foo\r\nbar\"" - ]], - ["string", [ - "'foo\r\nbar'" - ]], - ["string", [ - "\"'foo'\"" - ]], - ["string", [ - "'\"bar\"'" - ]], + ["string", ["\"\""]], + ["string", "''"], + ["string", ["\"foo\""]], + ["string", "'foo'"], + ["string", ["\"foo\r\nbar\""]], + ["string", "'foo\r\nbar'"], + ["string", ["\"'foo'\""]], + ["string", "'\"bar\"'"], ["string", [ "\"", ["variable", "$@"], @@ -78,67 +62,30 @@ STRING_END ]], ["string", [ "\"", - ["variable", [ - "${foo}" - ]], + ["variable", ["${foo}"]], "\"" ]], - ["punctuation", "\\"], - ["punctuation", "\\"], - ["string", [ - "\"foo\"" - ]], - ["punctuation", "\\"], - "'a ", - ["comment", "# ' not a string"], + ["punctuation", "\\"], ["punctuation", "\\"], ["string", ["\"foo\""]], + ["punctuation", "\\"], "'a ", ["comment", "# ' not a string"], - ["operator", [ - "<<" - ]], - ["string", [ - "STRING_END\r\nfoo\r\nbar\r\nSTRING_END" - ]], + ["operator", ["<<"]], ["string", ["STRING_END\r\nfoo\r\nbar\r\nSTRING_END"]], - ["operator", [ - "<<-" - ]], - ["string", [ - "STRING_END\r\nfoo\r\nbar\r\nSTRING_END" - ]], + ["operator", ["<<-"]], ["string", ["STRING_END\r\nfoo\r\nbar\r\nSTRING_END"]], - ["operator", [ - "<<" - ]], + ["operator", ["<<"]], ["string", [ - "EOF\r\nfoo ", - ["variable", "$@"], + "EOF\r\nfoo ", ["variable", "$@"], "\r\nbar\r\nEOF" ]], - ["operator", [ - "<<" - ]], - ["string", [ - "'EOF'\r\n'single quoted string'\r\n\"double quoted string\"\r\nEOF" - ]], + ["operator", ["<<"]], + ["string", ["'EOF'\r\n'single quoted string'\r\n\"double quoted string\"\r\nEOF"]], - ["operator", [ - "<<" - ]], - ["string", [ - "\"EOF\"\r\nfoo\r\n$bar\r\nEOF" - ]], + ["operator", ["<<"]], ["string", ["\"EOF\"\r\nfoo\r\n$bar\r\nEOF"]], - ["operator", [ - "<<" - ]], - ["string", [ - "STRING_END\r\n# comment\r\nSTRING_END" - ]], + ["operator", ["<<"]], ["string", ["STRING_END\r\n# comment\r\nSTRING_END"]], - ["string", [ - "\" # comment \"" - ]] + ["string", ["\" # comment \""]] ] ---------------------------------------------------- diff --git a/tests/languages/shell-session/command_string_feature.test b/tests/languages/shell-session/command_string_feature.test index a896f118e8..854314b8bb 100644 --- a/tests/languages/shell-session/command_string_feature.test +++ b/tests/languages/shell-session/command_string_feature.test @@ -28,9 +28,7 @@ EOF ["shell-symbol", "$"], ["bash", [ ["builtin", "echo"], - ["string", [ - "'Foo\r\n> Bar'" - ]] + ["string", "'Foo\r\n> Bar'"] ]] ]], @@ -38,9 +36,7 @@ EOF ["shell-symbol", "$"], ["bash", [ ["builtin", "echo"], - ["string", [ - "\"Foo\r\n> Bar\"" - ]] + ["string", ["\"Foo\r\n> Bar\""]] ]] ]], @@ -48,12 +44,8 @@ EOF ["shell-symbol", "$"], ["bash", [ ["builtin", "echo"], - ["operator", [ - "<<-" - ]], - ["string", [ - "STRING_END\r\nfoo\r\nbar\r\nSTRING_END" - ]] + ["operator", ["<<-"]], + ["string", ["STRING_END\r\nfoo\r\nbar\r\nSTRING_END"]] ]] ]], @@ -61,12 +53,8 @@ EOF ["shell-symbol", "$"], ["bash", [ ["builtin", "echo"], - ["operator", [ - "<<-" - ]], - ["string", [ - "\"STRING_END\"\r\nfoo\r\nbar\r\nSTRING_END" - ]] + ["operator", ["<<-"]], + ["string", ["\"STRING_END\"\r\nfoo\r\nbar\r\nSTRING_END"]] ]] ]], @@ -84,17 +72,14 @@ EOF ["shell-symbol", "$"], ["bash", [ ["function", "cat"], - ["operator", [ - "<<" - ]], + ["operator", ["<<"]], ["string", [ "\"EOF\"", ["bash", [ - ["operator", [ - ">" - ]], + ["operator", [">"]], " /etc/ipsec.secrets" ]], + "\r\n: RSA vpn-server-a.key\r\n# : RSA vpn-server-b.key\r\nEOF" ]] ]]