boazsegev / combine_pdf

A Pure ruby library to merge PDF files, number pages and maybe more...
MIT License
733 stars 154 forks source link

Fuzzer + various crashes #212

Open bcoles opened 2 years ago

bcoles commented 2 years ago

Here's an extremely rudimentary naive fuzzer for combine_pdf :

```ruby #!/usr/bin/env ruby #################################################### # ------------------------------------------------ # # Fuzz combine_pdf Ruby gem with mutated PDF files # # ------------------------------------------------ # # # # Each test case is written to 'fuzz.pdf' in the # # current working directory. # # # # Crashes and the associated backtrace are saved # # in the 'crashes' directory in the current # # working directory. # # # #################################################### # ~ bcoles require 'date' require 'combine_pdf' require 'colorize' require 'fileutils' require 'timeout' require 'securerandom' VERBOSE = false OUTPUT_DIR = "#{Dir.pwd}/crashes".freeze # # Show usage # def usage puts 'Usage: ./fuzz.rb [FILE2] [FILE3] [...]' puts 'Example: ./tools/fuzz.rb pdfs/**.pdf' exit 1 end # # Print status message # # @param [String] msg message to print # def print_status(msg = '') puts '[*] '.blue + msg if VERBOSE end # # Print progress messages # # @param [String] msg message to print # def print_good(msg = '') puts '[+] '.green + msg if VERBOSE end # # Print error message # # @param [String] msg message to print # def print_error(msg = '') puts '[-] '.red + msg end # # Setup environment # def setup FileUtils.mkdir_p OUTPUT_DIR unless File.directory? OUTPUT_DIR rescue => e print_error "Could not create output directory '#{OUTPUT_DIR}': #{e}" exit 1 end # # Generate a mutated PDF file with a single mitated byte # # @param [Path] f path to PDF file # def mutate_byte(f) data = IO.binread f position = SecureRandom.random_number data.size new_byte = SecureRandom.random_number 256 new_data = data.dup.tap { |s| s.setbyte(position, new_byte) } File.open(@fuzz_outfile, 'w') do |file| file.write new_data end end # # Generate a mutated PDF file with multiple mutated bytes # # @param [Path] f path to PDF file # def mutate_bytes(f) data = IO.binread f fuzz_factor = 200 num_writes = rand((data.size / fuzz_factor.to_f).ceil) + 1 new_data = data.dup num_writes.times do position = SecureRandom.random_number data.size new_byte = SecureRandom.random_number 256 new_data.tap { |stream| stream.setbyte position, new_byte } end File.open(@fuzz_outfile, 'w') do |file| file.write new_data end end # # Generate a mutated PDF file with all integers replaced by '-1' # # @param [Path] f path to PDF file # def clobber_integers(f) data = IO.binread f new_data = data.dup.gsub(/\d/, '-1') File.open(@fuzz_outfile, 'w') do |file| file.write new_data end end # # Generate a mutated PDF file with all strings 3 characters or longer # replaced with 2000 'A' characters # # @param [Path] f path to PDF file # def clobber_strings(f) data = IO.binread(f) new_data = data.dup.gsub(/[a-zA-Z]{3,}/, 'A' * 2000) File.open(@fuzz_outfile, 'w') do |file| file.write new_data end end # # Read a PDF file # # @param [String] f path to PDF file # def read(f) print_status "Processing '#{f}'" begin pdf = CombinePDF.new pdf << CombinePDF.load(f) rescue CombinePDF::ParsingError print_status "Could not parse PDF '#{f}': PDF is malformed" return end print_good 'Processing complete' print_status "Parsing '#{f}'" begin parse(pdf) rescue CombinePDF::ParsingError print_status "Could not parse PDF '#{f}': PDF is malformed" return end print_good 'Parsing complete' end # # Parse PDF # # @param [CombinePDF::PDF] pdf CombinePDF PDF # def parse(pdf) print_status 'Parsing PDF contents...' pdf.title pdf.author pdf.clear_forms_data pdf.outlines pdf.forms_data contents = '' pdf.pages.each do |page| contents << page.secure_injection.to_s contents << page.make_secure.to_s contents << page.make_unsecure.to_s contents << page.mediabox.to_s contents << page.cropbox.to_s contents << page.page_size.to_s contents << page.resources.to_s contents << page.fix_rotation.to_s contents << page.rotate_left.to_s contents << page.rotate_right.to_s contents << page.rotate_180.to_s end # puts contents if VERBOSE end # # Show summary of crashes # def summary puts puts "Complete! Crashes saved to '#{OUTPUT_DIR}'" puts puts `/usr/bin/head -n1 #{OUTPUT_DIR}/*.trace` if File.exist? '/usr/bin/head' end # # Report error message to STDOUT # and save fuzz test case and backtrace to OUTPUT_DIR # def report_crash(e) puts " - #{e.message}" puts e.backtrace.first fname = "#{DateTime.now.strftime('%Y%m%d%H%M%S%N')}_crash_#{rand(1000)}" FileUtils.mv @fuzz_outfile, "#{OUTPUT_DIR}/#{fname}.pdf" File.open("#{OUTPUT_DIR}/#{fname}.pdf.trace", 'w') do |file| file.write "#{e.message}\n#{e.backtrace.join "\n"}" end end # # Test combine_pdf with the mutated file # def test Timeout.timeout(@timeout) do read(@fuzz_outfile) end rescue SystemStackError => e report_crash e rescue Timeout::Error => e report_crash e rescue SyntaxError => e report_crash e rescue => e raise e unless e.backtrace.join("\n") =~ %r{combine_pdf} report_crash e end # # Generate random byte mutations and run test # # @param [String] f path to PDF file # def fuzz_bytes(f) iterations = 1000 1.upto(iterations) do |i| print "\r#{(i * 100) / iterations} % (#{i} / #{iterations})" mutate_bytes f test end end # # Generate integer mutations and run tests # # @param [String] f path to PDF file # def fuzz_integers(f) clobber_integers f test end # # Generate string mutations and run tests # # @param [String] f path to PDF file # def fuzz_strings(f) clobber_strings f test end puts '-' * 60 puts '% Fuzzer for combine_pdf Ruby gem' puts '-' * 60 puts usage if ARGV[0].nil? setup @timeout = 15 @fuzz_outfile = 'fuzz.pdf' trap 'SIGINT' do puts puts 'Caught interrupt. Exiting...' summary exit 130 end ARGV.each do |f| unless File.exist? f print_error "Could not find file '#{f}'" next end fuzz_integers f fuzz_strings f fuzz_bytes f puts '-' * 60 end summary ```

Here's the stack traces for the latest version on master using test data from pdf-reader as input.

crashes.zip

Summary:

``` $ head -n 2 crashes/*.trace ==> crashes/20220426190213126745428_crash_341.pdf.trace <== no implicit conversion of Symbol into String /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `+' ==> crashes/20220426190214152951768_crash_426.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426190214341671486_crash_713.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426190214444052741_crash_0.pdf.trace <== :"0" can't be coerced into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `+' ==> crashes/20220426190214686444966_crash_492.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426190214912506425_crash_295.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426190214929390431_crash_50.pdf.trace <== Hash can't be coerced into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `+' ==> crashes/20220426190215090244659_crash_427.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426190215105336924_crash_372.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426190215147813391_crash_559.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426190215416139804_crash_429.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426190531857239929_crash_477.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426190554714405144_crash_138.pdf.trace <== undefined method `+' for :"FontDescriptor\x9940":Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426190558573380373_crash_73.pdf.trace <== undefined method `+' for # /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426190702288408271_crash_774.pdf.trace <== stack level too deep /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:734:in `merge' ==> crashes/20220426190719754023238_crash_578.pdf.trace <== execution expired /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:502:in `[]' ==> crashes/20220426190751044259444_crash_793.pdf.trace <== stack level too deep /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:734:in `merge' ==> crashes/20220426190753386086549_crash_953.pdf.trace <== stack level too deep /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:734:in `merge' ==> crashes/20220426190943542034142_crash_631.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:575:in `[]' ==> crashes/20220426190946206240531_crash_649.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:575:in `[]' ==> crashes/20220426191024127412409_crash_29.pdf.trace <== undefined method `+' for # /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426191101101780932_crash_17.pdf.trace <== undefined method `+' for :"9":Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426191235923098521_crash_215.pdf.trace <== stack level too deep /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:605:in `extend' ==> crashes/20220426191258777032784_crash_215.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426191348660561350_crash_152.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426191352043419716_crash_195.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426191501709339569_crash_539.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426191631706620420_crash_536.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426191952999847269_crash_914.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426191953043258198_crash_77.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426191953401475229_crash_552.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:611:in `[]' ==> crashes/20220426191954146910314_crash_832.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:611:in `[]' ==> crashes/20220426191954195017865_crash_185.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `catalog_pages' ==> crashes/20220426191957466192534_crash_503.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426191958128974966_crash_491.pdf.trace <== index out of range /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:364:in `pos=' ==> crashes/20220426192003938396027_crash_41.pdf.trace <== undefined method `+' for :Transparency:Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426192017172559341_crash_304.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426192019509123235_crash_540.pdf.trace <== undefined method `+' for :Contents:Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426192125042179274_crash_665.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192209935262224_crash_14.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192214498144605_crash_7.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192214834927659_crash_115.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192219431382268_crash_804.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192223570456406_crash_228.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192240164626689_crash_422.pdf.trace <== execution expired ./fuzz.rb:189:in `inspect' ==> crashes/20220426192240709780793_crash_810.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192257040452835_crash_366.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192300328968226_crash_996.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192302948775686_crash_589.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192323370389407_crash_463.pdf.trace <== execution expired ./fuzz.rb:184:in `inspect' ==> crashes/20220426192324352526925_crash_928.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192349055110530_crash_576.pdf.trace <== execution expired ./fuzz.rb:184:in `inspect' ==> crashes/20220426192355993303935_crash_185.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192358893611003_crash_680.pdf.trace <== undefined method `between?' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_' ==> crashes/20220426192418348259575_crash_757.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192418370476584_crash_699.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426192418567253927_crash_720.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192418642321257_crash_843.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426192419091152694_crash_279.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426192419173649475_crash_711.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192419191502533_crash_849.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192420953526663_crash_852.pdf.trace <== index out of range /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:364:in `pos=' ==> crashes/20220426192423650748606_crash_802.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192425018620560_crash_298.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ==> crashes/20220426192425695795473_crash_566.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192426163078824_crash_706.pdf.trace <== undefined method `+' for :Info:Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426192427120775205_crash_704.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192427658877498_crash_555.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:545:in `[]' ==> crashes/20220426192435353532689_crash_614.pdf.trace <== undefined method `+' for :Pages:Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references' ==> crashes/20220426192435734418271_crash_600.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426192436018053493_crash_607.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426192436801062893_crash_935.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426192437095870739_crash_745.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:145:in `[]' ==> crashes/20220426192437183910820_crash_55.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192454586411051_crash_136.pdf.trace <== undefined method `-' for nil:NilClass /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426192454640819965_crash_76.pdf.trace <== undefined method `-' for :"792":Symbol /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation' ==> crashes/20220426192454717376548_crash_542.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192455414974113_crash_386.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192455597037997_crash_759.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]' ==> crashes/20220426192455674158577_crash_32.pdf.trace <== no implicit conversion of Symbol into Integer /var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]' ```

Unique crash messages:

$ head -n 1 crashes/*.trace | fgrep -v "==>" | sort -u 

:"0" can't be coerced into Integer
execution expired
Hash can't be coerced into Integer
index out of range
no implicit conversion of Symbol into Integer
no implicit conversion of Symbol into String
stack level too deep
undefined method `between?' for nil:NilClass
undefined method `-' for :"792":Symbol
undefined method `+' for :"9":Symbol
undefined method `+' for :Contents:Symbol
undefined method `+' for :"FontDescriptor\x9940":Symbol
undefined method `+' for #<Hash:0x000056265af07658>
undefined method `+' for #<Hash:0x000056265b040fd8>
undefined method `+' for :Info:Symbol
undefined method `-' for nil:NilClass
undefined method `+' for :Pages:Symbol
undefined method `+' for :Transparency:Symbol

Unique crash locations:

$ head -n 2 crashes/*.trace | grep ":in " | sort -u 
./fuzz.rb:184:in `inspect'
./fuzz.rb:189:in `inspect'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:145:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:412:in `fix_rotation'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/page_methods.rb:502:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:186:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:324:in `_parse_'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:364:in `pos='
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:513:in `catalog_pages'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:545:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:575:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:605:in `extend'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:611:in `[]'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `+'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:662:in `block in serialize_objects_and_references'
/var/lib/gems/2.7.0/gems/combine_pdf-1.0.22/lib/combine_pdf/parser.rb:734:in `merge'