rubygems-update 4.0.18 → 4.0.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf600fcd45beb7a21ff7e319301fa12ebb2fb74e800a11eb0ec49edd79e290ad
4
- data.tar.gz: 53a095fcf4f29c4e06adf5f5759ffd3f7d481b15553a549bc0d7dc6abc74c087
3
+ metadata.gz: fea8148baa9550b989b52e1b5a5bdd0331ce3f3658acd4e6a8655b4aca669d05
4
+ data.tar.gz: d6873bcf37f0e87a7c35663e446b5a907a833d469270fce61e06e5c384b26b64
5
5
  SHA512:
6
- metadata.gz: 412444397c9bb743e7a573e6838a0e5a5f4c5140bb1878eb11c0fe906c349d047c6d6ddeb0fe74b0da2560e4061359a8fbaa3ffab88b129e0df096406801d145
7
- data.tar.gz: fe0f8c100c204f73322acd599498e9fa71669e0286a1dc6ef7b576f94c98303d4d9a44117239a6bf6667191623f6d634b0f45424aa48fecd54092aff1c9480ae
6
+ metadata.gz: 959ce199999beef457228f6ca8ef0d74f6cd19cb433fe5fdf21ec42961df13b81b98209a21bb2c6c298521b201cf2f64161be7efd5a3ac92d155a6c0c17876d0
7
+ data.tar.gz: eb602763996a439e8f8598b14c08ead139b527a814e11c9acdae89c4c1556ede07fed87cdde079509b124510f5f3844e394ef74e69e3a532c1900b271d684b14
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.19 / 2026-08-20
4
+
5
+ ### Enhancements:
6
+
7
+ * Reject SafeMarshal collection lengths longer than the remaining input. Pull request [#9756](https://github.com/ruby/rubygems/pull/9756) by hsbt
8
+ * Installs bundler 4.0.19 as a default gem.
9
+
10
+ ### Bug fixes:
11
+
12
+ * Fix gem uninstall --user-install crash when GEM_HOME does not exist. Pull request [#9749](https://github.com/ruby/rubygems/pull/9749) by hsbt
13
+
14
+ ### Documentation:
15
+
16
+ * Document SPDX license handling for license= and licenses=. Pull request [#9766](https://github.com/ruby/rubygems/pull/9766) by hsbt
17
+
3
18
  ## 4.0.18 / 2026-08-05
4
19
 
5
20
  ### Enhancements:
data/bundler/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.19 / 2026-08-20
4
+
5
+ ### Enhancements:
6
+
7
+ * Validate the platform field in Gem::Installer#verify_spec. Pull request [#9780](https://github.com/ruby/rubygems/pull/9780) by hsbt
8
+ * Restrict UserDefined handling to explicit class set for Gem::SafeMashal. Pull request [#9770](https://github.com/ruby/rubygems/pull/9770) by jackorp
9
+ * Filter git command output against the configured URI. Pull request [#9778](https://github.com/ruby/rubygems/pull/9778) by hsbt
10
+ * Summarize cooldown-skipped versions at the end of install, update, and lock. Pull request [#9762](https://github.com/ruby/rubygems/pull/9762) by hsbt
11
+
12
+ ### Bug fixes:
13
+
14
+ * Make repeated bundle lock options accumulate. Pull request [#9748](https://github.com/ruby/rubygems/pull/9748) by hsbt
15
+ * Fail instead of warning when frozen mode can't update the lockfile. Pull request [#9750](https://github.com/ruby/rubygems/pull/9750) by hsbt
16
+ * Fix wrong $LOAD_PATH for gems installed in the same process. Pull request [#9784](https://github.com/ruby/rubygems/pull/9784) by hsbt
17
+
18
+ ### Documentation:
19
+
20
+ * Fix auto-clean default version in bundle config docs. Pull request [#9783](https://github.com/ruby/rubygems/pull/9783) by hsbt
21
+ * Correct Bundler 5 default path documentation. Pull request [#9771](https://github.com/ruby/rubygems/pull/9771) by alloutflo
22
+
3
23
  ## 4.0.18 / 2026-08-05
4
24
 
5
25
  ### Enhancements:
@@ -5,7 +5,7 @@ module Bundler
5
5
  module BuildMetadata
6
6
  # begin ivars
7
7
  @built_at = nil
8
- @git_commit_sha = "7e934435ff".freeze
8
+ @git_commit_sha = "2d0e3df43a".freeze
9
9
  # end ivars
10
10
 
11
11
  # A hash representation of the build metadata.
@@ -20,6 +20,17 @@ module Bundler
20
20
  Bundler.ui.info msg
21
21
  end
22
22
 
23
+ def self.output_cooldown_skipped_summary(definition = Bundler.definition)
24
+ skipped = definition.cooldown_skipped
25
+ return if skipped.empty?
26
+
27
+ Bundler.ui.info "The following gem versions were skipped by the cooldown setting:"
28
+ skipped.each do |entry|
29
+ days = entry[:available_in_days]
30
+ Bundler.ui.info " * #{entry[:name]} #{entry[:version]} (available in #{days} #{days == 1 ? "day" : "days"}), resolved #{entry[:resolved]} instead"
31
+ end
32
+ end
33
+
23
34
  def self.output_fund_metadata_summary
24
35
  return if Bundler.settings["ignore_funding_requests"]
25
36
  definition = Bundler.definition
@@ -64,6 +64,7 @@ module Bundler
64
64
  end
65
65
 
66
66
  Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
67
+ Bundler::CLI::Common.output_cooldown_skipped_summary(definition)
67
68
 
68
69
  if CLI::Common.clean_after_install?
69
70
  require_relative "clean"
@@ -26,6 +26,9 @@ module Bundler
26
26
  Bundler::Fetcher.disable_endpoint = options["full-index"]
27
27
 
28
28
  update = options[:update]
29
+ # --update is repeatable, so it parses as an array with one entry per
30
+ # occurrence, where a bare `--update` produces a `true` entry
31
+ update = update.include?(true) ? true : update.flatten if update.is_a?(Array)
29
32
  conservative = options[:conservative]
30
33
  bundler = options[:bundler]
31
34
 
@@ -44,12 +47,12 @@ module Bundler
44
47
 
45
48
  Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
46
49
 
47
- options["remove-platform"].each do |platform_string|
50
+ options["remove-platform"].flatten.each do |platform_string|
48
51
  platform = Gem::Platform.new(platform_string)
49
52
  definition.remove_platform(platform)
50
53
  end
51
54
 
52
- options["add-platform"].each do |platform_string|
55
+ options["add-platform"].flatten.each do |platform_string|
53
56
  platform = Gem::Platform.new(platform_string)
54
57
  if platform.to_s == "unknown"
55
58
  Bundler.ui.error "The platform `#{platform_string}` is unknown to RubyGems and can't be added to the lockfile."
@@ -77,6 +80,8 @@ module Bundler
77
80
  puts "Writing lockfile to #{file}"
78
81
  definition.write_lock(file, false)
79
82
  end
83
+
84
+ Bundler::CLI::Common.output_cooldown_skipped_summary(definition)
80
85
  end
81
86
 
82
87
  Bundler.ui.output_stream = previous_output_stream
@@ -118,6 +118,7 @@ module Bundler
118
118
  Bundler.ui.confirm "Bundle updated!"
119
119
  Bundler::CLI::Common.output_without_groups_message(:update)
120
120
  Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
121
+ Bundler::CLI::Common.output_cooldown_skipped_summary
121
122
 
122
123
  Bundler::CLI::Common.output_fund_metadata_summary
123
124
  end
@@ -626,15 +626,15 @@ module Bundler
626
626
  end
627
627
 
628
628
  desc "lock", "Creates a lockfile without installing"
629
- method_option "update", type: :array, lazy_default: true, banner: "ignore the existing lockfile, update all gems by default, or update list of given gems"
629
+ method_option "update", type: :array, lazy_default: true, repeatable: true, banner: "ignore the existing lockfile, update all gems by default, or update list of given gems"
630
630
  method_option "local", type: :boolean, default: false, banner: "do not attempt to fetch remote gemspecs and use the local gem cache only"
631
631
  method_option "print", type: :boolean, default: false, banner: "print the lockfile to STDOUT instead of writing to the file system"
632
632
  method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
633
633
  method_option "lockfile", type: :string, default: nil, banner: "the path the lockfile should be written to"
634
634
  method_option "full-index", type: :boolean, default: false, banner: "Fall back to using the single-file index of all gems"
635
635
  method_option "add-checksums", type: :boolean, default: false, banner: "Adds checksums to the lockfile"
636
- method_option "add-platform", type: :array, default: [], banner: "Add a new platform to the lockfile"
637
- method_option "remove-platform", type: :array, default: [], banner: "Remove a platform from the lockfile"
636
+ method_option "add-platform", type: :array, default: [], repeatable: true, banner: "Add a new platform to the lockfile"
637
+ method_option "remove-platform", type: :array, default: [], repeatable: true, banner: "Remove a platform from the lockfile"
638
638
  method_option "normalize-platforms", type: :boolean, default: false, banner: "Normalize lockfile platforms"
639
639
  method_option "patch", type: :boolean, banner: "If updating, prefer updating only to next patch version"
640
640
  method_option "minor", type: :boolean, banner: "If updating, prefer updating only to next minor version"
@@ -366,6 +366,12 @@ module Bundler
366
366
  sources.git_sources.filter_map {|s| File.realpath(s.path) if File.exist?(s.path) }
367
367
  end
368
368
 
369
+ # Versions excluded by cooldown during the last resolution, one entry per
370
+ # gem with the newest skipped version. Empty when no resolution ran.
371
+ def cooldown_skipped
372
+ @cooldown_skipped || []
373
+ end
374
+
369
375
  def groups
370
376
  dependencies.flat_map(&:groups).uniq
371
377
  end
@@ -404,7 +410,7 @@ module Bundler
404
410
  updating_major = locked_major < current_major
405
411
  end
406
412
 
407
- preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
413
+ preserve_unknown_sections ||= Bundler.frozen_bundle? || (!updating_major && !(unlocking? || @unlocking_bundler))
408
414
 
409
415
  if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
410
416
  return if Bundler.frozen_bundle?
@@ -413,8 +419,10 @@ module Bundler
413
419
  end
414
420
 
415
421
  if Bundler.frozen_bundle?
416
- Bundler.ui.error "Cannot write a changed lockfile while frozen."
417
- return
422
+ msg = lockfile_changes_summary("frozen mode is set") ||
423
+ "Your lockfile needs to be updated, but it can't be because frozen mode is set.\n\n" \
424
+ "Run `bundle install` elsewhere and add the updated #{SharedHelpers.relative_lockfile_path} to version control."
425
+ raise ProductionError, msg
418
426
  end
419
427
 
420
428
  # Convert to \r\n if the existing lock has them, i.e., Windows with
@@ -770,6 +778,8 @@ module Bundler
770
778
 
771
779
  result = SpecSet.new(resolver.start)
772
780
 
781
+ @cooldown_skipped = resolver.cooldown_skipped
782
+
773
783
  @resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
774
784
 
775
785
  @new_platforms.each do |platform|
@@ -50,6 +50,19 @@ module Bundler
50
50
  end
51
51
  end
52
52
 
53
+ # `require_paths` is overridden above, but `full_require_paths` (and so
54
+ # `load_paths`) is computed from `raw_require_paths`, which would otherwise
55
+ # report the default `lib` for every gem
56
+ def raw_require_paths
57
+ if @remote_specification
58
+ @remote_specification.raw_require_paths
59
+ elsif _local_specification
60
+ _local_specification.raw_require_paths
61
+ else
62
+ super
63
+ end
64
+ end
65
+
53
66
  # needed for inline
54
67
  def load_paths
55
68
  # remote specs aren't installed, and can't have load_paths
@@ -83,6 +83,12 @@ module Bundler
83
83
  install(options)
84
84
 
85
85
  Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available
86
+ # Drop the source caches too, since releasing resolution memory dropped
87
+ # the source indexes. A resolution happening after this point would
88
+ # otherwise rebuild them around a snapshot of installed gems taken
89
+ # before the install, and materialize against remote specs that don't
90
+ # know where the gems they stand for ended up.
91
+ @definition.sources.clear_cache
86
92
 
87
93
  lock
88
94
  Standalone.new(options[:standalone], @definition).generate if options[:standalone]
@@ -103,6 +103,11 @@ module Bundler
103
103
  end
104
104
 
105
105
  def bundler_checksum
106
+ # In frozen mode the lockfile can't change, so reproduce whatever bundler
107
+ # entry is already locked instead of recording one for the running bundler
108
+ # version, which may legitimately differ from the locked one.
109
+ return locked_bundler_checksum if Bundler.frozen_bundle?
110
+
106
111
  # `.dev` versions and `SKIP_BUNDLER_CHECKSUM` are deliberate opt-outs (used
107
112
  # by Bundler/RubyGems' own development and release tasks): never record a
108
113
  # checksum for Bundler itself in those cases.
@@ -138,5 +143,16 @@ module Bundler
138
143
 
139
144
  locked_gems.bundler_version != definition.bundler_version_to_lock
140
145
  end
146
+
147
+ def locked_bundler_checksum
148
+ locked_version = definition.locked_gems&.bundler_version
149
+ return [] unless locked_version
150
+
151
+ metadata_source = definition.sources.metadata_source
152
+ locked_spec = LazySpecification.new("bundler", locked_version, Gem::Platform::RUBY, metadata_source)
153
+ return [] if metadata_source.checksum_store.missing?(locked_spec)
154
+
155
+ [metadata_source.checksum_store.to_lock(locked_spec)]
156
+ end
141
157
  end
142
158
  end
@@ -82,7 +82,7 @@ The following is a list of all configuration keys and their purpose\. You can le
82
82
  .IP "\(bu" 4
83
83
  \fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR): The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\.
84
84
  .IP "\(bu" 4
85
- \fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. Defaults to \fBtrue\fR in Bundler 4, as long as \fBpath\fR is not explicitly configured\.
85
+ \fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. Defaults to \fBtrue\fR in Bundler 5, as long as \fBpath\fR is not explicitly configured\.
86
86
  .IP "\(bu" 4
87
87
  \fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\.
88
88
  .IP "\(bu" 4
@@ -147,7 +147,7 @@ Cooldown filtering depends on the gem server providing a per\-version \fBcreated
147
147
  .IP "\(bu" 4
148
148
  \fBonly\fR (\fBBUNDLE_ONLY\fR): A space\-separated list of groups to install only gems of the specified groups\. Please check carefully if you want to install also gems without a group, because they get put inside \fBdefault\fR group\. For example \fBonly test:default\fR will install all gems specified in test group and without one\.
149
149
  .IP "\(bu" 4
150
- \fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. When not set, Bundler install by default to a \fB\.bundle\fR directory relative to repository root in Bundler 4, and to the default system path (\fBGem\.dir\fR) before Bundler 4\. That means that before Bundler 4, Bundler shares this location with Rubygems, and \fBgem install \|\.\|\.\|\.\fR will have gems installed in the same location and therefore, gems installed without \fBpath\fR set will show up by calling \fBgem list\fR\. This will not be the case in Bundler 4\.
150
+ \fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. When not set, Bundler install by default to a \fB\.bundle\fR directory relative to repository root in Bundler 5, and to the default system path (\fBGem\.dir\fR) before Bundler 5\. That means that before Bundler 5, Bundler shares this location with Rubygems, and \fBgem install \|\.\|\.\|\.\fR will have gems installed in the same location and therefore, gems installed without \fBpath\fR set will show up by calling \fBgem list\fR\. This will not be the case in Bundler 5\.
151
151
  .IP "\(bu" 4
152
152
  \fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\.
153
153
  .IP "\(bu" 4
@@ -133,7 +133,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
133
133
  Defaults to `vendor/cache`.
134
134
  * `clean` (`BUNDLE_CLEAN`):
135
135
  Whether Bundler should run `bundle clean` automatically after
136
- `bundle install`. Defaults to `true` in Bundler 4, as long as `path` is not
136
+ `bundle install`. Defaults to `true` in Bundler 5, as long as `path` is not
137
137
  explicitly configured.
138
138
  * `console` (`BUNDLE_CONSOLE`):
139
139
  The console that `bundle console` starts. Defaults to `irb`.
@@ -245,12 +245,12 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
245
245
  The location on disk where all gems in your bundle will be located regardless
246
246
  of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location
247
247
  will be installed by `bundle install`. When not set, Bundler install by
248
- default to a `.bundle` directory relative to repository root in Bundler 4,
249
- and to the default system path (`Gem.dir`) before Bundler 4. That means that
250
- before Bundler 4, Bundler shares this location with Rubygems, and `gem
248
+ default to a `.bundle` directory relative to repository root in Bundler 5,
249
+ and to the default system path (`Gem.dir`) before Bundler 5. That means that
250
+ before Bundler 5, Bundler shares this location with Rubygems, and `gem
251
251
  install ...` will have gems installed in the same location and therefore,
252
252
  gems installed without `path` set will show up by calling `gem list`. This
253
- will not be the case in Bundler 4.
253
+ will not be the case in Bundler 5.
254
254
  * `path.system` (`BUNDLE_PATH__SYSTEM`):
255
255
  Whether Bundler will install gems into the default system path (`Gem.dir`).
256
256
  * `plugins` (`BUNDLE_PLUGINS`):
@@ -14,11 +14,15 @@ module Bundler
14
14
  require_relative "resolver/root"
15
15
  require_relative "resolver/strategy"
16
16
 
17
+ attr_reader :cooldown_skipped
18
+
17
19
  def initialize(base, gem_version_promoter, most_specific_locked_platform = nil)
18
20
  @source_requirements = base.source_requirements
19
21
  @base = base
20
22
  @gem_version_promoter = gem_version_promoter
21
23
  @most_specific_locked_platform = most_specific_locked_platform
24
+ @cooldown_skipped = []
25
+ @cooldown_skipped_specs = {}
22
26
  end
23
27
 
24
28
  def start
@@ -36,6 +40,8 @@ module Bundler
36
40
  root = Resolver::Root.new(name_for_explicit_dependency_source)
37
41
  root_version = Resolver::Candidate.new(0)
38
42
 
43
+ @cooldown_skipped_specs = {}
44
+
39
45
  @all_specs = Hash.new do |specs, name|
40
46
  source = source_for(name)
41
47
  matches = source.specs.search(name)
@@ -80,7 +86,9 @@ module Bundler
80
86
  solver = PubGrub::VersionSolver.new(source: self, root: root, strategy: Strategy.new(self), logger: logger)
81
87
  result = solver.solve
82
88
  resolved_specs = result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) }
83
- SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs)
89
+ spec_set = SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs)
90
+ @cooldown_skipped = cooldown_skipped_summary(spec_set)
91
+ spec_set
84
92
  rescue PubGrub::SolveFailure => e
85
93
  incompatibility = e.incompatibility
86
94
 
@@ -424,6 +432,7 @@ module Bundler
424
432
  specs.each do |spec|
425
433
  next unless cooldown_excluded?(spec)
426
434
  excluded[[spec.name, spec.version]] = true
435
+ (@cooldown_skipped_specs ||= {})[[spec.name, spec.version]] ||= spec
427
436
  end
428
437
  excluded
429
438
  end
@@ -466,6 +475,50 @@ module Bundler
466
475
  @cooldown_now ||= Time.now
467
476
  end
468
477
 
478
+ # Reports, per gem, the newest version that cooldown kept out of a
479
+ # successful resolution. A skipped version is only worth reporting when it
480
+ # is newer than the resolved version and satisfies every requirement the
481
+ # final resolution places on that gem, so we don't claim a version the
482
+ # resolver could never have picked anyway.
483
+ def cooldown_skipped_summary(spec_set)
484
+ return [] if @cooldown_skipped_specs.empty?
485
+
486
+ requirements = Hash.new {|h, name| h[name] = [] }
487
+ @requirements.each {|dep| requirements[dep.name] << dep.requirement }
488
+ spec_set.each do |spec|
489
+ spec.dependencies.each {|dep| requirements[dep.name] << dep.requirement }
490
+ end
491
+
492
+ resolved_versions = {}
493
+ spec_set.each do |spec|
494
+ version = resolved_versions[spec.name]
495
+ resolved_versions[spec.name] = spec.version if version.nil? || spec.version > version
496
+ end
497
+
498
+ newest_skipped = {}
499
+ @cooldown_skipped_specs.each do |(name, version), spec|
500
+ resolved = resolved_versions[name]
501
+ next unless resolved && version > resolved
502
+ next unless requirements[name].all? {|req| req.satisfied_by?(version) }
503
+ newest = newest_skipped[name]
504
+ newest_skipped[name] = spec if newest.nil? || version > newest.version
505
+ end
506
+
507
+ newest_skipped.values.sort_by(&:name).map do |spec|
508
+ {
509
+ name: spec.name,
510
+ version: spec.version,
511
+ resolved: resolved_versions[spec.name],
512
+ available_in_days: remaining_cooldown_days(spec),
513
+ }
514
+ end
515
+ end
516
+
517
+ def remaining_cooldown_days(spec)
518
+ remaining = (spec.remote.effective_cooldown * 86_400) - (cooldown_now - spec.created_at)
519
+ [(remaining / 86_400.0).ceil, 1].max
520
+ end
521
+
469
522
  def filter_remote_specs(specs, package)
470
523
  if package.prefer_local?
471
524
  local_specs = specs.select {|s| s.is_a?(StubSpecification) }
@@ -364,9 +364,10 @@ module Bundler
364
364
  git("rev-parse", "--verify", reference, dir: path).strip
365
365
  end
366
366
 
367
- # Adds credentials to the URI
367
+ # Adds credentials to the URI. This is the URI given to git, so it's
368
+ # also the one command output must be filtered against.
368
369
  def configured_uri
369
- if /https?:/.match?(uri)
370
+ @configured_uri ||= if /https?:/.match?(uri)
370
371
  remote = Gem::URI(uri)
371
372
  config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
372
373
  remote.userinfo ||= config_auth
@@ -409,7 +410,7 @@ module Bundler
409
410
  raise GitNotInstalledError.new unless Bundler.git_present?
410
411
 
411
412
  require "shellwords"
412
- URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
413
+ URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", configured_uri)
413
414
  end
414
415
 
415
416
  def run_command(*command, dir: nil)
@@ -429,10 +430,10 @@ module Bundler
429
430
  require "open3"
430
431
  out, err, status = Open3.capture3(*capture3_args_for(cmd, dir))
431
432
 
432
- filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
433
+ filtered_out = URICredentialsFilter.credential_filtered_string(out, configured_uri)
433
434
  return [filtered_out, status] if ignore_err
434
435
 
435
- filtered_err = URICredentialsFilter.credential_filtered_string(err, uri)
436
+ filtered_err = URICredentialsFilter.credential_filtered_string(err, configured_uri)
436
437
  [filtered_out, filtered_err, status]
437
438
  end
438
439
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "4.0.18".freeze
4
+ VERSION = "4.0.19".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= gem_version.segments.first
@@ -692,7 +692,7 @@ class Gem::Installer
692
692
  raise Gem::InstallError, "#{spec} has an invalid extensions"
693
693
  end
694
694
 
695
- if /\R/.match?(spec.platform.to_s)
695
+ unless /\A[\w.-]+\z/.match?(spec.platform.to_s)
696
696
  raise Gem::InstallError, "#{spec.platform} is an invalid platform"
697
697
  end
698
698
 
@@ -26,6 +26,9 @@ module Gem
26
26
  class NegativeLengthError < Error
27
27
  end
28
28
 
29
+ class LengthTooLongError < Error
30
+ end
31
+
29
32
  def initialize(io)
30
33
  @io = io
31
34
  @object_links = {}
@@ -93,6 +96,18 @@ module Gem
93
96
  end
94
97
  end
95
98
 
99
+ # Reads an element count and validates it against the number of bytes
100
+ # remaining in the input, since each element to be read consumes at
101
+ # least one byte. This prevents allocating huge backing stores for
102
+ # maliciously crafted lengths that could never be satisfied.
103
+ def read_count
104
+ count = read_integer
105
+ raise NegativeLengthError if count < 0
106
+ remaining = @io.size - @io.pos
107
+ raise LengthTooLongError, "expected #{count} elements, but only #{remaining} bytes remain" if count > remaining
108
+ count
109
+ end
110
+
96
111
  def read_element
97
112
  type = read_byte
98
113
  case type
@@ -172,9 +187,8 @@ module Gem
172
187
  private_constant :EMPTY_ARRAY
173
188
 
174
189
  def read_array
175
- length = read_integer
190
+ length = read_count
176
191
  return EMPTY_ARRAY if length == 0
177
- raise NegativeLengthError if length < 0
178
192
  elements = Array.new(length) do
179
193
  read_element
180
194
  end
@@ -183,8 +197,7 @@ module Gem
183
197
 
184
198
  def read_object_with_ivars
185
199
  object = read_element
186
- length = read_integer
187
- raise NegativeLengthError if length < 0
200
+ length = read_count
188
201
  ivars = Array.new(length) do
189
202
  [read_element, read_element]
190
203
  end
@@ -211,7 +224,7 @@ module Gem
211
224
  private_constant :EMPTY_HASH
212
225
 
213
226
  def read_hash
214
- length = read_integer
227
+ length = read_count
215
228
  return EMPTY_HASH if length == 0
216
229
  pairs = Array.new(length) do
217
230
  [read_element, read_element]
@@ -220,8 +233,7 @@ module Gem
220
233
  end
221
234
 
222
235
  def read_hash_with_default_value
223
- length = read_integer
224
- raise NegativeLengthError if length < 0
236
+ length = read_count
225
237
  pairs = Array.new(length) do
226
238
  [read_element, read_element]
227
239
  end
@@ -232,8 +244,7 @@ module Gem
232
244
  def read_object
233
245
  name = read_element
234
246
  object = Elements::Object.new(name)
235
- length = read_integer
236
- raise NegativeLengthError if length < 0
247
+ length = read_count
237
248
  ivars = Array.new(length) do
238
249
  [read_element, read_element]
239
250
  end
@@ -183,8 +183,15 @@ module Gem::SafeMarshal
183
183
  @symbols.fetch(o.offset)
184
184
  end
185
185
 
186
+ SAFE_USER_DEFINED_CLASSES = [::Time, ::Gem::Specification].freeze
187
+ private_constant :SAFE_USER_DEFINED_CLASSES
188
+
186
189
  def visit_Gem_SafeMarshal_Elements_UserDefined(o)
187
- register_object(call_method(resolve_class(o.name), :_load, o.binary_string))
190
+ klass = resolve_class(o.name)
191
+ unless SAFE_USER_DEFINED_CLASSES.include?(klass)
192
+ raise UnsupportedError.new("Unsupported user-defined class #{klass} in marshal stream", stack: formatted_stack)
193
+ end
194
+ register_object(call_method(klass, :_load, o.binary_string))
188
195
  end
189
196
 
190
197
  def visit_Gem_SafeMarshal_Elements_UserMarshal(o)
@@ -327,21 +327,30 @@ class Gem::Specification < Gem::BasicSpecification
327
327
  ##
328
328
  # The license for this gem.
329
329
  #
330
- # The license must be no more than 64 characters.
331
- #
332
- # This should just be the name of your license. The full text of the license
333
- # should be inside of the gem (at the top level) when you build it.
334
- #
335
- # The simplest way is to specify the standard SPDX ID
336
- # https://spdx.org/licenses/ for the license.
330
+ # The license must be no more than 64 characters, and should be a single
331
+ # SPDX license identifier from https://spdx.org/licenses/.
337
332
  # Ideally, you should pick one that is OSI (Open Source Initiative)
338
333
  # https://opensource.org/licenses/ approved.
339
334
  #
340
335
  # The most commonly used OSI-approved licenses are MIT and Apache-2.0.
341
336
  # GitHub also provides a license picker at https://choosealicense.com/.
342
337
  #
343
- # You can also use a custom license file along with your gemspec and specify
344
- # a LicenseRef-<idstring>, where idstring is the name of the file containing
338
+ # The full text of the license should be inside of the gem (at the top
339
+ # level) when you build it.
340
+ #
341
+ # RubyGems validates the license against the SPDX license list when you
342
+ # run <tt>gem build</tt> and warns about unknown or deprecated identifiers.
343
+ # An identifier may carry a trailing <tt>+</tt> (this version or any later
344
+ # version) and a license exception joined with WITH, for example
345
+ # <tt>Apache-2.0 WITH LLVM-exception</tt>.
346
+ #
347
+ # Compound SPDX license expressions such as <tt>MIT OR Apache-2.0</tt> are
348
+ # not currently supported. RubyGems treats the whole string as a single
349
+ # identifier and warns that it is invalid. For a gem available under more
350
+ # than one license, set each license as a separate entry with #licenses=.
351
+ #
352
+ # For a license that has no SPDX identifier, use Nonstandard, or
353
+ # LicenseRef-<idstring> where idstring is the name of the file containing
345
354
  # the license text.
346
355
  #
347
356
  # You should specify a license for your gem so that people know how they are
@@ -349,8 +358,6 @@ class Gem::Specification < Gem::BasicSpecification
349
358
  # specifying a license means all rights are reserved; others have no right
350
359
  # to use the code for any purpose.
351
360
  #
352
- # You can set multiple licenses with #licenses=
353
- #
354
361
  # Usage:
355
362
  # spec.license = 'MIT'
356
363
 
@@ -361,15 +368,20 @@ class Gem::Specification < Gem::BasicSpecification
361
368
  ##
362
369
  # The license(s) for the library.
363
370
  #
364
- # Each license must be a short name, no more than 64 characters.
371
+ # Each entry must be a single SPDX license identifier, no more than 64
372
+ # characters. Entries are validated independently, so a compound expression
373
+ # such as <tt>MIT OR Apache-2.0</tt> is not valid as an entry. Listing the
374
+ # identifiers as separate array elements is currently the only way RubyGems
375
+ # supports declaring a dual- or multi-licensed gem.
365
376
  #
366
- # This should just be the name of your license. The full
367
- # text of the license should be inside of the gem when you build it.
377
+ # Note that the array itself does not state how the licenses combine.
378
+ # Include the full text of each license in the gem and describe the exact
379
+ # terms there.
368
380
  #
369
381
  # See #license= for more discussion
370
382
  #
371
383
  # Usage:
372
- # spec.licenses = ['MIT', 'GPL-2.0']
384
+ # spec.licenses = ['MIT', 'GPL-2.0-only']
373
385
 
374
386
  def licenses=(licenses)
375
387
  @licenses = Array licenses
@@ -64,7 +64,8 @@ class Gem::Uninstaller
64
64
  @gem = gem
65
65
  @version = options[:version] || Gem::Requirement.default
66
66
  @install_dir = options[:install_dir]
67
- @gem_home = File.realpath(@install_dir || Gem.dir)
67
+ gem_home = @install_dir || Gem.dir
68
+ @gem_home = File.exist?(gem_home) ? File.realpath(gem_home) : gem_home
68
69
  @user_dir = File.exist?(Gem.user_dir) ? File.realpath(Gem.user_dir) : Gem.user_dir
69
70
  @force_executables = options[:executables]
70
71
  @force_all = options[:all]
data/lib/rubygems.rb CHANGED
@@ -9,7 +9,7 @@
9
9
  require "rbconfig"
10
10
 
11
11
  module Gem
12
- VERSION = "4.0.18"
12
+ VERSION = "4.0.19"
13
13
  end
14
14
 
15
15
  require_relative "rubygems/defaults"
@@ -1456,4 +1456,9 @@ else
1456
1456
  end
1457
1457
  eval File.read(path), nil, file
1458
1458
 
1459
+ # bundler/setup has to run before error_highlight, did_you_mean and
1460
+ # syntax_suggest are loaded, so that the Gemfile controls their versions
1461
+ # ([Bug #19089]). Ruby 4.1 autoloads them ([Feature #21951]) and deletes this
1462
+ # variable while loading RubyGems, so this can go once 4.1 is the oldest
1463
+ # supported version.
1459
1464
  require ENV["BUNDLER_SETUP"] if ENV["BUNDLER_SETUP"] && !defined?(Bundler)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubygems-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.18
4
+ version: 4.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -723,7 +723,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
723
723
  - !ruby/object:Gem::Version
724
724
  version: '0'
725
725
  requirements: []
726
- rubygems_version: 4.0.16
726
+ rubygems_version: 3.6.9
727
727
  specification_version: 4
728
728
  summary: RubyGems is a package management framework for Ruby. This gem is downloaded
729
729
  and installed by `gem update --system`, so that the `gem` CLI can update itself.