Permalink
Browse files

better filename sanitization: maintain compatibility with ruby 1.8.6

ruby 1.8.7 introduces Shellwords#escape, which provides comprehensive
Bourne shell parameter escaping.

To maintain compatibility with ruby 1.8.6, we import
Shellwords#shellescape which is a very compact method.
  • Loading branch information...
guns
guns committed Sep 13, 2010
1 parent 266cb9e commit af7c65136a3af8286fbdadb6e53b93782e53b906
Showing with 22 additions and 1 deletion.
  1. +22 −1 lib/net/scp.rb
View
@@ -338,7 +338,7 @@ def scp_command(mode, options)
# (See Net::SCP::Upload and Net::SCP::Download).
def start_command(mode, local, remote, options={}, &callback)
session.open_channel do |channel|
- command = "#{scp_command(mode, options)} #{remote.shellescape}"
+ command = "#{scp_command(mode, options)} #{shellescape remote}"
channel.exec(command) do |ch, success|
if success
channel[:local ] = local
@@ -399,6 +399,27 @@ def finish_state(channel)
def progress_callback(channel, name, sent, total)
channel[:callback].call(channel, name, sent, total) if channel[:callback]
end
+
+ # Imported from ruby 1.9.2 shellwords.rb
+ def shellescape(str)
+ # ruby 1.8.7+ implements String#shellescape
+ return str.shellescape if str.respond_to? :shellescape
+
+ # An empty argument will be skipped, so return empty quotes.
+ return "''" if str.empty?
+
+ str = str.dup
+
+ # Process as a single byte sequence because not all shell
+ # implementations are multibyte aware.
+ str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
+
+ # A LF cannot be escaped with a backslash because a backslash + LF
+ # combo is regarded as line continuation and simply ignored.
+ str.gsub!(/\n/, "'\n'")
+
+ return str
+ end
end
end

0 comments on commit af7c651

Please sign in to comment.