@@ -527,12 +527,13 @@ def normalize_path(pathname)
527527 # Loads a Gem::Specification from the TarEntry +entry+
528528
529529 def load_spec ( entry ) # :nodoc:
530+ limit = 10 * 1024 * 1024
530531 case entry . full_name
531532 when "metadata" then
532- @spec = Gem ::Specification . from_yaml entry . read
533+ @spec = Gem ::Specification . from_yaml limit_read ( entry , "metadata" , limit )
533534 when "metadata.gz" then
534535 Zlib ::GzipReader . wrap ( entry , external_encoding : Encoding ::UTF_8 ) do |gzio |
535- @spec = Gem ::Specification . from_yaml gzio . read
536+ @spec = Gem ::Specification . from_yaml limit_read ( gzio , "metadata.gz" , limit )
536537 end
537538 end
538539 end
@@ -556,7 +557,7 @@ def read_checksums(gem)
556557
557558 @checksums = gem . seek "checksums.yaml.gz" do |entry |
558559 Zlib ::GzipReader . wrap entry do |gz_io |
559- Gem ::SafeYAML . safe_load gz_io . read
560+ Gem ::SafeYAML . safe_load limit_read ( gz_io , "checksums.yaml.gz" , 10 * 1024 * 1024 )
560561 end
561562 end
562563 end
@@ -663,7 +664,7 @@ def verify_entry(entry)
663664
664665 case file_name
665666 when /\. sig$/ then
666- @signatures [ $`] = entry . read if @security_policy
667+ @signatures [ $`] = limit_read ( entry , file_name , 1024 * 1024 ) if @security_policy
667668 return
668669 else
669670 digest entry
@@ -723,6 +724,12 @@ def copy_stream(src, dst) # :nodoc:
723724 IO . copy_stream ( src , dst )
724725 end
725726 end
727+
728+ def limit_read ( io , name , limit )
729+ bytes = io . read ( limit + 1 )
730+ raise Gem ::Package ::FormatError , "#{ name } is too big (over #{ limit } bytes)" if bytes . size > limit
731+ bytes
732+ end
726733end
727734
728735require_relative "package/digest_io"
0 commit comments