rubygems-update 3.6.1 → 3.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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|
|