ruby-changes:44500
From: knu <ko1@a...>
Date: Sat, 5 Nov 2016 13:58:53 +0900 (JST)
Subject: [ruby-changes:44500] knu:r56573 (trunk): Fix the handling of the backslash in double quotes
knu 2016-11-05 13:58:48 +0900 (Sat, 05 Nov 2016) New Revision: 56573 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56573 Log: 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] Modified files: trunk/ChangeLog trunk/lib/shellwords.rb trunk/test/test_shellwords.rb Index: lib/shellwords.rb =================================================================== --- lib/shellwords.rb (revision 56572) +++ lib/shellwords.rb (revision 56573) @@ -6,7 +6,8 @@ https://github.com/ruby/ruby/blob/trunk/lib/shellwords.rb#L6 # 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 # @@ -55,7 +56,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/shellwords.rb#L56 # # === 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 @@ -81,7 +82,14 @@ module Shellwords https://github.com/ruby/ruby/blob/trunk/lib/shellwords.rb#L82 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 Index: ChangeLog =================================================================== --- ChangeLog (revision 56572) +++ ChangeLog (revision 56573) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Nov 5 13:52:52 2016 Akinori MUSHA <knu@i...> + + * 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@f...> * ext/pathname/pathname.c (Pathname#empty?): New method. Index: test/test_shellwords.rb =================================================================== --- test/test_shellwords.rb (revision 56572) +++ test/test_shellwords.rb (revision 56573) @@ -40,12 +40,24 @@ class TestShellwords < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/test_shellwords.rb#L40 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/