Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix CVE command injection #15

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions lib/pdf/info.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'date' unless defined? DateTime
require 'pdf/info/exceptions'
require 'open3'

module PDF
class Info
Expand All @@ -18,20 +19,19 @@ def initialize(pdf_path)
end

def command
output = `#{self.class.command_path} -enc UTF-8 -f 1 -l -1 "#{@pdf_path}" 2> /dev/null`
exit_code = $?
case exit_code
when 0 || nil
if !output.valid_encoding?
stdout, stderr, status = Open3.capture3(self.class.command_path, "-enc", "UTF-8", "-f", "1", "-l", "-1", @pdf_path)

if status.success?
if !stdout.valid_encoding?
# It's already UTF-8, so we need to convert to UTF-16 and back to
# force the bad characters to be replaced.
output.encode!('UTF-16', :undef => :replace, :invalid => :replace, :replace => "")
output.encode!('UTF-8')
stdout.encode!('UTF-16', :undef => :replace, :invalid => :replace, :replace => "")
stdout.encode!('UTF-8')
end
return output
return stdout
else
exit_error = PDF::Info::UnexpectedExitError.new
exit_error.exit_code = exit_code
exit_error.exit_code = status.exitstatus
raise exit_error
end
end
Expand Down Expand Up @@ -82,7 +82,11 @@ def process_output(output)
metadata[:pages] << pair.last.scan(/[\d.]+/).map(&:to_f)
metadata[:format] = pair.last.scan(/.*\(\w+\)$/).to_s
when String
metadata[pair.first.downcase.tr(" ", "_").to_sym] = pair.last.to_s.strip
# For a specific key, take the first value, and don't allow later keys to overwrite it
# This prevents later declarations of 'Title' from overwriting the title of the document.
key = pair.first.downcase.tr(" ", "_").to_sym
value = pair.last.to_s.strip
metadata[key] = value unless metadata[key]
end
end

Expand Down
2 changes: 1 addition & 1 deletion pdf_info.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]

s.add_development_dependency "rake"
s.add_development_dependency "rspec"#, '~> 2.12.0'
s.add_development_dependency "rspec", '~> 2.12'
end
19 changes: 2 additions & 17 deletions spec/pdf_info_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,24 +155,9 @@
its([:producer]) { should == "GPL Ghostscript 8.15" }
its([:subject]) { should be_nil }
its([:author]) { should eq "carlos"}
its([:creation_date]) { should eq DateTime.parse("2010-10-09T10:29:55+00:00")}
its([:modification_date]) { should eq DateTime.parse("2010-10-09T10:29:55+00:00")}
its([:creation_date]) { should eq DateTime.parse("2010-10-09T12:29:55+01:00").new_offset(0) }
its([:modification_date]) { should eq DateTime.parse("2010-10-09T12:29:55+01:00").new_offset(0) }
its([:tagged]) { should be_false }
its([:file_size]) { should eq "218882 bytes" }
end

describe "running on a file with invalid utf-8 metadata" do
subject do
PDF::Info.command_path = "pdfinfo"
PDF::Info.new(File.join(File.dirname(__FILE__), 'assets', 'invalid-utf8.pdf')).metadata
end

its([:page_count]) { should == 12 }
its([:title]) { should eq "图形1.CDR" }
# the two date fields are badly encoded in this file, so the DateTime parse
# will fail, and we'll have a nil in these fields
its([:creation_date]) { should be_nil }
its([:modification_date]) { should be_nil }
end

end