@@ -73,6 +73,9 @@ module Shellwords
73
73
# argv = Shellwords.split('here are "two words"')
74
74
# argv #=> ["here", "are", "two words"]
75
75
#
76
+ # +line+ must not contain NUL characters because of nature of
77
+ # +exec+ system call.
78
+ #
76
79
# Note, however, that this is not a command line parser. Shell
77
80
# metacharacters except for the single and double quotes and
78
81
# backslash are not treated as such.
@@ -87,9 +90,14 @@ module Shellwords
87
90
def shellsplit ( line )
88
91
words = [ ]
89
92
field = String . new
90
- line . scan ( /\G \s *(?>([^\s \\ \' \" ]+)|'([^\' ]*)'|"((?:[^\" \\ ]|\\ . )*)"|(\\ . ?)|(\S ))(\s |\z )?/m ) do
93
+ line . scan ( /\G \s *(?>([^\0 \ s\\ \' \" ]+)|'([^\0 \ ' ]*)'|"((?:[^\0 \ "\\ ]|\\ [^ \0 ] )*)"|(\\ [^ \0 ] ?)|(\S ))(\s |\z )?/m ) do
91
94
|word , sq , dq , esc , garbage , sep |
92
- raise ArgumentError , "Unmatched quote: #{ line . inspect } " if garbage
95
+ if garbage
96
+ b = $~. begin ( 0 )
97
+ line = $~[ 0 ]
98
+ line = "..." + line if b > 0
99
+ raise ArgumentError , "#{ garbage == "\0 " ? 'Nul character' : 'Unmatched quote' } at #{ b } : #{ line } "
100
+ end
93
101
# 2.2.3 Double-Quotes:
94
102
#
95
103
# The <backslash> shall retain its special meaning as an
@@ -118,6 +126,9 @@ class << self
118
126
# command line. +str+ can be a non-string object that responds to
119
127
# +to_s+.
120
128
#
129
+ # +str+ must not contain NUL characters because of nature of +exec+
130
+ # system call.
131
+ #
121
132
# Note that a resulted string should be used unquoted and is not
122
133
# intended for use in double quotes nor in single quotes.
123
134
#
@@ -150,6 +161,9 @@ def shellescape(str)
150
161
# An empty argument will be skipped, so return empty quotes.
151
162
return "''" . dup if str . empty?
152
163
164
+ # Shellwords cannot contain NUL characters.
165
+ raise ArgumentError , "NUL character" if str . index ( "\0 " )
166
+
153
167
str = str . dup
154
168
155
169
# Treat multibyte characters as is. It is the caller's responsibility
@@ -175,6 +189,7 @@ class << self
175
189
# All elements are joined into a single string with fields separated by a
176
190
# space, where each element is escaped for the Bourne shell and stringified
177
191
# using +to_s+.
192
+ # See also Shellwords.shellescape.
178
193
#
179
194
# ary = ["There's", "a", "time", "and", "place", "for", "everything"]
180
195
# argv = Shellwords.join(ary)
0 commit comments