зеркало из https://github.com/github/ruby.git
75 строки
1.9 KiB
Ruby
75 строки
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "stringio"
|
|
|
|
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[
|
|
Date
|
|
Time
|
|
Rational
|
|
|
|
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[
|
|
development
|
|
runtime
|
|
|
|
name
|
|
number
|
|
platform
|
|
dependencies
|
|
].freeze
|
|
private_constant :PERMITTED_SYMBOLS
|
|
|
|
PERMITTED_IVARS = {
|
|
"String" => %w[E encoding @taguri @debug_created_info],
|
|
"Time" => %w[
|
|
offset zone nano_num nano_den submicro
|
|
@_zone @marshal_with_utc_coercion
|
|
],
|
|
"Gem::Dependency" => %w[
|
|
@name @requirement @prerelease @version_requirement @version_requirements @type
|
|
@force_ruby_platform
|
|
],
|
|
"Gem::NameTuple" => %w[@name @version @platform],
|
|
"Gem::Platform" => %w[@os @cpu @version],
|
|
"Psych::PrivateType" => %w[@value @type_id],
|
|
}.freeze
|
|
private_constant :PERMITTED_IVARS
|
|
|
|
def self.safe_load(input)
|
|
load(input, permitted_classes: PERMITTED_CLASSES, permitted_symbols: PERMITTED_SYMBOLS, permitted_ivars: PERMITTED_IVARS)
|
|
end
|
|
|
|
def self.load(input, permitted_classes: [::Symbol], permitted_symbols: [], permitted_ivars: {})
|
|
root = Reader.new(StringIO.new(input, "r").binmode).read!
|
|
|
|
Visitors::ToRuby.new(
|
|
permitted_classes: permitted_classes,
|
|
permitted_symbols: permitted_symbols,
|
|
permitted_ivars: permitted_ivars,
|
|
).visit(root)
|
|
end
|
|
end
|
|
end
|