Skip to content

Commit

Permalink
Fix the handling of the backslash in double quotes
Browse files Browse the repository at this point in the history
* lib/shellwords.rb (Shellwords#shellsplit): Fix the handling of
  the backslash in double quotes to conform to the standard.
  [ruby-core:63807] [Bug ruby#10055]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56573 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
knu committed Nov 5, 2016
1 parent 7a78133 commit 2da5ae4
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Sat Nov 5 13:52:52 2016 Akinori MUSHA <[email protected]>

* lib/shellwords.rb (Shellwords#shellsplit): Fix the handling of
the backslash in double quotes to conform to the standard.
[ruby-core:63807] [Bug #10055]

Sat Nov 5 12:14:31 2016 Tanaka Akira <[email protected]>

* ext/pathname/pathname.c (Pathname#empty?): New method.
Expand Down
14 changes: 11 additions & 3 deletions lib/shellwords.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
# of the UNIX Bourne shell.
#
# The shellwords() function was originally a port of shellwords.pl,
# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001 [1]).
# but modified to conform to the Shell & Utilities volume of the IEEE
# Std 1003.1-2008, 2016 Edition [1].
#
# === Usage
#
Expand Down Expand Up @@ -55,7 +56,7 @@
#
# === Resources
#
# 1: {IEEE Std 1003.1-2004}[http://pubs.opengroup.org/onlinepubs/009695399/toc.htm]
# 1: {IEEE Std 1003.1-2008, 2016 Edition, the Shell & Utilities volume}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html]

module Shellwords
# Splits a string into an array of tokens in the same way the UNIX
Expand All @@ -81,7 +82,14 @@ def shellsplit(line)
line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
field << (word || sq || (dq || esc).gsub(/\\(.)/, '\\1'))
# 2.2.3 Double-Quotes:
#
# The <backslash> shall retain its special meaning as an
# escape character only when followed by one of the following
# characters when considered special:
#
# $ ` " \ <newline>
field << (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1'))
if sep
words << field
field = String.new
Expand Down
22 changes: 17 additions & 5 deletions test/test_shellwords.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,24 @@ def test_unmatched_quotes
end

def test_backslashes
cmdline, expected = [
%q{/a//b///c////d/////e/ "/a//b///c////d/////e/ "'/a//b///c////d/////e/ '/a//b///c////d/////e/ },
%q{a/b/c//d//e a/b/c//d//e /a//b///c////d/////e/ a/b/c//d//e }
].map { |str| str.tr("/", "\\\\") }

assert_equal [expected], shellwords(cmdline)
[
[
%q{/a//b///c////d/////e/ "/a//b///c////d/////e/ "'/a//b///c////d/////e/ '/a//b///c////d/////e/ },
'a/b/c//d//e /a/b//c//d///e/ /a//b///c////d/////e/ a/b/c//d//e '
],
[
%q{printf %s /"/$/`///"/r/n},
'printf', '%s', '"$`/"rn'
],
[
%q{printf %s "/"/$/`///"/r/n"},
'printf', '%s', '"$`/"/r/n'
]
].map { |strs|
cmdline, *expected = strs.map { |str| str.tr("/", "\\\\") }
assert_equal expected, shellwords(cmdline)
}
end

def test_stringification
Expand Down

0 comments on commit 2da5ae4

Please sign in to comment.