summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJosef Šimánek <josef.simanek@gmail.com>2022-12-17 08:47:52 +0100
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2022-12-20 13:15:02 +0900
commitf270aa3eda535f3eb3f77912cf4a7a80f240b89e (patch)
tree2bc0ad2c9f96a8820d19aaf9421f988ef951d24c /lib
parentefd103f3e58fcf3aeb6c4a0d3dd9233448698231 (diff)
[rubygems/rubygems] Use safe Marshal deserialization for dependency API response. - adds Bundler#safe_load_marshal and Bundler::SAFE_MARSHAL_CLASSES listing safe classes to deserialize
https://github.com/rubygems/rubygems/commit/e947c608cc
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6966
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler.rb18
-rw-r--r--lib/bundler/fetcher/dependency.rb2
2 files changed, 17 insertions, 3 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 658dda3871..5ae8b6120a 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -39,6 +39,16 @@ module Bundler
environment_preserver.replace_with_backup
SUDO_MUTEX = Thread::Mutex.new
+ SAFE_MARSHAL_CLASSES = [Symbol, TrueClass, String, Array, Hash].freeze
+ SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed.".freeze
+ SAFE_MARSHAL_PROC = proc do |object|
+ object.tap do
+ unless SAFE_MARSHAL_CLASSES.include?(object.class)
+ raise TypeError, format(SAFE_MARSHAL_ERROR, object.class, SAFE_MARSHAL_CLASSES.join(", "))
+ end
+ end
+ end
+
autoload :Definition, File.expand_path("bundler/definition", __dir__)
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
autoload :Deprecate, File.expand_path("bundler/deprecate", __dir__)
@@ -511,8 +521,12 @@ EOF
end
end
- def load_marshal(data)
- Marshal.load(data)
+ def safe_load_marshal(data)
+ load_marshal(data, :marshal_proc => SAFE_MARSHAL_PROC)
+ end
+
+ def load_marshal(data, marshal_proc: nil)
+ Marshal.load(data, marshal_proc)
rescue TypeError => e
raise MarshalError, "#{e.class}: #{e.message}"
end
diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb
index c52c32fb5b..332f86139d 100644
--- a/lib/bundler/fetcher/dependency.rb
+++ b/lib/bundler/fetcher/dependency.rb
@@ -55,7 +55,7 @@ module Bundler
gem_list = []
gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names|
marshalled_deps = downloader.fetch(dependency_api_uri(names)).body
- gem_list.concat(Bundler.load_marshal(marshalled_deps))
+ gem_list.concat(Bundler.safe_load_marshal(marshalled_deps))
end
gem_list
end