From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 16 Mar 2020 18:49:26 +0900 Subject: Fresh start --- jni/ruby/lib/rubygems/package/old.rb | 178 +++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 jni/ruby/lib/rubygems/package/old.rb (limited to 'jni/ruby/lib/rubygems/package/old.rb') diff --git a/jni/ruby/lib/rubygems/package/old.rb b/jni/ruby/lib/rubygems/package/old.rb new file mode 100644 index 0000000..d7b228d --- /dev/null +++ b/jni/ruby/lib/rubygems/package/old.rb @@ -0,0 +1,178 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +## +# The format class knows the guts of the ancient .gem file format and provides +# the capability to read such ancient gems. +# +# Please pretend this doesn't exist. + +class Gem::Package::Old < Gem::Package + + undef_method :spec= + + ## + # Creates a new old-format package reader for +gem+. Old-format packages + # cannot be written. + + def initialize gem + require 'fileutils' + require 'zlib' + Gem.load_yaml + + @contents = nil + @gem = gem + @security_policy = nil + @spec = nil + end + + ## + # A list of file names contained in this gem + + def contents + verify + + return @contents if @contents + + @gem.with_read_io do |io| + read_until_dashes io # spec + header = file_list io + + @contents = header.map { |file| file['path'] } + end + end + + ## + # Extracts the files in this package into +destination_dir+ + + def extract_files destination_dir + verify + + errstr = "Error reading files from gem" + + @gem.with_read_io do |io| + read_until_dashes io # spec + header = file_list io + raise Gem::Exception, errstr unless header + + header.each do |entry| + full_name = entry['path'] + + destination = install_location full_name, destination_dir + + file_data = '' + + read_until_dashes io do |line| + file_data << line + end + + file_data = file_data.strip.unpack("m")[0] + file_data = Zlib::Inflate.inflate file_data + + raise Gem::Package::FormatError, "#{full_name} in #{@gem} is corrupt" if + file_data.length != entry['size'].to_i + + FileUtils.rm_rf destination + + FileUtils.mkdir_p File.dirname destination + + open destination, 'wb', entry['mode'] do |out| + out.write file_data + end + + verbose destination + end + end + rescue Zlib::DataError + raise Gem::Exception, errstr + end + + ## + # Reads the file list section from the old-format gem +io+ + + def file_list io # :nodoc: + header = '' + + read_until_dashes io do |line| + header << line + end + + YAML.load header + end + + ## + # Reads lines until a "---" separator is found + + def read_until_dashes io # :nodoc: + while (line = io.gets) && line.chomp.strip != "---" do + yield line if block_given? + end + end + + ## + # Skips the Ruby self-install header in +io+. + + def skip_ruby io # :nodoc: + loop do + line = io.gets + + return if line.chomp == '__END__' + break unless line + end + + raise Gem::Exception, "Failed to find end of ruby script while reading gem" + end + + ## + # The specification for this gem + + def spec + verify + + return @spec if @spec + + yaml = '' + + @gem.with_read_io do |io| + skip_ruby io + read_until_dashes io do |line| + yaml << line + end + end + + yaml_error = if RUBY_VERSION < '1.9' then + YAML::ParseError + elsif YAML.const_defined?(:ENGINE) && YAML::ENGINE.yamler == 'syck' then + YAML::ParseError + else + YAML::SyntaxError + end + + begin + @spec = Gem::Specification.from_yaml yaml + rescue yaml_error + raise Gem::Exception, "Failed to parse gem specification out of gem file" + end + rescue ArgumentError + raise Gem::Exception, "Failed to parse gem specification out of gem file" + end + + ## + # Raises an exception if a security policy that verifies data is active. + # Old format gems cannot be verified as signed. + + def verify + return true unless @security_policy + + raise Gem::Security::Exception, + 'old format gems do not contain signatures and cannot be verified' if + @security_policy.verify_data + + true + end + +end + -- cgit v1.2.3