diff options
Diffstat (limited to 'lib/rubygems/safe_marshal.rb')
-rw-r--r-- | lib/rubygems/safe_marshal.rb | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/rubygems/safe_marshal.rb b/lib/rubygems/safe_marshal.rb new file mode 100644 index 0000000000..172b92d5a6 --- /dev/null +++ b/lib/rubygems/safe_marshal.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require_relative "safe_marshal/reader" +require_relative "safe_marshal/visitors/to_ruby" + +module Gem + ### + # This module is used for safely loading Marshal specs from a gem. The + # `safe_load` method defined on this module is specifically designed for + # loading Gem specifications. + + module SafeMarshal + PERMITTED_CLASSES = %w[ + Time + Date + + Gem::Dependency + Gem::NameTuple + Gem::Platform + Gem::Requirement + Gem::Specification + Gem::Version + Gem::Version::Requirement + + YAML::Syck::DefaultKey + YAML::PrivateType + ].freeze + private_constant :PERMITTED_CLASSES + + PERMITTED_SYMBOLS = %w[ + E + + offset + zone + nano_num + nano_den + submicro + + @_zone + @cpu + @force_ruby_platform + @marshal_with_utc_coercion + @name + @os + @platform + @prerelease + @requirement + @taguri + @type + @type_id + @value + @version + @version_requirement + @version_requirements + + development + runtime + ].freeze + private_constant :PERMITTED_SYMBOLS + + def self.safe_load(input) + load(input, permitted_classes: PERMITTED_CLASSES, permitted_symbols: PERMITTED_SYMBOLS) + end + + def self.load(input, permitted_classes: [::Symbol], permitted_symbols: []) + root = Reader.new(StringIO.new(input, "r")).read! + + Visitors::ToRuby.new(permitted_classes: permitted_classes, permitted_symbols: permitted_symbols).visit(root) + end + end +end |