rubygems-update 3.6.1 → 3.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/bundler/CHANGELOG.md +32 -0
- data/bundler/README.md +1 -1
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/outdated.rb +6 -4
- data/bundler/lib/bundler/definition.rb +2 -2
- data/bundler/lib/bundler/dependency.rb +1 -1
- data/bundler/lib/bundler/feature_flag.rb +2 -6
- data/bundler/lib/bundler/installer.rb +15 -1
- data/bundler/lib/bundler/man/bundle-add.1 +3 -3
- data/bundler/lib/bundler/man/bundle-binstubs.1 +3 -3
- data/bundler/lib/bundler/man/bundle-cache.1 +3 -3
- data/bundler/lib/bundler/man/bundle-check.1 +3 -3
- data/bundler/lib/bundler/man/bundle-clean.1 +3 -3
- data/bundler/lib/bundler/man/bundle-config.1 +3 -3
- data/bundler/lib/bundler/man/bundle-console.1 +3 -3
- data/bundler/lib/bundler/man/bundle-doctor.1 +3 -3
- data/bundler/lib/bundler/man/bundle-env.1 +3 -3
- data/bundler/lib/bundler/man/bundle-exec.1 +3 -3
- data/bundler/lib/bundler/man/bundle-fund.1 +3 -3
- data/bundler/lib/bundler/man/bundle-gem.1 +3 -3
- data/bundler/lib/bundler/man/bundle-help.1 +3 -3
- data/bundler/lib/bundler/man/bundle-info.1 +3 -3
- data/bundler/lib/bundler/man/bundle-init.1 +3 -3
- data/bundler/lib/bundler/man/bundle-inject.1 +3 -3
- data/bundler/lib/bundler/man/bundle-install.1 +3 -3
- data/bundler/lib/bundler/man/bundle-issue.1 +3 -3
- data/bundler/lib/bundler/man/bundle-licenses.1 +3 -3
- data/bundler/lib/bundler/man/bundle-list.1 +3 -3
- data/bundler/lib/bundler/man/bundle-lock.1 +4 -4
- data/bundler/lib/bundler/man/bundle-lock.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-open.1 +3 -3
- data/bundler/lib/bundler/man/bundle-outdated.1 +3 -3
- data/bundler/lib/bundler/man/bundle-platform.1 +3 -3
- data/bundler/lib/bundler/man/bundle-plugin.1 +3 -3
- data/bundler/lib/bundler/man/bundle-pristine.1 +3 -3
- data/bundler/lib/bundler/man/bundle-remove.1 +3 -3
- data/bundler/lib/bundler/man/bundle-show.1 +3 -3
- data/bundler/lib/bundler/man/bundle-update.1 +3 -3
- data/bundler/lib/bundler/man/bundle-version.1 +3 -3
- data/bundler/lib/bundler/man/bundle-viz.1 +3 -3
- data/bundler/lib/bundler/man/bundle.1 +3 -3
- data/bundler/lib/bundler/man/gemfile.5 +3 -3
- data/bundler/lib/bundler/plugin/index.rb +4 -0
- data/bundler/lib/bundler/resolver/base.rb +2 -1
- data/bundler/lib/bundler/resolver/package.rb +1 -1
- data/bundler/lib/bundler/resolver.rb +2 -1
- data/bundler/lib/bundler/ruby_dsl.rb +12 -3
- data/bundler/lib/bundler/rubygems_integration.rb +0 -12
- data/bundler/lib/bundler/self_manager.rb +3 -2
- data/bundler/lib/bundler/source/git.rb +1 -0
- data/bundler/lib/bundler/spec_set.rb +16 -2
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler.rb +10 -30
- data/doc/rubygems/POLICIES.md +1 -1
- data/lib/rubygems/commands/environment_command.rb +5 -0
- data/lib/rubygems/rdoc.rb +10 -1
- data/lib/rubygems/requirement.rb +4 -3
- data/lib/rubygems/safe_marshal/reader.rb +31 -14
- data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +29 -16
- data/lib/rubygems/specification.rb +3 -11
- data/lib/rubygems/uninstaller.rb +0 -1
- data/lib/rubygems/util/licenses.rb +19 -0
- data/lib/rubygems/version.rb +4 -1
- data/lib/rubygems.rb +9 -2
- data/rubygems-update.gemspec +1 -1
- metadata +3 -4
@@ -34,6 +34,10 @@ module Bundler
|
|
34
34
|
rescue GenericSystemCallError
|
35
35
|
# no need to fail when on a read-only FS, for example
|
36
36
|
nil
|
37
|
+
rescue ArgumentError => e
|
38
|
+
# ruby 3.4 checks writability in Dir.tmpdir
|
39
|
+
raise unless e.message&.include?("could not find a temporary directory")
|
40
|
+
nil
|
37
41
|
end
|
38
42
|
load_index(local_index_file) if SharedHelpers.in_bundle?
|
39
43
|
end
|
@@ -5,10 +5,11 @@ require_relative "package"
|
|
5
5
|
module Bundler
|
6
6
|
class Resolver
|
7
7
|
class Base
|
8
|
-
attr_reader :packages, :requirements, :source_requirements
|
8
|
+
attr_reader :packages, :requirements, :source_requirements, :locked_specs
|
9
9
|
|
10
10
|
def initialize(source_requirements, dependencies, base, platforms, options)
|
11
11
|
@source_requirements = source_requirements
|
12
|
+
@locked_specs = options[:locked_specs]
|
12
13
|
|
13
14
|
@base = base
|
14
15
|
|
@@ -18,7 +18,7 @@ module Bundler
|
|
18
18
|
def initialize(name, platforms, locked_specs:, unlock:, prerelease: false, prefer_local: false, dependency: nil)
|
19
19
|
@name = name
|
20
20
|
@platforms = platforms
|
21
|
-
@locked_version = locked_specs
|
21
|
+
@locked_version = locked_specs.version_for(name)
|
22
22
|
@unlock = unlock
|
23
23
|
@dependency = dependency || Dependency.new(name, @locked_version)
|
24
24
|
@top_level = !dependency.nil?
|
@@ -80,7 +80,8 @@ module Bundler
|
|
80
80
|
def solve_versions(root:, logger:)
|
81
81
|
solver = PubGrub::VersionSolver.new(source: self, root: root, logger: logger)
|
82
82
|
result = solver.solve
|
83
|
-
result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) }
|
83
|
+
resolved_specs = result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) }
|
84
|
+
SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs)
|
84
85
|
rescue PubGrub::SolveFailure => e
|
85
86
|
incompatibility = e.incompatibility
|
86
87
|
|
@@ -42,9 +42,18 @@ module Bundler
|
|
42
42
|
# Loads the file relative to the dirname of the Gemfile itself.
|
43
43
|
def normalize_ruby_file(filename)
|
44
44
|
file_content = Bundler.read_file(gemfile.dirname.join(filename))
|
45
|
-
# match "ruby-3.2.2" or "ruby 3.2.2" capturing version string up to the first space or comment
|
46
|
-
if /^
|
47
|
-
|
45
|
+
# match "ruby-3.2.2", ruby = "3.2.2" or "ruby 3.2.2" capturing version string up to the first space or comment
|
46
|
+
if /^ # Start of line
|
47
|
+
ruby # Literal "ruby"
|
48
|
+
[\s-]* # Optional whitespace or hyphens (for "ruby-3.2.2" format)
|
49
|
+
(?:=\s*)? # Optional equals sign with whitespace (for ruby = "3.2.2" format)
|
50
|
+
"? # Optional opening quote
|
51
|
+
( # Start capturing group
|
52
|
+
[^\s#"]+ # One or more chars that aren't spaces, #, or quotes
|
53
|
+
) # End capturing group
|
54
|
+
"? # Optional closing quote
|
55
|
+
/x.match(file_content)
|
56
|
+
$1
|
48
57
|
else
|
49
58
|
file_content.strip
|
50
59
|
end
|
@@ -134,18 +134,6 @@ module Bundler
|
|
134
134
|
loaded_gem_paths.flatten
|
135
135
|
end
|
136
136
|
|
137
|
-
def load_plugins
|
138
|
-
Gem.load_plugins
|
139
|
-
end
|
140
|
-
|
141
|
-
def load_plugin_files(plugin_files)
|
142
|
-
Gem.load_plugin_files(plugin_files)
|
143
|
-
end
|
144
|
-
|
145
|
-
def load_env_plugins
|
146
|
-
Gem.load_env_plugins
|
147
|
-
end
|
148
|
-
|
149
137
|
def ui=(obj)
|
150
138
|
Gem::DefaultUserInteraction.ui = obj
|
151
139
|
end
|
@@ -84,8 +84,9 @@ module Bundler
|
|
84
84
|
require "shellwords"
|
85
85
|
cmd = [*Shellwords.shellsplit(bundler_spec_original_cmd), *ARGV]
|
86
86
|
else
|
87
|
-
|
88
|
-
cmd
|
87
|
+
argv0 = File.exist?($PROGRAM_NAME) ? $PROGRAM_NAME : Process.argv0
|
88
|
+
cmd = [argv0, *ARGV]
|
89
|
+
cmd.unshift(Gem.ruby) unless File.executable?(argv0)
|
89
90
|
end
|
90
91
|
|
91
92
|
Bundler.with_original_env do
|
@@ -133,8 +133,8 @@ module Bundler
|
|
133
133
|
validation_set.incomplete_specs.any?
|
134
134
|
end
|
135
135
|
|
136
|
-
def missing_specs_for(
|
137
|
-
materialize_dependencies(
|
136
|
+
def missing_specs_for(deps)
|
137
|
+
materialize_dependencies(deps)
|
138
138
|
|
139
139
|
missing_specs
|
140
140
|
end
|
@@ -163,12 +163,20 @@ module Bundler
|
|
163
163
|
@specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
|
164
164
|
end
|
165
165
|
|
166
|
+
def specs_with_additional_variants_from(other)
|
167
|
+
sorted | additional_variants_from(other)
|
168
|
+
end
|
169
|
+
|
166
170
|
def delete_by_name(name)
|
167
171
|
@specs.reject! {|spec| spec.name == name }
|
168
172
|
|
169
173
|
reset!
|
170
174
|
end
|
171
175
|
|
176
|
+
def version_for(name)
|
177
|
+
self[name].first&.version
|
178
|
+
end
|
179
|
+
|
172
180
|
def what_required(spec)
|
173
181
|
unless req = find {|s| s.runtime_dependencies.any? {|d| d.name == spec.name } }
|
174
182
|
return [spec]
|
@@ -273,6 +281,12 @@ module Bundler
|
|
273
281
|
@specs.flat_map {|spec| spec.source.specs.search([spec.name, spec.version]).map(&:platform) }.uniq
|
274
282
|
end
|
275
283
|
|
284
|
+
def additional_variants_from(other)
|
285
|
+
other.select do |spec|
|
286
|
+
version_for(spec.name) == spec.version && valid_dependencies?(spec)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
276
290
|
def valid_dependencies?(s)
|
277
291
|
validate_deps(s) == :valid
|
278
292
|
end
|
data/bundler/lib/bundler.rb
CHANGED
@@ -212,7 +212,6 @@ module Bundler
|
|
212
212
|
# Bundler.require(:test) # requires second_gem
|
213
213
|
#
|
214
214
|
def require(*groups)
|
215
|
-
load_plugins
|
216
215
|
setup(*groups).require(*groups)
|
217
216
|
end
|
218
217
|
|
@@ -548,15 +547,7 @@ module Bundler
|
|
548
547
|
def load_gemspec_uncached(file, validate = false)
|
549
548
|
path = Pathname.new(file)
|
550
549
|
contents = read_file(file)
|
551
|
-
spec =
|
552
|
-
eval_yaml_gemspec(path, contents)
|
553
|
-
else
|
554
|
-
# Eval the gemspec from its parent directory, because some gemspecs
|
555
|
-
# depend on "./" relative paths.
|
556
|
-
SharedHelpers.chdir(path.dirname.to_s) do
|
557
|
-
eval_gemspec(path, contents)
|
558
|
-
end
|
559
|
-
end
|
550
|
+
spec = eval_gemspec(path, contents)
|
560
551
|
return unless spec
|
561
552
|
spec.loaded_from = path.expand_path.to_s
|
562
553
|
Bundler.rubygems.validate(spec) if validate
|
@@ -576,23 +567,6 @@ module Bundler
|
|
576
567
|
@feature_flag ||= FeatureFlag.new(VERSION)
|
577
568
|
end
|
578
569
|
|
579
|
-
def load_plugins(definition = Bundler.definition)
|
580
|
-
return if defined?(@load_plugins_ran)
|
581
|
-
|
582
|
-
Bundler.rubygems.load_plugins
|
583
|
-
|
584
|
-
requested_path_gems = definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
|
585
|
-
path_plugin_files = requested_path_gems.flat_map do |spec|
|
586
|
-
spec.matches_for_glob("rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
|
587
|
-
rescue TypeError
|
588
|
-
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
|
589
|
-
raise Gem::InvalidSpecificationException, error_message
|
590
|
-
end
|
591
|
-
Bundler.rubygems.load_plugin_files(path_plugin_files)
|
592
|
-
Bundler.rubygems.load_env_plugins
|
593
|
-
@load_plugins_ran = true
|
594
|
-
end
|
595
|
-
|
596
570
|
def reset!
|
597
571
|
reset_paths!
|
598
572
|
Plugin.reset!
|
@@ -675,12 +649,18 @@ module Bundler
|
|
675
649
|
Kernel.require "psych"
|
676
650
|
|
677
651
|
Gem::Specification.from_yaml(contents)
|
678
|
-
rescue ::Psych::SyntaxError, ArgumentError, Gem::EndOfYAMLException, Gem::Exception
|
679
|
-
eval_gemspec(path, contents)
|
680
652
|
end
|
681
653
|
|
682
654
|
def eval_gemspec(path, contents)
|
683
|
-
|
655
|
+
if contents.start_with?("---") # YAML header
|
656
|
+
eval_yaml_gemspec(path, contents)
|
657
|
+
else
|
658
|
+
# Eval the gemspec from its parent directory, because some gemspecs
|
659
|
+
# depend on "./" relative paths.
|
660
|
+
SharedHelpers.chdir(path.dirname.to_s) do
|
661
|
+
eval(contents, TOPLEVEL_BINDING.dup, path.expand_path.to_s)
|
662
|
+
end
|
663
|
+
end
|
684
664
|
rescue ScriptError, StandardError => e
|
685
665
|
msg = "There was an error while loading `#{path.basename}`: #{e.message}"
|
686
666
|
|
data/doc/rubygems/POLICIES.md
CHANGED
@@ -95,7 +95,7 @@ the version in all version files, synchronizes both changelogs to include all
|
|
95
95
|
backported changes and commits that change on top of the cherry-picks.
|
96
96
|
|
97
97
|
Note that this task requires all user facing pull requests to be tagged with
|
98
|
-
specific labels. See [Merging a PR](
|
98
|
+
specific labels. See [Merging a PR](../bundler/playbooks/MERGING_A_PR.md) for details.
|
99
99
|
|
100
100
|
Also note that when this task cherry-picks, it cherry-picks the merge commits
|
101
101
|
using the following command:
|
@@ -15,6 +15,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
|
|
15
15
|
version display the gem format version
|
16
16
|
remotesources display the remote gem servers
|
17
17
|
platform display the supported gem platforms
|
18
|
+
credentials display the path where credentials are stored
|
18
19
|
<omitted> display everything
|
19
20
|
EOF
|
20
21
|
args.gsub(/^\s+/, "")
|
@@ -88,6 +89,8 @@ lib/rubygems/defaults/operating_system.rb
|
|
88
89
|
Gem.sources.to_a.join("\n")
|
89
90
|
when /^platform/ then
|
90
91
|
Gem.platforms.join(File::PATH_SEPARATOR)
|
92
|
+
when /^credentials/, /^creds/ then
|
93
|
+
Gem.configuration.credentials_path
|
91
94
|
when nil then
|
92
95
|
show_environment
|
93
96
|
else
|
@@ -114,6 +117,8 @@ lib/rubygems/defaults/operating_system.rb
|
|
114
117
|
|
115
118
|
out << " - USER INSTALLATION DIRECTORY: #{Gem.user_dir}\n"
|
116
119
|
|
120
|
+
out << " - CREDENTIALS FILE: #{Gem.configuration.credentials_path}\n"
|
121
|
+
|
117
122
|
out << " - RUBYGEMS PREFIX: #{Gem.prefix}\n" unless Gem.prefix.nil?
|
118
123
|
|
119
124
|
out << " - RUBY EXECUTABLE: #{Gem.ruby}\n"
|
data/lib/rubygems/rdoc.rb
CHANGED
@@ -6,8 +6,17 @@ begin
|
|
6
6
|
require "rdoc/rubygems_hook"
|
7
7
|
module Gem
|
8
8
|
RDoc = ::RDoc::RubygemsHook
|
9
|
+
|
10
|
+
##
|
11
|
+
# Returns whether RDoc defines its own install hooks through a RubyGems
|
12
|
+
# plugin. This and whatever is guarded by it can be removed once no
|
13
|
+
# supported Ruby ships with RDoc older than 6.9.0.
|
14
|
+
|
15
|
+
def self.rdoc_hooks_defined_via_plugin?
|
16
|
+
Gem::Version.new(::RDoc::VERSION) >= Gem::Version.new("6.9.0")
|
17
|
+
end
|
9
18
|
end
|
10
19
|
|
11
|
-
Gem.done_installing(&Gem::RDoc.method(:generation_hook))
|
20
|
+
Gem.done_installing(&Gem::RDoc.method(:generation_hook)) unless Gem.rdoc_hooks_defined_via_plugin?
|
12
21
|
rescue LoadError
|
13
22
|
end
|
data/lib/rubygems/requirement.rb
CHANGED
@@ -22,7 +22,7 @@ class Gem::Requirement
|
|
22
22
|
|
23
23
|
SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
|
24
24
|
|
25
|
-
quoted = OPS.keys
|
25
|
+
quoted = Regexp.union(OPS.keys)
|
26
26
|
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*".freeze # :nodoc:
|
27
27
|
|
28
28
|
##
|
@@ -201,7 +201,8 @@ class Gem::Requirement
|
|
201
201
|
def marshal_load(array) # :nodoc:
|
202
202
|
@requirements = array[0]
|
203
203
|
|
204
|
-
raise TypeError, "wrong @requirements" unless Array === @requirements
|
204
|
+
raise TypeError, "wrong @requirements" unless Array === @requirements &&
|
205
|
+
@requirements.all? {|r| r.size == 2 && (r.first.is_a?(String) || r[0] = "=") && r.last.is_a?(Gem::Version) }
|
205
206
|
end
|
206
207
|
|
207
208
|
def yaml_initialize(tag, vals) # :nodoc:
|
@@ -238,7 +239,7 @@ class Gem::Requirement
|
|
238
239
|
def satisfied_by?(version)
|
239
240
|
raise ArgumentError, "Need a Gem::Version: #{version.inspect}" unless
|
240
241
|
Gem::Version === version
|
241
|
-
requirements.all? {|op, rv| OPS
|
242
|
+
requirements.all? {|op, rv| OPS.fetch(op).call version, rv }
|
242
243
|
end
|
243
244
|
|
244
245
|
alias_method :===, :satisfied_by?
|
@@ -20,6 +20,12 @@ module Gem
|
|
20
20
|
class EOFError < Error
|
21
21
|
end
|
22
22
|
|
23
|
+
class DataTooShortError < Error
|
24
|
+
end
|
25
|
+
|
26
|
+
class NegativeLengthError < Error
|
27
|
+
end
|
28
|
+
|
23
29
|
def initialize(io)
|
24
30
|
@io = io
|
25
31
|
end
|
@@ -27,7 +33,7 @@ module Gem
|
|
27
33
|
def read!
|
28
34
|
read_header
|
29
35
|
root = read_element
|
30
|
-
raise UnconsumedBytesError unless @io.eof?
|
36
|
+
raise UnconsumedBytesError, "expected EOF, got #{@io.read(10).inspect}... after top-level element #{root.class}" unless @io.eof?
|
31
37
|
root
|
32
38
|
end
|
33
39
|
|
@@ -41,8 +47,16 @@ module Gem
|
|
41
47
|
raise UnsupportedVersionError, "Unsupported marshal version #{v.bytes.map(&:ord).join(".")}, expected #{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" unless v == MARSHAL_VERSION
|
42
48
|
end
|
43
49
|
|
50
|
+
def read_bytes(n)
|
51
|
+
raise NegativeLengthError if n < 0
|
52
|
+
str = @io.read(n)
|
53
|
+
raise EOFError, "expected #{n} bytes, got EOF" if str.nil?
|
54
|
+
raise DataTooShortError, "expected #{n} bytes, got #{str.inspect}" unless str.bytesize == n
|
55
|
+
str
|
56
|
+
end
|
57
|
+
|
44
58
|
def read_byte
|
45
|
-
@io.getbyte
|
59
|
+
@io.getbyte || raise(EOFError, "Unexpected EOF")
|
46
60
|
end
|
47
61
|
|
48
62
|
def read_integer
|
@@ -67,8 +81,6 @@ module Gem
|
|
67
81
|
read_byte | (read_byte << 8) | -0x10000
|
68
82
|
when 0xFF
|
69
83
|
read_byte | -0x100
|
70
|
-
when nil
|
71
|
-
raise EOFError, "Unexpected EOF"
|
72
84
|
else
|
73
85
|
signed = (b ^ 128) - 128
|
74
86
|
if b >= 128
|
@@ -107,8 +119,6 @@ module Gem
|
|
107
119
|
when 47 then read_regexp # ?/
|
108
120
|
when 83 then read_struct # ?S
|
109
121
|
when 67 then read_user_class # ?C
|
110
|
-
when nil
|
111
|
-
raise EOFError, "Unexpected EOF"
|
112
122
|
else
|
113
123
|
raise Error, "Unknown marshal type discriminator #{type.chr.inspect} (#{type})"
|
114
124
|
end
|
@@ -127,7 +137,7 @@ module Gem
|
|
127
137
|
Elements::Symbol.new(byte.chr)
|
128
138
|
end
|
129
139
|
else
|
130
|
-
name =
|
140
|
+
name = read_bytes(len)
|
131
141
|
Elements::Symbol.new(name)
|
132
142
|
end
|
133
143
|
end
|
@@ -138,7 +148,7 @@ module Gem
|
|
138
148
|
def read_string
|
139
149
|
length = read_integer
|
140
150
|
return EMPTY_STRING if length == 0
|
141
|
-
str =
|
151
|
+
str = read_bytes(length)
|
142
152
|
Elements::String.new(str)
|
143
153
|
end
|
144
154
|
|
@@ -152,7 +162,7 @@ module Gem
|
|
152
162
|
|
153
163
|
def read_user_defined
|
154
164
|
name = read_element
|
155
|
-
binary_string =
|
165
|
+
binary_string = read_bytes(read_integer)
|
156
166
|
Elements::UserDefined.new(name, binary_string)
|
157
167
|
end
|
158
168
|
|
@@ -162,6 +172,7 @@ module Gem
|
|
162
172
|
def read_array
|
163
173
|
length = read_integer
|
164
174
|
return EMPTY_ARRAY if length == 0
|
175
|
+
raise NegativeLengthError if length < 0
|
165
176
|
elements = Array.new(length) do
|
166
177
|
read_element
|
167
178
|
end
|
@@ -170,7 +181,9 @@ module Gem
|
|
170
181
|
|
171
182
|
def read_object_with_ivars
|
172
183
|
object = read_element
|
173
|
-
|
184
|
+
length = read_integer
|
185
|
+
raise NegativeLengthError if length < 0
|
186
|
+
ivars = Array.new(length) do
|
174
187
|
[read_element, read_element]
|
175
188
|
end
|
176
189
|
Elements::WithIvars.new(object, ivars)
|
@@ -239,7 +252,9 @@ module Gem
|
|
239
252
|
end
|
240
253
|
|
241
254
|
def read_hash_with_default_value
|
242
|
-
|
255
|
+
length = read_integer
|
256
|
+
raise NegativeLengthError if length < 0
|
257
|
+
pairs = Array.new(length) do
|
243
258
|
[read_element, read_element]
|
244
259
|
end
|
245
260
|
default = read_element
|
@@ -249,7 +264,9 @@ module Gem
|
|
249
264
|
def read_object
|
250
265
|
name = read_element
|
251
266
|
object = Elements::Object.new(name)
|
252
|
-
|
267
|
+
length = read_integer
|
268
|
+
raise NegativeLengthError if length < 0
|
269
|
+
ivars = Array.new(length) do
|
253
270
|
[read_element, read_element]
|
254
271
|
end
|
255
272
|
Elements::WithIvars.new(object, ivars)
|
@@ -260,13 +277,13 @@ module Gem
|
|
260
277
|
end
|
261
278
|
|
262
279
|
def read_float
|
263
|
-
string =
|
280
|
+
string = read_bytes(read_integer)
|
264
281
|
Elements::Float.new(string)
|
265
282
|
end
|
266
283
|
|
267
284
|
def read_bignum
|
268
285
|
sign = read_byte
|
269
|
-
data =
|
286
|
+
data = read_bytes(read_integer * 2)
|
270
287
|
Elements::Bignum.new(sign, data)
|
271
288
|
end
|
272
289
|
|
@@ -45,7 +45,7 @@ module Gem::SafeMarshal
|
|
45
45
|
idx = 0
|
46
46
|
# not idiomatic, but there's a huge number of IMEMOs allocated here, so we avoid the block
|
47
47
|
# because this is such a hot path when doing a bundle install with the full index
|
48
|
-
|
48
|
+
while idx < size
|
49
49
|
push_stack idx
|
50
50
|
array << visit(elements[idx])
|
51
51
|
idx += 1
|
@@ -98,16 +98,21 @@ module Gem::SafeMarshal
|
|
98
98
|
end
|
99
99
|
|
100
100
|
s = e.object.binary_string
|
101
|
+
# 122 is the largest integer that can be represented in marshal in a single byte
|
102
|
+
raise TimeTooLargeError.new("binary string too large", stack: formatted_stack) if s.bytesize > 122
|
101
103
|
|
102
104
|
marshal_string = "\x04\bIu:\tTime".b
|
103
|
-
marshal_string.concat(s.
|
105
|
+
marshal_string.concat(s.bytesize + 5)
|
104
106
|
marshal_string << s
|
107
|
+
# internal is limited to 5, so no overflow is possible
|
105
108
|
marshal_string.concat(internal.size + 5)
|
106
109
|
|
107
110
|
internal.each do |k, v|
|
111
|
+
k = k.name
|
112
|
+
# ivar name can't be too large because only known ivars are in the internal ivars list
|
108
113
|
marshal_string.concat(":")
|
109
|
-
marshal_string.concat(k.
|
110
|
-
marshal_string.concat(k
|
114
|
+
marshal_string.concat(k.bytesize + 5)
|
115
|
+
marshal_string.concat(k)
|
111
116
|
dumped = Marshal.dump(v)
|
112
117
|
dumped[0, 2] = ""
|
113
118
|
marshal_string.concat(dumped)
|
@@ -171,11 +176,11 @@ module Gem::SafeMarshal
|
|
171
176
|
end
|
172
177
|
|
173
178
|
def visit_Gem_SafeMarshal_Elements_ObjectLink(o)
|
174
|
-
@objects
|
179
|
+
@objects.fetch(o.offset)
|
175
180
|
end
|
176
181
|
|
177
182
|
def visit_Gem_SafeMarshal_Elements_SymbolLink(o)
|
178
|
-
@symbols
|
183
|
+
@symbols.fetch(o.offset)
|
179
184
|
end
|
180
185
|
|
181
186
|
def visit_Gem_SafeMarshal_Elements_UserDefined(o)
|
@@ -219,16 +224,18 @@ module Gem::SafeMarshal
|
|
219
224
|
end
|
220
225
|
|
221
226
|
def visit_Gem_SafeMarshal_Elements_Float(f)
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
227
|
+
register_object(
|
228
|
+
case f.string
|
229
|
+
when "inf"
|
230
|
+
::Float::INFINITY
|
231
|
+
when "-inf"
|
232
|
+
-::Float::INFINITY
|
233
|
+
when "nan"
|
234
|
+
::Float::NAN
|
235
|
+
else
|
236
|
+
f.string.to_f
|
237
|
+
end
|
238
|
+
)
|
232
239
|
end
|
233
240
|
|
234
241
|
def visit_Gem_SafeMarshal_Elements_Bignum(b)
|
@@ -374,6 +381,12 @@ module Gem::SafeMarshal
|
|
374
381
|
class Error < StandardError
|
375
382
|
end
|
376
383
|
|
384
|
+
class TimeTooLargeError < Error
|
385
|
+
def initialize(message, stack:)
|
386
|
+
super "#{message} @ #{stack.join "."}"
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
377
390
|
class UnpermittedSymbolError < Error
|
378
391
|
def initialize(symbol:, stack:)
|
379
392
|
@symbol = symbol
|
@@ -1322,7 +1322,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1322
1322
|
spec.instance_variable_set :@description, array[13]
|
1323
1323
|
spec.instance_variable_set :@homepage, array[14]
|
1324
1324
|
spec.instance_variable_set :@has_rdoc, array[15]
|
1325
|
-
spec.instance_variable_set :@licenses,
|
1325
|
+
spec.instance_variable_set :@licenses, array[17]
|
1326
1326
|
spec.instance_variable_set :@metadata, array[18]
|
1327
1327
|
spec.instance_variable_set :@loaded, false
|
1328
1328
|
spec.instance_variable_set :@activated, false
|
@@ -1817,16 +1817,8 @@ class Gem::Specification < Gem::BasicSpecification
|
|
1817
1817
|
def encode_with(coder) # :nodoc:
|
1818
1818
|
coder.add "name", @name
|
1819
1819
|
coder.add "version", @version
|
1820
|
-
platform
|
1821
|
-
|
1822
|
-
"ruby"
|
1823
|
-
when String then
|
1824
|
-
@new_platform
|
1825
|
-
else
|
1826
|
-
@new_platform.to_s
|
1827
|
-
end
|
1828
|
-
coder.add "platform", platform
|
1829
|
-
coder.add "original_platform", @original_platform.to_s if platform != @original_platform.to_s
|
1820
|
+
coder.add "platform", platform.to_s
|
1821
|
+
coder.add "original_platform", original_platform.to_s if platform.to_s != original_platform.to_s
|
1830
1822
|
|
1831
1823
|
attributes = @@attributes.map(&:to_s) - %w[name version platform]
|
1832
1824
|
attributes.each do |name|
|