From bfc0632ff891a9c33cf3caf3cae34d47875f8baf Mon Sep 17 00:00:00 2001 From: Andre Arko Date: Mon, 18 Feb 2013 21:41:38 -0800 Subject: [PATCH] abstract Marshal.load failures --- lib/bundler.rb | 7 +++++++ lib/bundler/fetcher.rb | 13 ++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index 791a71cb503..61fb7a07103 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -81,6 +81,7 @@ def initialize(conflicts, msg = nil) end class InvalidSpecSet < StandardError; end + class MarshalError < StandardError; end class << self attr_writer :ui, :bundle_path @@ -284,6 +285,12 @@ def read_file(file) File.open(file, "rb") { |f| f.read } end + def load_marshal(data) + Marshal.load(data) + rescue => e + raise MarshalError, "#{e.class}: #{e.message}" + end + def load_gemspec(file) @gemspec_cache ||= {} key = File.expand_path(file) diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 9036b0ecd59..ebbf0b77254 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -83,7 +83,10 @@ def fetch_spec(spec) uri = URI.parse("#{@remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}") spec_rz = (uri.scheme == "file") ? Gem.read_binary(uri.path) : fetch(uri) - Marshal.load Gem.inflate(spec_rz) + Bundler.load_marshal Gem.inflate(spec_rz) + rescue MarshalError => e + raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \ + "Your network or your gem server is probably having issues right now." end # return the specs in the bundler format as an index @@ -143,9 +146,9 @@ def fetch_remote_specs(gem_names, full_dependency_list = [], last_spec_list = [] fetch_remote_specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list) # fall back to the legacy index in the following cases # 1. Gemcutter Endpoint doesn't return a 200 - # 2,3. Marshal blob doesn't load properly - # 4. One of the YAML gemspecs has the Syck::DefaultKey problem - rescue HTTPError, ArgumentError, TypeError, GemspecError => e + # 2. Marshal blob doesn't load properly + # 3. One of the YAML gemspecs has the Syck::DefaultKey problem + rescue HTTPError, MarshalError, GemspecError => e @use_api = false # new line now that the dots are over @@ -226,7 +229,7 @@ def dependency_api_uri(gem_names = []) def fetch_dependency_remote_specs(gem_names) Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(',')}" marshalled_deps = fetch dependency_api_uri(gem_names) - gem_list = Marshal.load(marshalled_deps) + gem_list = Bundler.load_marshal(marshalled_deps) deps_list = [] spec_list = gem_list.map do |s|