lib/sup/message_chunks.rb in sup-0.13.2.1 vs lib/sup/message_chunks.rb in sup-0.14.0

- old
+ new

@@ -1,8 +1,7 @@ require 'tempfile' require 'rbconfig' -require 'shellwords' ## Here we define all the "chunks" that a message is parsed ## into. Chunks are used by ThreadViewMode to render a message. Chunks ## are used for both MIME stuff like attachments, for Sup's parsing of ## the message body into text, quote, and signature regions, and for @@ -58,12 +57,10 @@ module Redwood module Chunk class Attachment - ## please see note in write_to_disk on important usage - ## of quotes to avoid remote command injection. HookManager.register "mime-decode", <<EOS Decodes a MIME attachment into text form. The text will be displayed directly in Sup. For attachments that you wish to use a separate program to view (e.g. images), you should use the mime-view hook instead. @@ -76,13 +73,10 @@ the empty array. Return value: The decoded text of the attachment, or nil if not decoded. EOS - - ## please see note in write_to_disk on important usage - ## of quotes to avoid remote command injection. HookManager.register "mime-view", <<EOS Views a non-text MIME attachment. This hook allows you to run third-party programs for attachments that require such a thing (e.g. images). To instead display a text version of the attachment directly in Sup, use the mime-decode hook instead. @@ -104,22 +98,12 @@ ## raw_content is the post-MIME-decode content. this is used for ## saving the attachment to disk. attr_reader :content_type, :filename, :lines, :raw_content bool_reader :quotable - ## store tempfile objects as class variables so that they - ## are not removed when the viewing process returns. they - ## should be garbage collected when the class variable is removed. - @@view_tempfiles = [] - def initialize content_type, filename, encoded_content, sibling_types @content_type = content_type.downcase - if Shellwords.escape(@content_type) != @content_type - warn "content_type #{@content_type} is not safe, changed to application/octet-stream" - @content_type = 'application/octet-stream' - end - @filename = filename @quotable = false # changed to true if we can parse it through the # mime-decode hook, or if it's plain text @raw_content = if encoded_content.body @@ -130,21 +114,19 @@ text = case @content_type when /^text\/plain\b/ @raw_content else - ## please see note in write_to_disk on important usage - ## of quotes to avoid remote command injection. - HookManager.run "mime-decode", :content_type => @content_type, + HookManager.run "mime-decode", :content_type => content_type, :filename => lambda { write_to_disk }, :charset => encoded_content.charset, :sibling_types => sibling_types end @lines = nil if text - text = text.transcode(encoded_content.charset || $encoding) + text = text.transcode(encoded_content.charset || $encoding, text.encoding) @lines = text.gsub("\r\n", "\n").gsub(/\t/, " ").gsub(/\r/, "").split("\n") @quotable = true end end @@ -163,49 +145,33 @@ def inlineable?; false end def expandable?; !viewable? end def initial_state; :open end def viewable?; @lines.nil? end def view_default! path - ## please see note in write_to_disk on important usage - ## of quotes to avoid remote command injection. case RbConfig::CONFIG['arch'] when /darwin/ - cmd = "open #{path}" + cmd = "open '#{path}'" else - cmd = "/usr/bin/run-mailcap --action=view #{@content_type}:#{path}" + cmd = "/usr/bin/run-mailcap --action=view '#{@content_type}:#{path}'" end debug "running: #{cmd.inspect}" BufferManager.shell_out(cmd) $? == 0 end def view! - ## please see note in write_to_disk on important usage - ## of quotes to avoid remote command injection. - write_to_disk do |file| - - @@view_tempfiles.push file # make sure the tempfile is not garbage collected before sup stops - - ret = HookManager.run "mime-view", :content_type => @content_type, - :filename => file.path - ret || view_default!(file.path) - end + path = write_to_disk + ret = HookManager.run "mime-view", :content_type => @content_type, + :filename => path + ret || view_default!(path) end - ## note that the path returned from write_to_disk is - ## Shellwords.escaped and is intended to be used without single - ## or double quotes. the use of either opens sup up for remote - ## code injection through the file name. def write_to_disk - begin - file = Tempfile.new(["sup", Shellwords.escape(@filename.gsub("/", "_")) || "sup-attachment"]) - file.print @raw_content - yield file if block_given? - return file.path - ensure - file.close - end + file = Tempfile.new(["sup", @filename.gsub("/", "_") || "sup-attachment"]) + file.print @raw_content + file.close + file.path end ## used when viewing the attachment as text def to_s @lines || @raw_content @@ -261,10 +227,10 @@ end class EnclosedMessage attr_reader :lines def initialize from, to, cc, date, subj - @from = from ? "unknown sender" : from.full_address + @from = from ? "unknown sender" : from.full_adress @to = to ? "" : to.map { |p| p.full_address }.join(", ") @cc = cc ? "" : cc.map { |p| p.full_address }.join(", ") if date @date = date.rfc822 else