mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix the handling of the backslash in double quotes
* lib/shellwords.rb (Shellwords#shellsplit): Fix the handling of the backslash in double quotes to conform to the standard. [ruby-core:63807] [Bug #10055] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56573 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7a78133a41
commit
2da5ae4232
3 changed files with 34 additions and 8 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Sat Nov 5 13:52:52 2016 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* 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 <akr@fsij.org>
|
Sat Nov 5 12:14:31 2016 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* ext/pathname/pathname.c (Pathname#empty?): New method.
|
* ext/pathname/pathname.c (Pathname#empty?): New method.
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
# of the UNIX Bourne shell.
|
# of the UNIX Bourne shell.
|
||||||
#
|
#
|
||||||
# The shellwords() function was originally a port of shellwords.pl,
|
# 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
|
# === Usage
|
||||||
#
|
#
|
||||||
|
@ -55,7 +56,7 @@
|
||||||
#
|
#
|
||||||
# === Resources
|
# === 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
|
module Shellwords
|
||||||
# Splits a string into an array of tokens in the same way the UNIX
|
# Splits a string into an array of tokens in the same way the UNIX
|
||||||
|
@ -81,7 +82,14 @@ module Shellwords
|
||||||
line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
|
line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
|
||||||
|word, sq, dq, esc, garbage, sep|
|
|word, sq, dq, esc, garbage, sep|
|
||||||
raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
|
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
|
if sep
|
||||||
words << field
|
words << field
|
||||||
field = String.new
|
field = String.new
|
||||||
|
|
|
@ -40,12 +40,24 @@ class TestShellwords < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_backslashes
|
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
|
end
|
||||||
|
|
||||||
def test_stringification
|
def test_stringification
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue