class Gem::Package::Old

这个格式类了解旧式 .gem 文件格式的内部结构,并提供读取此类旧式 gem 的能力。

请假装这个不存在。

公共类方法

new(gem, security_policy) 点击切换源代码

gem 创建一个新的旧格式包读取器。旧格式的包无法写入。

# File rubygems/package/old.rb, line 22
def initialize(gem, security_policy)
  require "fileutils"
  require "zlib"
  Gem.load_yaml

  @contents        = nil
  @gem             = gem
  @security_policy = security_policy
  @spec            = nil
end

公共实例方法

contents() 点击切换源代码

此 gem 中包含的文件名列表

# File rubygems/package/old.rb, line 36
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
extract_files(destination_dir) 点击切换源代码

将此包中的文件解压到 destination_dir

# File rubygems/package/old.rb, line 52
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 = String.new

      read_until_dashes io do |line|
        file_data << line
      end

      file_data = file_data.strip.unpack1("m")
      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), mode: dir_mode && 0o755

      File.open destination, "wb", file_mode(entry["mode"]) do |out|
        out.write file_data
      end

      verbose destination
    end
  end
rescue Zlib::DataError
  raise Gem::Exception, errstr
end
spec() 点击切换源代码

此 gem 的规范

# File rubygems/package/old.rb, line 133
def spec
  verify

  return @spec if @spec

  yaml = String.new

  @gem.with_read_io do |io|
    skip_ruby io
    read_until_dashes io do |line|
      yaml << line
    end
  end

  begin
    @spec = Gem::Specification.from_yaml yaml
  rescue Psych::SyntaxError
    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
verify() 点击切换源代码

如果启用了验证数据的安全策略,则引发异常。Old 格式的 gem 无法验证签名。

# File rubygems/package/old.rb, line 160
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