зеркало из https://github.com/github/ruby.git
[rubygems/rubygems] Bundler error handling
https://github.com/rubygems/rubygems/commit/63b422b71a
This commit is contained in:
Родитель
f0d1b0cc4b
Коммит
e52f9bd41e
|
@ -517,7 +517,11 @@ EOF
|
|||
def safe_load_marshal(data)
|
||||
if Gem.respond_to?(:load_safe_marshal)
|
||||
Gem.load_safe_marshal
|
||||
Gem::SafeMarshal.safe_load(data)
|
||||
begin
|
||||
Gem::SafeMarshal.safe_load(data)
|
||||
rescue Gem::SafeMarshal::Reader::Error, Gem::SafeMarshal::Visitors::ToRuby::Error => e
|
||||
raise MarshalError, "#{e.class}: #{e.message}"
|
||||
end
|
||||
else
|
||||
load_marshal(data, :marshal_proc => SafeMarshal.proc)
|
||||
end
|
||||
|
|
|
@ -111,7 +111,7 @@ module Bundler
|
|||
spec_file_name = "#{spec.join "-"}.gemspec"
|
||||
|
||||
uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
|
||||
if uri.scheme == "file"
|
||||
spec = if uri.scheme == "file"
|
||||
path = Bundler.rubygems.correct_for_windows_path(uri.path)
|
||||
Bundler.safe_load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
|
||||
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
|
||||
|
@ -119,6 +119,8 @@ module Bundler
|
|||
else
|
||||
Bundler.safe_load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
|
||||
end
|
||||
raise MarshalError, "is #{spec.inspect}" unless spec.is_a?(Gem::Specification)
|
||||
spec
|
||||
rescue MarshalError
|
||||
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
|
||||
"Your network or your gem server is probably having issues right now."
|
||||
|
|
|
@ -496,7 +496,9 @@ module Bundler
|
|||
fetcher = gem_remote_fetcher
|
||||
fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
|
||||
string = fetcher.fetch_path(path)
|
||||
Bundler.safe_load_marshal(string)
|
||||
specs = Bundler.safe_load_marshal(string)
|
||||
raise MarshalError, "Specs #{name} from #{remote} is expected to be an Array but was unexpected class #{specs.class}" unless specs.is_a?(Array)
|
||||
specs
|
||||
rescue Gem::RemoteFetcher::FetchError
|
||||
# it's okay for prerelease to fail
|
||||
raise unless name == "prerelease_specs"
|
||||
|
|
|
@ -62,7 +62,7 @@ module Gem
|
|||
end
|
||||
|
||||
def self.load(input, permitted_classes: [::Symbol], permitted_symbols: [], permitted_ivars: {})
|
||||
root = Reader.new(StringIO.new(input, "r")).read!
|
||||
root = Reader.new(StringIO.new(input, "r").binmode).read!
|
||||
|
||||
Visitors::ToRuby.new(
|
||||
permitted_classes: permitted_classes,
|
||||
|
|
|
@ -5,7 +5,16 @@ require_relative "elements"
|
|||
module Gem
|
||||
module SafeMarshal
|
||||
class Reader
|
||||
class UnconsumedBytesError < StandardError
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
class UnsupportedVersionError < Error
|
||||
end
|
||||
|
||||
class UnconsumedBytesError < Error
|
||||
end
|
||||
|
||||
class NotImplementedError < Error
|
||||
end
|
||||
|
||||
def initialize(io)
|
||||
|
@ -26,7 +35,7 @@ module Gem
|
|||
|
||||
def read_header
|
||||
v = @io.read(2)
|
||||
raise "Unsupported marshal version #{v.inspect}, expected #{MARSHAL_VERSION.inspect}" unless v == MARSHAL_VERSION
|
||||
raise UnsupportedVersionError, "Unsupported marshal version #{v.bytes.map(&:ord).join(".")}, expected #{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" unless v == MARSHAL_VERSION
|
||||
end
|
||||
|
||||
def read_byte
|
||||
|
@ -80,7 +89,7 @@ module Gem
|
|||
when 91 then read_array # ?[
|
||||
when 102 then read_float # ?f
|
||||
when 105 then Elements::Integer.new int: read_integer # ?i
|
||||
when 108 then read_bignum
|
||||
when 108 then read_bignum # ?l
|
||||
when 111 then read_object # ?o
|
||||
when 117 then read_user_defined # ?u
|
||||
when 123 then read_hash # ?{
|
||||
|
@ -94,7 +103,7 @@ module Gem
|
|||
when "S".ord then read_struct
|
||||
when "C".ord then read_user_class
|
||||
else
|
||||
raise "Unsupported marshal type discriminator #{type.chr.inspect} (#{type})"
|
||||
raise Error, "Unknown marshal type discriminator #{type.chr.inspect} (#{type})"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -177,6 +186,38 @@ module Gem
|
|||
def read_bignum
|
||||
Elements::Bignum.new(sign: read_byte, data: @io.read(read_integer * 2))
|
||||
end
|
||||
|
||||
def read_extended_object
|
||||
raise NotImplementedError, "Reading Marshal objects of type extended_object is not implemented"
|
||||
end
|
||||
|
||||
def read_class
|
||||
raise NotImplementedError, "Reading Marshal objects of type class is not implemented"
|
||||
end
|
||||
|
||||
def read_module
|
||||
raise NotImplementedError, "Reading Marshal objects of type module is not implemented"
|
||||
end
|
||||
|
||||
def read_class_or_module
|
||||
raise NotImplementedError, "Reading Marshal objects of type class_or_module is not implemented"
|
||||
end
|
||||
|
||||
def read_data
|
||||
raise NotImplementedError, "Reading Marshal objects of type data is not implemented"
|
||||
end
|
||||
|
||||
def read_regexp
|
||||
raise NotImplementedError, "Reading Marshal objects of type regexp is not implemented"
|
||||
end
|
||||
|
||||
def read_struct
|
||||
raise NotImplementedError, "Reading Marshal objects of type struct is not implemented"
|
||||
end
|
||||
|
||||
def read_user_class
|
||||
raise NotImplementedError, "Reading Marshal objects of type user_class is not implemented"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -305,7 +305,10 @@ module Gem::SafeMarshal
|
|||
raise MethodCallError, "Unable to call #{method.inspect} on #{receiver.inspect}, perhaps it is a class using marshal compat, which is not visible in ruby? #{e}"
|
||||
end
|
||||
|
||||
class UnpermittedSymbolError < StandardError
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
class UnpermittedSymbolError < Error
|
||||
def initialize(symbol:, stack:)
|
||||
@symbol = symbol
|
||||
@stack = stack
|
||||
|
@ -313,7 +316,7 @@ module Gem::SafeMarshal
|
|||
end
|
||||
end
|
||||
|
||||
class UnpermittedIvarError < StandardError
|
||||
class UnpermittedIvarError < Error
|
||||
def initialize(symbol:, klass:, stack:)
|
||||
@symbol = symbol
|
||||
@klass = klass
|
||||
|
@ -322,7 +325,7 @@ module Gem::SafeMarshal
|
|||
end
|
||||
end
|
||||
|
||||
class UnpermittedClassError < StandardError
|
||||
class UnpermittedClassError < Error
|
||||
def initialize(name:, stack:)
|
||||
@name = name
|
||||
@stack = stack
|
||||
|
@ -330,10 +333,10 @@ module Gem::SafeMarshal
|
|||
end
|
||||
end
|
||||
|
||||
class FormatError < StandardError
|
||||
class FormatError < Error
|
||||
end
|
||||
|
||||
class MethodCallError < StandardError
|
||||
class MethodCallError < Error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe Bundler do
|
|||
end
|
||||
|
||||
it "loads simple structure" do
|
||||
simple_structure = { "name" => [:abc] }
|
||||
simple_structure = { "name" => [:development] }
|
||||
data = Marshal.dump(simple_structure)
|
||||
expect(Bundler.safe_load_marshal(data)).to eq(simple_structure)
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче