Skip to content

Bump rubocop from 1.79.2 to 1.88.0#1003

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/bundler/rubocop-1.88.0
Open

Bump rubocop from 1.79.2 to 1.88.0#1003
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/bundler/rubocop-1.88.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 17, 2026

Copy link
Copy Markdown
Contributor

Bumps rubocop from 1.79.2 to 1.88.0.

Release notes

Sourced from rubocop's releases.

RuboCop v1.88.0

New features

  • #15166: Add a new Recursive option to Style/MutableConstant. When enabled, the cop checks and freezes mutable literals nested inside arrays and hashes. The option is disabled by default to preserve existing behavior. ([@​paracycle][])

Bug fixes

  • #15220: Fix a bad autocorrect for Lint/RedundantSplatExpansion when splatting an empty literal (e.g. when *[] or rescue *[]), which expanded to invalid or semantically different code. ([@​bbatsov][])
  • #15221: Fix a bad autocorrect for Lint/RegexpAsCondition when the regexp literal is negated (e.g. if !/foo/), which inverted the condition. ([@​bbatsov][])
  • #15242: Fix a bad autocorrect for Lint/SymbolConversion when the receiver is an interpolated string containing an embedded double quote (e.g. "foo#{bar}\"qux".to_sym), which produced a syntax error. ([@​bbatsov][])
  • #15270: Fix a crash for Style/CombinableLoops when a for loop has an empty body, and stop autocorrecting consecutive for loops whose iteration variables differ (which produced code referencing an undefined variable). ([@​bbatsov][])
  • #15272: Fix a crash for Style/ConstantVisibility when a visibility declaration has a numeric literal argument (e.g. private_constant 42). ([@​bbatsov][])
  • #15215: Fix a false negative for Lint/OrderedMagicComments when an encoding magic comment is preceded by a magic comment other than frozen_string_literal (e.g. shareable_constant_value). ([@​bbatsov][])
  • #15228: Fix a false negative for Lint/RedundantWithIndex when the block takes no arguments (e.g. ary.each_with_index { do_something }). ([@​bbatsov][])
  • #15230: Fix a false negative for Lint/RequireRelativeSelfPath when requiring the current file by name with its extension (e.g. require_relative 'foo.rb') and the file path is absolute. ([@​bbatsov][])
  • #15229: Fix a false negative for Lint/SafeNavigationChain when an ordinary method is chained after a parenthesized safe navigation call (e.g. (x&.foo).bar). ([@​bbatsov][])
  • #15225: Fix a false negative for Lint/SafeNavigationWithEmpty when the receiver of &.empty? is a local variable, instance variable, constant, or other non-method-call expression. ([@​bbatsov][])
  • #15231: Fix a false negative for Lint/SendWithMixinArgument when send/public_send/__send__ is called with no explicit receiver or with a self receiver (e.g. send(:include, Bar)). ([@​bbatsov][])
  • #15248: Fix a false negative for Lint/ToEnumArguments when more positional arguments are passed than the method accepts (e.g. def m(x); to_enum(:m, x, extra); end), which raises ArgumentError when the enumerator is used. ([@​bbatsov][])
  • #15249: Fix a false negative for Lint/UnescapedBracketInRegexp when an unescaped ] is preceded by an escaped backslash (e.g. /abc\\]123/). ([@​bbatsov][])
  • #15267: Fix a false positive for Style/ArrayIntersectWithSingleElement with a splat argument (e.g. array.intersect?([*foo])), which is not a single element and was incorrectly rewritten to array.include?(*foo). ([@​bbatsov][])
  • #15272: Fix a false positive for Style/ColonMethodCall with chained JRuby interop calls (e.g. Java::com::something_method). ([@​bbatsov][])
  • #15271: Fix a false positive for Style/ConditionalAssignment with EnforcedStyle: assign_inside_condition when assigning an unless without an else branch (e.g. x = unless cond; 1; end), which was rewritten to move the assignment inside the unless and changed behavior when the condition was true. ([@​bbatsov][])
  • #14401: Fix a false positive for Layout/BlockAlignment with EnforcedStyleAlignWith: start_of_line when a block is passed as a method argument. ([@​augustocbx][])
  • #15216: Fix a false positive for Lint/RaiseException when raise Exception is used inside a module nested within an allowed implicit namespace (e.g. Gem). ([@​bbatsov][])
  • #15219: Fix a false positive for Lint/RedundantDirGlobSort when sort is given a comparator block or a block-pass argument, which is not redundant with the default sorting. ([@​bbatsov][])
  • #15224: Fix a false positive for Lint/ShadowingOuterLocalVariable when a block argument has the same name as a pattern variable from a different in branch of the same case. ([@​bbatsov][])
  • #15239: Fix a false positive for Lint/SuppressedExceptionInNumberConversion when the numeric constructor already passes exception: false (e.g. Integer(arg, exception: false) rescue nil), which also produced an autocorrect with a duplicate exception: false keyword. ([@​bbatsov][])
  • #15243: Fix a false positive for Lint/TopLevelReturnWithArgument when a return with an argument is inside a numbered-parameter block or an it block. ([@​bbatsov][])
  • #15245: Fix a false positive for Lint/UselessRuby2Keywords when ruby2_keywords in a nested class or module refers to a method of the same name defined in an outer scope. ([@​bbatsov][])
  • #15246: Fix a false positive for Lint/UselessSetterCall when a multiple assignment uses nested destructuring (e.g. (a, b), c = arg, other_arg), which misaligned variables with the right-hand side values. ([@​bbatsov][])
  • #15125: Fix a false positive for Style/ZeroLengthPredicate when File::Stat.new(...).size.zero? is used. ([@​augustocbx][])
  • #15196: Fix --start-server to wait until the server is running before returning, which fixes a flaky --restart-server spec and a race for commands run right after starting the server. ([@​koic][])
  • #15272: Fix Style/Alias not detecting block scope for numbered-parameter and it blocks, which caused a false positive for alias_method and a false negative for alias inside such blocks. ([@​bbatsov][])
  • #15281: Fix an incorrect autocorrect when Style/IfUnlessModifier and Style/Next correct the same conditional. ([@​fynsta][])
  • #15260: Fix an error for Style/FileWrite when a literal or variable is passed to write in the block form. ([@​koic][])
  • #15276: Fix an error for Style/RedundantFormat when the format string is a heredoc with format arguments. ([@​fynsta][])
  • #15270: Fix an incorrect autocorrect for Style/AndOr when an operand is next, break, or yield with an argument (e.g. foo and next 1), which produced invalid Ruby like foo && next 1. ([@​bbatsov][])
  • #15267: Fix an incorrect autocorrect for Style/ArrayFirstLast when arr[0]/arr[-1] is the target of a compound assignment (e.g. arr[0] += 1), which produced arr.first += 1 and raised NoMethodError. ([@​bbatsov][])
  • #15267: Fix an incorrect autocorrect for Style/ArrayIntersect where a negated predicate on a safe-navigation chain (e.g. a&.intersection(b)&.none?) was rewritten to !a&.intersect?(b), flipping the result when the receiver is nil. ([@​bbatsov][])
  • #15273: Fix an incorrect autocorrect for Style/BlockDelimiters that converted a single-line do...end block containing a block-level rescue or ensure to {...}, producing invalid Ruby. ([@​bbatsov][])
  • #15268: Fix an incorrect autocorrect for Style/CaseEquality when the argument is an operator or unary expression (e.g. Array === a + b), which produced mis-parsed code like a + b.is_a?(Array). ([@​bbatsov][])
  • #15268: Fix an incorrect autocorrect for Style/ClassEqualityComparison inside a namespace when the class name string is already fully qualified (e.g. bar.class.name == '::Bar'), which produced instance_of?(::::Bar) and was a syntax error. ([@​bbatsov][])
  • #15268: Fix an incorrect autocorrect for Style/ClassEqualityComparison when comparing Class itself to a string literal (e.g. var.class == 'Date'), which produced var.instance_of?('Date') and raised TypeError; such comparisons are no longer autocorrected. ([@​bbatsov][])
  • #15274: Fix an incorrect autocorrect for Style/ClassMethodsDefinitions that corrupted a preceding comment containing def <name> and left the method undefined as a class method. ([@​bbatsov][])
  • #15270: Fix an incorrect autocorrect for Style/ComparableClamp when the clamped value is an operator expression (e.g. a + b), which produced mis-parsed code like a + b.clamp(low, high). ([@​bbatsov][])
  • #15267: Fix an incorrect autocorrect for Style/ConcatArrayLiterals with an empty array literal argument (e.g. arr.concat([], [b])), which produced invalid Ruby like arr.push(, b). ([@​bbatsov][])
  • #15274: Fix an incorrect autocorrect for Style/DigChain that duplicated a trailing comment and dropped indentation when the chain was inside a method or block. ([@​bbatsov][])
  • #15288: Fix an incorrect autocorrect for Lint/UselessTimes when a 1.times block takes a single destructured (|(a, b)|) or splat (|*a|) argument, which produced a body referencing an undefined variable. ([@​bbatsov][])
  • #15280: Fix an incorrect autocorrect for Style/ConditionalAssignment with EnforcedStyle: assign_inside_condition and a single-line case. ([@​fynsta][])

... (truncated)

Changelog

Sourced from rubocop's changelog.

1.88.0 (2026-06-16)

New features

  • #15166: Add a new Recursive option to Style/MutableConstant. When enabled, the cop checks and freezes mutable literals nested inside arrays and hashes. The option is disabled by default to preserve existing behavior. ([@​paracycle][])

Bug fixes

  • #15220: Fix a bad autocorrect for Lint/RedundantSplatExpansion when splatting an empty literal (e.g. when *[] or rescue *[]), which expanded to invalid or semantically different code. ([@​bbatsov][])
  • #15221: Fix a bad autocorrect for Lint/RegexpAsCondition when the regexp literal is negated (e.g. if !/foo/), which inverted the condition. ([@​bbatsov][])
  • #15242: Fix a bad autocorrect for Lint/SymbolConversion when the receiver is an interpolated string containing an embedded double quote (e.g. "foo#{bar}\"qux".to_sym), which produced a syntax error. ([@​bbatsov][])
  • #15270: Fix a crash for Style/CombinableLoops when a for loop has an empty body, and stop autocorrecting consecutive for loops whose iteration variables differ (which produced code referencing an undefined variable). ([@​bbatsov][])
  • #15272: Fix a crash for Style/ConstantVisibility when a visibility declaration has a numeric literal argument (e.g. private_constant 42). ([@​bbatsov][])
  • #15215: Fix a false negative for Lint/OrderedMagicComments when an encoding magic comment is preceded by a magic comment other than frozen_string_literal (e.g. shareable_constant_value). ([@​bbatsov][])
  • #15228: Fix a false negative for Lint/RedundantWithIndex when the block takes no arguments (e.g. ary.each_with_index { do_something }). ([@​bbatsov][])
  • #15230: Fix a false negative for Lint/RequireRelativeSelfPath when requiring the current file by name with its extension (e.g. require_relative 'foo.rb') and the file path is absolute. ([@​bbatsov][])
  • #15229: Fix a false negative for Lint/SafeNavigationChain when an ordinary method is chained after a parenthesized safe navigation call (e.g. (x&.foo).bar). ([@​bbatsov][])
  • #15225: Fix a false negative for Lint/SafeNavigationWithEmpty when the receiver of &.empty? is a local variable, instance variable, constant, or other non-method-call expression. ([@​bbatsov][])
  • #15231: Fix a false negative for Lint/SendWithMixinArgument when send/public_send/__send__ is called with no explicit receiver or with a self receiver (e.g. send(:include, Bar)). ([@​bbatsov][])
  • #15248: Fix a false negative for Lint/ToEnumArguments when more positional arguments are passed than the method accepts (e.g. def m(x); to_enum(:m, x, extra); end), which raises ArgumentError when the enumerator is used. ([@​bbatsov][])
  • #15249: Fix a false negative for Lint/UnescapedBracketInRegexp when an unescaped ] is preceded by an escaped backslash (e.g. /abc\\]123/). ([@​bbatsov][])
  • #15267: Fix a false positive for Style/ArrayIntersectWithSingleElement with a splat argument (e.g. array.intersect?([*foo])), which is not a single element and was incorrectly rewritten to array.include?(*foo). ([@​bbatsov][])
  • #15272: Fix a false positive for Style/ColonMethodCall with chained JRuby interop calls (e.g. Java::com::something_method). ([@​bbatsov][])
  • #15271: Fix a false positive for Style/ConditionalAssignment with EnforcedStyle: assign_inside_condition when assigning an unless without an else branch (e.g. x = unless cond; 1; end), which was rewritten to move the assignment inside the unless and changed behavior when the condition was true. ([@​bbatsov][])
  • #14401: Fix a false positive for Layout/BlockAlignment with EnforcedStyleAlignWith: start_of_line when a block is passed as a method argument. ([@​augustocbx][])
  • #15216: Fix a false positive for Lint/RaiseException when raise Exception is used inside a module nested within an allowed implicit namespace (e.g. Gem). ([@​bbatsov][])
  • #15219: Fix a false positive for Lint/RedundantDirGlobSort when sort is given a comparator block or a block-pass argument, which is not redundant with the default sorting. ([@​bbatsov][])
  • #15224: Fix a false positive for Lint/ShadowingOuterLocalVariable when a block argument has the same name as a pattern variable from a different in branch of the same case. ([@​bbatsov][])
  • #15239: Fix a false positive for Lint/SuppressedExceptionInNumberConversion when the numeric constructor already passes exception: false (e.g. Integer(arg, exception: false) rescue nil), which also produced an autocorrect with a duplicate exception: false keyword. ([@​bbatsov][])
  • #15243: Fix a false positive for Lint/TopLevelReturnWithArgument when a return with an argument is inside a numbered-parameter block or an it block. ([@​bbatsov][])
  • #15245: Fix a false positive for Lint/UselessRuby2Keywords when ruby2_keywords in a nested class or module refers to a method of the same name defined in an outer scope. ([@​bbatsov][])
  • #15246: Fix a false positive for Lint/UselessSetterCall when a multiple assignment uses nested destructuring (e.g. (a, b), c = arg, other_arg), which misaligned variables with the right-hand side values. ([@​bbatsov][])
  • #15125: Fix a false positive for Style/ZeroLengthPredicate when File::Stat.new(...).size.zero? is used. ([@​augustocbx][])
  • #15196: Fix --start-server to wait until the server is running before returning, which fixes a flaky --restart-server spec and a race for commands run right after starting the server. ([@​koic][])
  • #15272: Fix Style/Alias not detecting block scope for numbered-parameter and it blocks, which caused a false positive for alias_method and a false negative for alias inside such blocks. ([@​bbatsov][])
  • #15281: Fix an incorrect autocorrect when Style/IfUnlessModifier and Style/Next correct the same conditional. ([@​fynsta][])
  • #15260: Fix an error for Style/FileWrite when a literal or variable is passed to write in the block form. ([@​koic][])
  • #15276: Fix an error for Style/RedundantFormat when the format string is a heredoc with format arguments. ([@​fynsta][])
  • #15270: Fix an incorrect autocorrect for Style/AndOr when an operand is next, break, or yield with an argument (e.g. foo and next 1), which produced invalid Ruby like foo && next 1. ([@​bbatsov][])
  • #15267: Fix an incorrect autocorrect for Style/ArrayFirstLast when arr[0]/arr[-1] is the target of a compound assignment (e.g. arr[0] += 1), which produced arr.first += 1 and raised NoMethodError. ([@​bbatsov][])
  • #15267: Fix an incorrect autocorrect for Style/ArrayIntersect where a negated predicate on a safe-navigation chain (e.g. a&.intersection(b)&.none?) was rewritten to !a&.intersect?(b), flipping the result when the receiver is nil. ([@​bbatsov][])
  • #15273: Fix an incorrect autocorrect for Style/BlockDelimiters that converted a single-line do...end block containing a block-level rescue or ensure to {...}, producing invalid Ruby. ([@​bbatsov][])
  • #15268: Fix an incorrect autocorrect for Style/CaseEquality when the argument is an operator or unary expression (e.g. Array === a + b), which produced mis-parsed code like a + b.is_a?(Array). ([@​bbatsov][])
  • #15268: Fix an incorrect autocorrect for Style/ClassEqualityComparison inside a namespace when the class name string is already fully qualified (e.g. bar.class.name == '::Bar'), which produced instance_of?(::::Bar) and was a syntax error. ([@​bbatsov][])
  • #15268: Fix an incorrect autocorrect for Style/ClassEqualityComparison when comparing Class itself to a string literal (e.g. var.class == 'Date'), which produced var.instance_of?('Date') and raised TypeError; such comparisons are no longer autocorrected. ([@​bbatsov][])
  • #15274: Fix an incorrect autocorrect for Style/ClassMethodsDefinitions that corrupted a preceding comment containing def <name> and left the method undefined as a class method. ([@​bbatsov][])
  • #15270: Fix an incorrect autocorrect for Style/ComparableClamp when the clamped value is an operator expression (e.g. a + b), which produced mis-parsed code like a + b.clamp(low, high). ([@​bbatsov][])
  • #15267: Fix an incorrect autocorrect for Style/ConcatArrayLiterals with an empty array literal argument (e.g. arr.concat([], [b])), which produced invalid Ruby like arr.push(, b). ([@​bbatsov][])
  • #15274: Fix an incorrect autocorrect for Style/DigChain that duplicated a trailing comment and dropped indentation when the chain was inside a method or block. ([@​bbatsov][])
  • #15288: Fix an incorrect autocorrect for Lint/UselessTimes when a 1.times block takes a single destructured (|(a, b)|) or splat (|*a|) argument, which produced a body referencing an undefined variable. ([@​bbatsov][])

... (truncated)

Commits
  • 37bf5ad Cut 1.88
  • cd0c2e3 Update Changelog
  • b7af64a [Fix #12276] Record pending cops options in the auto-gen-config command
  • bbd7ff2 Add hk integration docs
  • 117e40a Merge pull request #15293 from RedZapdos123/fix-literal-interp-hash-symbol
  • 4d95141 [Fix #15291] Fix hash symbol interpolation
  • 0347d27 Add Recursive option to Style/MutableConstant
  • f0d92b4 Fix incorrect autocorrects for Style/FileWrite with heredocs
  • 32df346 Fix an incorrect autocorrect for Style/Semicolon with heredocs
  • 4c221fb [Fix #15269] Fix a false positive where cop Include patterns matched parent...
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.79.2 to 1.88.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](rubocop/rubocop@v1.79.2...v1.88.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-version: 1.88.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies ruby Pull requests that update Ruby code labels Jun 17, 2026
3 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

gem compare json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT require_paths:
    2.19.5: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.5", "lib"]
    2.19.9: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.9", "lib"]
  DIFFERENT rubygems_version:
    2.19.5: 4.0.6
    2.19.9: 4.1.0.dev
  DIFFERENT version:
    2.19.5: 2.19.5
    2.19.9: 2.19.9
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
            CHANGES.md +22/-0
            README.md +11/-0
            ext/json/ext/fbuffer/fbuffer.h +31/-23
            ext/json/ext/generator/generator.c +16/-15
            ext/json/ext/parser/parser.c +69/-27
            lib/json/truffle_ruby/generator.rb +3/-0
            lib/json/version.rb +1/-1
  DIFFERENT extra_rdoc_files:
    2.19.5->2.19.9:
      * Changed:
            README.md +11/-0

2 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

gem compare json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT require_paths:
    2.19.5: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.5", "lib"]
    2.19.9: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.9", "lib"]
  DIFFERENT rubygems_version:
    2.19.5: 4.0.6
    2.19.9: 4.1.0.dev
  DIFFERENT version:
    2.19.5: 2.19.5
    2.19.9: 2.19.9
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
            CHANGES.md +22/-0
            README.md +11/-0
            ext/json/ext/fbuffer/fbuffer.h +31/-23
            ext/json/ext/generator/generator.c +16/-15
            ext/json/ext/parser/parser.c +69/-27
            lib/json/truffle_ruby/generator.rb +3/-0
            lib/json/version.rb +1/-1
  DIFFERENT extra_rdoc_files:
    2.19.5->2.19.9:
      * Changed:
            README.md +11/-0

@github-actions

Copy link
Copy Markdown
Contributor

gem compare json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT require_paths:
    2.19.5: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.5", "lib"]
    2.19.9: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.9", "lib"]
  DIFFERENT rubygems_version:
    2.19.5: 4.0.6
    2.19.9: 4.1.0.dev
  DIFFERENT version:
    2.19.5: 2.19.5
    2.19.9: 2.19.9
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
            CHANGES.md +22/-0
            README.md +11/-0
            ext/json/ext/fbuffer/fbuffer.h +31/-23
            ext/json/ext/generator/generator.c +16/-15
            ext/json/ext/parser/parser.c +69/-27
            lib/json/truffle_ruby/generator.rb +3/-0
            lib/json/version.rb +1/-1
  DIFFERENT extra_rdoc_files:
    2.19.5->2.19.9:
      * Changed:
            README.md +11/-0

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
        CHANGES.md
                --- /tmp/d20260617-456-i2itej/json-2.19.5/CHANGES.md	2026-06-17 02:33:34.548403169 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/CHANGES.md	2026-06-17 02:33:34.554403278 +0000
                @@ -4,0 +5,22 @@
                +### 2026-06-11 (2.19.9)
                +
                +* Fix buffer overflow that could lead to a crash when writing JSON directly into an IO
                +  with `JSON.generate(object, io)`. [CVE-PENDING].
                +
                +### 2026-06-03 (2.19.8)
                +
                +* Fix 1-byte buffer overread on EOS errors.
                +* Handle invalid types passed as `max_nesting` option.
                +
                +### 2026-05-28 (2.19.7)
                +
                +* Fix some more edge cases with out of range floats.
                +* Ensure the string provided to `JSON.parse` can't be mutated during parsing.
                +* Add missing write barriers in `State#dup`.
                +* Further validate generator `depth` config.
                +
                +### 2026-05-28 (2.19.6)
                +
                +* Cleanly handle overly large `depth` generator argument.
                +* Add missing write barrier in `ParserConfig`.
                +
        README.md
                --- /tmp/d20260617-456-i2itej/json-2.19.5/README.md	2026-06-17 02:33:34.548403169 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/README.md	2026-06-17 02:33:34.554403278 +0000
                @@ -251,0 +252,11 @@
                +## Security
                +
                +When parsing or serializing untrusted input, parser and generator options should never be user controlled.
                +
                +```ruby
                +# Dangerous, DO NOT DO THIS.
                +JSON.generate(params[:data], params[:options])
                +```
                +
                +Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes.
                +
        ext/json/ext/fbuffer/fbuffer.h
                --- /tmp/d20260617-456-i2itej/json-2.19.5/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:34.548403169 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:34.554403278 +0000
                @@ -40 +40 @@
                -static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
                +static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
                @@ -42,2 +42,5 @@
                -    fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                -    if (stack_buffer) {
                +    if (RTEST(io)) {
                +        JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
                +        fb->io = io;
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
                +    } else {
                @@ -46,0 +50 @@
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                @@ -82 +86 @@
                -static void fbuffer_realloc(FBuffer *fb, size_t required)
                +static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
                @@ -84 +88 @@
                -    if (required > fb->capa) {
                +    if (new_capa > fb->capa) {
                @@ -87 +91 @@
                -            fb->ptr = ALLOC_N(char, required);
                +            fb->ptr = ALLOC_N(char, new_capa);
                @@ -91 +95 @@
                -            REALLOC_N(fb->ptr, char, required);
                +            REALLOC_N(fb->ptr, char, new_capa);
                @@ -93 +97 @@
                -        fb->capa = required;
                +        fb->capa = new_capa;
                @@ -100,3 +104 @@
                -        if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
                -            fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
                -        } else {
                +        if (fb->capa != 0) {
                @@ -104,4 +106,3 @@
                -        }
                -
                -        if (RB_LIKELY(requested < fb->capa)) {
                -            return;
                +            if (RB_LIKELY(requested < fb->capa)) {
                +                return;
                +            }
                @@ -111 +112,2 @@
                -    size_t required;
                +    size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
                +    size_t needed_capa = requested + fb->len;
                @@ -113,3 +115,2 @@
                -    if (RB_UNLIKELY(!fb->ptr)) {
                -        fb->ptr = ALLOC_N(char, fb->initial_length);
                -        fb->capa = fb->initial_length;
                +    while (new_capa < needed_capa) {
                +        new_capa *= 2;
                @@ -118,3 +119 @@
                -    for (required = fb->capa; requested > required - fb->len; required <<= 1);
                -
                -    fbuffer_realloc(fb, required);
                +    fbuffer_realloc(fb, new_capa);
                @@ -133,0 +133,9 @@
                +static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
                +{
                +    size_t result = a * b;
                +    if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
                +        rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
                +    }
                +    return result;
                +}
                +
                @@ -178 +186 @@
                -    fbuffer_inc_capa(fb, repeat * len);
                +    fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
        ext/json/ext/generator/generator.c
                --- /tmp/d20260617-456-i2itej/json-2.19.5/ext/json/ext/generator/generator.c	2026-06-17 02:33:34.549403187 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/ext/json/ext/generator/generator.c	2026-06-17 02:33:34.555403297 +0000
                @@ -1307,4 +1307,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
                @@ -1370,6 +1368,8 @@
                -    objState->indent = origState->indent;
                -    objState->space = origState->space;
                -    objState->space_before = origState->space_before;
                -    objState->object_nl = origState->object_nl;
                -    objState->array_nl = origState->array_nl;
                -    objState->as_json = origState->as_json;
                +
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->indent);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space_before);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->as_json);
                +
                @@ -1582 +1582 @@
                -    return RTEST(num) ? FIX2LONG(num) : 0;
                +    return RTEST(num) ? NUM2LONG(num) : 0;
                @@ -1592,0 +1593,3 @@
                +    if (RB_UNLIKELY(d > INT_MAX)) {
                +        rb_raise(rb_eArgError, "depth is too large (got %ld)", d);
                +    }
                @@ -1864,4 +1867,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
        ext/json/ext/parser/parser.c
                --- /tmp/d20260617-456-i2itej/json-2.19.5/ext/json/ext/parser/parser.c	2026-06-17 02:33:34.549403187 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/ext/json/ext/parser/parser.c	2026-06-17 02:33:34.555403297 +0000
                @@ -387,0 +388,7 @@
                +    JSON_ASSERT(state->cursor <= state->end);
                +
                +    // Redundant but helpful for hardening
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1024,0 +1032,7 @@
                +
                +    // If the string ended with an unterminated escape sequence, we might
                +    // have gone past the end.
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1205 +1219,5 @@
                -        exponent = negative_exponent ? -abs_exponent : abs_exponent;
                +        if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) {
                +            exponent = negative_exponent ? INT64_MIN : INT64_MAX;
                +        } else {
                +            exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent;
                +        }
                @@ -1460 +1478,11 @@
                -  int encindex = RB_ENCODING_GET(source);
                +    StringValue(source);
                +    int encindex = RB_ENCODING_GET(source);
                +
                +    if (RB_LIKELY(encindex == utf8_encindex)) {
                +        return source;
                +    }
                +
                +    if (encindex == binary_encindex) {
                +        // For historical reason, we silently reinterpret binary strings as UTF-8
                +        return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                +    }
                @@ -1462 +1490,2 @@
                -  if (RB_LIKELY(encindex == utf8_encindex)) {
                +    source = rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +    StringValue(source);
                @@ -1464 +1493 @@
                -  }
                +}
                @@ -1466,4 +1495,4 @@
                - if (encindex == binary_encindex) {
                -    // For historical reason, we silently reinterpret binary strings as UTF-8
                -    return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                -  }
                +struct parser_config_init_args {
                +    JSON_ParserConfig *config;
                +    VALUE self;
                +};
                @@ -1471 +1500,4 @@
                -  return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
                +{
                +    *dest = val;
                +    if (self) RB_OBJ_WRITTEN(self, Qundef, val);
                @@ -1476 +1508,3 @@
                -    JSON_ParserConfig *config = (JSON_ParserConfig *)data;
                +    struct parser_config_init_args *args = (struct parser_config_init_args *)data;
                +    JSON_ParserConfig *config = args->config;
                +    VALUE self = args->self;
                @@ -1485 +1519 @@
                -    else if (key == sym_on_load)                    { config->on_load_proc = RTEST(val) ? val : Qfalse; }
                +    else if (key == sym_on_load)                    { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
                @@ -1490 +1524 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1493 +1527 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1502 +1536 @@
                -                    config->decimal_class = rb_path_to_class(mod_path);
                +                    parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
                @@ -1510 +1544 @@
                -                    config->decimal_class = rb_mKernel;
                +                    parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
                @@ -1520 +1554 @@
                -static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
                +static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
                @@ -1523,0 +1558,5 @@
                +    struct parser_config_init_args args = {
                +        .config = config,
                +        .self = self,
                +    };
                +
                @@ -1529 +1568 @@
                -            rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
                +            rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
                @@ -1563,3 +1602 @@
                -    parser_config_init(config, opts);
                -
                -    RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
                +    parser_config_init(config, opts, self);
                @@ -1570 +1607 @@
                -static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
                +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src)
                @@ -1572,2 +1609,8 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                +    VALUE Vsource = convert_encoding(src);
                +
                +    // Ensure the string isn't mutated under us.
                +    // The classic API to use is `rb_str_locktmp`, but then we'd
                +    // need to use `rb_protect` to make sure we always unlock.
                +    if (Vsource == src) {
                +        Vsource = rb_str_new_frozen(Vsource);
                +    }
                @@ -1583,0 +1627 @@
                +
                @@ -1601,0 +1646 @@
                +    RB_GC_GUARD(Vsource);
                @@ -1622,3 +1666,0 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                -
                @@ -1627 +1669 @@
                -    parser_config_init(config, opts);
                +    parser_config_init(config, opts, false);
        lib/json/truffle_ruby/generator.rb
                --- /tmp/d20260617-456-i2itej/json-2.19.5/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:34.553403260 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:34.558403351 +0000
                @@ -309,0 +310,3 @@
                +            unless opts[:max_nesting].is_a?(Integer)
                +              raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
                +            end
        lib/json/version.rb
                --- /tmp/d20260617-456-i2itej/json-2.19.5/lib/json/version.rb	2026-06-17 02:33:34.553403260 +0000
                +++ /tmp/d20260617-456-i2itej/json-2.19.9/lib/json/version.rb	2026-06-17 02:33:34.558403351 +0000
                @@ -4 +4 @@
                -  VERSION = '2.19.5'
                +  VERSION = '2.19.9'

@github-actions

Copy link
Copy Markdown
Contributor

gem compare json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT require_paths:
    2.19.5: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.5", "lib"]
    2.19.9: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.9", "lib"]
  DIFFERENT rubygems_version:
    2.19.5: 4.0.6
    2.19.9: 4.1.0.dev
  DIFFERENT version:
    2.19.5: 2.19.5
    2.19.9: 2.19.9
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
            CHANGES.md +22/-0
            README.md +11/-0
            ext/json/ext/fbuffer/fbuffer.h +31/-23
            ext/json/ext/generator/generator.c +16/-15
            ext/json/ext/parser/parser.c +69/-27
            lib/json/truffle_ruby/generator.rb +3/-0
            lib/json/version.rb +1/-1
  DIFFERENT extra_rdoc_files:
    2.19.5->2.19.9:
      * Changed:
            README.md +11/-0

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
        CHANGES.md
                --- /tmp/d20260617-489-sff567/json-2.19.5/CHANGES.md	2026-06-17 02:33:42.258881570 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/CHANGES.md	2026-06-17 02:33:42.267881665 +0000
                @@ -4,0 +5,22 @@
                +### 2026-06-11 (2.19.9)
                +
                +* Fix buffer overflow that could lead to a crash when writing JSON directly into an IO
                +  with `JSON.generate(object, io)`. [CVE-PENDING].
                +
                +### 2026-06-03 (2.19.8)
                +
                +* Fix 1-byte buffer overread on EOS errors.
                +* Handle invalid types passed as `max_nesting` option.
                +
                +### 2026-05-28 (2.19.7)
                +
                +* Fix some more edge cases with out of range floats.
                +* Ensure the string provided to `JSON.parse` can't be mutated during parsing.
                +* Add missing write barriers in `State#dup`.
                +* Further validate generator `depth` config.
                +
                +### 2026-05-28 (2.19.6)
                +
                +* Cleanly handle overly large `depth` generator argument.
                +* Add missing write barrier in `ParserConfig`.
                +
        README.md
                --- /tmp/d20260617-489-sff567/json-2.19.5/README.md	2026-06-17 02:33:42.258881570 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/README.md	2026-06-17 02:33:42.268881675 +0000
                @@ -251,0 +252,11 @@
                +## Security
                +
                +When parsing or serializing untrusted input, parser and generator options should never be user controlled.
                +
                +```ruby
                +# Dangerous, DO NOT DO THIS.
                +JSON.generate(params[:data], params[:options])
                +```
                +
                +Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes.
                +
        ext/json/ext/fbuffer/fbuffer.h
                --- /tmp/d20260617-489-sff567/json-2.19.5/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:42.258881570 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:42.268881675 +0000
                @@ -40 +40 @@
                -static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
                +static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
                @@ -42,2 +42,5 @@
                -    fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                -    if (stack_buffer) {
                +    if (RTEST(io)) {
                +        JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
                +        fb->io = io;
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
                +    } else {
                @@ -46,0 +50 @@
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                @@ -82 +86 @@
                -static void fbuffer_realloc(FBuffer *fb, size_t required)
                +static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
                @@ -84 +88 @@
                -    if (required > fb->capa) {
                +    if (new_capa > fb->capa) {
                @@ -87 +91 @@
                -            fb->ptr = ALLOC_N(char, required);
                +            fb->ptr = ALLOC_N(char, new_capa);
                @@ -91 +95 @@
                -            REALLOC_N(fb->ptr, char, required);
                +            REALLOC_N(fb->ptr, char, new_capa);
                @@ -93 +97 @@
                -        fb->capa = required;
                +        fb->capa = new_capa;
                @@ -100,3 +104 @@
                -        if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
                -            fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
                -        } else {
                +        if (fb->capa != 0) {
                @@ -104,4 +106,3 @@
                -        }
                -
                -        if (RB_LIKELY(requested < fb->capa)) {
                -            return;
                +            if (RB_LIKELY(requested < fb->capa)) {
                +                return;
                +            }
                @@ -111 +112,2 @@
                -    size_t required;
                +    size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
                +    size_t needed_capa = requested + fb->len;
                @@ -113,3 +115,2 @@
                -    if (RB_UNLIKELY(!fb->ptr)) {
                -        fb->ptr = ALLOC_N(char, fb->initial_length);
                -        fb->capa = fb->initial_length;
                +    while (new_capa < needed_capa) {
                +        new_capa *= 2;
                @@ -118,3 +119 @@
                -    for (required = fb->capa; requested > required - fb->len; required <<= 1);
                -
                -    fbuffer_realloc(fb, required);
                +    fbuffer_realloc(fb, new_capa);
                @@ -133,0 +133,9 @@
                +static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
                +{
                +    size_t result = a * b;
                +    if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
                +        rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
                +    }
                +    return result;
                +}
                +
                @@ -178 +186 @@
                -    fbuffer_inc_capa(fb, repeat * len);
                +    fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
        ext/json/ext/generator/generator.c
                --- /tmp/d20260617-489-sff567/json-2.19.5/ext/json/ext/generator/generator.c	2026-06-17 02:33:42.259881580 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/ext/json/ext/generator/generator.c	2026-06-17 02:33:42.269881686 +0000
                @@ -1307,4 +1307,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
                @@ -1370,6 +1368,8 @@
                -    objState->indent = origState->indent;
                -    objState->space = origState->space;
                -    objState->space_before = origState->space_before;
                -    objState->object_nl = origState->object_nl;
                -    objState->array_nl = origState->array_nl;
                -    objState->as_json = origState->as_json;
                +
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->indent);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space_before);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->as_json);
                +
                @@ -1582 +1582 @@
                -    return RTEST(num) ? FIX2LONG(num) : 0;
                +    return RTEST(num) ? NUM2LONG(num) : 0;
                @@ -1592,0 +1593,3 @@
                +    if (RB_UNLIKELY(d > INT_MAX)) {
                +        rb_raise(rb_eArgError, "depth is too large (got %ld)", d);
                +    }
                @@ -1864,4 +1867,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
        ext/json/ext/parser/parser.c
                --- /tmp/d20260617-489-sff567/json-2.19.5/ext/json/ext/parser/parser.c	2026-06-17 02:33:42.260881591 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/ext/json/ext/parser/parser.c	2026-06-17 02:33:42.269881686 +0000
                @@ -387,0 +388,7 @@
                +    JSON_ASSERT(state->cursor <= state->end);
                +
                +    // Redundant but helpful for hardening
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1024,0 +1032,7 @@
                +
                +    // If the string ended with an unterminated escape sequence, we might
                +    // have gone past the end.
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1205 +1219,5 @@
                -        exponent = negative_exponent ? -abs_exponent : abs_exponent;
                +        if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) {
                +            exponent = negative_exponent ? INT64_MIN : INT64_MAX;
                +        } else {
                +            exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent;
                +        }
                @@ -1460 +1478,11 @@
                -  int encindex = RB_ENCODING_GET(source);
                +    StringValue(source);
                +    int encindex = RB_ENCODING_GET(source);
                +
                +    if (RB_LIKELY(encindex == utf8_encindex)) {
                +        return source;
                +    }
                +
                +    if (encindex == binary_encindex) {
                +        // For historical reason, we silently reinterpret binary strings as UTF-8
                +        return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                +    }
                @@ -1462 +1490,2 @@
                -  if (RB_LIKELY(encindex == utf8_encindex)) {
                +    source = rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +    StringValue(source);
                @@ -1464 +1493 @@
                -  }
                +}
                @@ -1466,4 +1495,4 @@
                - if (encindex == binary_encindex) {
                -    // For historical reason, we silently reinterpret binary strings as UTF-8
                -    return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                -  }
                +struct parser_config_init_args {
                +    JSON_ParserConfig *config;
                +    VALUE self;
                +};
                @@ -1471 +1500,4 @@
                -  return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
                +{
                +    *dest = val;
                +    if (self) RB_OBJ_WRITTEN(self, Qundef, val);
                @@ -1476 +1508,3 @@
                -    JSON_ParserConfig *config = (JSON_ParserConfig *)data;
                +    struct parser_config_init_args *args = (struct parser_config_init_args *)data;
                +    JSON_ParserConfig *config = args->config;
                +    VALUE self = args->self;
                @@ -1485 +1519 @@
                -    else if (key == sym_on_load)                    { config->on_load_proc = RTEST(val) ? val : Qfalse; }
                +    else if (key == sym_on_load)                    { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
                @@ -1490 +1524 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1493 +1527 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1502 +1536 @@
                -                    config->decimal_class = rb_path_to_class(mod_path);
                +                    parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
                @@ -1510 +1544 @@
                -                    config->decimal_class = rb_mKernel;
                +                    parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
                @@ -1520 +1554 @@
                -static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
                +static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
                @@ -1523,0 +1558,5 @@
                +    struct parser_config_init_args args = {
                +        .config = config,
                +        .self = self,
                +    };
                +
                @@ -1529 +1568 @@
                -            rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
                +            rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
                @@ -1563,3 +1602 @@
                -    parser_config_init(config, opts);
                -
                -    RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
                +    parser_config_init(config, opts, self);
                @@ -1570 +1607 @@
                -static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
                +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src)
                @@ -1572,2 +1609,8 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                +    VALUE Vsource = convert_encoding(src);
                +
                +    // Ensure the string isn't mutated under us.
                +    // The classic API to use is `rb_str_locktmp`, but then we'd
                +    // need to use `rb_protect` to make sure we always unlock.
                +    if (Vsource == src) {
                +        Vsource = rb_str_new_frozen(Vsource);
                +    }
                @@ -1583,0 +1627 @@
                +
                @@ -1601,0 +1646 @@
                +    RB_GC_GUARD(Vsource);
                @@ -1622,3 +1666,0 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                -
                @@ -1627 +1669 @@
                -    parser_config_init(config, opts);
                +    parser_config_init(config, opts, false);
        lib/json/truffle_ruby/generator.rb
                --- /tmp/d20260617-489-sff567/json-2.19.5/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:42.266881654 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:42.274881739 +0000
                @@ -309,0 +310,3 @@
                +            unless opts[:max_nesting].is_a?(Integer)
                +              raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
                +            end
        lib/json/version.rb
                --- /tmp/d20260617-489-sff567/json-2.19.5/lib/json/version.rb	2026-06-17 02:33:42.266881654 +0000
                +++ /tmp/d20260617-489-sff567/json-2.19.9/lib/json/version.rb	2026-06-17 02:33:42.274881739 +0000
                @@ -4 +4 @@
                -  VERSION = '2.19.5'
                +  VERSION = '2.19.9'

@github-actions

Copy link
Copy Markdown
Contributor

gem compare parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT date:
    1.28.0: 2026-04-02 00:00:00 UTC
    2.1.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.28.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v1.28.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v1.28.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki"}
    2.1.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v2.1.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki", "changelog_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/CHANGELOG.md", "rubygems_mfa_required" => "true"}
  DIFFERENT required_ruby_version:
    1.28.0: >= 2.7
    2.1.0: >= 3.3
  DIFFERENT rubygems_version:
    1.28.0: 3.4.10
    2.1.0: 4.0.3
  DIFFERENT version:
    1.28.0: 1.28.0
    2.1.0: 2.1.0
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
            lib/parallel/serializer.rb +52/-0
      * Changed:
            lib/parallel.rb +68/-40
            lib/parallel/version.rb +1/-1

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
        CHANGES.md
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/CHANGES.md	2026-06-17 02:33:46.819520914 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/CHANGES.md	2026-06-17 02:33:46.827520835 +0000
                @@ -4,0 +5,22 @@
                +### 2026-06-11 (2.19.9)
                +
                +* Fix buffer overflow that could lead to a crash when writing JSON directly into an IO
                +  with `JSON.generate(object, io)`. [CVE-PENDING].
                +
                +### 2026-06-03 (2.19.8)
                +
                +* Fix 1-byte buffer overread on EOS errors.
                +* Handle invalid types passed as `max_nesting` option.
                +
                +### 2026-05-28 (2.19.7)
                +
                +* Fix some more edge cases with out of range floats.
                +* Ensure the string provided to `JSON.parse` can't be mutated during parsing.
                +* Add missing write barriers in `State#dup`.
                +* Further validate generator `depth` config.
                +
                +### 2026-05-28 (2.19.6)
                +
                +* Cleanly handle overly large `depth` generator argument.
                +* Add missing write barrier in `ParserConfig`.
                +
        README.md
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/README.md	2026-06-17 02:33:46.819520914 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/README.md	2026-06-17 02:33:46.827520835 +0000
                @@ -251,0 +252,11 @@
                +## Security
                +
                +When parsing or serializing untrusted input, parser and generator options should never be user controlled.
                +
                +```ruby
                +# Dangerous, DO NOT DO THIS.
                +JSON.generate(params[:data], params[:options])
                +```
                +
                +Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes.
                +
        ext/json/ext/fbuffer/fbuffer.h
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:46.819520914 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:46.828520825 +0000
                @@ -40 +40 @@
                -static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
                +static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
                @@ -42,2 +42,5 @@
                -    fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                -    if (stack_buffer) {
                +    if (RTEST(io)) {
                +        JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
                +        fb->io = io;
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
                +    } else {
                @@ -46,0 +50 @@
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                @@ -82 +86 @@
                -static void fbuffer_realloc(FBuffer *fb, size_t required)
                +static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
                @@ -84 +88 @@
                -    if (required > fb->capa) {
                +    if (new_capa > fb->capa) {
                @@ -87 +91 @@
                -            fb->ptr = ALLOC_N(char, required);
                +            fb->ptr = ALLOC_N(char, new_capa);
                @@ -91 +95 @@
                -            REALLOC_N(fb->ptr, char, required);
                +            REALLOC_N(fb->ptr, char, new_capa);
                @@ -93 +97 @@
                -        fb->capa = required;
                +        fb->capa = new_capa;
                @@ -100,3 +104 @@
                -        if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
                -            fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
                -        } else {
                +        if (fb->capa != 0) {
                @@ -104,4 +106,3 @@
                -        }
                -
                -        if (RB_LIKELY(requested < fb->capa)) {
                -            return;
                +            if (RB_LIKELY(requested < fb->capa)) {
                +                return;
                +            }
                @@ -111 +112,2 @@
                -    size_t required;
                +    size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
                +    size_t needed_capa = requested + fb->len;
                @@ -113,3 +115,2 @@
                -    if (RB_UNLIKELY(!fb->ptr)) {
                -        fb->ptr = ALLOC_N(char, fb->initial_length);
                -        fb->capa = fb->initial_length;
                +    while (new_capa < needed_capa) {
                +        new_capa *= 2;
                @@ -118,3 +119 @@
                -    for (required = fb->capa; requested > required - fb->len; required <<= 1);
                -
                -    fbuffer_realloc(fb, required);
                +    fbuffer_realloc(fb, new_capa);
                @@ -133,0 +133,9 @@
                +static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
                +{
                +    size_t result = a * b;
                +    if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
                +        rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
                +    }
                +    return result;
                +}
                +
                @@ -178 +186 @@
                -    fbuffer_inc_capa(fb, repeat * len);
                +    fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
        ext/json/ext/generator/generator.c
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/ext/json/ext/generator/generator.c	2026-06-17 02:33:46.820520904 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/ext/json/ext/generator/generator.c	2026-06-17 02:33:46.828520825 +0000
                @@ -1307,4 +1307,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
                @@ -1370,6 +1368,8 @@
                -    objState->indent = origState->indent;
                -    objState->space = origState->space;
                -    objState->space_before = origState->space_before;
                -    objState->object_nl = origState->object_nl;
                -    objState->array_nl = origState->array_nl;
                -    objState->as_json = origState->as_json;
                +
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->indent);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space_before);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->as_json);
                +
                @@ -1582 +1582 @@
                -    return RTEST(num) ? FIX2LONG(num) : 0;
                +    return RTEST(num) ? NUM2LONG(num) : 0;
                @@ -1592,0 +1593,3 @@
                +    if (RB_UNLIKELY(d > INT_MAX)) {
                +        rb_raise(rb_eArgError, "depth is too large (got %ld)", d);
                +    }
                @@ -1864,4 +1867,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
        ext/json/ext/parser/parser.c
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/ext/json/ext/parser/parser.c	2026-06-17 02:33:46.820520904 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/ext/json/ext/parser/parser.c	2026-06-17 02:33:46.829520815 +0000
                @@ -387,0 +388,7 @@
                +    JSON_ASSERT(state->cursor <= state->end);
                +
                +    // Redundant but helpful for hardening
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1024,0 +1032,7 @@
                +
                +    // If the string ended with an unterminated escape sequence, we might
                +    // have gone past the end.
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1205 +1219,5 @@
                -        exponent = negative_exponent ? -abs_exponent : abs_exponent;
                +        if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) {
                +            exponent = negative_exponent ? INT64_MIN : INT64_MAX;
                +        } else {
                +            exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent;
                +        }
                @@ -1460 +1478,11 @@
                -  int encindex = RB_ENCODING_GET(source);
                +    StringValue(source);
                +    int encindex = RB_ENCODING_GET(source);
                +
                +    if (RB_LIKELY(encindex == utf8_encindex)) {
                +        return source;
                +    }
                +
                +    if (encindex == binary_encindex) {
                +        // For historical reason, we silently reinterpret binary strings as UTF-8
                +        return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                +    }
                @@ -1462 +1490,2 @@
                -  if (RB_LIKELY(encindex == utf8_encindex)) {
                +    source = rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +    StringValue(source);
                @@ -1464 +1493 @@
                -  }
                +}
                @@ -1466,4 +1495,4 @@
                - if (encindex == binary_encindex) {
                -    // For historical reason, we silently reinterpret binary strings as UTF-8
                -    return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                -  }
                +struct parser_config_init_args {
                +    JSON_ParserConfig *config;
                +    VALUE self;
                +};
                @@ -1471 +1500,4 @@
                -  return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
                +{
                +    *dest = val;
                +    if (self) RB_OBJ_WRITTEN(self, Qundef, val);
                @@ -1476 +1508,3 @@
                -    JSON_ParserConfig *config = (JSON_ParserConfig *)data;
                +    struct parser_config_init_args *args = (struct parser_config_init_args *)data;
                +    JSON_ParserConfig *config = args->config;
                +    VALUE self = args->self;
                @@ -1485 +1519 @@
                -    else if (key == sym_on_load)                    { config->on_load_proc = RTEST(val) ? val : Qfalse; }
                +    else if (key == sym_on_load)                    { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
                @@ -1490 +1524 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1493 +1527 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1502 +1536 @@
                -                    config->decimal_class = rb_path_to_class(mod_path);
                +                    parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
                @@ -1510 +1544 @@
                -                    config->decimal_class = rb_mKernel;
                +                    parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
                @@ -1520 +1554 @@
                -static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
                +static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
                @@ -1523,0 +1558,5 @@
                +    struct parser_config_init_args args = {
                +        .config = config,
                +        .self = self,
                +    };
                +
                @@ -1529 +1568 @@
                -            rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
                +            rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
                @@ -1563,3 +1602 @@
                -    parser_config_init(config, opts);
                -
                -    RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
                +    parser_config_init(config, opts, self);
                @@ -1570 +1607 @@
                -static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
                +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src)
                @@ -1572,2 +1609,8 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                +    VALUE Vsource = convert_encoding(src);
                +
                +    // Ensure the string isn't mutated under us.
                +    // The classic API to use is `rb_str_locktmp`, but then we'd
                +    // need to use `rb_protect` to make sure we always unlock.
                +    if (Vsource == src) {
                +        Vsource = rb_str_new_frozen(Vsource);
                +    }
                @@ -1583,0 +1627 @@
                +
                @@ -1601,0 +1646 @@
                +    RB_GC_GUARD(Vsource);
                @@ -1622,3 +1666,0 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                -
                @@ -1627 +1669 @@
                -    parser_config_init(config, opts);
                +    parser_config_init(config, opts, false);
        lib/json/truffle_ruby/generator.rb
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:46.826520845 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:46.832520785 +0000
                @@ -309,0 +310,3 @@
                +            unless opts[:max_nesting].is_a?(Integer)
                +              raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
                +            end
        lib/json/version.rb
                --- /tmp/d20260617-460-hevf9e/json-2.19.5/lib/json/version.rb	2026-06-17 02:33:46.826520845 +0000
                +++ /tmp/d20260617-460-hevf9e/json-2.19.9/lib/json/version.rb	2026-06-17 02:33:46.832520785 +0000
                @@ -4 +4 @@
                -  VERSION = '2.19.5'
                +  VERSION = '2.19.9'

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
        CHANGES.md
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/CHANGES.md	2026-06-17 02:33:52.132665390 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/CHANGES.md	2026-06-17 02:33:52.138665338 +0000
                @@ -4,0 +5,22 @@
                +### 2026-06-11 (2.19.9)
                +
                +* Fix buffer overflow that could lead to a crash when writing JSON directly into an IO
                +  with `JSON.generate(object, io)`. [CVE-PENDING].
                +
                +### 2026-06-03 (2.19.8)
                +
                +* Fix 1-byte buffer overread on EOS errors.
                +* Handle invalid types passed as `max_nesting` option.
                +
                +### 2026-05-28 (2.19.7)
                +
                +* Fix some more edge cases with out of range floats.
                +* Ensure the string provided to `JSON.parse` can't be mutated during parsing.
                +* Add missing write barriers in `State#dup`.
                +* Further validate generator `depth` config.
                +
                +### 2026-05-28 (2.19.6)
                +
                +* Cleanly handle overly large `depth` generator argument.
                +* Add missing write barrier in `ParserConfig`.
                +
        README.md
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/README.md	2026-06-17 02:33:52.132665390 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/README.md	2026-06-17 02:33:52.139665329 +0000
                @@ -251,0 +252,11 @@
                +## Security
                +
                +When parsing or serializing untrusted input, parser and generator options should never be user controlled.
                +
                +```ruby
                +# Dangerous, DO NOT DO THIS.
                +JSON.generate(params[:data], params[:options])
                +```
                +
                +Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes.
                +
        ext/json/ext/fbuffer/fbuffer.h
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:52.133665382 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:33:52.139665329 +0000
                @@ -40 +40 @@
                -static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
                +static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
                @@ -42,2 +42,5 @@
                -    fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                -    if (stack_buffer) {
                +    if (RTEST(io)) {
                +        JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
                +        fb->io = io;
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
                +    } else {
                @@ -46,0 +50 @@
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                @@ -82 +86 @@
                -static void fbuffer_realloc(FBuffer *fb, size_t required)
                +static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
                @@ -84 +88 @@
                -    if (required > fb->capa) {
                +    if (new_capa > fb->capa) {
                @@ -87 +91 @@
                -            fb->ptr = ALLOC_N(char, required);
                +            fb->ptr = ALLOC_N(char, new_capa);
                @@ -91 +95 @@
                -            REALLOC_N(fb->ptr, char, required);
                +            REALLOC_N(fb->ptr, char, new_capa);
                @@ -93 +97 @@
                -        fb->capa = required;
                +        fb->capa = new_capa;
                @@ -100,3 +104 @@
                -        if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
                -            fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
                -        } else {
                +        if (fb->capa != 0) {
                @@ -104,4 +106,3 @@
                -        }
                -
                -        if (RB_LIKELY(requested < fb->capa)) {
                -            return;
                +            if (RB_LIKELY(requested < fb->capa)) {
                +                return;
                +            }
                @@ -111 +112,2 @@
                -    size_t required;
                +    size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
                +    size_t needed_capa = requested + fb->len;
                @@ -113,3 +115,2 @@
                -    if (RB_UNLIKELY(!fb->ptr)) {
                -        fb->ptr = ALLOC_N(char, fb->initial_length);
                -        fb->capa = fb->initial_length;
                +    while (new_capa < needed_capa) {
                +        new_capa *= 2;
                @@ -118,3 +119 @@
                -    for (required = fb->capa; requested > required - fb->len; required <<= 1);
                -
                -    fbuffer_realloc(fb, required);
                +    fbuffer_realloc(fb, new_capa);
                @@ -133,0 +133,9 @@
                +static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
                +{
                +    size_t result = a * b;
                +    if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
                +        rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
                +    }
                +    return result;
                +}
                +
                @@ -178 +186 @@
                -    fbuffer_inc_capa(fb, repeat * len);
                +    fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
        ext/json/ext/generator/generator.c
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/ext/json/ext/generator/generator.c	2026-06-17 02:33:52.133665382 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/ext/json/ext/generator/generator.c	2026-06-17 02:33:52.140665321 +0000
                @@ -1307,4 +1307,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
                @@ -1370,6 +1368,8 @@
                -    objState->indent = origState->indent;
                -    objState->space = origState->space;
                -    objState->space_before = origState->space_before;
                -    objState->object_nl = origState->object_nl;
                -    objState->array_nl = origState->array_nl;
                -    objState->as_json = origState->as_json;
                +
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->indent);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space_before);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->as_json);
                +
                @@ -1582 +1582 @@
                -    return RTEST(num) ? FIX2LONG(num) : 0;
                +    return RTEST(num) ? NUM2LONG(num) : 0;
                @@ -1592,0 +1593,3 @@
                +    if (RB_UNLIKELY(d > INT_MAX)) {
                +        rb_raise(rb_eArgError, "depth is too large (got %ld)", d);
                +    }
                @@ -1864,4 +1867,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
        ext/json/ext/parser/parser.c
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/ext/json/ext/parser/parser.c	2026-06-17 02:33:52.134665373 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/ext/json/ext/parser/parser.c	2026-06-17 02:33:52.140665321 +0000
                @@ -387,0 +388,7 @@
                +    JSON_ASSERT(state->cursor <= state->end);
                +
                +    // Redundant but helpful for hardening
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1024,0 +1032,7 @@
                +
                +    // If the string ended with an unterminated escape sequence, we might
                +    // have gone past the end.
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1205 +1219,5 @@
                -        exponent = negative_exponent ? -abs_exponent : abs_exponent;
                +        if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) {
                +            exponent = negative_exponent ? INT64_MIN : INT64_MAX;
                +        } else {
                +            exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent;
                +        }
                @@ -1460 +1478,11 @@
                -  int encindex = RB_ENCODING_GET(source);
                +    StringValue(source);
                +    int encindex = RB_ENCODING_GET(source);
                +
                +    if (RB_LIKELY(encindex == utf8_encindex)) {
                +        return source;
                +    }
                +
                +    if (encindex == binary_encindex) {
                +        // For historical reason, we silently reinterpret binary strings as UTF-8
                +        return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                +    }
                @@ -1462 +1490,2 @@
                -  if (RB_LIKELY(encindex == utf8_encindex)) {
                +    source = rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +    StringValue(source);
                @@ -1464 +1493 @@
                -  }
                +}
                @@ -1466,4 +1495,4 @@
                - if (encindex == binary_encindex) {
                -    // For historical reason, we silently reinterpret binary strings as UTF-8
                -    return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                -  }
                +struct parser_config_init_args {
                +    JSON_ParserConfig *config;
                +    VALUE self;
                +};
                @@ -1471 +1500,4 @@
                -  return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
                +{
                +    *dest = val;
                +    if (self) RB_OBJ_WRITTEN(self, Qundef, val);
                @@ -1476 +1508,3 @@
                -    JSON_ParserConfig *config = (JSON_ParserConfig *)data;
                +    struct parser_config_init_args *args = (struct parser_config_init_args *)data;
                +    JSON_ParserConfig *config = args->config;
                +    VALUE self = args->self;
                @@ -1485 +1519 @@
                -    else if (key == sym_on_load)                    { config->on_load_proc = RTEST(val) ? val : Qfalse; }
                +    else if (key == sym_on_load)                    { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
                @@ -1490 +1524 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1493 +1527 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1502 +1536 @@
                -                    config->decimal_class = rb_path_to_class(mod_path);
                +                    parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
                @@ -1510 +1544 @@
                -                    config->decimal_class = rb_mKernel;
                +                    parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
                @@ -1520 +1554 @@
                -static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
                +static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
                @@ -1523,0 +1558,5 @@
                +    struct parser_config_init_args args = {
                +        .config = config,
                +        .self = self,
                +    };
                +
                @@ -1529 +1568 @@
                -            rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
                +            rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
                @@ -1563,3 +1602 @@
                -    parser_config_init(config, opts);
                -
                -    RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
                +    parser_config_init(config, opts, self);
                @@ -1570 +1607 @@
                -static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
                +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src)
                @@ -1572,2 +1609,8 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                +    VALUE Vsource = convert_encoding(src);
                +
                +    // Ensure the string isn't mutated under us.
                +    // The classic API to use is `rb_str_locktmp`, but then we'd
                +    // need to use `rb_protect` to make sure we always unlock.
                +    if (Vsource == src) {
                +        Vsource = rb_str_new_frozen(Vsource);
                +    }
                @@ -1583,0 +1627 @@
                +
                @@ -1601,0 +1646 @@
                +    RB_GC_GUARD(Vsource);
                @@ -1622,3 +1666,0 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                -
                @@ -1627 +1669 @@
                -    parser_config_init(config, opts);
                +    parser_config_init(config, opts, false);
        lib/json/truffle_ruby/generator.rb
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:52.138665338 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/lib/json/truffle_ruby/generator.rb	2026-06-17 02:33:52.144665286 +0000
                @@ -309,0 +310,3 @@
                +            unless opts[:max_nesting].is_a?(Integer)
                +              raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
                +            end
        lib/json/version.rb
                --- /tmp/d20260617-470-v6yd64/json-2.19.5/lib/json/version.rb	2026-06-17 02:33:52.138665338 +0000
                +++ /tmp/d20260617-470-v6yd64/json-2.19.9/lib/json/version.rb	2026-06-17 02:33:52.144665286 +0000
                @@ -4 +4 @@
                -  VERSION = '2.19.5'
                +  VERSION = '2.19.9'

@github-actions

Copy link
Copy Markdown
Contributor

gem compare parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT date:
    1.28.0: 2026-04-02 00:00:00 UTC
    2.1.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.28.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v1.28.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v1.28.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki"}
    2.1.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v2.1.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki", "changelog_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/CHANGELOG.md", "rubygems_mfa_required" => "true"}
  DIFFERENT required_ruby_version:
    1.28.0: >= 2.7
    2.1.0: >= 3.3
  DIFFERENT rubygems_version:
    1.28.0: 3.4.10
    2.1.0: 4.0.3
  DIFFERENT version:
    1.28.0: 1.28.0
    2.1.0: 2.1.0
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
            lib/parallel/serializer.rb +52/-0
      * Changed:
            lib/parallel.rb +68/-40
            lib/parallel/version.rb +1/-1

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
        lib/parallel/serializer.rb
                --- /tmp/20260617-674-31tzh1	2026-06-17 02:33:59.991863185 +0000
                +++ /tmp/d20260617-674-x0nehp/parallel-2.1.0/lib/parallel/serializer.rb	2026-06-17 02:33:59.991863185 +0000
                @@ -0,0 +1,52 @@
                +# frozen_string_literal: true
                +require 'openssl'
                +require 'securerandom'
                +
                +module Parallel
                +  # Pluggable wire serializers. Each must respond to `dump(data, io)` /
                +  # `load(io)` (used directly by Worker) and `dump(data)` / `load(string)`
                +  # (used by wrappers like Hmac).
                +  module Serializer
                +    # Raw Marshal. Fast but trusts anything written to the pipe — a same-UID
                +    # attacker that reopens /proc/<pid>/fd/<n> can inject Marshal gadgets (RCE).
                +    Marshal = ::Marshal
                +
                +    # Wraps any inner serializer with a length-prefixed HMAC-SHA256 frame keyed
                +    # on a per-worker secret generated before fork. Forged frames from a
                +    # pipe-injector fail verification.
                +    class Hmac
                +      LENGTH_FORMAT = 'N' # 32-bit big-endian unsigned int
                +      LENGTH_BYTES = 4
                +      MAC_BYTES = 32 # SHA256
                +
                +      def initialize(inner: Marshal, secret: SecureRandom.bytes(32))
                +        @inner = inner
                +        @secret = secret
                +      end
                +
                +      def dump(data, io)
                +        payload = @inner.dump(data)
                +        mac = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        io.write([payload.bytesize].pack(LENGTH_FORMAT), mac, payload)
                +      end
                +
                +      def load(io)
                +        # nil at frame boundary = clean EOF (worker died / pipe closed between messages)
                +        header = io.read(LENGTH_BYTES) || raise(EOFError) # eof stops worker
                +        raise SecurityError, "truncated frame header" if header.bytesize != LENGTH_BYTES
                +
                +        length = header.unpack1(LENGTH_FORMAT)
                +        mac = io.read(MAC_BYTES)
                +        raise SecurityError, "truncated frame mac" if mac.nil? || mac.bytesize != MAC_BYTES
                +
                +        payload = io.read(length)
                +        raise SecurityError, "truncated frame payload" if payload.nil? || payload.bytesize != length
                +
                +        expected = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        raise SecurityError, "HMAC mismatch on worker pipe" unless OpenSSL.fixed_length_secure_compare(mac, expected)
                +
                +        @inner.load(payload)
                +      end
                +    end
                +  end
                +end
      * Changed:
        lib/parallel.rb
                --- /tmp/d20260617-674-x0nehp/parallel-1.28.0/lib/parallel.rb	2026-06-17 02:33:59.990863167 +0000
                +++ /tmp/d20260617-674-x0nehp/parallel-2.1.0/lib/parallel.rb	2026-06-17 02:33:59.991863185 +0000
                @@ -3,0 +4 @@
                +require 'parallel/serializer'
                @@ -66 +67 @@
                -    def initialize(read, write, pid)
                +    def initialize(read, write, pid, serializer)
                @@ -69,0 +71 @@
                +      @serializer = serializer
                @@ -86 +88 @@
                -        Marshal.dump(data, write)
                +        @serializer.dump(data, write)
                @@ -92 +94 @@
                -        Marshal.load(read)
                +        @serializer.load(read)
                @@ -269 +271 @@
                -      elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
                +      elsif RUBY_PLATFORM.include?('java') && !options[:in_processes]
                @@ -473,0 +476,2 @@
                +      use_port = defined?(Ractor::Port)
                +
                @@ -475,13 +479,4 @@
                -      ractors = Array.new(options.fetch(:count)) do
                -        Ractor.new do
                -          loop do
                -            got = receive
                -            (klass, method_name), item, index = got
                -            break if index == :break
                -            begin
                -              Ractor.yield [nil, klass.send(method_name, item), item, index]
                -            rescue StandardError => e
                -              Ractor.yield [e, nil, item, index]
                -            end
                -          end
                -        end
                +      ports = {} # port (ruby 4+) or ractor (ruby 3) => ractor
                +      options.fetch(:count).times do
                +        port, ractor = ractor_build(use_port)
                +        ports[port] = ractor
                @@ -491,3 +486,3 @@
                -      ractors.dup.each do |ractor|
                -        if (set = job_factory.next)
                -          item, index = set
                +      ports.dup.each do |port, ractor|
                +        if (job = job_factory.next)
                +          item, index = job
                @@ -496,3 +491,3 @@
                -        else
                -          ractor.send([[nil, nil], nil, :break]) # stop the ractor
                -          ractors.delete ractor
                +        else # not enough work, `receive` would hang
                +          ractor_stop ractor
                +          ports.delete port
                @@ -502,4 +497,5 @@
                -      # replace with new items
                -      while (set = job_factory.next)
                -        item_next, index_next = set
                -        done, (exception, result, item, index) = Ractor.select(*ractors)
                +      # receive result and send new items to done ractors
                +      while (job = job_factory.next)
                +        # receive result
                +        done_port, (exception, result, item_prev, index_prev) = Ractor.select(*ports.keys)
                +        done_ractor = ports[done_port]
                @@ -507 +503 @@
                -          ractors.delete done
                +          ports.delete done_port
                @@ -510,2 +506 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +        ractor_result item_prev, index_prev, result, results, results_mutex, options
                @@ -512,0 +508,2 @@
                +        # send new
                +        item_next, index_next = job
                @@ -514 +511 @@
                -        done.send([callback, item_next, index_next])
                +        done_ractor.send([callback, item_next, index_next])
                @@ -518,2 +515,2 @@
                -      ractors.each do |ractor|
                -        (new_exception, result, item, index) = ractor.take
                +      ports.each do |port, ractor|
                +        (new_exception, result, item, index) = use_port ? port.receive : ractor.take
                @@ -522,3 +519,2 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                -        ractor.send([[nil, nil], nil, :break]) # stop the ractor
                +        ractor_result item, index, result, results, results_mutex, options
                +        ractor_stop ractor
                @@ -529,0 +526,30 @@
                +    def ractor_build(use_port)
                +      args = use_port ? [Ractor::Port.new] : []
                +      ractor = Ractor.new(*args) do |port|
                +        loop do
                +          (klass, method_name), item, index = receive
                +          break if index == :break
                +          begin
                +            result = [nil, klass.send(method_name, item), item, index]
                +          rescue StandardError => e
                +            result = [e, nil, item, index]
                +          end
                +          if port
                +            port.send result
                +          else
                +            Ractor.yield result
                +          end
                +        end
                +      end
                +      [use_port ? args.first : ractor, ractor]
                +    end
                +
                +    def ractor_result(item, index, result, results, results_mutex, options)
                +      instrument_finish item, index, result, options
                +      results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +    end
                +
                +    def ractor_stop(ractor)
                +      ractor.send([[nil, nil], nil, :break])
                +    end
                +
                @@ -600,0 +627 @@
                +      options[:serializer] ||= Serializer::Marshal
                @@ -621 +648 @@
                -      Worker.new(parent_read, parent_write, pid)
                +      Worker.new(parent_read, parent_write, pid, options[:serializer])
                @@ -624,0 +652 @@
                +      serializer = options.fetch(:serializer)
                @@ -626 +654 @@
                -        data = Marshal.load(read)
                +        data = serializer.load(read)
                @@ -635 +663 @@
                -          rescue Exception # # rubocop:disable Lint/RescueException
                +          rescue Exception # rubocop:disable Lint/RescueException
                @@ -640 +668 @@
                -          Marshal.dump(result, write)
                +          serializer.dump(result, write)
        lib/parallel/version.rb
                --- /tmp/d20260617-674-x0nehp/parallel-1.28.0/lib/parallel/version.rb	2026-06-17 02:33:59.990863167 +0000
                +++ /tmp/d20260617-674-x0nehp/parallel-2.1.0/lib/parallel/version.rb	2026-06-17 02:33:59.991863185 +0000
                @@ -3 +3 @@
                -  VERSION = Version = '1.28.0' # rubocop:disable Naming/ConstantName
                +  VERSION = Version = '2.1.0' # rubocop:disable Naming/ConstantName

@github-actions

Copy link
Copy Markdown
Contributor

gem compare parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT date:
    1.28.0: 2026-04-02 00:00:00 UTC
    2.1.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.28.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v1.28.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v1.28.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki"}
    2.1.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v2.1.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki", "changelog_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/CHANGELOG.md", "rubygems_mfa_required" => "true"}
  DIFFERENT required_ruby_version:
    1.28.0: >= 2.7
    2.1.0: >= 3.3
  DIFFERENT rubygems_version:
    1.28.0: 3.4.10
    2.1.0: 4.0.3
  DIFFERENT version:
    1.28.0: 1.28.0
    2.1.0: 2.1.0
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
            lib/parallel/serializer.rb +52/-0
      * Changed:
            lib/parallel.rb +68/-40
            lib/parallel/version.rb +1/-1

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

gem compare parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT date:
    1.28.0: 2026-04-02 00:00:00 UTC
    2.1.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.28.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v1.28.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v1.28.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki"}
    2.1.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v2.1.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki", "changelog_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/CHANGELOG.md", "rubygems_mfa_required" => "true"}
  DIFFERENT required_ruby_version:
    1.28.0: >= 2.7
    2.1.0: >= 3.3
  DIFFERENT rubygems_version:
    1.28.0: 3.4.10
    2.1.0: 4.0.3
  DIFFERENT version:
    1.28.0: 1.28.0
    2.1.0: 2.1.0
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
            lib/parallel/serializer.rb +52/-0
      * Changed:
            lib/parallel.rb +68/-40
            lib/parallel/version.rb +1/-1

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
        lib/parallel/serializer.rb
                --- /tmp/20260617-719-8go1xa	2026-06-17 02:34:13.227209077 +0000
                +++ /tmp/d20260617-719-es8fz7/parallel-2.1.0/lib/parallel/serializer.rb	2026-06-17 02:34:13.227209077 +0000
                @@ -0,0 +1,52 @@
                +# frozen_string_literal: true
                +require 'openssl'
                +require 'securerandom'
                +
                +module Parallel
                +  # Pluggable wire serializers. Each must respond to `dump(data, io)` /
                +  # `load(io)` (used directly by Worker) and `dump(data)` / `load(string)`
                +  # (used by wrappers like Hmac).
                +  module Serializer
                +    # Raw Marshal. Fast but trusts anything written to the pipe — a same-UID
                +    # attacker that reopens /proc/<pid>/fd/<n> can inject Marshal gadgets (RCE).
                +    Marshal = ::Marshal
                +
                +    # Wraps any inner serializer with a length-prefixed HMAC-SHA256 frame keyed
                +    # on a per-worker secret generated before fork. Forged frames from a
                +    # pipe-injector fail verification.
                +    class Hmac
                +      LENGTH_FORMAT = 'N' # 32-bit big-endian unsigned int
                +      LENGTH_BYTES = 4
                +      MAC_BYTES = 32 # SHA256
                +
                +      def initialize(inner: Marshal, secret: SecureRandom.bytes(32))
                +        @inner = inner
                +        @secret = secret
                +      end
                +
                +      def dump(data, io)
                +        payload = @inner.dump(data)
                +        mac = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        io.write([payload.bytesize].pack(LENGTH_FORMAT), mac, payload)
                +      end
                +
                +      def load(io)
                +        # nil at frame boundary = clean EOF (worker died / pipe closed between messages)
                +        header = io.read(LENGTH_BYTES) || raise(EOFError) # eof stops worker
                +        raise SecurityError, "truncated frame header" if header.bytesize != LENGTH_BYTES
                +
                +        length = header.unpack1(LENGTH_FORMAT)
                +        mac = io.read(MAC_BYTES)
                +        raise SecurityError, "truncated frame mac" if mac.nil? || mac.bytesize != MAC_BYTES
                +
                +        payload = io.read(length)
                +        raise SecurityError, "truncated frame payload" if payload.nil? || payload.bytesize != length
                +
                +        expected = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        raise SecurityError, "HMAC mismatch on worker pipe" unless OpenSSL.fixed_length_secure_compare(mac, expected)
                +
                +        @inner.load(payload)
                +      end
                +    end
                +  end
                +end
      * Changed:
        lib/parallel.rb
                --- /tmp/d20260617-719-es8fz7/parallel-1.28.0/lib/parallel.rb	2026-06-17 02:34:13.226209066 +0000
                +++ /tmp/d20260617-719-es8fz7/parallel-2.1.0/lib/parallel.rb	2026-06-17 02:34:13.226209066 +0000
                @@ -3,0 +4 @@
                +require 'parallel/serializer'
                @@ -66 +67 @@
                -    def initialize(read, write, pid)
                +    def initialize(read, write, pid, serializer)
                @@ -69,0 +71 @@
                +      @serializer = serializer
                @@ -86 +88 @@
                -        Marshal.dump(data, write)
                +        @serializer.dump(data, write)
                @@ -92 +94 @@
                -        Marshal.load(read)
                +        @serializer.load(read)
                @@ -269 +271 @@
                -      elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
                +      elsif RUBY_PLATFORM.include?('java') && !options[:in_processes]
                @@ -473,0 +476,2 @@
                +      use_port = defined?(Ractor::Port)
                +
                @@ -475,13 +479,4 @@
                -      ractors = Array.new(options.fetch(:count)) do
                -        Ractor.new do
                -          loop do
                -            got = receive
                -            (klass, method_name), item, index = got
                -            break if index == :break
                -            begin
                -              Ractor.yield [nil, klass.send(method_name, item), item, index]
                -            rescue StandardError => e
                -              Ractor.yield [e, nil, item, index]
                -            end
                -          end
                -        end
                +      ports = {} # port (ruby 4+) or ractor (ruby 3) => ractor
                +      options.fetch(:count).times do
                +        port, ractor = ractor_build(use_port)
                +        ports[port] = ractor
                @@ -491,3 +486,3 @@
                -      ractors.dup.each do |ractor|
                -        if (set = job_factory.next)
                -          item, index = set
                +      ports.dup.each do |port, ractor|
                +        if (job = job_factory.next)
                +          item, index = job
                @@ -496,3 +491,3 @@
                -        else
                -          ractor.send([[nil, nil], nil, :break]) # stop the ractor
                -          ractors.delete ractor
                +        else # not enough work, `receive` would hang
                +          ractor_stop ractor
                +          ports.delete port
                @@ -502,4 +497,5 @@
                -      # replace with new items
                -      while (set = job_factory.next)
                -        item_next, index_next = set
                -        done, (exception, result, item, index) = Ractor.select(*ractors)
                +      # receive result and send new items to done ractors
                +      while (job = job_factory.next)
                +        # receive result
                +        done_port, (exception, result, item_prev, index_prev) = Ractor.select(*ports.keys)
                +        done_ractor = ports[done_port]
                @@ -507 +503 @@
                -          ractors.delete done
                +          ports.delete done_port
                @@ -510,2 +506 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +        ractor_result item_prev, index_prev, result, results, results_mutex, options
                @@ -512,0 +508,2 @@
                +        # send new
                +        item_next, index_next = job
                @@ -514 +511 @@
                -        done.send([callback, item_next, index_next])
                +        done_ractor.send([callback, item_next, index_next])
                @@ -518,2 +515,2 @@
                -      ractors.each do |ractor|
                -        (new_exception, result, item, index) = ractor.take
                +      ports.each do |port, ractor|
                +        (new_exception, result, item, index) = use_port ? port.receive : ractor.take
                @@ -522,3 +519,2 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                -        ractor.send([[nil, nil], nil, :break]) # stop the ractor
                +        ractor_result item, index, result, results, results_mutex, options
                +        ractor_stop ractor
                @@ -529,0 +526,30 @@
                +    def ractor_build(use_port)
                +      args = use_port ? [Ractor::Port.new] : []
                +      ractor = Ractor.new(*args) do |port|
                +        loop do
                +          (klass, method_name), item, index = receive
                +          break if index == :break
                +          begin
                +            result = [nil, klass.send(method_name, item), item, index]
                +          rescue StandardError => e
                +            result = [e, nil, item, index]
                +          end
                +          if port
                +            port.send result
                +          else
                +            Ractor.yield result
                +          end
                +        end
                +      end
                +      [use_port ? args.first : ractor, ractor]
                +    end
                +
                +    def ractor_result(item, index, result, results, results_mutex, options)
                +      instrument_finish item, index, result, options
                +      results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +    end
                +
                +    def ractor_stop(ractor)
                +      ractor.send([[nil, nil], nil, :break])
                +    end
                +
                @@ -600,0 +627 @@
                +      options[:serializer] ||= Serializer::Marshal
                @@ -621 +648 @@
                -      Worker.new(parent_read, parent_write, pid)
                +      Worker.new(parent_read, parent_write, pid, options[:serializer])
                @@ -624,0 +652 @@
                +      serializer = options.fetch(:serializer)
                @@ -626 +654 @@
                -        data = Marshal.load(read)
                +        data = serializer.load(read)
                @@ -635 +663 @@
                -          rescue Exception # # rubocop:disable Lint/RescueException
                +          rescue Exception # rubocop:disable Lint/RescueException
                @@ -640 +668 @@
                -          Marshal.dump(result, write)
                +          serializer.dump(result, write)
        lib/parallel/version.rb
                --- /tmp/d20260617-719-es8fz7/parallel-1.28.0/lib/parallel/version.rb	2026-06-17 02:34:13.226209066 +0000
                +++ /tmp/d20260617-719-es8fz7/parallel-2.1.0/lib/parallel/version.rb	2026-06-17 02:34:13.227209077 +0000
                @@ -3 +3 @@
                -  VERSION = Version = '1.28.0' # rubocop:disable Naming/ConstantName
                +  VERSION = Version = '2.1.0' # rubocop:disable Naming/ConstantName

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
        lib/parallel/serializer.rb
                --- /tmp/20260617-692-tpht1j	2026-06-17 02:34:16.541582387 +0000
                +++ /tmp/d20260617-692-j0txcv/parallel-2.1.0/lib/parallel/serializer.rb	2026-06-17 02:34:16.540582390 +0000
                @@ -0,0 +1,52 @@
                +# frozen_string_literal: true
                +require 'openssl'
                +require 'securerandom'
                +
                +module Parallel
                +  # Pluggable wire serializers. Each must respond to `dump(data, io)` /
                +  # `load(io)` (used directly by Worker) and `dump(data)` / `load(string)`
                +  # (used by wrappers like Hmac).
                +  module Serializer
                +    # Raw Marshal. Fast but trusts anything written to the pipe — a same-UID
                +    # attacker that reopens /proc/<pid>/fd/<n> can inject Marshal gadgets (RCE).
                +    Marshal = ::Marshal
                +
                +    # Wraps any inner serializer with a length-prefixed HMAC-SHA256 frame keyed
                +    # on a per-worker secret generated before fork. Forged frames from a
                +    # pipe-injector fail verification.
                +    class Hmac
                +      LENGTH_FORMAT = 'N' # 32-bit big-endian unsigned int
                +      LENGTH_BYTES = 4
                +      MAC_BYTES = 32 # SHA256
                +
                +      def initialize(inner: Marshal, secret: SecureRandom.bytes(32))
                +        @inner = inner
                +        @secret = secret
                +      end
                +
                +      def dump(data, io)
                +        payload = @inner.dump(data)
                +        mac = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        io.write([payload.bytesize].pack(LENGTH_FORMAT), mac, payload)
                +      end
                +
                +      def load(io)
                +        # nil at frame boundary = clean EOF (worker died / pipe closed between messages)
                +        header = io.read(LENGTH_BYTES) || raise(EOFError) # eof stops worker
                +        raise SecurityError, "truncated frame header" if header.bytesize != LENGTH_BYTES
                +
                +        length = header.unpack1(LENGTH_FORMAT)
                +        mac = io.read(MAC_BYTES)
                +        raise SecurityError, "truncated frame mac" if mac.nil? || mac.bytesize != MAC_BYTES
                +
                +        payload = io.read(length)
                +        raise SecurityError, "truncated frame payload" if payload.nil? || payload.bytesize != length
                +
                +        expected = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        raise SecurityError, "HMAC mismatch on worker pipe" unless OpenSSL.fixed_length_secure_compare(mac, expected)
                +
                +        @inner.load(payload)
                +      end
                +    end
                +  end
                +end
      * Changed:
        lib/parallel.rb
                --- /tmp/d20260617-692-j0txcv/parallel-1.28.0/lib/parallel.rb	2026-06-17 02:34:16.540582390 +0000
                +++ /tmp/d20260617-692-j0txcv/parallel-2.1.0/lib/parallel.rb	2026-06-17 02:34:16.540582390 +0000
                @@ -3,0 +4 @@
                +require 'parallel/serializer'
                @@ -66 +67 @@
                -    def initialize(read, write, pid)
                +    def initialize(read, write, pid, serializer)
                @@ -69,0 +71 @@
                +      @serializer = serializer
                @@ -86 +88 @@
                -        Marshal.dump(data, write)
                +        @serializer.dump(data, write)
                @@ -92 +94 @@
                -        Marshal.load(read)
                +        @serializer.load(read)
                @@ -269 +271 @@
                -      elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
                +      elsif RUBY_PLATFORM.include?('java') && !options[:in_processes]
                @@ -473,0 +476,2 @@
                +      use_port = defined?(Ractor::Port)
                +
                @@ -475,13 +479,4 @@
                -      ractors = Array.new(options.fetch(:count)) do
                -        Ractor.new do
                -          loop do
                -            got = receive
                -            (klass, method_name), item, index = got
                -            break if index == :break
                -            begin
                -              Ractor.yield [nil, klass.send(method_name, item), item, index]
                -            rescue StandardError => e
                -              Ractor.yield [e, nil, item, index]
                -            end
                -          end
                -        end
                +      ports = {} # port (ruby 4+) or ractor (ruby 3) => ractor
                +      options.fetch(:count).times do
                +        port, ractor = ractor_build(use_port)
                +        ports[port] = ractor
                @@ -491,3 +486,3 @@
                -      ractors.dup.each do |ractor|
                -        if (set = job_factory.next)
                -          item, index = set
                +      ports.dup.each do |port, ractor|
                +        if (job = job_factory.next)
                +          item, index = job
                @@ -496,3 +491,3 @@
                -        else
                -          ractor.send([[nil, nil], nil, :break]) # stop the ractor
                -          ractors.delete ractor
                +        else # not enough work, `receive` would hang
                +          ractor_stop ractor
                +          ports.delete port
                @@ -502,4 +497,5 @@
                -      # replace with new items
                -      while (set = job_factory.next)
                -        item_next, index_next = set
                -        done, (exception, result, item, index) = Ractor.select(*ractors)
                +      # receive result and send new items to done ractors
                +      while (job = job_factory.next)
                +        # receive result
                +        done_port, (exception, result, item_prev, index_prev) = Ractor.select(*ports.keys)
                +        done_ractor = ports[done_port]
                @@ -507 +503 @@
                -          ractors.delete done
                +          ports.delete done_port
                @@ -510,2 +506 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +        ractor_result item_prev, index_prev, result, results, results_mutex, options
                @@ -512,0 +508,2 @@
                +        # send new
                +        item_next, index_next = job
                @@ -514 +511 @@
                -        done.send([callback, item_next, index_next])
                +        done_ractor.send([callback, item_next, index_next])
                @@ -518,2 +515,2 @@
                -      ractors.each do |ractor|
                -        (new_exception, result, item, index) = ractor.take
                +      ports.each do |port, ractor|
                +        (new_exception, result, item, index) = use_port ? port.receive : ractor.take
                @@ -522,3 +519,2 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                -        ractor.send([[nil, nil], nil, :break]) # stop the ractor
                +        ractor_result item, index, result, results, results_mutex, options
                +        ractor_stop ractor
                @@ -529,0 +526,30 @@
                +    def ractor_build(use_port)
                +      args = use_port ? [Ractor::Port.new] : []
                +      ractor = Ractor.new(*args) do |port|
                +        loop do
                +          (klass, method_name), item, index = receive
                +          break if index == :break
                +          begin
                +            result = [nil, klass.send(method_name, item), item, index]
                +          rescue StandardError => e
                +            result = [e, nil, item, index]
                +          end
                +          if port
                +            port.send result
                +          else
                +            Ractor.yield result
                +          end
                +        end
                +      end
                +      [use_port ? args.first : ractor, ractor]
                +    end
                +
                +    def ractor_result(item, index, result, results, results_mutex, options)
                +      instrument_finish item, index, result, options
                +      results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +    end
                +
                +    def ractor_stop(ractor)
                +      ractor.send([[nil, nil], nil, :break])
                +    end
                +
                @@ -600,0 +627 @@
                +      options[:serializer] ||= Serializer::Marshal
                @@ -621 +648 @@
                -      Worker.new(parent_read, parent_write, pid)
                +      Worker.new(parent_read, parent_write, pid, options[:serializer])
                @@ -624,0 +652 @@
                +      serializer = options.fetch(:serializer)
                @@ -626 +654 @@
                -        data = Marshal.load(read)
                +        data = serializer.load(read)
                @@ -635 +663 @@
                -          rescue Exception # # rubocop:disable Lint/RescueException
                +          rescue Exception # rubocop:disable Lint/RescueException
                @@ -640 +668 @@
                -          Marshal.dump(result, write)
                +          serializer.dump(result, write)
        lib/parallel/version.rb
                --- /tmp/d20260617-692-j0txcv/parallel-1.28.0/lib/parallel/version.rb	2026-06-17 02:34:16.540582390 +0000
                +++ /tmp/d20260617-692-j0txcv/parallel-2.1.0/lib/parallel/version.rb	2026-06-17 02:34:16.540582390 +0000
                @@ -3 +3 @@
                -  VERSION = Version = '1.28.0' # rubocop:disable Naming/ConstantName
                +  VERSION = Version = '2.1.0' # rubocop:disable Naming/ConstantName

@github-actions

Copy link
Copy Markdown
Contributor

gem compare rubocop 1.79.2 1.88.0

Compared versions: ["1.79.2", "1.88.0"]
  DIFFERENT date:
    1.79.2: 2025-08-05 00:00:00 UTC
    1.88.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.79.2: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.79.2", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.79/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
    1.88.0: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.88.0", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.88/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
  DIFFERENT rubygems_version:
    1.79.2: 3.6.2
    1.88.0: 3.6.9
  DIFFERENT version:
    1.79.2: 1.79.2
    1.88.0: 1.88.0
  DIFFERENT files:
    1.79.2->1.88.0:
      * Added:
            lib/rubocop/cli/command/list_enabled_cops_for.rb +40/-0
            lib/rubocop/cli/command/mcp.rb +19/-0
            lib/rubocop/cop/correctors.rb +28/-0
            lib/rubocop/cop/internal_affairs/itblock_handler.rb +69/-0
            lib/rubocop/cop/lint/data_define_override.rb +63/-0
            lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113/-0
            lib/rubocop/cop/mixin.rb +86/-0
            lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63/-0
            lib/rubocop/cop/mixin/project_index_help.rb +48/-0
            lib/rubocop/cop/style/array_intersect_with_single_element.rb +50/-0
            lib/rubocop/cop/style/empty_class_definition.rb +119/-0
            lib/rubocop/cop/style/file_open.rb +84/-0
            lib/rubocop/cop/style/hash_lookup_method.rb +106/-0
            lib/rubocop/cop/style/map_join.rb +123/-0
            lib/rubocop/cop/style/module_member_existence_check.rb +110/-0
            lib/rubocop/cop/style/negative_array_index.rb +220/-0
            lib/rubocop/cop/style/one_class_per_file.rb +115/-0
            lib/rubocop/cop/style/partition_instead_of_double_select.rb +270/-0
            lib/rubocop/cop/style/predicate_with_kind.rb +84/-0
            lib/rubocop/cop/style/reduce_to_hash.rb +200/-0
            lib/rubocop/cop/style/redundant_min_max_by.rb +93/-0
            lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114/-0
            lib/rubocop/cop/style/reverse_find.rb +51/-0
            lib/rubocop/cop/style/select_by_kind.rb +158/-0
            lib/rubocop/cop/style/select_by_range.rb +197/-0
            lib/rubocop/cop/style/tally_method.rb +181/-0
            lib/rubocop/lsp/disable_comment_edits.rb +135/-0
            lib/rubocop/mcp/server.rb +200/-0
            lib/rubocop/project_index_loader.rb +66/-0
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
            config/default.yml +259/-90
            config/obsoletion.yml +30/-1
            exe/rubocop +1/-8
            lib/rubocop.rb +28/-96
            lib/rubocop/cache_config.rb +29/-0
            lib/rubocop/cli.rb +35/-9
            lib/rubocop/cli/command/auto_generate_config.rb +36/-4
            lib/rubocop/cli/command/lsp.rb +1/-1
            lib/rubocop/cli/command/show_cops.rb +2/-2
            lib/rubocop/cli/command/show_docs_url.rb +4/-8
            lib/rubocop/cli/command/suggest_extensions.rb +1/-1
            lib/rubocop/comment_config.rb +59/-17
            lib/rubocop/config.rb +14/-10
            lib/rubocop/config_finder.rb +1/-1
            lib/rubocop/config_loader.rb +37/-23
            lib/rubocop/config_loader_resolver.rb +20/-10
            lib/rubocop/config_obsoletion/extracted_cop.rb +4/-2
            lib/rubocop/config_store.rb +7/-2
            lib/rubocop/config_validator.rb +1/-1
            lib/rubocop/cop/autocorrect_logic.rb +10/-5
            lib/rubocop/cop/base.rb +25/-4
            lib/rubocop/cop/bundler/gem_comment.rb +2/-2
            lib/rubocop/cop/bundler/gem_version.rb +28/-28
            lib/rubocop/cop/bundler/ordered_gems.rb +1/-2
            lib/rubocop/cop/correctors/alignment_corrector.rb +26/-7
            lib/rubocop/cop/correctors/condition_corrector.rb +1/-1
            lib/rubocop/cop/correctors/for_to_each_corrector.rb +7/-2
            lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1/-5
            lib/rubocop/cop/correctors/parentheses_corrector.rb +33/-2
            lib/rubocop/cop/correctors/percent_literal_corrector.rb +2/-2
            lib/rubocop/cop/documentation.rb +2/-3
            lib/rubocop/cop/exclude_limit.rb +31/-5
            lib/rubocop/cop/gemspec/duplicated_assignment.rb +2/-2
            lib/rubocop/cop/gemspec/ordered_dependencies.rb +1/-2
            lib/rubocop/cop/gemspec/require_mfa.rb +5/-5
            lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12/-7
            lib/rubocop/cop/internal_affairs.rb +1/-0
            lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8/-8
            lib/rubocop/cop/internal_affairs/location_exists.rb +28/-2
            lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1/-0
            lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9/-9
            lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3/-1
            lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1/-1
            lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1/-1
            lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5/-3
            lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4/-4
            lib/rubocop/cop/layout/argument_alignment.rb +2/-2
            lib/rubocop/cop/layout/array_alignment.rb +1/-1
            lib/rubocop/cop/layout/begin_end_alignment.rb +1/-1
            lib/rubocop/cop/layout/block_alignment.rb +41/-4
            lib/rubocop/cop/layout/case_indentation.rb +3/-1
            lib/rubocop/cop/layout/class_structure.rb +14/-7
            lib/rubocop/cop/layout/dot_position.rb +2/-2
            lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26/-7
            lib/rubocop/cop/layout/empty_line_between_defs.rb +31/-13
            lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2/-2
            lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1/-0
            lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12/-2
            lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16/-2
            lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16/-2
            lib/rubocop/cop/layout/end_alignment.rb +10/-3
            lib/rubocop/cop/layout/first_argument_indentation.rb +34/-1
            lib/rubocop/cop/layout/first_array_element_line_break.rb +26/-0
            lib/rubocop/cop/layout/first_hash_element_indentation.rb +7/-1
            lib/rubocop/cop/layout/first_hash_element_line_break.rb +28/-28
            lib/rubocop/cop/layout/hash_alignment.rb +3/-6
            lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2/-2
            lib/rubocop/cop/layout/heredoc_indentation.rb +33/-3
            lib/rubocop/cop/layout/indentation_style.rb +1/-1
            lib/rubocop/cop/layout/indentation_width.rb +123/-7
            lib/rubocop/cop/layout/line_continuation_spacing.rb +1/-1
            lib/rubocop/cop/layout/line_length.rb +26/-9
            lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57/-57
            lib/rubocop/cop/layout/multiline_assignment_layout.rb +9/-2
            lib/rubocop/cop/layout/multiline_block_layout.rb +2/-0
            lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56/-56
            lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1/-1
            lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229/-39
            lib/rubocop/cop/layout/multiline_operation_indentation.rb +8/-4
            lib/rubocop/cop/layout/parameter_alignment.rb +1/-1
            lib/rubocop/cop/layout/redundant_line_break.rb +3/-1
            lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13/-3
            lib/rubocop/cop/layout/space_after_comma.rb +2/-10
            lib/rubocop/cop/layout/space_after_semicolon.rb +1/-1
            lib/rubocop/cop/layout/space_around_block_parameters.rb +1/-1
            lib/rubocop/cop/layout/space_around_keyword.rb +4/-2
            lib/rubocop/cop/layout/space_before_brackets.rb +1/-1
            lib/rubocop/cop/layout/space_in_lambda_literal.rb +9/-8
            lib/rubocop/cop/layout/trailing_whitespace.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_assignment.rb +1/-11
            lib/rubocop/cop/lint/ambiguous_block_association.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1/-10
            lib/rubocop/cop/lint/circular_argument_reference.rb +45/-3
            lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4/-3
            lib/rubocop/cop/lint/constant_reassignment.rb +93/-11
            lib/rubocop/cop/lint/constant_resolution.rb +6/-6
            lib/rubocop/cop/lint/cop_directive_syntax.rb +14/-8
            lib/rubocop/cop/lint/debugger.rb +0/-3
            lib/rubocop/cop/lint/deprecated_constants.rb +2/-8
            lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4/-1
            lib/rubocop/cop/lint/duplicate_match_pattern.rb +4/-4
            lib/rubocop/cop/lint/duplicate_methods.rb +111/-12
            lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5/-42
            lib/rubocop/cop/lint/else_layout.rb +19/-0
            lib/rubocop/cop/lint/empty_block.rb +4/-4
            lib/rubocop/cop/lint/empty_conditional_body.rb +6/-1
            lib/rubocop/cop/lint/empty_in_pattern.rb +8/-1
            lib/rubocop/cop/lint/empty_interpolation.rb +11/-0
            lib/rubocop/cop/lint/empty_when.rb +8/-1
            lib/rubocop/cop/lint/ensure_return.rb +19/-1
            lib/rubocop/cop/lint/erb_new_arguments.rb +4/-2
            lib/rubocop/cop/lint/float_comparison.rb +2/-1
            lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5/-1
            lib/rubocop/cop/lint/interpolation_check.rb +25/-5
            lib/rubocop/cop/lint/lambda_without_literal_block.rb +1/-1
            lib/rubocop/cop/lint/literal_as_condition.rb +5/-1
            lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11/-1
            lib/rubocop/cop/lint/literal_in_interpolation.rb +9/-12
            lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19/-10
            lib/rubocop/cop/lint/multiple_comparison.rb +2/-2
            lib/rubocop/cop/lint/next_without_accumulator.rb +2/-0
            lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20/-0
            lib/rubocop/cop/lint/non_deterministic_require_order.rb +4/-2
            lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1/-1
            lib/rubocop/cop/lint/number_conversion.rb +19/-10
            lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1/-1
            lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3/-0
            lib/rubocop/cop/lint/ordered_magic_comments.rb +7/-7
            lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2/-12
            lib/rubocop/cop/lint/raise_exception.rb +1/-1
            lib/rubocop/cop/lint/rand_one.rb +1/-1
            lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27/-10
            lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6/-12
            lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15/-4
            lib/rubocop/cop/lint/redundant_require_statement.rb +4/-2
            lib/rubocop/cop/lint/redundant_safe_navigation.rb +36/-12
            lib/rubocop/cop/lint/redundant_splat_expansion.rb +12/-2
            lib/rubocop/cop/lint/redundant_type_conversion.rb +10/-3
            lib/rubocop/cop/lint/redundant_with_index.rb +1/-1
            lib/rubocop/cop/lint/redundant_with_object.rb +5/-0
            lib/rubocop/cop/lint/refinement_import_methods.rb +8/-1
            lib/rubocop/cop/lint/regexp_as_condition.rb +9/-1
            lib/rubocop/cop/lint/require_parentheses.rb +13/-4
            lib/rubocop/cop/lint/require_range_parentheses.rb +2/-1
            lib/rubocop/cop/lint/require_relative_self_path.rb +7/-5
            lib/rubocop/cop/lint/rescue_exception.rb +1/-4
            lib/rubocop/cop/lint/rescue_type.rb +1/-1
            lib/rubocop/cop/lint/safe_navigation_chain.rb +18/-0
            lib/rubocop/cop/lint/safe_navigation_consistency.rb +7/-1
            lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1/-1
            lib/rubocop/cop/lint/script_permission.rb +5/-1
            lib/rubocop/cop/lint/self_assignment.rb +39/-7
            lib/rubocop/cop/lint/send_with_mixin_argument.rb +1/-1
            lib/rubocop/cop/lint/shadowed_argument.rb +7/-7
            lib/rubocop/cop/lint/shadowed_exception.rb +1/-1
            lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14/-0
            lib/rubocop/cop/lint/shared_mutable_default.rb +3/-1
            lib/rubocop/cop/lint/struct_new_override.rb +17/-1
            lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12/-0
            lib/rubocop/cop/lint/symbol_conversion.rb +21/-4
            lib/rubocop/cop/lint/syntax.rb +25/-1
            lib/rubocop/cop/lint/to_enum_arguments.rb +28/-1
            lib/rubocop/cop/lint/to_json.rb +12/-16
            lib/rubocop/cop/lint/top_level_return_with_argument.rb +1/-1
            lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5/-1
            lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +4/-2
            lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1/-0
            lib/rubocop/cop/lint/unreachable_code.rb +7/-5
            lib/rubocop/cop/lint/unused_method_argument.rb +10/-0
            lib/rubocop/cop/lint/uri_escape_unescape.rb +2/-0
            lib/rubocop/cop/lint/useless_assignment.rb +53/-25
            lib/rubocop/cop/lint/useless_constant_scoping.rb +4/-4
            lib/rubocop/cop/lint/useless_default_value_argument.rb +2/-0
            lib/rubocop/cop/lint/useless_or.rb +15/-2
            lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8/-4
            lib/rubocop/cop/lint/useless_setter_call.rb +4/-1
            lib/rubocop/cop/lint/useless_times.rb +22/-1
            lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37/-11
            lib/rubocop/cop/lint/void.rb +39/-12
            lib/rubocop/cop/message_annotator.rb +1/-1
            lib/rubocop/cop/metrics/block_length.rb +1/-1
            lib/rubocop/cop/metrics/block_nesting.rb +23/-0
            lib/rubocop/cop/metrics/collection_literal_length.rb +1/-1
            lib/rubocop/cop/metrics/method_length.rb +1/-1
            lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4/-3
            lib/rubocop/cop/metrics/utils/iterating_block.rb +1/-1
            lib/rubocop/cop/migration/department_name.rb +12/-1
            lib/rubocop/cop/mixin/check_line_breakable.rb +2/-2
            lib/rubocop/cop/mixin/check_single_line_suitability.rb +4/-6
            lib/rubocop/cop/mixin/code_length.rb +1/-1
            lib/rubocop/cop/mixin/configurable_max.rb +6/-5
            lib/rubocop/cop/mixin/end_keyword_alignment.rb +1/-7
            lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5/-5
            lib/rubocop/cop/mixin/hash_transform_method.rb +10/-60
            lib/rubocop/cop/mixin/line_length_help.rb +21/-2
            lib/rubocop/cop/mixin/method_complexity.rb +1/-1
            lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1/-1
            lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1/-1
            lib/rubocop/cop/mixin/space_after_punctuation.rb +5/-4
            lib/rubocop/cop/mixin/statement_modifier.rb +0/-6
            lib/rubocop/cop/mixin/trailing_comma.rb +8/-5
            lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/block_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1/-1
            lib/rubocop/cop/naming/method_name.rb +5/-3
            lib/rubocop/cop/naming/predicate_method.rb +32/-8
            lib/rubocop/cop/naming/predicate_prefix.rb +12/-12
            lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1/-1
            lib/rubocop/cop/offense.rb +17/-1
            lib/rubocop/cop/registry.rb +62/-38
            lib/rubocop/cop/security/eval.rb +15/-2
            lib/rubocop/cop/security/io_methods.rb +1/-1
            lib/rubocop/cop/security/json_load.rb +33/-11
            lib/rubocop/cop/style/access_modifier_declarations.rb +15/-4
            lib/rubocop/cop/style/accessor_grouping.rb +4/-2
            lib/rubocop/cop/style/alias.rb +15/-3
            lib/rubocop/cop/style/and_or.rb +2/-1
            lib/rubocop/cop/style/arguments_forwarding.rb +24/-6
            lib/rubocop/cop/style/array_first_last.rb +12/-1
            lib/rubocop/cop/style/array_intersect.rb +50/-12
            lib/rubocop/cop/style/array_join.rb +4/-2
            lib/rubocop/cop/style/ascii_comments.rb +6/-3
            lib/rubocop/cop/style/attr.rb +5/-2
            lib/rubocop/cop/style/bare_percent_literals.rb +4/-3
            lib/rubocop/cop/style/begin_block.rb +3/-1
            lib/rubocop/cop/style/bitwise_predicate.rb +8/-1
            lib/rubocop/cop/style/block_delimiters.rb +42/-35
            lib/rubocop/cop/style/case_equality.rb +29/-15
            lib/rubocop/cop/style/character_literal.rb +2/-2
            lib/rubocop/cop/style/class_and_module_children.rb +19/-2
            lib/rubocop/cop/style/class_equality_comparison.rb +21/-13
            lib/rubocop/cop/style/class_methods_definitions.rb +11/-5
            lib/rubocop/cop/style/collection_compact.rb +36/-16
            lib/rubocop/cop/style/colon_method_call.rb +16/-7
            lib/rubocop/cop/style/combinable_loops.rb +5/-0
            lib/rubocop/cop/style/comparable_clamp.rb +12/-1
            lib/rubocop/cop/style/concat_array_literals.rb +7/-1
            lib/rubocop/cop/style/conditional_assignment.rb +14/-19
            lib/rubocop/cop/style/constant_visibility.rb +20/-12
            lib/rubocop/cop/style/copyright.rb +22/-11
            lib/rubocop/cop/style/date_time.rb +4/-4
            lib/rubocop/cop/style/dig_chain.rb +5/-0
            lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1/-1
            lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6/-1
            lib/rubocop/cop/style/documentation.rb +6/-6
            lib/rubocop/cop/style/documentation_method.rb +7/-7
            lib/rubocop/cop/style/double_negation.rb +1/-1
            lib/rubocop/cop/style/each_for_simple_loop.rb +1/-1
            lib/rubocop/cop/style/each_with_object.rb +2/-0
            lib/rubocop/cop/style/empty_block_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_lambda_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_method.rb +0/-6
            lib/rubocop/cop/style/encoding.rb +7/-1
            lib/rubocop/cop/style/end_block.rb +3/-1
            lib/rubocop/cop/style/endless_method.rb +23/-5
            lib/rubocop/cop/style/explicit_block_argument.rb +1/-1
            lib/rubocop/cop/style/fetch_env_var.rb +1/-1
            lib/rubocop/cop/style/file_write.rb +21/-16
            lib/rubocop/cop/style/float_division.rb +15/-1
            lib/rubocop/cop/style/for.rb +3/-0
            lib/rubocop/cop/style/format_string.rb +4/-3
            lib/rubocop/cop/style/format_string_token.rb +49/-5
            lib/rubocop/cop/style/global_vars.rb +5/-2
            lib/rubocop/cop/style/guard_clause.rb +27/-22
            lib/rubocop/cop/style/hash_as_last_array_item.rb +27/-9
            lib/rubocop/cop/style/hash_conversion.rb +1/-1
            lib/rubocop/cop/style/hash_slice.rb +16/-0
            lib/rubocop/cop/style/hash_syntax.rb +1/-1
            lib/rubocop/cop/style/hash_transform_keys.rb +17/-7
            lib/rubocop/cop/style/hash_transform_values.rb +17/-7
            lib/rubocop/cop/style/if_inside_else.rb +16/-7
            lib/rubocop/cop/style/if_unless_modifier.rb +58/-18
            lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12/-12
            lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4/-1
            lib/rubocop/cop/style/if_with_semicolon.rb +7/-5
            lib/rubocop/cop/style/infinite_loop.rb +1/-1
            lib/rubocop/cop/style/inline_comment.rb +4/-1
            lib/rubocop/cop/style/ip_addresses.rb +1/-2
            lib/rubocop/cop/style/lambda_call.rb +8/-8
            lib/rubocop/cop/style/magic_comment_format.rb +3/-3
            lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17/-4
            lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15/-2
            lib/rubocop/cop/style/method_def_parentheses.rb +2/-4
            lib/rubocop/cop/style/min_max_comparison.rb +1/-1
            lib/rubocop/cop/style/multiline_if_then.rb +4/-4
            lib/rubocop/cop/style/multiline_method_signature.rb +2/-4
            lib/rubocop/cop/style/mutable_constant.rb +106/-12
            lib/rubocop/cop/style/nil_comparison.rb +11/-10
            lib/rubocop/cop/style/nil_lambda.rb +1/-1
            lib/rubocop/cop/style/non_nil_check.rb +5/-11
            lib/rubocop/cop/style/not.rb +2/-0
            lib/rubocop/cop/style/numeric_literals.rb +3/-2
            lib/rubocop/cop/style/one_line_conditional.rb +21/-12
            lib/rubocop/cop/style/operator_method_call.rb +11/-2
            lib/rubocop/cop/style/parallel_assignment.rb +14/-3
            lib/rubocop/cop/style/percent_literal_delimiters.rb +2/-0
            lib/rubocop/cop/style/preferred_hash_methods.rb +12/-12
            lib/rubocop/cop/style/proc.rb +3/-2
            lib/rubocop/cop/style/raise_args.rb +1/-1
            lib/rubocop/cop/style/redundant_argument.rb +2/-0
            lib/rubocop/cop/style/redundant_array_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_begin.rb +37/-3
            lib/rubocop/cop/style/redundant_condition.rb +6/-3
            lib/rubocop/cop/style/redundant_constant_base.rb +5/-5
            lib/rubocop/cop/style/redundant_each.rb +3/-3
            lib/rubocop/cop/style/redundant_exception.rb +1/-1
            lib/rubocop/cop/style/redundant_fetch_block.rb +1/-1
            lib/rubocop/cop/style/redundant_format.rb +27/-5
            lib/rubocop/cop/style/redundant_interpolation.rb +11/-2
            lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +27/-11
            lib/rubocop/cop/style/redundant_line_continuation.rb +16/-0
            lib/rubocop/cop/style/redundant_parentheses.rb +36/-30
            lib/rubocop/cop/style/redundant_percent_q.rb +5/-3
            lib/rubocop/cop/style/redundant_regexp_argument.rb +9/-0
            lib/rubocop/cop/style/redundant_regexp_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_regexp_escape.rb +8/-0
            lib/rubocop/cop/style/redundant_return.rb +3/-1
            lib/rubocop/cop/style/redundant_self.rb +2/-2
            lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0/-5
            lib/rubocop/cop/style/redundant_sort.rb +7/-7
            lib/rubocop/cop/style/regexp_literal.rb +31/-2
            lib/rubocop/cop/style/rescue_modifier.rb +3/-3
            lib/rubocop/cop/style/safe_navigation.rb +25/-8
            lib/rubocop/cop/style/select_by_regexp.rb +51/-21
            lib/rubocop/cop/style/self_assignment.rb +1/-1
            lib/rubocop/cop/style/semicolon.rb +41/-8
            lib/rubocop/cop/style/single_line_block_params.rb +2/-2
            lib/rubocop/cop/style/single_line_do_end_block.rb +1/-1
            lib/rubocop/cop/style/single_line_methods.rb +3/-1
            lib/rubocop/cop/style/sole_nested_conditional.rb +12/-3
            lib/rubocop/cop/style/special_global_vars.rb +6/-1
            lib/rubocop/cop/style/string_concatenation.rb +17/-13
            lib/rubocop/cop/style/struct_inheritance.rb +13/-0
            lib/rubocop/cop/style/super_arguments.rb +2/-2
            lib/rubocop/cop/style/symbol_array.rb +1/-1
            lib/rubocop/cop/style/symbol_proc.rb +7/-6
            lib/rubocop/cop/style/top_level_method_definition.rb +2/-2
            lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45/-0
            lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1/-1
            lib/rubocop/cop/style/trailing_method_end_statement.rb +1/-0
            lib/rubocop/cop/style/trailing_underscore_variable.rb +11/-11
            lib/rubocop/cop/style/unless_else.rb +10/-9
            lib/rubocop/cop/style/unless_logical_operators.rb +3/-3
            lib/rubocop/cop/style/while_until_do.rb +7/-0
            lib/rubocop/cop/style/while_until_modifier.rb +16/-0
            lib/rubocop/cop/style/word_array.rb +1/-0
            lib/rubocop/cop/style/yoda_condition.rb +1/-1
            lib/rubocop/cop/style/yoda_expression.rb +1/-1
            lib/rubocop/cop/style/zero_length_predicate.rb +6/-3
            lib/rubocop/cop/team.rb +87/-36
            lib/rubocop/cop/util.rb +2/-3
            lib/rubocop/cop/utils/format_string.rb +10/-0
            lib/rubocop/cop/variable_force.rb +9/-7
            lib/rubocop/cop/variable_force/branch.rb +30/-6
            lib/rubocop/cop/variable_force/variable.rb +1/-1
            lib/rubocop/cops_documentation_generator.rb +4/-4
            lib/rubocop/directive_comment.rb +48/-4
            lib/rubocop/file_patterns.rb +9/-1
            lib/rubocop/formatter.rb +22/-21
            lib/rubocop/formatter/clang_style_formatter.rb +5/-2
            lib/rubocop/formatter/disabled_config_formatter.rb +38/-14
            lib/rubocop/formatter/formatter_set.rb +2/-2
            lib/rubocop/formatter/junit_formatter.rb +1/-1
            lib/rubocop/formatter/simple_text_formatter.rb +0/-2
            lib/rubocop/formatter/tap_formatter.rb +5/-2
            lib/rubocop/formatter/worst_offenders_formatter.rb +1/-1
            lib/rubocop/lsp/diagnostic.rb +18/-33
            lib/rubocop/lsp/routes.rb +42/-6
            lib/rubocop/lsp/runtime.rb +13/-4
            lib/rubocop/lsp/stdin_runner.rb +8/-17
            lib/rubocop/magic_comment.rb +20/-0
            lib/rubocop/options.rb +35/-4
            lib/rubocop/path_util.rb +14/-2
            lib/rubocop/plugin/loader.rb +1/-1
            lib/rubocop/rake_task.rb +1/-1
            lib/rubocop/remote_config.rb +10/-8
            lib/rubocop/result_cache.rb +61/-38
            lib/rubocop/rspec/cop_helper.rb +8/-0
            lib/rubocop/rspec/shared_contexts.rb +39/-5
            lib/rubocop/rspec/support.rb +2/-1
            lib/rubocop/runner.rb +134/-57
            lib/rubocop/server/cache.rb +6/-29
            lib/rubocop/server/core.rb +8/-0
            lib/rubocop/target_finder.rb +17/-10
            lib/rubocop/target_ruby.rb +31/-14
            lib/rubocop/version.rb +21/-3
            lib/ruby_lsp/rubocop/addon.rb +23/-8
            lib/ruby_lsp/rubocop/runtime_adapter.rb +49/-15
  DIFFERENT extra_rdoc_files:
    1.79.2->1.88.0:
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
  DIFFERENT runtime dependencies:
    1.79.2->1.88.0:
      * Updated:
            parallel from: ["~> 1.10"] to: [">= 1.10"]
            rubocop-ast from: [">= 1.46.0", "< 2.0"] to: [">= 1.49.0", "< 2.0"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
        lib/parallel/serializer.rb
                --- /tmp/20260617-693-cknqm5	2026-06-17 02:34:27.104184140 +0000
                +++ /tmp/d20260617-693-tccz09/parallel-2.1.0/lib/parallel/serializer.rb	2026-06-17 02:34:27.103184145 +0000
                @@ -0,0 +1,52 @@
                +# frozen_string_literal: true
                +require 'openssl'
                +require 'securerandom'
                +
                +module Parallel
                +  # Pluggable wire serializers. Each must respond to `dump(data, io)` /
                +  # `load(io)` (used directly by Worker) and `dump(data)` / `load(string)`
                +  # (used by wrappers like Hmac).
                +  module Serializer
                +    # Raw Marshal. Fast but trusts anything written to the pipe — a same-UID
                +    # attacker that reopens /proc/<pid>/fd/<n> can inject Marshal gadgets (RCE).
                +    Marshal = ::Marshal
                +
                +    # Wraps any inner serializer with a length-prefixed HMAC-SHA256 frame keyed
                +    # on a per-worker secret generated before fork. Forged frames from a
                +    # pipe-injector fail verification.
                +    class Hmac
                +      LENGTH_FORMAT = 'N' # 32-bit big-endian unsigned int
                +      LENGTH_BYTES = 4
                +      MAC_BYTES = 32 # SHA256
                +
                +      def initialize(inner: Marshal, secret: SecureRandom.bytes(32))
                +        @inner = inner
                +        @secret = secret
                +      end
                +
                +      def dump(data, io)
                +        payload = @inner.dump(data)
                +        mac = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        io.write([payload.bytesize].pack(LENGTH_FORMAT), mac, payload)
                +      end
                +
                +      def load(io)
                +        # nil at frame boundary = clean EOF (worker died / pipe closed between messages)
                +        header = io.read(LENGTH_BYTES) || raise(EOFError) # eof stops worker
                +        raise SecurityError, "truncated frame header" if header.bytesize != LENGTH_BYTES
                +
                +        length = header.unpack1(LENGTH_FORMAT)
                +        mac = io.read(MAC_BYTES)
                +        raise SecurityError, "truncated frame mac" if mac.nil? || mac.bytesize != MAC_BYTES
                +
                +        payload = io.read(length)
                +        raise SecurityError, "truncated frame payload" if payload.nil? || payload.bytesize != length
                +
                +        expected = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        raise SecurityError, "HMAC mismatch on worker pipe" unless OpenSSL.fixed_length_secure_compare(mac, expected)
                +
                +        @inner.load(payload)
                +      end
                +    end
                +  end
                +end
      * Changed:
        lib/parallel.rb
                --- /tmp/d20260617-693-tccz09/parallel-1.28.0/lib/parallel.rb	2026-06-17 02:34:27.102184151 +0000
                +++ /tmp/d20260617-693-tccz09/parallel-2.1.0/lib/parallel.rb	2026-06-17 02:34:27.103184145 +0000
                @@ -3,0 +4 @@
                +require 'parallel/serializer'
                @@ -66 +67 @@
                -    def initialize(read, write, pid)
                +    def initialize(read, write, pid, serializer)
                @@ -69,0 +71 @@
                +      @serializer = serializer
                @@ -86 +88 @@
                -        Marshal.dump(data, write)
                +        @serializer.dump(data, write)
                @@ -92 +94 @@
                -        Marshal.load(read)
                +        @serializer.load(read)
                @@ -269 +271 @@
                -      elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
                +      elsif RUBY_PLATFORM.include?('java') && !options[:in_processes]
                @@ -473,0 +476,2 @@
                +      use_port = defined?(Ractor::Port)
                +
                @@ -475,13 +479,4 @@
                -      ractors = Array.new(options.fetch(:count)) do
                -        Ractor.new do
                -          loop do
                -            got = receive
                -            (klass, method_name), item, index = got
                -            break if index == :break
                -            begin
                -              Ractor.yield [nil, klass.send(method_name, item), item, index]
                -            rescue StandardError => e
                -              Ractor.yield [e, nil, item, index]
                -            end
                -          end
                -        end
                +      ports = {} # port (ruby 4+) or ractor (ruby 3) => ractor
                +      options.fetch(:count).times do
                +        port, ractor = ractor_build(use_port)
                +        ports[port] = ractor
                @@ -491,3 +486,3 @@
                -      ractors.dup.each do |ractor|
                -        if (set = job_factory.next)
                -          item, index = set
                +      ports.dup.each do |port, ractor|
                +        if (job = job_factory.next)
                +          item, index = job
                @@ -496,3 +491,3 @@
                -        else
                -          ractor.send([[nil, nil], nil, :break]) # stop the ractor
                -          ractors.delete ractor
                +        else # not enough work, `receive` would hang
                +          ractor_stop ractor
                +          ports.delete port
                @@ -502,4 +497,5 @@
                -      # replace with new items
                -      while (set = job_factory.next)
                -        item_next, index_next = set
                -        done, (exception, result, item, index) = Ractor.select(*ractors)
                +      # receive result and send new items to done ractors
                +      while (job = job_factory.next)
                +        # receive result
                +        done_port, (exception, result, item_prev, index_prev) = Ractor.select(*ports.keys)
                +        done_ractor = ports[done_port]
                @@ -507 +503 @@
                -          ractors.delete done
                +          ports.delete done_port
                @@ -510,2 +506 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +        ractor_result item_prev, index_prev, result, results, results_mutex, options
                @@ -512,0 +508,2 @@
                +        # send new
                +        item_next, index_next = job
                @@ -514 +511 @@
                -        done.send([callback, item_next, index_next])
                +        done_ractor.send([callback, item_next, index_next])
                @@ -518,2 +515,2 @@
                -      ractors.each do |ractor|
                -        (new_exception, result, item, index) = ractor.take
                +      ports.each do |port, ractor|
                +        (new_exception, result, item, index) = use_port ? port.receive : ractor.take
                @@ -522,3 +519,2 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                -        ractor.send([[nil, nil], nil, :break]) # stop the ractor
                +        ractor_result item, index, result, results, results_mutex, options
                +        ractor_stop ractor
                @@ -529,0 +526,30 @@
                +    def ractor_build(use_port)
                +      args = use_port ? [Ractor::Port.new] : []
                +      ractor = Ractor.new(*args) do |port|
                +        loop do
                +          (klass, method_name), item, index = receive
                +          break if index == :break
                +          begin
                +            result = [nil, klass.send(method_name, item), item, index]
                +          rescue StandardError => e
                +            result = [e, nil, item, index]
                +          end
                +          if port
                +            port.send result
                +          else
                +            Ractor.yield result
                +          end
                +        end
                +      end
                +      [use_port ? args.first : ractor, ractor]
                +    end
                +
                +    def ractor_result(item, index, result, results, results_mutex, options)
                +      instrument_finish item, index, result, options
                +      results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +    end
                +
                +    def ractor_stop(ractor)
                +      ractor.send([[nil, nil], nil, :break])
                +    end
                +
                @@ -600,0 +627 @@
                +      options[:serializer] ||= Serializer::Marshal
                @@ -621 +648 @@
                -      Worker.new(parent_read, parent_write, pid)
                +      Worker.new(parent_read, parent_write, pid, options[:serializer])
                @@ -624,0 +652 @@
                +      serializer = options.fetch(:serializer)
                @@ -626 +654 @@
                -        data = Marshal.load(read)
                +        data = serializer.load(read)
                @@ -635 +663 @@
                -          rescue Exception # # rubocop:disable Lint/RescueException
                +          rescue Exception # rubocop:disable Lint/RescueException
                @@ -640 +668 @@
                -          Marshal.dump(result, write)
                +          serializer.dump(result, write)
        lib/parallel/version.rb
                --- /tmp/d20260617-693-tccz09/parallel-1.28.0/lib/parallel/version.rb	2026-06-17 02:34:27.102184151 +0000
                +++ /tmp/d20260617-693-tccz09/parallel-2.1.0/lib/parallel/version.rb	2026-06-17 02:34:27.104184140 +0000
                @@ -3 +3 @@
                -  VERSION = Version = '1.28.0' # rubocop:disable Naming/ConstantName
                +  VERSION = Version = '2.1.0' # rubocop:disable Naming/ConstantName

@github-actions

Copy link
Copy Markdown
Contributor

gem compare rubocop 1.79.2 1.88.0

Compared versions: ["1.79.2", "1.88.0"]
  DIFFERENT date:
    1.79.2: 2025-08-05 00:00:00 UTC
    1.88.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.79.2: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.79.2", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.79/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
    1.88.0: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.88.0", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.88/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
  DIFFERENT rubygems_version:
    1.79.2: 3.6.2
    1.88.0: 3.6.9
  DIFFERENT version:
    1.79.2: 1.79.2
    1.88.0: 1.88.0
  DIFFERENT files:
    1.79.2->1.88.0:
      * Added:
            lib/rubocop/cli/command/list_enabled_cops_for.rb +40/-0
            lib/rubocop/cli/command/mcp.rb +19/-0
            lib/rubocop/cop/correctors.rb +28/-0
            lib/rubocop/cop/internal_affairs/itblock_handler.rb +69/-0
            lib/rubocop/cop/lint/data_define_override.rb +63/-0
            lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113/-0
            lib/rubocop/cop/mixin.rb +86/-0
            lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63/-0
            lib/rubocop/cop/mixin/project_index_help.rb +48/-0
            lib/rubocop/cop/style/array_intersect_with_single_element.rb +50/-0
            lib/rubocop/cop/style/empty_class_definition.rb +119/-0
            lib/rubocop/cop/style/file_open.rb +84/-0
            lib/rubocop/cop/style/hash_lookup_method.rb +106/-0
            lib/rubocop/cop/style/map_join.rb +123/-0
            lib/rubocop/cop/style/module_member_existence_check.rb +110/-0
            lib/rubocop/cop/style/negative_array_index.rb +220/-0
            lib/rubocop/cop/style/one_class_per_file.rb +115/-0
            lib/rubocop/cop/style/partition_instead_of_double_select.rb +270/-0
            lib/rubocop/cop/style/predicate_with_kind.rb +84/-0
            lib/rubocop/cop/style/reduce_to_hash.rb +200/-0
            lib/rubocop/cop/style/redundant_min_max_by.rb +93/-0
            lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114/-0
            lib/rubocop/cop/style/reverse_find.rb +51/-0
            lib/rubocop/cop/style/select_by_kind.rb +158/-0
            lib/rubocop/cop/style/select_by_range.rb +197/-0
            lib/rubocop/cop/style/tally_method.rb +181/-0
            lib/rubocop/lsp/disable_comment_edits.rb +135/-0
            lib/rubocop/mcp/server.rb +200/-0
            lib/rubocop/project_index_loader.rb +66/-0
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
            config/default.yml +259/-90
            config/obsoletion.yml +30/-1
            exe/rubocop +1/-8
            lib/rubocop.rb +28/-96
            lib/rubocop/cache_config.rb +29/-0
            lib/rubocop/cli.rb +35/-9
            lib/rubocop/cli/command/auto_generate_config.rb +36/-4
            lib/rubocop/cli/command/lsp.rb +1/-1
            lib/rubocop/cli/command/show_cops.rb +2/-2
            lib/rubocop/cli/command/show_docs_url.rb +4/-8
            lib/rubocop/cli/command/suggest_extensions.rb +1/-1
            lib/rubocop/comment_config.rb +59/-17
            lib/rubocop/config.rb +14/-10
            lib/rubocop/config_finder.rb +1/-1
            lib/rubocop/config_loader.rb +37/-23
            lib/rubocop/config_loader_resolver.rb +20/-10
            lib/rubocop/config_obsoletion/extracted_cop.rb +4/-2
            lib/rubocop/config_store.rb +7/-2
            lib/rubocop/config_validator.rb +1/-1
            lib/rubocop/cop/autocorrect_logic.rb +10/-5
            lib/rubocop/cop/base.rb +25/-4
            lib/rubocop/cop/bundler/gem_comment.rb +2/-2
            lib/rubocop/cop/bundler/gem_version.rb +28/-28
            lib/rubocop/cop/bundler/ordered_gems.rb +1/-2
            lib/rubocop/cop/correctors/alignment_corrector.rb +26/-7
            lib/rubocop/cop/correctors/condition_corrector.rb +1/-1
            lib/rubocop/cop/correctors/for_to_each_corrector.rb +7/-2
            lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1/-5
            lib/rubocop/cop/correctors/parentheses_corrector.rb +33/-2
            lib/rubocop/cop/correctors/percent_literal_corrector.rb +2/-2
            lib/rubocop/cop/documentation.rb +2/-3
            lib/rubocop/cop/exclude_limit.rb +31/-5
            lib/rubocop/cop/gemspec/duplicated_assignment.rb +2/-2
            lib/rubocop/cop/gemspec/ordered_dependencies.rb +1/-2
            lib/rubocop/cop/gemspec/require_mfa.rb +5/-5
            lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12/-7
            lib/rubocop/cop/internal_affairs.rb +1/-0
            lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8/-8
            lib/rubocop/cop/internal_affairs/location_exists.rb +28/-2
            lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1/-0
            lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9/-9
            lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3/-1
            lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1/-1
            lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1/-1
            lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5/-3
            lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4/-4
            lib/rubocop/cop/layout/argument_alignment.rb +2/-2
            lib/rubocop/cop/layout/array_alignment.rb +1/-1
            lib/rubocop/cop/layout/begin_end_alignment.rb +1/-1
            lib/rubocop/cop/layout/block_alignment.rb +41/-4
            lib/rubocop/cop/layout/case_indentation.rb +3/-1
            lib/rubocop/cop/layout/class_structure.rb +14/-7
            lib/rubocop/cop/layout/dot_position.rb +2/-2
            lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26/-7
            lib/rubocop/cop/layout/empty_line_between_defs.rb +31/-13
            lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2/-2
            lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1/-0
            lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12/-2
            lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16/-2
            lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16/-2
            lib/rubocop/cop/layout/end_alignment.rb +10/-3
            lib/rubocop/cop/layout/first_argument_indentation.rb +34/-1
            lib/rubocop/cop/layout/first_array_element_line_break.rb +26/-0
            lib/rubocop/cop/layout/first_hash_element_indentation.rb +7/-1
            lib/rubocop/cop/layout/first_hash_element_line_break.rb +28/-28
            lib/rubocop/cop/layout/hash_alignment.rb +3/-6
            lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2/-2
            lib/rubocop/cop/layout/heredoc_indentation.rb +33/-3
            lib/rubocop/cop/layout/indentation_style.rb +1/-1
            lib/rubocop/cop/layout/indentation_width.rb +123/-7
            lib/rubocop/cop/layout/line_continuation_spacing.rb +1/-1
            lib/rubocop/cop/layout/line_length.rb +26/-9
            lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57/-57
            lib/rubocop/cop/layout/multiline_assignment_layout.rb +9/-2
            lib/rubocop/cop/layout/multiline_block_layout.rb +2/-0
            lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56/-56
            lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1/-1
            lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229/-39
            lib/rubocop/cop/layout/multiline_operation_indentation.rb +8/-4
            lib/rubocop/cop/layout/parameter_alignment.rb +1/-1
            lib/rubocop/cop/layout/redundant_line_break.rb +3/-1
            lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13/-3
            lib/rubocop/cop/layout/space_after_comma.rb +2/-10
            lib/rubocop/cop/layout/space_after_semicolon.rb +1/-1
            lib/rubocop/cop/layout/space_around_block_parameters.rb +1/-1
            lib/rubocop/cop/layout/space_around_keyword.rb +4/-2
            lib/rubocop/cop/layout/space_before_brackets.rb +1/-1
            lib/rubocop/cop/layout/space_in_lambda_literal.rb +9/-8
            lib/rubocop/cop/layout/trailing_whitespace.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_assignment.rb +1/-11
            lib/rubocop/cop/lint/ambiguous_block_association.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1/-10
            lib/rubocop/cop/lint/circular_argument_reference.rb +45/-3
            lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4/-3
            lib/rubocop/cop/lint/constant_reassignment.rb +93/-11
            lib/rubocop/cop/lint/constant_resolution.rb +6/-6
            lib/rubocop/cop/lint/cop_directive_syntax.rb +14/-8
            lib/rubocop/cop/lint/debugger.rb +0/-3
            lib/rubocop/cop/lint/deprecated_constants.rb +2/-8
            lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4/-1
            lib/rubocop/cop/lint/duplicate_match_pattern.rb +4/-4
            lib/rubocop/cop/lint/duplicate_methods.rb +111/-12
            lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5/-42
            lib/rubocop/cop/lint/else_layout.rb +19/-0
            lib/rubocop/cop/lint/empty_block.rb +4/-4
            lib/rubocop/cop/lint/empty_conditional_body.rb +6/-1
            lib/rubocop/cop/lint/empty_in_pattern.rb +8/-1
            lib/rubocop/cop/lint/empty_interpolation.rb +11/-0
            lib/rubocop/cop/lint/empty_when.rb +8/-1
            lib/rubocop/cop/lint/ensure_return.rb +19/-1
            lib/rubocop/cop/lint/erb_new_arguments.rb +4/-2
            lib/rubocop/cop/lint/float_comparison.rb +2/-1
            lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5/-1
            lib/rubocop/cop/lint/interpolation_check.rb +25/-5
            lib/rubocop/cop/lint/lambda_without_literal_block.rb +1/-1
            lib/rubocop/cop/lint/literal_as_condition.rb +5/-1
            lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11/-1
            lib/rubocop/cop/lint/literal_in_interpolation.rb +9/-12
            lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19/-10
            lib/rubocop/cop/lint/multiple_comparison.rb +2/-2
            lib/rubocop/cop/lint/next_without_accumulator.rb +2/-0
            lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20/-0
            lib/rubocop/cop/lint/non_deterministic_require_order.rb +4/-2
            lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1/-1
            lib/rubocop/cop/lint/number_conversion.rb +19/-10
            lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1/-1
            lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3/-0
            lib/rubocop/cop/lint/ordered_magic_comments.rb +7/-7
            lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2/-12
            lib/rubocop/cop/lint/raise_exception.rb +1/-1
            lib/rubocop/cop/lint/rand_one.rb +1/-1
            lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27/-10
            lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6/-12
            lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15/-4
            lib/rubocop/cop/lint/redundant_require_statement.rb +4/-2
            lib/rubocop/cop/lint/redundant_safe_navigation.rb +36/-12
            lib/rubocop/cop/lint/redundant_splat_expansion.rb +12/-2
            lib/rubocop/cop/lint/redundant_type_conversion.rb +10/-3
            lib/rubocop/cop/lint/redundant_with_index.rb +1/-1
            lib/rubocop/cop/lint/redundant_with_object.rb +5/-0
            lib/rubocop/cop/lint/refinement_import_methods.rb +8/-1
            lib/rubocop/cop/lint/regexp_as_condition.rb +9/-1
            lib/rubocop/cop/lint/require_parentheses.rb +13/-4
            lib/rubocop/cop/lint/require_range_parentheses.rb +2/-1
            lib/rubocop/cop/lint/require_relative_self_path.rb +7/-5
            lib/rubocop/cop/lint/rescue_exception.rb +1/-4
            lib/rubocop/cop/lint/rescue_type.rb +1/-1
            lib/rubocop/cop/lint/safe_navigation_chain.rb +18/-0
            lib/rubocop/cop/lint/safe_navigation_consistency.rb +7/-1
            lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1/-1
            lib/rubocop/cop/lint/script_permission.rb +5/-1
            lib/rubocop/cop/lint/self_assignment.rb +39/-7
            lib/rubocop/cop/lint/send_with_mixin_argument.rb +1/-1
            lib/rubocop/cop/lint/shadowed_argument.rb +7/-7
            lib/rubocop/cop/lint/shadowed_exception.rb +1/-1
            lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14/-0
            lib/rubocop/cop/lint/shared_mutable_default.rb +3/-1
            lib/rubocop/cop/lint/struct_new_override.rb +17/-1
            lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12/-0
            lib/rubocop/cop/lint/symbol_conversion.rb +21/-4
            lib/rubocop/cop/lint/syntax.rb +25/-1
            lib/rubocop/cop/lint/to_enum_arguments.rb +28/-1
            lib/rubocop/cop/lint/to_json.rb +12/-16
            lib/rubocop/cop/lint/top_level_return_with_argument.rb +1/-1
            lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5/-1
            lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +4/-2
            lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1/-0
            lib/rubocop/cop/lint/unreachable_code.rb +7/-5
            lib/rubocop/cop/lint/unused_method_argument.rb +10/-0
            lib/rubocop/cop/lint/uri_escape_unescape.rb +2/-0
            lib/rubocop/cop/lint/useless_assignment.rb +53/-25
            lib/rubocop/cop/lint/useless_constant_scoping.rb +4/-4
            lib/rubocop/cop/lint/useless_default_value_argument.rb +2/-0
            lib/rubocop/cop/lint/useless_or.rb +15/-2
            lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8/-4
            lib/rubocop/cop/lint/useless_setter_call.rb +4/-1
            lib/rubocop/cop/lint/useless_times.rb +22/-1
            lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37/-11
            lib/rubocop/cop/lint/void.rb +39/-12
            lib/rubocop/cop/message_annotator.rb +1/-1
            lib/rubocop/cop/metrics/block_length.rb +1/-1
            lib/rubocop/cop/metrics/block_nesting.rb +23/-0
            lib/rubocop/cop/metrics/collection_literal_length.rb +1/-1
            lib/rubocop/cop/metrics/method_length.rb +1/-1
            lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4/-3
            lib/rubocop/cop/metrics/utils/iterating_block.rb +1/-1
            lib/rubocop/cop/migration/department_name.rb +12/-1
            lib/rubocop/cop/mixin/check_line_breakable.rb +2/-2
            lib/rubocop/cop/mixin/check_single_line_suitability.rb +4/-6
            lib/rubocop/cop/mixin/code_length.rb +1/-1
            lib/rubocop/cop/mixin/configurable_max.rb +6/-5
            lib/rubocop/cop/mixin/end_keyword_alignment.rb +1/-7
            lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5/-5
            lib/rubocop/cop/mixin/hash_transform_method.rb +10/-60
            lib/rubocop/cop/mixin/line_length_help.rb +21/-2
            lib/rubocop/cop/mixin/method_complexity.rb +1/-1
            lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1/-1
            lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1/-1
            lib/rubocop/cop/mixin/space_after_punctuation.rb +5/-4
            lib/rubocop/cop/mixin/statement_modifier.rb +0/-6
            lib/rubocop/cop/mixin/trailing_comma.rb +8/-5
            lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/block_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1/-1
            lib/rubocop/cop/naming/method_name.rb +5/-3
            lib/rubocop/cop/naming/predicate_method.rb +32/-8
            lib/rubocop/cop/naming/predicate_prefix.rb +12/-12
            lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1/-1
            lib/rubocop/cop/offense.rb +17/-1
            lib/rubocop/cop/registry.rb +62/-38
            lib/rubocop/cop/security/eval.rb +15/-2
            lib/rubocop/cop/security/io_methods.rb +1/-1
            lib/rubocop/cop/security/json_load.rb +33/-11
            lib/rubocop/cop/style/access_modifier_declarations.rb +15/-4
            lib/rubocop/cop/style/accessor_grouping.rb +4/-2
            lib/rubocop/cop/style/alias.rb +15/-3
            lib/rubocop/cop/style/and_or.rb +2/-1
            lib/rubocop/cop/style/arguments_forwarding.rb +24/-6
            lib/rubocop/cop/style/array_first_last.rb +12/-1
            lib/rubocop/cop/style/array_intersect.rb +50/-12
            lib/rubocop/cop/style/array_join.rb +4/-2
            lib/rubocop/cop/style/ascii_comments.rb +6/-3
            lib/rubocop/cop/style/attr.rb +5/-2
            lib/rubocop/cop/style/bare_percent_literals.rb +4/-3
            lib/rubocop/cop/style/begin_block.rb +3/-1
            lib/rubocop/cop/style/bitwise_predicate.rb +8/-1
            lib/rubocop/cop/style/block_delimiters.rb +42/-35
            lib/rubocop/cop/style/case_equality.rb +29/-15
            lib/rubocop/cop/style/character_literal.rb +2/-2
            lib/rubocop/cop/style/class_and_module_children.rb +19/-2
            lib/rubocop/cop/style/class_equality_comparison.rb +21/-13
            lib/rubocop/cop/style/class_methods_definitions.rb +11/-5
            lib/rubocop/cop/style/collection_compact.rb +36/-16
            lib/rubocop/cop/style/colon_method_call.rb +16/-7
            lib/rubocop/cop/style/combinable_loops.rb +5/-0
            lib/rubocop/cop/style/comparable_clamp.rb +12/-1
            lib/rubocop/cop/style/concat_array_literals.rb +7/-1
            lib/rubocop/cop/style/conditional_assignment.rb +14/-19
            lib/rubocop/cop/style/constant_visibility.rb +20/-12
            lib/rubocop/cop/style/copyright.rb +22/-11
            lib/rubocop/cop/style/date_time.rb +4/-4
            lib/rubocop/cop/style/dig_chain.rb +5/-0
            lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1/-1
            lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6/-1
            lib/rubocop/cop/style/documentation.rb +6/-6
            lib/rubocop/cop/style/documentation_method.rb +7/-7
            lib/rubocop/cop/style/double_negation.rb +1/-1
            lib/rubocop/cop/style/each_for_simple_loop.rb +1/-1
            lib/rubocop/cop/style/each_with_object.rb +2/-0
            lib/rubocop/cop/style/empty_block_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_lambda_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_method.rb +0/-6
            lib/rubocop/cop/style/encoding.rb +7/-1
            lib/rubocop/cop/style/end_block.rb +3/-1
            lib/rubocop/cop/style/endless_method.rb +23/-5
            lib/rubocop/cop/style/explicit_block_argument.rb +1/-1
            lib/rubocop/cop/style/fetch_env_var.rb +1/-1
            lib/rubocop/cop/style/file_write.rb +21/-16
            lib/rubocop/cop/style/float_division.rb +15/-1
            lib/rubocop/cop/style/for.rb +3/-0
            lib/rubocop/cop/style/format_string.rb +4/-3
            lib/rubocop/cop/style/format_string_token.rb +49/-5
            lib/rubocop/cop/style/global_vars.rb +5/-2
            lib/rubocop/cop/style/guard_clause.rb +27/-22
            lib/rubocop/cop/style/hash_as_last_array_item.rb +27/-9
            lib/rubocop/cop/style/hash_conversion.rb +1/-1
            lib/rubocop/cop/style/hash_slice.rb +16/-0
            lib/rubocop/cop/style/hash_syntax.rb +1/-1
            lib/rubocop/cop/style/hash_transform_keys.rb +17/-7
            lib/rubocop/cop/style/hash_transform_values.rb +17/-7
            lib/rubocop/cop/style/if_inside_else.rb +16/-7
            lib/rubocop/cop/style/if_unless_modifier.rb +58/-18
            lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12/-12
            lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4/-1
            lib/rubocop/cop/style/if_with_semicolon.rb +7/-5
            lib/rubocop/cop/style/infinite_loop.rb +1/-1
            lib/rubocop/cop/style/inline_comment.rb +4/-1
            lib/rubocop/cop/style/ip_addresses.rb +1/-2
            lib/rubocop/cop/style/lambda_call.rb +8/-8
            lib/rubocop/cop/style/magic_comment_format.rb +3/-3
            lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17/-4
            lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15/-2
            lib/rubocop/cop/style/method_def_parentheses.rb +2/-4
            lib/rubocop/cop/style/min_max_comparison.rb +1/-1
            lib/rubocop/cop/style/multiline_if_then.rb +4/-4
            lib/rubocop/cop/style/multiline_method_signature.rb +2/-4
            lib/rubocop/cop/style/mutable_constant.rb +106/-12
            lib/rubocop/cop/style/nil_comparison.rb +11/-10
            lib/rubocop/cop/style/nil_lambda.rb +1/-1
            lib/rubocop/cop/style/non_nil_check.rb +5/-11
            lib/rubocop/cop/style/not.rb +2/-0
            lib/rubocop/cop/style/numeric_literals.rb +3/-2
            lib/rubocop/cop/style/one_line_conditional.rb +21/-12
            lib/rubocop/cop/style/operator_method_call.rb +11/-2
            lib/rubocop/cop/style/parallel_assignment.rb +14/-3
            lib/rubocop/cop/style/percent_literal_delimiters.rb +2/-0
            lib/rubocop/cop/style/preferred_hash_methods.rb +12/-12
            lib/rubocop/cop/style/proc.rb +3/-2
            lib/rubocop/cop/style/raise_args.rb +1/-1
            lib/rubocop/cop/style/redundant_argument.rb +2/-0
            lib/rubocop/cop/style/redundant_array_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_begin.rb +37/-3
            lib/rubocop/cop/style/redundant_condition.rb +6/-3
            lib/rubocop/cop/style/redundant_constant_base.rb +5/-5
            lib/rubocop/cop/style/redundant_each.rb +3/-3
            lib/rubocop/cop/style/redundant_exception.rb +1/-1
            lib/rubocop/cop/style/redundant_fetch_block.rb +1/-1
            lib/rubocop/cop/style/redundant_format.rb +27/-5
            lib/rubocop/cop/style/redundant_interpolation.rb +11/-2
            lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +27/-11
            lib/rubocop/cop/style/redundant_line_continuation.rb +16/-0
            lib/rubocop/cop/style/redundant_parentheses.rb +36/-30
            lib/rubocop/cop/style/redundant_percent_q.rb +5/-3
            lib/rubocop/cop/style/redundant_regexp_argument.rb +9/-0
            lib/rubocop/cop/style/redundant_regexp_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_regexp_escape.rb +8/-0
            lib/rubocop/cop/style/redundant_return.rb +3/-1
            lib/rubocop/cop/style/redundant_self.rb +2/-2
            lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0/-5
            lib/rubocop/cop/style/redundant_sort.rb +7/-7
            lib/rubocop/cop/style/regexp_literal.rb +31/-2
            lib/rubocop/cop/style/rescue_modifier.rb +3/-3
            lib/rubocop/cop/style/safe_navigation.rb +25/-8
            lib/rubocop/cop/style/select_by_regexp.rb +51/-21
            lib/rubocop/cop/style/self_assignment.rb +1/-1
            lib/rubocop/cop/style/semicolon.rb +41/-8
            lib/rubocop/cop/style/single_line_block_params.rb +2/-2
            lib/rubocop/cop/style/single_line_do_end_block.rb +1/-1
            lib/rubocop/cop/style/single_line_methods.rb +3/-1
            lib/rubocop/cop/style/sole_nested_conditional.rb +12/-3
            lib/rubocop/cop/style/special_global_vars.rb +6/-1
            lib/rubocop/cop/style/string_concatenation.rb +17/-13
            lib/rubocop/cop/style/struct_inheritance.rb +13/-0
            lib/rubocop/cop/style/super_arguments.rb +2/-2
            lib/rubocop/cop/style/symbol_array.rb +1/-1
            lib/rubocop/cop/style/symbol_proc.rb +7/-6
            lib/rubocop/cop/style/top_level_method_definition.rb +2/-2
            lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45/-0
            lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1/-1
            lib/rubocop/cop/style/trailing_method_end_statement.rb +1/-0
            lib/rubocop/cop/style/trailing_underscore_variable.rb +11/-11
            lib/rubocop/cop/style/unless_else.rb +10/-9
            lib/rubocop/cop/style/unless_logical_operators.rb +3/-3
            lib/rubocop/cop/style/while_until_do.rb +7/-0
            lib/rubocop/cop/style/while_until_modifier.rb +16/-0
            lib/rubocop/cop/style/word_array.rb +1/-0
            lib/rubocop/cop/style/yoda_condition.rb +1/-1
            lib/rubocop/cop/style/yoda_expression.rb +1/-1
            lib/rubocop/cop/style/zero_length_predicate.rb +6/-3
            lib/rubocop/cop/team.rb +87/-36
            lib/rubocop/cop/util.rb +2/-3
            lib/rubocop/cop/utils/format_string.rb +10/-0
            lib/rubocop/cop/variable_force.rb +9/-7
            lib/rubocop/cop/variable_force/branch.rb +30/-6
            lib/rubocop/cop/variable_force/variable.rb +1/-1
            lib/rubocop/cops_documentation_generator.rb +4/-4
            lib/rubocop/directive_comment.rb +48/-4
            lib/rubocop/file_patterns.rb +9/-1
            lib/rubocop/formatter.rb +22/-21
            lib/rubocop/formatter/clang_style_formatter.rb +5/-2
            lib/rubocop/formatter/disabled_config_formatter.rb +38/-14
            lib/rubocop/formatter/formatter_set.rb +2/-2
            lib/rubocop/formatter/junit_formatter.rb +1/-1
            lib/rubocop/formatter/simple_text_formatter.rb +0/-2
            lib/rubocop/formatter/tap_formatter.rb +5/-2
            lib/rubocop/formatter/worst_offenders_formatter.rb +1/-1
            lib/rubocop/lsp/diagnostic.rb +18/-33
            lib/rubocop/lsp/routes.rb +42/-6
            lib/rubocop/lsp/runtime.rb +13/-4
            lib/rubocop/lsp/stdin_runner.rb +8/-17
            lib/rubocop/magic_comment.rb +20/-0
            lib/rubocop/options.rb +35/-4
            lib/rubocop/path_util.rb +14/-2
            lib/rubocop/plugin/loader.rb +1/-1
            lib/rubocop/rake_task.rb +1/-1
            lib/rubocop/remote_config.rb +10/-8
            lib/rubocop/result_cache.rb +61/-38
            lib/rubocop/rspec/cop_helper.rb +8/-0
            lib/rubocop/rspec/shared_contexts.rb +39/-5
            lib/rubocop/rspec/support.rb +2/-1
            lib/rubocop/runner.rb +134/-57
            lib/rubocop/server/cache.rb +6/-29
            lib/rubocop/server/core.rb +8/-0
            lib/rubocop/target_finder.rb +17/-10
            lib/rubocop/target_ruby.rb +31/-14
            lib/rubocop/version.rb +21/-3
            lib/ruby_lsp/rubocop/addon.rb +23/-8
            lib/ruby_lsp/rubocop/runtime_adapter.rb +49/-15
  DIFFERENT extra_rdoc_files:
    1.79.2->1.88.0:
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
  DIFFERENT runtime dependencies:
    1.79.2->1.88.0:
      * Updated:
            parallel from: ["~> 1.10"] to: [">= 1.10"]
            rubocop-ast from: [">= 1.46.0", "< 2.0"] to: [">= 1.49.0", "< 2.0"]

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

gem compare rubocop 1.79.2 1.88.0

Compared versions: ["1.79.2", "1.88.0"]
  DIFFERENT date:
    1.79.2: 2025-08-05 00:00:00 UTC
    1.88.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.79.2: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.79.2", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.79/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
    1.88.0: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.88.0", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.88/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
  DIFFERENT rubygems_version:
    1.79.2: 3.6.2
    1.88.0: 3.6.9
  DIFFERENT version:
    1.79.2: 1.79.2
    1.88.0: 1.88.0
  DIFFERENT files:
    1.79.2->1.88.0:
      * Added:
            lib/rubocop/cli/command/list_enabled_cops_for.rb +40/-0
            lib/rubocop/cli/command/mcp.rb +19/-0
            lib/rubocop/cop/correctors.rb +28/-0
            lib/rubocop/cop/internal_affairs/itblock_handler.rb +69/-0
            lib/rubocop/cop/lint/data_define_override.rb +63/-0
            lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113/-0
            lib/rubocop/cop/mixin.rb +86/-0
            lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63/-0
            lib/rubocop/cop/mixin/project_index_help.rb +48/-0
            lib/rubocop/cop/style/array_intersect_with_single_element.rb +50/-0
            lib/rubocop/cop/style/empty_class_definition.rb +119/-0
            lib/rubocop/cop/style/file_open.rb +84/-0
            lib/rubocop/cop/style/hash_lookup_method.rb +106/-0
            lib/rubocop/cop/style/map_join.rb +123/-0
            lib/rubocop/cop/style/module_member_existence_check.rb +110/-0
            lib/rubocop/cop/style/negative_array_index.rb +220/-0
            lib/rubocop/cop/style/one_class_per_file.rb +115/-0
            lib/rubocop/cop/style/partition_instead_of_double_select.rb +270/-0
            lib/rubocop/cop/style/predicate_with_kind.rb +84/-0
            lib/rubocop/cop/style/reduce_to_hash.rb +200/-0
            lib/rubocop/cop/style/redundant_min_max_by.rb +93/-0
            lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114/-0
            lib/rubocop/cop/style/reverse_find.rb +51/-0
            lib/rubocop/cop/style/select_by_kind.rb +158/-0
            lib/rubocop/cop/style/select_by_range.rb +197/-0
            lib/rubocop/cop/style/tally_method.rb +181/-0
            lib/rubocop/lsp/disable_comment_edits.rb +135/-0
            lib/rubocop/mcp/server.rb +200/-0
            lib/rubocop/project_index_loader.rb +66/-0
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
            config/default.yml +259/-90
            config/obsoletion.yml +30/-1
            exe/rubocop +1/-8
            lib/rubocop.rb +28/-96
            lib/rubocop/cache_config.rb +29/-0
            lib/rubocop/cli.rb +35/-9
            lib/rubocop/cli/command/auto_generate_config.rb +36/-4
            lib/rubocop/cli/command/lsp.rb +1/-1
            lib/rubocop/cli/command/show_cops.rb +2/-2
            lib/rubocop/cli/command/show_docs_url.rb +4/-8
            lib/rubocop/cli/command/suggest_extensions.rb +1/-1
            lib/rubocop/comment_config.rb +59/-17
            lib/rubocop/config.rb +14/-10
            lib/rubocop/config_finder.rb +1/-1
            lib/rubocop/config_loader.rb +37/-23
            lib/rubocop/config_loader_resolver.rb +20/-10
            lib/rubocop/config_obsoletion/extracted_cop.rb +4/-2
            lib/rubocop/config_store.rb +7/-2
            lib/rubocop/config_validator.rb +1/-1
            lib/rubocop/cop/autocorrect_logic.rb +10/-5
            lib/rubocop/cop/base.rb +25/-4
            lib/rubocop/cop/bundler/gem_comment.rb +2/-2
            lib/rubocop/cop/bundler/gem_version.rb +28/-28
            lib/rubocop/cop/bundler/ordered_gems.rb +1/-2
            lib/rubocop/cop/correctors/alignment_corrector.rb +26/-7
            lib/rubocop/cop/correctors/condition_corrector.rb +1/-1
            lib/rubocop/cop/correctors/for_to_each_corrector.rb +7/-2
            lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1/-5
            lib/rubocop/cop/correctors/parentheses_corrector.rb +33/-2
            lib/rubocop/cop/correctors/percent_literal_corrector.rb +2/-2
            lib/rubocop/cop/documentation.rb +2/-3
            lib/rubocop/cop/exclude_limit.rb +31/-5
            lib/rubocop/cop/gemspec/duplicated_assignment.rb +2/-2
            lib/rubocop/cop/gemspec/ordered_dependencies.rb +1/-2
            lib/rubocop/cop/gemspec/require_mfa.rb +5/-5
            lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12/-7
            lib/rubocop/cop/internal_affairs.rb +1/-0
            lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8/-8
            lib/rubocop/cop/internal_affairs/location_exists.rb +28/-2
            lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1/-0
            lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9/-9
            lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3/-1
            lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1/-1
            lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1/-1
            lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5/-3
            lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4/-4
            lib/rubocop/cop/layout/argument_alignment.rb +2/-2
            lib/rubocop/cop/layout/array_alignment.rb +1/-1
            lib/rubocop/cop/layout/begin_end_alignment.rb +1/-1
            lib/rubocop/cop/layout/block_alignment.rb +41/-4
            lib/rubocop/cop/layout/case_indentation.rb +3/-1
            lib/rubocop/cop/layout/class_structure.rb +14/-7
            lib/rubocop/cop/layout/dot_position.rb +2/-2
            lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26/-7
            lib/rubocop/cop/layout/empty_line_between_defs.rb +31/-13
            lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2/-2
            lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1/-0
            lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12/-2
            lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16/-2
            lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16/-2
            lib/rubocop/cop/layout/end_alignment.rb +10/-3
            lib/rubocop/cop/layout/first_argument_indentation.rb +34/-1
            lib/rubocop/cop/layout/first_array_element_line_break.rb +26/-0
            lib/rubocop/cop/layout/first_hash_element_indentation.rb +7/-1
            lib/rubocop/cop/layout/first_hash_element_line_break.rb +28/-28
            lib/rubocop/cop/layout/hash_alignment.rb +3/-6
            lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2/-2
            lib/rubocop/cop/layout/heredoc_indentation.rb +33/-3
            lib/rubocop/cop/layout/indentation_style.rb +1/-1
            lib/rubocop/cop/layout/indentation_width.rb +123/-7
            lib/rubocop/cop/layout/line_continuation_spacing.rb +1/-1
            lib/rubocop/cop/layout/line_length.rb +26/-9
            lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57/-57
            lib/rubocop/cop/layout/multiline_assignment_layout.rb +9/-2
            lib/rubocop/cop/layout/multiline_block_layout.rb +2/-0
            lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56/-56
            lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1/-1
            lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229/-39
            lib/rubocop/cop/layout/multiline_operation_indentation.rb +8/-4
            lib/rubocop/cop/layout/parameter_alignment.rb +1/-1
            lib/rubocop/cop/layout/redundant_line_break.rb +3/-1
            lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13/-3
            lib/rubocop/cop/layout/space_after_comma.rb +2/-10
            lib/rubocop/cop/layout/space_after_semicolon.rb +1/-1
            lib/rubocop/cop/layout/space_around_block_parameters.rb +1/-1
            lib/rubocop/cop/layout/space_around_keyword.rb +4/-2
            lib/rubocop/cop/layout/space_before_brackets.rb +1/-1
            lib/rubocop/cop/layout/space_in_lambda_literal.rb +9/-8
            lib/rubocop/cop/layout/trailing_whitespace.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_assignment.rb +1/-11
            lib/rubocop/cop/lint/ambiguous_block_association.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1/-10
            lib/rubocop/cop/lint/circular_argument_reference.rb +45/-3
            lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4/-3
            lib/rubocop/cop/lint/constant_reassignment.rb +93/-11
            lib/rubocop/cop/lint/constant_resolution.rb +6/-6
            lib/rubocop/cop/lint/cop_directive_syntax.rb +14/-8
            lib/rubocop/cop/lint/debugger.rb +0/-3
            lib/rubocop/cop/lint/deprecated_constants.rb +2/-8
            lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4/-1
            lib/rubocop/cop/lint/duplicate_match_pattern.rb +4/-4
            lib/rubocop/cop/lint/duplicate_methods.rb +111/-12
            lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5/-42
            lib/rubocop/cop/lint/else_layout.rb +19/-0
            lib/rubocop/cop/lint/empty_block.rb +4/-4
            lib/rubocop/cop/lint/empty_conditional_body.rb +6/-1
            lib/rubocop/cop/lint/empty_in_pattern.rb +8/-1
            lib/rubocop/cop/lint/empty_interpolation.rb +11/-0
            lib/rubocop/cop/lint/empty_when.rb +8/-1
            lib/rubocop/cop/lint/ensure_return.rb +19/-1
            lib/rubocop/cop/lint/erb_new_arguments.rb +4/-2
            lib/rubocop/cop/lint/float_comparison.rb +2/-1
            lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5/-1
            lib/rubocop/cop/lint/interpolation_check.rb +25/-5
            lib/rubocop/cop/lint/lambda_without_literal_block.rb +1/-1
            lib/rubocop/cop/lint/literal_as_condition.rb +5/-1
            lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11/-1
            lib/rubocop/cop/lint/literal_in_interpolation.rb +9/-12
            lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19/-10
            lib/rubocop/cop/lint/multiple_comparison.rb +2/-2
            lib/rubocop/cop/lint/next_without_accumulator.rb +2/-0
            lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20/-0
            lib/rubocop/cop/lint/non_deterministic_require_order.rb +4/-2
            lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1/-1
            lib/rubocop/cop/lint/number_conversion.rb +19/-10
            lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1/-1
            lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3/-0
            lib/rubocop/cop/lint/ordered_magic_comments.rb +7/-7
            lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2/-12
            lib/rubocop/cop/lint/raise_exception.rb +1/-1
            lib/rubocop/cop/lint/rand_one.rb +1/-1
            lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27/-10
            lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6/-12
            lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15/-4
            lib/rubocop/cop/lint/redundant_require_statement.rb +4/-2
            lib/rubocop/cop/lint/redundant_safe_navigation.rb +36/-12
            lib/rubocop/cop/lint/redundant_splat_expansion.rb +12/-2
            lib/rubocop/cop/lint/redundant_type_conversion.rb +10/-3
            lib/rubocop/cop/lint/redundant_with_index.rb +1/-1
            lib/rubocop/cop/lint/redundant_with_object.rb +5/-0
            lib/rubocop/cop/lint/refinement_import_methods.rb +8/-1
            lib/rubocop/cop/lint/regexp_as_condition.rb +9/-1
            lib/rubocop/cop/lint/require_parentheses.rb +13/-4
            lib/rubocop/cop/lint/require_range_parentheses.rb +2/-1
            lib/rubocop/cop/lint/require_relative_self_path.rb +7/-5
            lib/rubocop/cop/lint/rescue_exception.rb +1/-4
            lib/rubocop/cop/lint/rescue_type.rb +1/-1
            lib/rubocop/cop/lint/safe_navigation_chain.rb +18/-0
            lib/rubocop/cop/lint/safe_navigation_consistency.rb +7/-1
            lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1/-1
            lib/rubocop/cop/lint/script_permission.rb +5/-1
            lib/rubocop/cop/lint/self_assignment.rb +39/-7
            lib/rubocop/cop/lint/send_with_mixin_argument.rb +1/-1
            lib/rubocop/cop/lint/shadowed_argument.rb +7/-7
            lib/rubocop/cop/lint/shadowed_exception.rb +1/-1
            lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14/-0
            lib/rubocop/cop/lint/shared_mutable_default.rb +3/-1
            lib/rubocop/cop/lint/struct_new_override.rb +17/-1
            lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12/-0
            lib/rubocop/cop/lint/symbol_conversion.rb +21/-4
            lib/rubocop/cop/lint/syntax.rb +25/-1
            lib/rubocop/cop/lint/to_enum_arguments.rb +28/-1
            lib/rubocop/cop/lint/to_json.rb +12/-16
            lib/rubocop/cop/lint/top_level_return_with_argument.rb +1/-1
            lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5/-1
            lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +4/-2
            lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1/-0
            lib/rubocop/cop/lint/unreachable_code.rb +7/-5
            lib/rubocop/cop/lint/unused_method_argument.rb +10/-0
            lib/rubocop/cop/lint/uri_escape_unescape.rb +2/-0
            lib/rubocop/cop/lint/useless_assignment.rb +53/-25
            lib/rubocop/cop/lint/useless_constant_scoping.rb +4/-4
            lib/rubocop/cop/lint/useless_default_value_argument.rb +2/-0
            lib/rubocop/cop/lint/useless_or.rb +15/-2
            lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8/-4
            lib/rubocop/cop/lint/useless_setter_call.rb +4/-1
            lib/rubocop/cop/lint/useless_times.rb +22/-1
            lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37/-11
            lib/rubocop/cop/lint/void.rb +39/-12
            lib/rubocop/cop/message_annotator.rb +1/-1
            lib/rubocop/cop/metrics/block_length.rb +1/-1
            lib/rubocop/cop/metrics/block_nesting.rb +23/-0
            lib/rubocop/cop/metrics/collection_literal_length.rb +1/-1
            lib/rubocop/cop/metrics/method_length.rb +1/-1
            lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4/-3
            lib/rubocop/cop/metrics/utils/iterating_block.rb +1/-1
            lib/rubocop/cop/migration/department_name.rb +12/-1
            lib/rubocop/cop/mixin/check_line_breakable.rb +2/-2
            lib/rubocop/cop/mixin/check_single_line_suitability.rb +4/-6
            lib/rubocop/cop/mixin/code_length.rb +1/-1
            lib/rubocop/cop/mixin/configurable_max.rb +6/-5
            lib/rubocop/cop/mixin/end_keyword_alignment.rb +1/-7
            lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5/-5
            lib/rubocop/cop/mixin/hash_transform_method.rb +10/-60
            lib/rubocop/cop/mixin/line_length_help.rb +21/-2
            lib/rubocop/cop/mixin/method_complexity.rb +1/-1
            lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1/-1
            lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1/-1
            lib/rubocop/cop/mixin/space_after_punctuation.rb +5/-4
            lib/rubocop/cop/mixin/statement_modifier.rb +0/-6
            lib/rubocop/cop/mixin/trailing_comma.rb +8/-5
            lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/block_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1/-1
            lib/rubocop/cop/naming/method_name.rb +5/-3
            lib/rubocop/cop/naming/predicate_method.rb +32/-8
            lib/rubocop/cop/naming/predicate_prefix.rb +12/-12
            lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1/-1
            lib/rubocop/cop/offense.rb +17/-1
            lib/rubocop/cop/registry.rb +62/-38
            lib/rubocop/cop/security/eval.rb +15/-2
            lib/rubocop/cop/security/io_methods.rb +1/-1
            lib/rubocop/cop/security/json_load.rb +33/-11
            lib/rubocop/cop/style/access_modifier_declarations.rb +15/-4
            lib/rubocop/cop/style/accessor_grouping.rb +4/-2
            lib/rubocop/cop/style/alias.rb +15/-3
            lib/rubocop/cop/style/and_or.rb +2/-1
            lib/rubocop/cop/style/arguments_forwarding.rb +24/-6
            lib/rubocop/cop/style/array_first_last.rb +12/-1
            lib/rubocop/cop/style/array_intersect.rb +50/-12
            lib/rubocop/cop/style/array_join.rb +4/-2
            lib/rubocop/cop/style/ascii_comments.rb +6/-3
            lib/rubocop/cop/style/attr.rb +5/-2
            lib/rubocop/cop/style/bare_percent_literals.rb +4/-3
            lib/rubocop/cop/style/begin_block.rb +3/-1
            lib/rubocop/cop/style/bitwise_predicate.rb +8/-1
            lib/rubocop/cop/style/block_delimiters.rb +42/-35
            lib/rubocop/cop/style/case_equality.rb +29/-15
            lib/rubocop/cop/style/character_literal.rb +2/-2
            lib/rubocop/cop/style/class_and_module_children.rb +19/-2
            lib/rubocop/cop/style/class_equality_comparison.rb +21/-13
            lib/rubocop/cop/style/class_methods_definitions.rb +11/-5
            lib/rubocop/cop/style/collection_compact.rb +36/-16
            lib/rubocop/cop/style/colon_method_call.rb +16/-7
            lib/rubocop/cop/style/combinable_loops.rb +5/-0
            lib/rubocop/cop/style/comparable_clamp.rb +12/-1
            lib/rubocop/cop/style/concat_array_literals.rb +7/-1
            lib/rubocop/cop/style/conditional_assignment.rb +14/-19
            lib/rubocop/cop/style/constant_visibility.rb +20/-12
            lib/rubocop/cop/style/copyright.rb +22/-11
            lib/rubocop/cop/style/date_time.rb +4/-4
            lib/rubocop/cop/style/dig_chain.rb +5/-0
            lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1/-1
            lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6/-1
            lib/rubocop/cop/style/documentation.rb +6/-6
            lib/rubocop/cop/style/documentation_method.rb +7/-7
            lib/rubocop/cop/style/double_negation.rb +1/-1
            lib/rubocop/cop/style/each_for_simple_loop.rb +1/-1
            lib/rubocop/cop/style/each_with_object.rb +2/-0
            lib/rubocop/cop/style/empty_block_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_lambda_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_method.rb +0/-6
            lib/rubocop/cop/style/encoding.rb +7/-1
            lib/rubocop/cop/style/end_block.rb +3/-1
            lib/rubocop/cop/style/endless_method.rb +23/-5
            lib/rubocop/cop/style/explicit_block_argument.rb +1/-1
            lib/rubocop/cop/style/fetch_env_var.rb +1/-1
            lib/rubocop/cop/style/file_write.rb +21/-16
            lib/rubocop/cop/style/float_division.rb +15/-1
            lib/rubocop/cop/style/for.rb +3/-0
            lib/rubocop/cop/style/format_string.rb +4/-3
            lib/rubocop/cop/style/format_string_token.rb +49/-5
            lib/rubocop/cop/style/global_vars.rb +5/-2
            lib/rubocop/cop/style/guard_clause.rb +27/-22
            lib/rubocop/cop/style/hash_as_last_array_item.rb +27/-9
            lib/rubocop/cop/style/hash_conversion.rb +1/-1
            lib/rubocop/cop/style/hash_slice.rb +16/-0
            lib/rubocop/cop/style/hash_syntax.rb +1/-1
            lib/rubocop/cop/style/hash_transform_keys.rb +17/-7
            lib/rubocop/cop/style/hash_transform_values.rb +17/-7
            lib/rubocop/cop/style/if_inside_else.rb +16/-7
            lib/rubocop/cop/style/if_unless_modifier.rb +58/-18
            lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12/-12
            lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4/-1
            lib/rubocop/cop/style/if_with_semicolon.rb +7/-5
            lib/rubocop/cop/style/infinite_loop.rb +1/-1
            lib/rubocop/cop/style/inline_comment.rb +4/-1
            lib/rubocop/cop/style/ip_addresses.rb +1/-2
            lib/rubocop/cop/style/lambda_call.rb +8/-8
            lib/rubocop/cop/style/magic_comment_format.rb +3/-3
            lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17/-4
            lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15/-2
            lib/rubocop/cop/style/method_def_parentheses.rb +2/-4
            lib/rubocop/cop/style/min_max_comparison.rb +1/-1
            lib/rubocop/cop/style/multiline_if_then.rb +4/-4
            lib/rubocop/cop/style/multiline_method_signature.rb +2/-4
            lib/rubocop/cop/style/mutable_constant.rb +106/-12
            lib/rubocop/cop/style/nil_comparison.rb +11/-10
            lib/rubocop/cop/style/nil_lambda.rb +1/-1
            lib/rubocop/cop/style/non_nil_check.rb +5/-11
            lib/rubocop/cop/style/not.rb +2/-0
            lib/rubocop/cop/style/numeric_literals.rb +3/-2
            lib/rubocop/cop/style/one_line_conditional.rb +21/-12
            lib/rubocop/cop/style/operator_method_call.rb +11/-2
            lib/rubocop/cop/style/parallel_assignment.rb +14/-3
            lib/rubocop/cop/style/percent_literal_delimiters.rb +2/-0
            lib/rubocop/cop/style/preferred_hash_methods.rb +12/-12
            lib/rubocop/cop/style/proc.rb +3/-2
            lib/rubocop/cop/style/raise_args.rb +1/-1
            lib/rubocop/cop/style/redundant_argument.rb +2/-0
            lib/rubocop/cop/style/redundant_array_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_begin.rb +37/-3
            lib/rubocop/cop/style/redundant_condition.rb +6/-3
            lib/rubocop/cop/style/redundant_constant_base.rb +5/-5
            lib/rubocop/cop/style/redundant_each.rb +3/-3
            lib/rubocop/cop/style/redundant_exception.rb +1/-1
            lib/rubocop/cop/style/redundant_fetch_block.rb +1/-1
            lib/rubocop/cop/style/redundant_format.rb +27/-5
            lib/rubocop/cop/style/redundant_interpolation.rb +11/-2
            lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +27/-11
            lib/rubocop/cop/style/redundant_line_continuation.rb +16/-0
            lib/rubocop/cop/style/redundant_parentheses.rb +36/-30
            lib/rubocop/cop/style/redundant_percent_q.rb +5/-3
            lib/rubocop/cop/style/redundant_regexp_argument.rb +9/-0
            lib/rubocop/cop/style/redundant_regexp_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_regexp_escape.rb +8/-0
            lib/rubocop/cop/style/redundant_return.rb +3/-1
            lib/rubocop/cop/style/redundant_self.rb +2/-2
            lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0/-5
            lib/rubocop/cop/style/redundant_sort.rb +7/-7
            lib/rubocop/cop/style/regexp_literal.rb +31/-2
            lib/rubocop/cop/style/rescue_modifier.rb +3/-3
            lib/rubocop/cop/style/safe_navigation.rb +25/-8
            lib/rubocop/cop/style/select_by_regexp.rb +51/-21
            lib/rubocop/cop/style/self_assignment.rb +1/-1
            lib/rubocop/cop/style/semicolon.rb +41/-8
            lib/rubocop/cop/style/single_line_block_params.rb +2/-2
            lib/rubocop/cop/style/single_line_do_end_block.rb +1/-1
            lib/rubocop/cop/style/single_line_methods.rb +3/-1
            lib/rubocop/cop/style/sole_nested_conditional.rb +12/-3
            lib/rubocop/cop/style/special_global_vars.rb +6/-1
            lib/rubocop/cop/style/string_concatenation.rb +17/-13
            lib/rubocop/cop/style/struct_inheritance.rb +13/-0
            lib/rubocop/cop/style/super_arguments.rb +2/-2
            lib/rubocop/cop/style/symbol_array.rb +1/-1
            lib/rubocop/cop/style/symbol_proc.rb +7/-6
            lib/rubocop/cop/style/top_level_method_definition.rb +2/-2
            lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45/-0
            lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1/-1
            lib/rubocop/cop/style/trailing_method_end_statement.rb +1/-0
            lib/rubocop/cop/style/trailing_underscore_variable.rb +11/-11
            lib/rubocop/cop/style/unless_else.rb +10/-9
            lib/rubocop/cop/style/unless_logical_operators.rb +3/-3
            lib/rubocop/cop/style/while_until_do.rb +7/-0
            lib/rubocop/cop/style/while_until_modifier.rb +16/-0
            lib/rubocop/cop/style/word_array.rb +1/-0
            lib/rubocop/cop/style/yoda_condition.rb +1/-1
            lib/rubocop/cop/style/yoda_expression.rb +1/-1
            lib/rubocop/cop/style/zero_length_predicate.rb +6/-3
            lib/rubocop/cop/team.rb +87/-36
            lib/rubocop/cop/util.rb +2/-3
            lib/rubocop/cop/utils/format_string.rb +10/-0
            lib/rubocop/cop/variable_force.rb +9/-7
            lib/rubocop/cop/variable_force/branch.rb +30/-6
            lib/rubocop/cop/variable_force/variable.rb +1/-1
            lib/rubocop/cops_documentation_generator.rb +4/-4
            lib/rubocop/directive_comment.rb +48/-4
            lib/rubocop/file_patterns.rb +9/-1
            lib/rubocop/formatter.rb +22/-21
            lib/rubocop/formatter/clang_style_formatter.rb +5/-2
            lib/rubocop/formatter/disabled_config_formatter.rb +38/-14
            lib/rubocop/formatter/formatter_set.rb +2/-2
            lib/rubocop/formatter/junit_formatter.rb +1/-1
            lib/rubocop/formatter/simple_text_formatter.rb +0/-2
            lib/rubocop/formatter/tap_formatter.rb +5/-2
            lib/rubocop/formatter/worst_offenders_formatter.rb +1/-1
            lib/rubocop/lsp/diagnostic.rb +18/-33
            lib/rubocop/lsp/routes.rb +42/-6
            lib/rubocop/lsp/runtime.rb +13/-4
            lib/rubocop/lsp/stdin_runner.rb +8/-17
            lib/rubocop/magic_comment.rb +20/-0
            lib/rubocop/options.rb +35/-4
            lib/rubocop/path_util.rb +14/-2
            lib/rubocop/plugin/loader.rb +1/-1
            lib/rubocop/rake_task.rb +1/-1
            lib/rubocop/remote_config.rb +10/-8
            lib/rubocop/result_cache.rb +61/-38
            lib/rubocop/rspec/cop_helper.rb +8/-0
            lib/rubocop/rspec/shared_contexts.rb +39/-5
            lib/rubocop/rspec/support.rb +2/-1
            lib/rubocop/runner.rb +134/-57
            lib/rubocop/server/cache.rb +6/-29
            lib/rubocop/server/core.rb +8/-0
            lib/rubocop/target_finder.rb +17/-10
            lib/rubocop/target_ruby.rb +31/-14
            lib/rubocop/version.rb +21/-3
            lib/ruby_lsp/rubocop/addon.rb +23/-8
            lib/ruby_lsp/rubocop/runtime_adapter.rb +49/-15
  DIFFERENT extra_rdoc_files:
    1.79.2->1.88.0:
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
  DIFFERENT runtime dependencies:
    1.79.2->1.88.0:
      * Updated:
            parallel from: ["~> 1.10"] to: [">= 1.10"]
            rubocop-ast from: [">= 1.46.0", "< 2.0"] to: [">= 1.49.0", "< 2.0"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff rubocop 1.79.2 1.88.0

Diff too large (818033 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff rubocop 1.79.2 1.88.0

Diff too large (818029 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff rubocop 1.79.2 1.88.0

Diff too large (818033 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT date:
    3.1.4: 2025-01-13 00:00:00 UTC
    3.2.0: 2025-09-09 00:00:00 UTC
  DIFFERENT description:
    3.1.4: [Unicode 16.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
    3.2.0: [Unicode 17.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
  DIFFERENT version:
    3.1.4: 3.1.4
    3.2.0: 3.2.0
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
            CHANGELOG.md +8/-0
            README.md +5/-5
            lib/unicode/display_width/constants.rb +2/-2
            lib/unicode/display_width/emoji_support.rb +5/-2
  DIFFERENT extra_rdoc_files:
    3.1.4->3.2.0:
      * Changed:
            README.md +5/-5
            CHANGELOG.md +8/-0
  DIFFERENT runtime dependencies:
    3.1.4->3.2.0:
      * Updated:
            unicode-emoji from: ["~> 4.0", ">= 4.0.4"] to: ["~> 4.1"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT require_paths:
    2.19.5: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.5", "lib"]
    2.19.9: ["/opt/hostedtoolcache/Ruby/4.0.5/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.19.9", "lib"]
  DIFFERENT rubygems_version:
    2.19.5: 4.0.6
    2.19.9: 4.1.0.dev
  DIFFERENT version:
    2.19.5: 2.19.5
    2.19.9: 2.19.9
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
            CHANGES.md +22/-0
            README.md +11/-0
            ext/json/ext/fbuffer/fbuffer.h +31/-23
            ext/json/ext/generator/generator.c +16/-15
            ext/json/ext/parser/parser.c +69/-27
            lib/json/truffle_ruby/generator.rb +3/-0
            lib/json/version.rb +1/-1
  DIFFERENT extra_rdoc_files:
    2.19.5->2.19.9:
      * Changed:
            README.md +11/-0

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT date:
    3.1.4: 2025-01-13 00:00:00 UTC
    3.2.0: 2025-09-09 00:00:00 UTC
  DIFFERENT description:
    3.1.4: [Unicode 16.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
    3.2.0: [Unicode 17.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
  DIFFERENT version:
    3.1.4: 3.1.4
    3.2.0: 3.2.0
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
            CHANGELOG.md +8/-0
            README.md +5/-5
            lib/unicode/display_width/constants.rb +2/-2
            lib/unicode/display_width/emoji_support.rb +5/-2
  DIFFERENT extra_rdoc_files:
    3.1.4->3.2.0:
      * Changed:
            README.md +5/-5
            CHANGELOG.md +8/-0
  DIFFERENT runtime dependencies:
    3.1.4->3.2.0:
      * Updated:
            unicode-emoji from: ["~> 4.0", ">= 4.0.4"] to: ["~> 4.1"]

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT date:
    3.1.4: 2025-01-13 00:00:00 UTC
    3.2.0: 2025-09-09 00:00:00 UTC
  DIFFERENT description:
    3.1.4: [Unicode 16.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
    3.2.0: [Unicode 17.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
  DIFFERENT version:
    3.1.4: 3.1.4
    3.2.0: 3.2.0
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
            CHANGELOG.md +8/-0
            README.md +5/-5
            lib/unicode/display_width/constants.rb +2/-2
            lib/unicode/display_width/emoji_support.rb +5/-2
  DIFFERENT extra_rdoc_files:
    3.1.4->3.2.0:
      * Changed:
            README.md +5/-5
            CHANGELOG.md +8/-0
  DIFFERENT runtime dependencies:
    3.1.4->3.2.0:
      * Updated:
            unicode-emoji from: ["~> 4.0", ">= 4.0.4"] to: ["~> 4.1"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
        CHANGELOG.md
                --- /tmp/d20260617-8300-upn9ej/unicode-display_width-3.1.4/CHANGELOG.md	2026-06-17 02:35:14.956416305 +0000
                +++ /tmp/d20260617-8300-upn9ej/unicode-display_width-3.2.0/CHANGELOG.md	2026-06-17 02:35:14.956416305 +0000
                @@ -2,0 +3,8 @@
                +## 3.2.0
                +
                +- Unicode 17.0
                +
                +## 3.1.5
                +
                +- Cache Emoji support level for performance reasons #30, patch by @Earlopain:
                +
        README.md
                --- /tmp/d20260617-8300-upn9ej/unicode-display_width-3.1.4/README.md	2026-06-17 02:35:14.956416305 +0000
                +++ /tmp/d20260617-8300-upn9ej/unicode-display_width-3.2.0/README.md	2026-06-17 02:35:14.956416305 +0000
                @@ -3 +3 @@
                -Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth()](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                +Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                @@ -5 +5 @@
                -Unicode version: **16.0.0** (September 2024)
                +Unicode version: **17.0.0** (September 2025)
                @@ -111,2 +111,2 @@
                -Single Emoji character with Skin Tone Modifier            | 2
                -Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is configured to `:rgi` / `:rgi_at`
                +Single Emoji character with Skin Tone Modifier            | 2 unless Emoji mode is `:none` or `vs16`
                +Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is `:rgi` / `:rgi_at`
                @@ -191 +191 @@
                -- Copyright (c) 2011, 2015-2024 Jan Lelis, https://janlelis.com, released under the MIT
                +- Copyright (c) 2011, 2015-2025 Jan Lelis, https://janlelis.com, released under the MIT
        data/display_width.marshal.gz
                Binary files /tmp/d20260617-8300-upn9ej/unicode-display_width-3.1.4/data/display_width.marshal.gz and /tmp/d20260617-8300-upn9ej/unicode-display_width-3.2.0/data/display_width.marshal.gz differ
        lib/unicode/display_width/constants.rb
                --- /tmp/d20260617-8300-upn9ej/unicode-display_width-3.1.4/lib/unicode/display_width/constants.rb	2026-06-17 02:35:14.956416305 +0000
                +++ /tmp/d20260617-8300-upn9ej/unicode-display_width-3.2.0/lib/unicode/display_width/constants.rb	2026-06-17 02:35:14.957416302 +0000
                @@ -5,2 +5,2 @@
                -    VERSION = "3.1.4"
                -    UNICODE_VERSION = "16.0.0"
                +    VERSION = "3.2.0"
                +    UNICODE_VERSION = "17.0.0"
        lib/unicode/display_width/emoji_support.rb
                --- /tmp/d20260617-8300-upn9ej/unicode-display_width-3.1.4/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:35:14.956416305 +0000
                +++ /tmp/d20260617-8300-upn9ej/unicode-display_width-3.2.0/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:35:14.957416302 +0000
                @@ -1,2 +1 @@
                -# require "rbconfig"
                -# RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # windows
                +# frozen_string_literal: true
                @@ -15,0 +15,4 @@
                +        @recommended ||= _recommended
                +      end
                +
                +      def self._recommended

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
        CHANGELOG.md
                --- /tmp/d20260617-8300-2d5jld/unicode-display_width-3.1.4/CHANGELOG.md	2026-06-17 02:35:21.442324488 +0000
                +++ /tmp/d20260617-8300-2d5jld/unicode-display_width-3.2.0/CHANGELOG.md	2026-06-17 02:35:21.444324523 +0000
                @@ -2,0 +3,8 @@
                +## 3.2.0
                +
                +- Unicode 17.0
                +
                +## 3.1.5
                +
                +- Cache Emoji support level for performance reasons #30, patch by @Earlopain:
                +
        README.md
                --- /tmp/d20260617-8300-2d5jld/unicode-display_width-3.1.4/README.md	2026-06-17 02:35:21.443324505 +0000
                +++ /tmp/d20260617-8300-2d5jld/unicode-display_width-3.2.0/README.md	2026-06-17 02:35:21.444324523 +0000
                @@ -3 +3 @@
                -Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth()](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                +Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                @@ -5 +5 @@
                -Unicode version: **16.0.0** (September 2024)
                +Unicode version: **17.0.0** (September 2025)
                @@ -111,2 +111,2 @@
                -Single Emoji character with Skin Tone Modifier            | 2
                -Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is configured to `:rgi` / `:rgi_at`
                +Single Emoji character with Skin Tone Modifier            | 2 unless Emoji mode is `:none` or `vs16`
                +Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is `:rgi` / `:rgi_at`
                @@ -191 +191 @@
                -- Copyright (c) 2011, 2015-2024 Jan Lelis, https://janlelis.com, released under the MIT
                +- Copyright (c) 2011, 2015-2025 Jan Lelis, https://janlelis.com, released under the MIT
        data/display_width.marshal.gz
                Binary files /tmp/d20260617-8300-2d5jld/unicode-display_width-3.1.4/data/display_width.marshal.gz and /tmp/d20260617-8300-2d5jld/unicode-display_width-3.2.0/data/display_width.marshal.gz differ
        lib/unicode/display_width/constants.rb
                --- /tmp/d20260617-8300-2d5jld/unicode-display_width-3.1.4/lib/unicode/display_width/constants.rb	2026-06-17 02:35:21.443324505 +0000
                +++ /tmp/d20260617-8300-2d5jld/unicode-display_width-3.2.0/lib/unicode/display_width/constants.rb	2026-06-17 02:35:21.444324523 +0000
                @@ -5,2 +5,2 @@
                -    VERSION = "3.1.4"
                -    UNICODE_VERSION = "16.0.0"
                +    VERSION = "3.2.0"
                +    UNICODE_VERSION = "17.0.0"
        lib/unicode/display_width/emoji_support.rb
                --- /tmp/d20260617-8300-2d5jld/unicode-display_width-3.1.4/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:35:21.443324505 +0000
                +++ /tmp/d20260617-8300-2d5jld/unicode-display_width-3.2.0/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:35:21.444324523 +0000
                @@ -1,2 +1 @@
                -# require "rbconfig"
                -# RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # windows
                +# frozen_string_literal: true
                @@ -15,0 +15,4 @@
                +        @recommended ||= _recommended
                +      end
                +
                +      def self._recommended

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-emoji 4.0.4 4.2.0

Compared versions: ["4.0.4", "4.2.0"]
  DIFFERENT date:
    4.0.4: 2024-11-19 00:00:00 UTC
    4.2.0: 2025-12-17 00:00:00 UTC
  DIFFERENT description:
    4.0.4: [Emoji 16.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
    4.2.0: [Emoji 17.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
  DIFFERENT required_ruby_version:
    4.0.4: >= 2.5, < 4.0
    4.2.0: >= 2.5
  DIFFERENT version:
    4.0.4: 4.0.4
    4.2.0: 4.2.0
  DIFFERENT files:
    4.0.4->4.2.0:
      * Changed:
            CHANGELOG.md +11/-0
            Gemfile +2/-0
            Gemfile.lock +5/-1
            README.md +4/-4
            Rakefile +1/-1
            lib/unicode/emoji/constants.rb +4/-3
            lib/unicode/emoji/generated/regex.rb +1/-1
            lib/unicode/emoji/generated/regex_basic.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_picto.rb +1/-1
            lib/unicode/emoji/generated/regex_picto_no_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_possible.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_presentation.rb +1/-1
            lib/unicode/emoji/generated/regex_text.rb +1/-1
            lib/unicode/emoji/generated/regex_valid.rb +1/-1
            lib/unicode/emoji/generated/regex_valid_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed_include_text.rb +1/-1
            lib/unicode/emoji/generated_native/regex.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_text.rb +1/-1
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
            unicode-emoji.gemspec +1/-1
  DIFFERENT test_files:
    4.0.4->4.2.0:
      * Changed:
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
  DIFFERENT Gemfile dependencies
    4.0.4->4.2.0:
      * Added:
            mutex_m [">= 0"] (runtime)
            ostruct [">= 0"] (runtime)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
        CHANGELOG.md
                --- /tmp/d20260617-8330-ng488h/unicode-display_width-3.1.4/CHANGELOG.md	2026-06-17 02:35:30.816026766 +0000
                +++ /tmp/d20260617-8330-ng488h/unicode-display_width-3.2.0/CHANGELOG.md	2026-06-17 02:35:30.819026798 +0000
                @@ -2,0 +3,8 @@
                +## 3.2.0
                +
                +- Unicode 17.0
                +
                +## 3.1.5
                +
                +- Cache Emoji support level for performance reasons #30, patch by @Earlopain:
                +
        README.md
                --- /tmp/d20260617-8330-ng488h/unicode-display_width-3.1.4/README.md	2026-06-17 02:35:30.817026777 +0000
                +++ /tmp/d20260617-8330-ng488h/unicode-display_width-3.2.0/README.md	2026-06-17 02:35:30.819026798 +0000
                @@ -3 +3 @@
                -Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth()](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                +Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                @@ -5 +5 @@
                -Unicode version: **16.0.0** (September 2024)
                +Unicode version: **17.0.0** (September 2025)
                @@ -111,2 +111,2 @@
                -Single Emoji character with Skin Tone Modifier            | 2
                -Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is configured to `:rgi` / `:rgi_at`
                +Single Emoji character with Skin Tone Modifier            | 2 unless Emoji mode is `:none` or `vs16`
                +Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is `:rgi` / `:rgi_at`
                @@ -191 +191 @@
                -- Copyright (c) 2011, 2015-2024 Jan Lelis, https://janlelis.com, released under the MIT
                +- Copyright (c) 2011, 2015-2025 Jan Lelis, https://janlelis.com, released under the MIT
        data/display_width.marshal.gz
                Binary files /tmp/d20260617-8330-ng488h/unicode-display_width-3.1.4/data/display_width.marshal.gz and /tmp/d20260617-8330-ng488h/unicode-display_width-3.2.0/data/display_width.marshal.gz differ
        lib/unicode/display_width/constants.rb
                --- /tmp/d20260617-8330-ng488h/unicode-display_width-3.1.4/lib/unicode/display_width/constants.rb	2026-06-17 02:35:30.817026777 +0000
                +++ /tmp/d20260617-8330-ng488h/unicode-display_width-3.2.0/lib/unicode/display_width/constants.rb	2026-06-17 02:35:30.821026819 +0000
                @@ -5,2 +5,2 @@
                -    VERSION = "3.1.4"
                -    UNICODE_VERSION = "16.0.0"
                +    VERSION = "3.2.0"
                +    UNICODE_VERSION = "17.0.0"
        lib/unicode/display_width/emoji_support.rb
                --- /tmp/d20260617-8330-ng488h/unicode-display_width-3.1.4/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:35:30.817026777 +0000
                +++ /tmp/d20260617-8330-ng488h/unicode-display_width-3.2.0/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:35:30.821026819 +0000
                @@ -1,2 +1 @@
                -# require "rbconfig"
                -# RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # windows
                +# frozen_string_literal: true
                @@ -15,0 +15,4 @@
                +        @recommended ||= _recommended
                +      end
                +
                +      def self._recommended

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-emoji 4.0.4 4.2.0

Compared versions: ["4.0.4", "4.2.0"]
  DIFFERENT date:
    4.0.4: 2024-11-19 00:00:00 UTC
    4.2.0: 2025-12-17 00:00:00 UTC
  DIFFERENT description:
    4.0.4: [Emoji 16.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
    4.2.0: [Emoji 17.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
  DIFFERENT required_ruby_version:
    4.0.4: >= 2.5, < 4.0
    4.2.0: >= 2.5
  DIFFERENT version:
    4.0.4: 4.0.4
    4.2.0: 4.2.0
  DIFFERENT files:
    4.0.4->4.2.0:
      * Changed:
            CHANGELOG.md +11/-0
            Gemfile +2/-0
            Gemfile.lock +5/-1
            README.md +4/-4
            Rakefile +1/-1
            lib/unicode/emoji/constants.rb +4/-3
            lib/unicode/emoji/generated/regex.rb +1/-1
            lib/unicode/emoji/generated/regex_basic.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_picto.rb +1/-1
            lib/unicode/emoji/generated/regex_picto_no_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_possible.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_presentation.rb +1/-1
            lib/unicode/emoji/generated/regex_text.rb +1/-1
            lib/unicode/emoji/generated/regex_valid.rb +1/-1
            lib/unicode/emoji/generated/regex_valid_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed_include_text.rb +1/-1
            lib/unicode/emoji/generated_native/regex.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_text.rb +1/-1
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
            unicode-emoji.gemspec +1/-1
  DIFFERENT test_files:
    4.0.4->4.2.0:
      * Changed:
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
  DIFFERENT Gemfile dependencies
    4.0.4->4.2.0:
      * Added:
            mutex_m [">= 0"] (runtime)
            ostruct [">= 0"] (runtime)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff rubocop 1.79.2 1.88.0

Diff too large (818032 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff json 2.19.5 2.19.9

Compared versions: ["2.19.5", "2.19.9"]
  DIFFERENT files:
    2.19.5->2.19.9:
      * Changed:
        CHANGES.md
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/CHANGES.md	2026-06-17 02:35:39.585331874 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/CHANGES.md	2026-06-17 02:35:39.591331978 +0000
                @@ -4,0 +5,22 @@
                +### 2026-06-11 (2.19.9)
                +
                +* Fix buffer overflow that could lead to a crash when writing JSON directly into an IO
                +  with `JSON.generate(object, io)`. [CVE-PENDING].
                +
                +### 2026-06-03 (2.19.8)
                +
                +* Fix 1-byte buffer overread on EOS errors.
                +* Handle invalid types passed as `max_nesting` option.
                +
                +### 2026-05-28 (2.19.7)
                +
                +* Fix some more edge cases with out of range floats.
                +* Ensure the string provided to `JSON.parse` can't be mutated during parsing.
                +* Add missing write barriers in `State#dup`.
                +* Further validate generator `depth` config.
                +
                +### 2026-05-28 (2.19.6)
                +
                +* Cleanly handle overly large `depth` generator argument.
                +* Add missing write barrier in `ParserConfig`.
                +
        README.md
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/README.md	2026-06-17 02:35:39.585331874 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/README.md	2026-06-17 02:35:39.591331978 +0000
                @@ -251,0 +252,11 @@
                +## Security
                +
                +When parsing or serializing untrusted input, parser and generator options should never be user controlled.
                +
                +```ruby
                +# Dangerous, DO NOT DO THIS.
                +JSON.generate(params[:data], params[:options])
                +```
                +
                +Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes.
                +
        ext/json/ext/fbuffer/fbuffer.h
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:35:39.585331874 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/ext/json/ext/fbuffer/fbuffer.h	2026-06-17 02:35:39.591331978 +0000
                @@ -40 +40 @@
                -static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
                +static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
                @@ -42,2 +42,5 @@
                -    fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                -    if (stack_buffer) {
                +    if (RTEST(io)) {
                +        JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
                +        fb->io = io;
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
                +    } else {
                @@ -46,0 +50 @@
                +        fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
                @@ -82 +86 @@
                -static void fbuffer_realloc(FBuffer *fb, size_t required)
                +static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
                @@ -84 +88 @@
                -    if (required > fb->capa) {
                +    if (new_capa > fb->capa) {
                @@ -87 +91 @@
                -            fb->ptr = ALLOC_N(char, required);
                +            fb->ptr = ALLOC_N(char, new_capa);
                @@ -91 +95 @@
                -            REALLOC_N(fb->ptr, char, required);
                +            REALLOC_N(fb->ptr, char, new_capa);
                @@ -93 +97 @@
                -        fb->capa = required;
                +        fb->capa = new_capa;
                @@ -100,3 +104 @@
                -        if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
                -            fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
                -        } else {
                +        if (fb->capa != 0) {
                @@ -104,4 +106,3 @@
                -        }
                -
                -        if (RB_LIKELY(requested < fb->capa)) {
                -            return;
                +            if (RB_LIKELY(requested < fb->capa)) {
                +                return;
                +            }
                @@ -111 +112,2 @@
                -    size_t required;
                +    size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
                +    size_t needed_capa = requested + fb->len;
                @@ -113,3 +115,2 @@
                -    if (RB_UNLIKELY(!fb->ptr)) {
                -        fb->ptr = ALLOC_N(char, fb->initial_length);
                -        fb->capa = fb->initial_length;
                +    while (new_capa < needed_capa) {
                +        new_capa *= 2;
                @@ -118,3 +119 @@
                -    for (required = fb->capa; requested > required - fb->len; required <<= 1);
                -
                -    fbuffer_realloc(fb, required);
                +    fbuffer_realloc(fb, new_capa);
                @@ -133,0 +133,9 @@
                +static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
                +{
                +    size_t result = a * b;
                +    if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
                +        rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
                +    }
                +    return result;
                +}
                +
                @@ -178 +186 @@
                -    fbuffer_inc_capa(fb, repeat * len);
                +    fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
        ext/json/ext/generator/generator.c
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/ext/json/ext/generator/generator.c	2026-06-17 02:35:39.586331891 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/ext/json/ext/generator/generator.c	2026-06-17 02:35:39.592331995 +0000
                @@ -1307,4 +1307,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
                @@ -1370,6 +1368,8 @@
                -    objState->indent = origState->indent;
                -    objState->space = origState->space;
                -    objState->space_before = origState->space_before;
                -    objState->object_nl = origState->object_nl;
                -    objState->array_nl = origState->array_nl;
                -    objState->as_json = origState->as_json;
                +
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->indent);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->space_before);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl);
                +    RB_OBJ_WRITTEN(obj, Qundef, objState->as_json);
                +
                @@ -1582 +1582 @@
                -    return RTEST(num) ? FIX2LONG(num) : 0;
                +    return RTEST(num) ? NUM2LONG(num) : 0;
                @@ -1592,0 +1593,3 @@
                +    if (RB_UNLIKELY(d > INT_MAX)) {
                +        rb_raise(rb_eArgError, "depth is too large (got %ld)", d);
                +    }
                @@ -1864,4 +1867,2 @@
                -    FBuffer buffer = {
                -        .io = RTEST(io) ? io : Qfalse,
                -    };
                -    fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
                +    FBuffer buffer = { 0 };
                +    fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
        ext/json/ext/parser/parser.c
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/ext/json/ext/parser/parser.c	2026-06-17 02:35:39.586331891 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/ext/json/ext/parser/parser.c	2026-06-17 02:35:39.592331995 +0000
                @@ -387,0 +388,7 @@
                +    JSON_ASSERT(state->cursor <= state->end);
                +
                +    // Redundant but helpful for hardening
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1024,0 +1032,7 @@
                +
                +    // If the string ended with an unterminated escape sequence, we might
                +    // have gone past the end.
                +    if (RB_UNLIKELY(state->cursor > state->end)) {
                +        state->cursor = state->end;
                +    }
                +
                @@ -1205 +1219,5 @@
                -        exponent = negative_exponent ? -abs_exponent : abs_exponent;
                +        if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) {
                +            exponent = negative_exponent ? INT64_MIN : INT64_MAX;
                +        } else {
                +            exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent;
                +        }
                @@ -1460 +1478,11 @@
                -  int encindex = RB_ENCODING_GET(source);
                +    StringValue(source);
                +    int encindex = RB_ENCODING_GET(source);
                +
                +    if (RB_LIKELY(encindex == utf8_encindex)) {
                +        return source;
                +    }
                +
                +    if (encindex == binary_encindex) {
                +        // For historical reason, we silently reinterpret binary strings as UTF-8
                +        return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                +    }
                @@ -1462 +1490,2 @@
                -  if (RB_LIKELY(encindex == utf8_encindex)) {
                +    source = rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +    StringValue(source);
                @@ -1464 +1493 @@
                -  }
                +}
                @@ -1466,4 +1495,4 @@
                - if (encindex == binary_encindex) {
                -    // For historical reason, we silently reinterpret binary strings as UTF-8
                -    return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
                -  }
                +struct parser_config_init_args {
                +    JSON_ParserConfig *config;
                +    VALUE self;
                +};
                @@ -1471 +1500,4 @@
                -  return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
                +static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
                +{
                +    *dest = val;
                +    if (self) RB_OBJ_WRITTEN(self, Qundef, val);
                @@ -1476 +1508,3 @@
                -    JSON_ParserConfig *config = (JSON_ParserConfig *)data;
                +    struct parser_config_init_args *args = (struct parser_config_init_args *)data;
                +    JSON_ParserConfig *config = args->config;
                +    VALUE self = args->self;
                @@ -1485 +1519 @@
                -    else if (key == sym_on_load)                    { config->on_load_proc = RTEST(val) ? val : Qfalse; }
                +    else if (key == sym_on_load)                    { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
                @@ -1490 +1524 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1493 +1527 @@
                -                config->decimal_class = val;
                +                parser_config_wb_write(self, &config->decimal_class, val);
                @@ -1502 +1536 @@
                -                    config->decimal_class = rb_path_to_class(mod_path);
                +                    parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
                @@ -1510 +1544 @@
                -                    config->decimal_class = rb_mKernel;
                +                    parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
                @@ -1520 +1554 @@
                -static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
                +static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
                @@ -1523,0 +1558,5 @@
                +    struct parser_config_init_args args = {
                +        .config = config,
                +        .self = self,
                +    };
                +
                @@ -1529 +1568 @@
                -            rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
                +            rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
                @@ -1563,3 +1602 @@
                -    parser_config_init(config, opts);
                -
                -    RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
                +    parser_config_init(config, opts, self);
                @@ -1570 +1607 @@
                -static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
                +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src)
                @@ -1572,2 +1609,8 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                +    VALUE Vsource = convert_encoding(src);
                +
                +    // Ensure the string isn't mutated under us.
                +    // The classic API to use is `rb_str_locktmp`, but then we'd
                +    // need to use `rb_protect` to make sure we always unlock.
                +    if (Vsource == src) {
                +        Vsource = rb_str_new_frozen(Vsource);
                +    }
                @@ -1583,0 +1627 @@
                +
                @@ -1601,0 +1646 @@
                +    RB_GC_GUARD(Vsource);
                @@ -1622,3 +1666,0 @@
                -    Vsource = convert_encoding(StringValue(Vsource));
                -    StringValue(Vsource);
                -
                @@ -1627 +1669 @@
                -    parser_config_init(config, opts);
                +    parser_config_init(config, opts, false);
        lib/json/truffle_ruby/generator.rb
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/lib/json/truffle_ruby/generator.rb	2026-06-17 02:35:39.590331960 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/lib/json/truffle_ruby/generator.rb	2026-06-17 02:35:39.596332064 +0000
                @@ -309,0 +310,3 @@
                +            unless opts[:max_nesting].is_a?(Integer)
                +              raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
                +            end
        lib/json/version.rb
                --- /tmp/d20260617-594-jfaj2i/json-2.19.5/lib/json/version.rb	2026-06-17 02:35:39.590331960 +0000
                +++ /tmp/d20260617-594-jfaj2i/json-2.19.9/lib/json/version.rb	2026-06-17 02:35:39.596332064 +0000
                @@ -4 +4 @@
                -  VERSION = '2.19.5'
                +  VERSION = '2.19.9'

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-emoji 4.0.4 4.2.0

Compared versions: ["4.0.4", "4.2.0"]
  DIFFERENT date:
    4.0.4: 2024-11-19 00:00:00 UTC
    4.2.0: 2025-12-17 00:00:00 UTC
  DIFFERENT description:
    4.0.4: [Emoji 16.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
    4.2.0: [Emoji 17.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
  DIFFERENT required_ruby_version:
    4.0.4: >= 2.5, < 4.0
    4.2.0: >= 2.5
  DIFFERENT version:
    4.0.4: 4.0.4
    4.2.0: 4.2.0
  DIFFERENT files:
    4.0.4->4.2.0:
      * Changed:
            CHANGELOG.md +11/-0
            Gemfile +2/-0
            Gemfile.lock +5/-1
            README.md +4/-4
            Rakefile +1/-1
            lib/unicode/emoji/constants.rb +4/-3
            lib/unicode/emoji/generated/regex.rb +1/-1
            lib/unicode/emoji/generated/regex_basic.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_picto.rb +1/-1
            lib/unicode/emoji/generated/regex_picto_no_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_possible.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_presentation.rb +1/-1
            lib/unicode/emoji/generated/regex_text.rb +1/-1
            lib/unicode/emoji/generated/regex_valid.rb +1/-1
            lib/unicode/emoji/generated/regex_valid_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed_include_text.rb +1/-1
            lib/unicode/emoji/generated_native/regex.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_text.rb +1/-1
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
            unicode-emoji.gemspec +1/-1
  DIFFERENT test_files:
    4.0.4->4.2.0:
      * Changed:
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
  DIFFERENT Gemfile dependencies
    4.0.4->4.2.0:
      * Added:
            mutex_m [">= 0"] (runtime)
            ostruct [">= 0"] (runtime)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-emoji 4.0.4 4.2.0

Diff too large (918698 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT date:
    3.1.4: 2025-01-13 00:00:00 UTC
    3.2.0: 2025-09-09 00:00:00 UTC
  DIFFERENT description:
    3.1.4: [Unicode 16.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
    3.2.0: [Unicode 17.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
  DIFFERENT version:
    3.1.4: 3.1.4
    3.2.0: 3.2.0
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
            CHANGELOG.md +8/-0
            README.md +5/-5
            lib/unicode/display_width/constants.rb +2/-2
            lib/unicode/display_width/emoji_support.rb +5/-2
  DIFFERENT extra_rdoc_files:
    3.1.4->3.2.0:
      * Changed:
            README.md +5/-5
            CHANGELOG.md +8/-0
  DIFFERENT runtime dependencies:
    3.1.4->3.2.0:
      * Updated:
            unicode-emoji from: ["~> 4.0", ">= 4.0.4"] to: ["~> 4.1"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT date:
    1.28.0: 2026-04-02 00:00:00 UTC
    2.1.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.28.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v1.28.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v1.28.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki"}
    2.1.0: {"bug_tracker_uri" => "https://github.com/grosser/parallel/issues", "documentation_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/Readme.md", "source_code_uri" => "https://github.com/grosser/parallel/tree/v2.1.0", "wiki_uri" => "https://github.com/grosser/parallel/wiki", "changelog_uri" => "https://github.com/grosser/parallel/blob/v2.1.0/CHANGELOG.md", "rubygems_mfa_required" => "true"}
  DIFFERENT required_ruby_version:
    1.28.0: >= 2.7
    2.1.0: >= 3.3
  DIFFERENT rubygems_version:
    1.28.0: 3.4.10
    2.1.0: 4.0.3
  DIFFERENT version:
    1.28.0: 1.28.0
    2.1.0: 2.1.0
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
            lib/parallel/serializer.rb +52/-0
      * Changed:
            lib/parallel.rb +68/-40
            lib/parallel/version.rb +1/-1

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-emoji 4.0.4 4.2.0

Diff too large (918698 chars)

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-emoji 4.0.4 4.2.0

Diff too large (918698 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff parallel 1.28.0 2.1.0

Compared versions: ["1.28.0", "2.1.0"]
  DIFFERENT files:
    1.28.0->2.1.0:
      * Added:
        lib/parallel/serializer.rb
                --- /tmp/20260617-815-mb1dbe	2026-06-17 02:36:05.370677327 +0000
                +++ /tmp/d20260617-815-4bq9qe/parallel-2.1.0/lib/parallel/serializer.rb	2026-06-17 02:36:05.369677316 +0000
                @@ -0,0 +1,52 @@
                +# frozen_string_literal: true
                +require 'openssl'
                +require 'securerandom'
                +
                +module Parallel
                +  # Pluggable wire serializers. Each must respond to `dump(data, io)` /
                +  # `load(io)` (used directly by Worker) and `dump(data)` / `load(string)`
                +  # (used by wrappers like Hmac).
                +  module Serializer
                +    # Raw Marshal. Fast but trusts anything written to the pipe — a same-UID
                +    # attacker that reopens /proc/<pid>/fd/<n> can inject Marshal gadgets (RCE).
                +    Marshal = ::Marshal
                +
                +    # Wraps any inner serializer with a length-prefixed HMAC-SHA256 frame keyed
                +    # on a per-worker secret generated before fork. Forged frames from a
                +    # pipe-injector fail verification.
                +    class Hmac
                +      LENGTH_FORMAT = 'N' # 32-bit big-endian unsigned int
                +      LENGTH_BYTES = 4
                +      MAC_BYTES = 32 # SHA256
                +
                +      def initialize(inner: Marshal, secret: SecureRandom.bytes(32))
                +        @inner = inner
                +        @secret = secret
                +      end
                +
                +      def dump(data, io)
                +        payload = @inner.dump(data)
                +        mac = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        io.write([payload.bytesize].pack(LENGTH_FORMAT), mac, payload)
                +      end
                +
                +      def load(io)
                +        # nil at frame boundary = clean EOF (worker died / pipe closed between messages)
                +        header = io.read(LENGTH_BYTES) || raise(EOFError) # eof stops worker
                +        raise SecurityError, "truncated frame header" if header.bytesize != LENGTH_BYTES
                +
                +        length = header.unpack1(LENGTH_FORMAT)
                +        mac = io.read(MAC_BYTES)
                +        raise SecurityError, "truncated frame mac" if mac.nil? || mac.bytesize != MAC_BYTES
                +
                +        payload = io.read(length)
                +        raise SecurityError, "truncated frame payload" if payload.nil? || payload.bytesize != length
                +
                +        expected = OpenSSL::HMAC.digest('SHA256', @secret, payload)
                +        raise SecurityError, "HMAC mismatch on worker pipe" unless OpenSSL.fixed_length_secure_compare(mac, expected)
                +
                +        @inner.load(payload)
                +      end
                +    end
                +  end
                +end
      * Changed:
        lib/parallel.rb
                --- /tmp/d20260617-815-4bq9qe/parallel-1.28.0/lib/parallel.rb	2026-06-17 02:36:05.369677316 +0000
                +++ /tmp/d20260617-815-4bq9qe/parallel-2.1.0/lib/parallel.rb	2026-06-17 02:36:05.369677316 +0000
                @@ -3,0 +4 @@
                +require 'parallel/serializer'
                @@ -66 +67 @@
                -    def initialize(read, write, pid)
                +    def initialize(read, write, pid, serializer)
                @@ -69,0 +71 @@
                +      @serializer = serializer
                @@ -86 +88 @@
                -        Marshal.dump(data, write)
                +        @serializer.dump(data, write)
                @@ -92 +94 @@
                -        Marshal.load(read)
                +        @serializer.load(read)
                @@ -269 +271 @@
                -      elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes]
                +      elsif RUBY_PLATFORM.include?('java') && !options[:in_processes]
                @@ -473,0 +476,2 @@
                +      use_port = defined?(Ractor::Port)
                +
                @@ -475,13 +479,4 @@
                -      ractors = Array.new(options.fetch(:count)) do
                -        Ractor.new do
                -          loop do
                -            got = receive
                -            (klass, method_name), item, index = got
                -            break if index == :break
                -            begin
                -              Ractor.yield [nil, klass.send(method_name, item), item, index]
                -            rescue StandardError => e
                -              Ractor.yield [e, nil, item, index]
                -            end
                -          end
                -        end
                +      ports = {} # port (ruby 4+) or ractor (ruby 3) => ractor
                +      options.fetch(:count).times do
                +        port, ractor = ractor_build(use_port)
                +        ports[port] = ractor
                @@ -491,3 +486,3 @@
                -      ractors.dup.each do |ractor|
                -        if (set = job_factory.next)
                -          item, index = set
                +      ports.dup.each do |port, ractor|
                +        if (job = job_factory.next)
                +          item, index = job
                @@ -496,3 +491,3 @@
                -        else
                -          ractor.send([[nil, nil], nil, :break]) # stop the ractor
                -          ractors.delete ractor
                +        else # not enough work, `receive` would hang
                +          ractor_stop ractor
                +          ports.delete port
                @@ -502,4 +497,5 @@
                -      # replace with new items
                -      while (set = job_factory.next)
                -        item_next, index_next = set
                -        done, (exception, result, item, index) = Ractor.select(*ractors)
                +      # receive result and send new items to done ractors
                +      while (job = job_factory.next)
                +        # receive result
                +        done_port, (exception, result, item_prev, index_prev) = Ractor.select(*ports.keys)
                +        done_ractor = ports[done_port]
                @@ -507 +503 @@
                -          ractors.delete done
                +          ports.delete done_port
                @@ -510,2 +506 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +        ractor_result item_prev, index_prev, result, results, results_mutex, options
                @@ -512,0 +508,2 @@
                +        # send new
                +        item_next, index_next = job
                @@ -514 +511 @@
                -        done.send([callback, item_next, index_next])
                +        done_ractor.send([callback, item_next, index_next])
                @@ -518,2 +515,2 @@
                -      ractors.each do |ractor|
                -        (new_exception, result, item, index) = ractor.take
                +      ports.each do |port, ractor|
                +        (new_exception, result, item, index) = use_port ? port.receive : ractor.take
                @@ -522,3 +519,2 @@
                -        instrument_finish item, index, result, options
                -        results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                -        ractor.send([[nil, nil], nil, :break]) # stop the ractor
                +        ractor_result item, index, result, results, results_mutex, options
                +        ractor_stop ractor
                @@ -529,0 +526,30 @@
                +    def ractor_build(use_port)
                +      args = use_port ? [Ractor::Port.new] : []
                +      ractor = Ractor.new(*args) do |port|
                +        loop do
                +          (klass, method_name), item, index = receive
                +          break if index == :break
                +          begin
                +            result = [nil, klass.send(method_name, item), item, index]
                +          rescue StandardError => e
                +            result = [e, nil, item, index]
                +          end
                +          if port
                +            port.send result
                +          else
                +            Ractor.yield result
                +          end
                +        end
                +      end
                +      [use_port ? args.first : ractor, ractor]
                +    end
                +
                +    def ractor_result(item, index, result, results, results_mutex, options)
                +      instrument_finish item, index, result, options
                +      results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) }
                +    end
                +
                +    def ractor_stop(ractor)
                +      ractor.send([[nil, nil], nil, :break])
                +    end
                +
                @@ -600,0 +627 @@
                +      options[:serializer] ||= Serializer::Marshal
                @@ -621 +648 @@
                -      Worker.new(parent_read, parent_write, pid)
                +      Worker.new(parent_read, parent_write, pid, options[:serializer])
                @@ -624,0 +652 @@
                +      serializer = options.fetch(:serializer)
                @@ -626 +654 @@
                -        data = Marshal.load(read)
                +        data = serializer.load(read)
                @@ -635 +663 @@
                -          rescue Exception # # rubocop:disable Lint/RescueException
                +          rescue Exception # rubocop:disable Lint/RescueException
                @@ -640 +668 @@
                -          Marshal.dump(result, write)
                +          serializer.dump(result, write)
        lib/parallel/version.rb
                --- /tmp/d20260617-815-4bq9qe/parallel-1.28.0/lib/parallel/version.rb	2026-06-17 02:36:05.369677316 +0000
                +++ /tmp/d20260617-815-4bq9qe/parallel-2.1.0/lib/parallel/version.rb	2026-06-17 02:36:05.369677316 +0000
                @@ -3 +3 @@
                -  VERSION = Version = '1.28.0' # rubocop:disable Naming/ConstantName
                +  VERSION = Version = '2.1.0' # rubocop:disable Naming/ConstantName

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
        CHANGELOG.md
                --- /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.1.4/CHANGELOG.md	2026-06-17 02:36:06.896233300 +0000
                +++ /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.2.0/CHANGELOG.md	2026-06-17 02:36:06.898233294 +0000
                @@ -2,0 +3,8 @@
                +## 3.2.0
                +
                +- Unicode 17.0
                +
                +## 3.1.5
                +
                +- Cache Emoji support level for performance reasons #30, patch by @Earlopain:
                +
        README.md
                --- /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.1.4/README.md	2026-06-17 02:36:06.896233300 +0000
                +++ /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.2.0/README.md	2026-06-17 02:36:06.898233294 +0000
                @@ -3 +3 @@
                -Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth()](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                +Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                @@ -5 +5 @@
                -Unicode version: **16.0.0** (September 2024)
                +Unicode version: **17.0.0** (September 2025)
                @@ -111,2 +111,2 @@
                -Single Emoji character with Skin Tone Modifier            | 2
                -Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is configured to `:rgi` / `:rgi_at`
                +Single Emoji character with Skin Tone Modifier            | 2 unless Emoji mode is `:none` or `vs16`
                +Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is `:rgi` / `:rgi_at`
                @@ -191 +191 @@
                -- Copyright (c) 2011, 2015-2024 Jan Lelis, https://janlelis.com, released under the MIT
                +- Copyright (c) 2011, 2015-2025 Jan Lelis, https://janlelis.com, released under the MIT
        data/display_width.marshal.gz
                Binary files /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.1.4/data/display_width.marshal.gz and /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.2.0/data/display_width.marshal.gz differ
        lib/unicode/display_width/constants.rb
                --- /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.1.4/lib/unicode/display_width/constants.rb	2026-06-17 02:36:06.897233297 +0000
                +++ /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.2.0/lib/unicode/display_width/constants.rb	2026-06-17 02:36:06.898233294 +0000
                @@ -5,2 +5,2 @@
                -    VERSION = "3.1.4"
                -    UNICODE_VERSION = "16.0.0"
                +    VERSION = "3.2.0"
                +    UNICODE_VERSION = "17.0.0"
        lib/unicode/display_width/emoji_support.rb
                --- /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.1.4/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:36:06.897233297 +0000
                +++ /tmp/d20260617-8330-d3y2n4/unicode-display_width-3.2.0/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:36:06.899233291 +0000
                @@ -1,2 +1 @@
                -# require "rbconfig"
                -# RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # windows
                +# frozen_string_literal: true
                @@ -15,0 +15,4 @@
                +        @recommended ||= _recommended
                +      end
                +
                +      def self._recommended

@github-actions

Copy link
Copy Markdown
Contributor

gem compare rubocop 1.79.2 1.88.0

Compared versions: ["1.79.2", "1.88.0"]
  DIFFERENT date:
    1.79.2: 2025-08-05 00:00:00 UTC
    1.88.0: 1980-01-02 00:00:00 UTC
  DIFFERENT metadata:
    1.79.2: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.79.2", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.79/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
    1.88.0: {"homepage_uri" => "https://rubocop.org/", "changelog_uri" => "https://github.com/rubocop/rubocop/releases/tag/v1.88.0", "source_code_uri" => "https://github.com/rubocop/rubocop/", "documentation_uri" => "https://docs.rubocop.org/rubocop/1.88/", "bug_tracker_uri" => "https://github.com/rubocop/rubocop/issues", "rubygems_mfa_required" => "true"}
  DIFFERENT rubygems_version:
    1.79.2: 3.6.2
    1.88.0: 3.6.9
  DIFFERENT version:
    1.79.2: 1.79.2
    1.88.0: 1.88.0
  DIFFERENT files:
    1.79.2->1.88.0:
      * Added:
            lib/rubocop/cli/command/list_enabled_cops_for.rb +40/-0
            lib/rubocop/cli/command/mcp.rb +19/-0
            lib/rubocop/cop/correctors.rb +28/-0
            lib/rubocop/cop/internal_affairs/itblock_handler.rb +69/-0
            lib/rubocop/cop/lint/data_define_override.rb +63/-0
            lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113/-0
            lib/rubocop/cop/mixin.rb +86/-0
            lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63/-0
            lib/rubocop/cop/mixin/project_index_help.rb +48/-0
            lib/rubocop/cop/style/array_intersect_with_single_element.rb +50/-0
            lib/rubocop/cop/style/empty_class_definition.rb +119/-0
            lib/rubocop/cop/style/file_open.rb +84/-0
            lib/rubocop/cop/style/hash_lookup_method.rb +106/-0
            lib/rubocop/cop/style/map_join.rb +123/-0
            lib/rubocop/cop/style/module_member_existence_check.rb +110/-0
            lib/rubocop/cop/style/negative_array_index.rb +220/-0
            lib/rubocop/cop/style/one_class_per_file.rb +115/-0
            lib/rubocop/cop/style/partition_instead_of_double_select.rb +270/-0
            lib/rubocop/cop/style/predicate_with_kind.rb +84/-0
            lib/rubocop/cop/style/reduce_to_hash.rb +200/-0
            lib/rubocop/cop/style/redundant_min_max_by.rb +93/-0
            lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114/-0
            lib/rubocop/cop/style/reverse_find.rb +51/-0
            lib/rubocop/cop/style/select_by_kind.rb +158/-0
            lib/rubocop/cop/style/select_by_range.rb +197/-0
            lib/rubocop/cop/style/tally_method.rb +181/-0
            lib/rubocop/lsp/disable_comment_edits.rb +135/-0
            lib/rubocop/mcp/server.rb +200/-0
            lib/rubocop/project_index_loader.rb +66/-0
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
            config/default.yml +259/-90
            config/obsoletion.yml +30/-1
            exe/rubocop +1/-8
            lib/rubocop.rb +28/-96
            lib/rubocop/cache_config.rb +29/-0
            lib/rubocop/cli.rb +35/-9
            lib/rubocop/cli/command/auto_generate_config.rb +36/-4
            lib/rubocop/cli/command/lsp.rb +1/-1
            lib/rubocop/cli/command/show_cops.rb +2/-2
            lib/rubocop/cli/command/show_docs_url.rb +4/-8
            lib/rubocop/cli/command/suggest_extensions.rb +1/-1
            lib/rubocop/comment_config.rb +59/-17
            lib/rubocop/config.rb +14/-10
            lib/rubocop/config_finder.rb +1/-1
            lib/rubocop/config_loader.rb +37/-23
            lib/rubocop/config_loader_resolver.rb +20/-10
            lib/rubocop/config_obsoletion/extracted_cop.rb +4/-2
            lib/rubocop/config_store.rb +7/-2
            lib/rubocop/config_validator.rb +1/-1
            lib/rubocop/cop/autocorrect_logic.rb +10/-5
            lib/rubocop/cop/base.rb +25/-4
            lib/rubocop/cop/bundler/gem_comment.rb +2/-2
            lib/rubocop/cop/bundler/gem_version.rb +28/-28
            lib/rubocop/cop/bundler/ordered_gems.rb +1/-2
            lib/rubocop/cop/correctors/alignment_corrector.rb +26/-7
            lib/rubocop/cop/correctors/condition_corrector.rb +1/-1
            lib/rubocop/cop/correctors/for_to_each_corrector.rb +7/-2
            lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1/-5
            lib/rubocop/cop/correctors/parentheses_corrector.rb +33/-2
            lib/rubocop/cop/correctors/percent_literal_corrector.rb +2/-2
            lib/rubocop/cop/documentation.rb +2/-3
            lib/rubocop/cop/exclude_limit.rb +31/-5
            lib/rubocop/cop/gemspec/duplicated_assignment.rb +2/-2
            lib/rubocop/cop/gemspec/ordered_dependencies.rb +1/-2
            lib/rubocop/cop/gemspec/require_mfa.rb +5/-5
            lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12/-7
            lib/rubocop/cop/internal_affairs.rb +1/-0
            lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8/-8
            lib/rubocop/cop/internal_affairs/location_exists.rb +28/-2
            lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1/-0
            lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9/-9
            lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3/-1
            lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1/-1
            lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1/-1
            lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5/-3
            lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4/-4
            lib/rubocop/cop/layout/argument_alignment.rb +2/-2
            lib/rubocop/cop/layout/array_alignment.rb +1/-1
            lib/rubocop/cop/layout/begin_end_alignment.rb +1/-1
            lib/rubocop/cop/layout/block_alignment.rb +41/-4
            lib/rubocop/cop/layout/case_indentation.rb +3/-1
            lib/rubocop/cop/layout/class_structure.rb +14/-7
            lib/rubocop/cop/layout/dot_position.rb +2/-2
            lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26/-7
            lib/rubocop/cop/layout/empty_line_between_defs.rb +31/-13
            lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2/-2
            lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1/-0
            lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12/-2
            lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16/-2
            lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16/-2
            lib/rubocop/cop/layout/end_alignment.rb +10/-3
            lib/rubocop/cop/layout/first_argument_indentation.rb +34/-1
            lib/rubocop/cop/layout/first_array_element_line_break.rb +26/-0
            lib/rubocop/cop/layout/first_hash_element_indentation.rb +7/-1
            lib/rubocop/cop/layout/first_hash_element_line_break.rb +28/-28
            lib/rubocop/cop/layout/hash_alignment.rb +3/-6
            lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2/-2
            lib/rubocop/cop/layout/heredoc_indentation.rb +33/-3
            lib/rubocop/cop/layout/indentation_style.rb +1/-1
            lib/rubocop/cop/layout/indentation_width.rb +123/-7
            lib/rubocop/cop/layout/line_continuation_spacing.rb +1/-1
            lib/rubocop/cop/layout/line_length.rb +26/-9
            lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57/-57
            lib/rubocop/cop/layout/multiline_assignment_layout.rb +9/-2
            lib/rubocop/cop/layout/multiline_block_layout.rb +2/-0
            lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56/-56
            lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1/-1
            lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229/-39
            lib/rubocop/cop/layout/multiline_operation_indentation.rb +8/-4
            lib/rubocop/cop/layout/parameter_alignment.rb +1/-1
            lib/rubocop/cop/layout/redundant_line_break.rb +3/-1
            lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13/-3
            lib/rubocop/cop/layout/space_after_comma.rb +2/-10
            lib/rubocop/cop/layout/space_after_semicolon.rb +1/-1
            lib/rubocop/cop/layout/space_around_block_parameters.rb +1/-1
            lib/rubocop/cop/layout/space_around_keyword.rb +4/-2
            lib/rubocop/cop/layout/space_before_brackets.rb +1/-1
            lib/rubocop/cop/layout/space_in_lambda_literal.rb +9/-8
            lib/rubocop/cop/layout/trailing_whitespace.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_assignment.rb +1/-11
            lib/rubocop/cop/lint/ambiguous_block_association.rb +1/-1
            lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1/-10
            lib/rubocop/cop/lint/circular_argument_reference.rb +45/-3
            lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4/-3
            lib/rubocop/cop/lint/constant_reassignment.rb +93/-11
            lib/rubocop/cop/lint/constant_resolution.rb +6/-6
            lib/rubocop/cop/lint/cop_directive_syntax.rb +14/-8
            lib/rubocop/cop/lint/debugger.rb +0/-3
            lib/rubocop/cop/lint/deprecated_constants.rb +2/-8
            lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4/-1
            lib/rubocop/cop/lint/duplicate_match_pattern.rb +4/-4
            lib/rubocop/cop/lint/duplicate_methods.rb +111/-12
            lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5/-42
            lib/rubocop/cop/lint/else_layout.rb +19/-0
            lib/rubocop/cop/lint/empty_block.rb +4/-4
            lib/rubocop/cop/lint/empty_conditional_body.rb +6/-1
            lib/rubocop/cop/lint/empty_in_pattern.rb +8/-1
            lib/rubocop/cop/lint/empty_interpolation.rb +11/-0
            lib/rubocop/cop/lint/empty_when.rb +8/-1
            lib/rubocop/cop/lint/ensure_return.rb +19/-1
            lib/rubocop/cop/lint/erb_new_arguments.rb +4/-2
            lib/rubocop/cop/lint/float_comparison.rb +2/-1
            lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5/-1
            lib/rubocop/cop/lint/interpolation_check.rb +25/-5
            lib/rubocop/cop/lint/lambda_without_literal_block.rb +1/-1
            lib/rubocop/cop/lint/literal_as_condition.rb +5/-1
            lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11/-1
            lib/rubocop/cop/lint/literal_in_interpolation.rb +9/-12
            lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19/-10
            lib/rubocop/cop/lint/multiple_comparison.rb +2/-2
            lib/rubocop/cop/lint/next_without_accumulator.rb +2/-0
            lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20/-0
            lib/rubocop/cop/lint/non_deterministic_require_order.rb +4/-2
            lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1/-1
            lib/rubocop/cop/lint/number_conversion.rb +19/-10
            lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1/-1
            lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3/-0
            lib/rubocop/cop/lint/ordered_magic_comments.rb +7/-7
            lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2/-12
            lib/rubocop/cop/lint/raise_exception.rb +1/-1
            lib/rubocop/cop/lint/rand_one.rb +1/-1
            lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27/-10
            lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6/-12
            lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15/-4
            lib/rubocop/cop/lint/redundant_require_statement.rb +4/-2
            lib/rubocop/cop/lint/redundant_safe_navigation.rb +36/-12
            lib/rubocop/cop/lint/redundant_splat_expansion.rb +12/-2
            lib/rubocop/cop/lint/redundant_type_conversion.rb +10/-3
            lib/rubocop/cop/lint/redundant_with_index.rb +1/-1
            lib/rubocop/cop/lint/redundant_with_object.rb +5/-0
            lib/rubocop/cop/lint/refinement_import_methods.rb +8/-1
            lib/rubocop/cop/lint/regexp_as_condition.rb +9/-1
            lib/rubocop/cop/lint/require_parentheses.rb +13/-4
            lib/rubocop/cop/lint/require_range_parentheses.rb +2/-1
            lib/rubocop/cop/lint/require_relative_self_path.rb +7/-5
            lib/rubocop/cop/lint/rescue_exception.rb +1/-4
            lib/rubocop/cop/lint/rescue_type.rb +1/-1
            lib/rubocop/cop/lint/safe_navigation_chain.rb +18/-0
            lib/rubocop/cop/lint/safe_navigation_consistency.rb +7/-1
            lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1/-1
            lib/rubocop/cop/lint/script_permission.rb +5/-1
            lib/rubocop/cop/lint/self_assignment.rb +39/-7
            lib/rubocop/cop/lint/send_with_mixin_argument.rb +1/-1
            lib/rubocop/cop/lint/shadowed_argument.rb +7/-7
            lib/rubocop/cop/lint/shadowed_exception.rb +1/-1
            lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14/-0
            lib/rubocop/cop/lint/shared_mutable_default.rb +3/-1
            lib/rubocop/cop/lint/struct_new_override.rb +17/-1
            lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +12/-0
            lib/rubocop/cop/lint/symbol_conversion.rb +21/-4
            lib/rubocop/cop/lint/syntax.rb +25/-1
            lib/rubocop/cop/lint/to_enum_arguments.rb +28/-1
            lib/rubocop/cop/lint/to_json.rb +12/-16
            lib/rubocop/cop/lint/top_level_return_with_argument.rb +1/-1
            lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5/-1
            lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +4/-2
            lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1/-0
            lib/rubocop/cop/lint/unreachable_code.rb +7/-5
            lib/rubocop/cop/lint/unused_method_argument.rb +10/-0
            lib/rubocop/cop/lint/uri_escape_unescape.rb +2/-0
            lib/rubocop/cop/lint/useless_assignment.rb +53/-25
            lib/rubocop/cop/lint/useless_constant_scoping.rb +4/-4
            lib/rubocop/cop/lint/useless_default_value_argument.rb +2/-0
            lib/rubocop/cop/lint/useless_or.rb +15/-2
            lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8/-4
            lib/rubocop/cop/lint/useless_setter_call.rb +4/-1
            lib/rubocop/cop/lint/useless_times.rb +22/-1
            lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37/-11
            lib/rubocop/cop/lint/void.rb +39/-12
            lib/rubocop/cop/message_annotator.rb +1/-1
            lib/rubocop/cop/metrics/block_length.rb +1/-1
            lib/rubocop/cop/metrics/block_nesting.rb +23/-0
            lib/rubocop/cop/metrics/collection_literal_length.rb +1/-1
            lib/rubocop/cop/metrics/method_length.rb +1/-1
            lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4/-3
            lib/rubocop/cop/metrics/utils/iterating_block.rb +1/-1
            lib/rubocop/cop/migration/department_name.rb +12/-1
            lib/rubocop/cop/mixin/check_line_breakable.rb +2/-2
            lib/rubocop/cop/mixin/check_single_line_suitability.rb +4/-6
            lib/rubocop/cop/mixin/code_length.rb +1/-1
            lib/rubocop/cop/mixin/configurable_max.rb +6/-5
            lib/rubocop/cop/mixin/end_keyword_alignment.rb +1/-7
            lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5/-5
            lib/rubocop/cop/mixin/hash_transform_method.rb +10/-60
            lib/rubocop/cop/mixin/line_length_help.rb +21/-2
            lib/rubocop/cop/mixin/method_complexity.rb +1/-1
            lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1/-1
            lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1/-1
            lib/rubocop/cop/mixin/space_after_punctuation.rb +5/-4
            lib/rubocop/cop/mixin/statement_modifier.rb +0/-6
            lib/rubocop/cop/mixin/trailing_comma.rb +8/-5
            lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/block_parameter_name.rb +1/-1
            lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1/-1
            lib/rubocop/cop/naming/method_name.rb +5/-3
            lib/rubocop/cop/naming/predicate_method.rb +32/-8
            lib/rubocop/cop/naming/predicate_prefix.rb +12/-12
            lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1/-1
            lib/rubocop/cop/offense.rb +17/-1
            lib/rubocop/cop/registry.rb +62/-38
            lib/rubocop/cop/security/eval.rb +15/-2
            lib/rubocop/cop/security/io_methods.rb +1/-1
            lib/rubocop/cop/security/json_load.rb +33/-11
            lib/rubocop/cop/style/access_modifier_declarations.rb +15/-4
            lib/rubocop/cop/style/accessor_grouping.rb +4/-2
            lib/rubocop/cop/style/alias.rb +15/-3
            lib/rubocop/cop/style/and_or.rb +2/-1
            lib/rubocop/cop/style/arguments_forwarding.rb +24/-6
            lib/rubocop/cop/style/array_first_last.rb +12/-1
            lib/rubocop/cop/style/array_intersect.rb +50/-12
            lib/rubocop/cop/style/array_join.rb +4/-2
            lib/rubocop/cop/style/ascii_comments.rb +6/-3
            lib/rubocop/cop/style/attr.rb +5/-2
            lib/rubocop/cop/style/bare_percent_literals.rb +4/-3
            lib/rubocop/cop/style/begin_block.rb +3/-1
            lib/rubocop/cop/style/bitwise_predicate.rb +8/-1
            lib/rubocop/cop/style/block_delimiters.rb +42/-35
            lib/rubocop/cop/style/case_equality.rb +29/-15
            lib/rubocop/cop/style/character_literal.rb +2/-2
            lib/rubocop/cop/style/class_and_module_children.rb +19/-2
            lib/rubocop/cop/style/class_equality_comparison.rb +21/-13
            lib/rubocop/cop/style/class_methods_definitions.rb +11/-5
            lib/rubocop/cop/style/collection_compact.rb +36/-16
            lib/rubocop/cop/style/colon_method_call.rb +16/-7
            lib/rubocop/cop/style/combinable_loops.rb +5/-0
            lib/rubocop/cop/style/comparable_clamp.rb +12/-1
            lib/rubocop/cop/style/concat_array_literals.rb +7/-1
            lib/rubocop/cop/style/conditional_assignment.rb +14/-19
            lib/rubocop/cop/style/constant_visibility.rb +20/-12
            lib/rubocop/cop/style/copyright.rb +22/-11
            lib/rubocop/cop/style/date_time.rb +4/-4
            lib/rubocop/cop/style/dig_chain.rb +5/-0
            lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1/-1
            lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6/-1
            lib/rubocop/cop/style/documentation.rb +6/-6
            lib/rubocop/cop/style/documentation_method.rb +7/-7
            lib/rubocop/cop/style/double_negation.rb +1/-1
            lib/rubocop/cop/style/each_for_simple_loop.rb +1/-1
            lib/rubocop/cop/style/each_with_object.rb +2/-0
            lib/rubocop/cop/style/empty_block_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_lambda_parameter.rb +1/-1
            lib/rubocop/cop/style/empty_method.rb +0/-6
            lib/rubocop/cop/style/encoding.rb +7/-1
            lib/rubocop/cop/style/end_block.rb +3/-1
            lib/rubocop/cop/style/endless_method.rb +23/-5
            lib/rubocop/cop/style/explicit_block_argument.rb +1/-1
            lib/rubocop/cop/style/fetch_env_var.rb +1/-1
            lib/rubocop/cop/style/file_write.rb +21/-16
            lib/rubocop/cop/style/float_division.rb +15/-1
            lib/rubocop/cop/style/for.rb +3/-0
            lib/rubocop/cop/style/format_string.rb +4/-3
            lib/rubocop/cop/style/format_string_token.rb +49/-5
            lib/rubocop/cop/style/global_vars.rb +5/-2
            lib/rubocop/cop/style/guard_clause.rb +27/-22
            lib/rubocop/cop/style/hash_as_last_array_item.rb +27/-9
            lib/rubocop/cop/style/hash_conversion.rb +1/-1
            lib/rubocop/cop/style/hash_slice.rb +16/-0
            lib/rubocop/cop/style/hash_syntax.rb +1/-1
            lib/rubocop/cop/style/hash_transform_keys.rb +17/-7
            lib/rubocop/cop/style/hash_transform_values.rb +17/-7
            lib/rubocop/cop/style/if_inside_else.rb +16/-7
            lib/rubocop/cop/style/if_unless_modifier.rb +58/-18
            lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12/-12
            lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4/-1
            lib/rubocop/cop/style/if_with_semicolon.rb +7/-5
            lib/rubocop/cop/style/infinite_loop.rb +1/-1
            lib/rubocop/cop/style/inline_comment.rb +4/-1
            lib/rubocop/cop/style/ip_addresses.rb +1/-2
            lib/rubocop/cop/style/lambda_call.rb +8/-8
            lib/rubocop/cop/style/magic_comment_format.rb +3/-3
            lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17/-4
            lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15/-2
            lib/rubocop/cop/style/method_def_parentheses.rb +2/-4
            lib/rubocop/cop/style/min_max_comparison.rb +1/-1
            lib/rubocop/cop/style/multiline_if_then.rb +4/-4
            lib/rubocop/cop/style/multiline_method_signature.rb +2/-4
            lib/rubocop/cop/style/mutable_constant.rb +106/-12
            lib/rubocop/cop/style/nil_comparison.rb +11/-10
            lib/rubocop/cop/style/nil_lambda.rb +1/-1
            lib/rubocop/cop/style/non_nil_check.rb +5/-11
            lib/rubocop/cop/style/not.rb +2/-0
            lib/rubocop/cop/style/numeric_literals.rb +3/-2
            lib/rubocop/cop/style/one_line_conditional.rb +21/-12
            lib/rubocop/cop/style/operator_method_call.rb +11/-2
            lib/rubocop/cop/style/parallel_assignment.rb +14/-3
            lib/rubocop/cop/style/percent_literal_delimiters.rb +2/-0
            lib/rubocop/cop/style/preferred_hash_methods.rb +12/-12
            lib/rubocop/cop/style/proc.rb +3/-2
            lib/rubocop/cop/style/raise_args.rb +1/-1
            lib/rubocop/cop/style/redundant_argument.rb +2/-0
            lib/rubocop/cop/style/redundant_array_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_begin.rb +37/-3
            lib/rubocop/cop/style/redundant_condition.rb +6/-3
            lib/rubocop/cop/style/redundant_constant_base.rb +5/-5
            lib/rubocop/cop/style/redundant_each.rb +3/-3
            lib/rubocop/cop/style/redundant_exception.rb +1/-1
            lib/rubocop/cop/style/redundant_fetch_block.rb +1/-1
            lib/rubocop/cop/style/redundant_format.rb +27/-5
            lib/rubocop/cop/style/redundant_interpolation.rb +11/-2
            lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +27/-11
            lib/rubocop/cop/style/redundant_line_continuation.rb +16/-0
            lib/rubocop/cop/style/redundant_parentheses.rb +36/-30
            lib/rubocop/cop/style/redundant_percent_q.rb +5/-3
            lib/rubocop/cop/style/redundant_regexp_argument.rb +9/-0
            lib/rubocop/cop/style/redundant_regexp_constructor.rb +2/-2
            lib/rubocop/cop/style/redundant_regexp_escape.rb +8/-0
            lib/rubocop/cop/style/redundant_return.rb +3/-1
            lib/rubocop/cop/style/redundant_self.rb +2/-2
            lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0/-5
            lib/rubocop/cop/style/redundant_sort.rb +7/-7
            lib/rubocop/cop/style/regexp_literal.rb +31/-2
            lib/rubocop/cop/style/rescue_modifier.rb +3/-3
            lib/rubocop/cop/style/safe_navigation.rb +25/-8
            lib/rubocop/cop/style/select_by_regexp.rb +51/-21
            lib/rubocop/cop/style/self_assignment.rb +1/-1
            lib/rubocop/cop/style/semicolon.rb +41/-8
            lib/rubocop/cop/style/single_line_block_params.rb +2/-2
            lib/rubocop/cop/style/single_line_do_end_block.rb +1/-1
            lib/rubocop/cop/style/single_line_methods.rb +3/-1
            lib/rubocop/cop/style/sole_nested_conditional.rb +12/-3
            lib/rubocop/cop/style/special_global_vars.rb +6/-1
            lib/rubocop/cop/style/string_concatenation.rb +17/-13
            lib/rubocop/cop/style/struct_inheritance.rb +13/-0
            lib/rubocop/cop/style/super_arguments.rb +2/-2
            lib/rubocop/cop/style/symbol_array.rb +1/-1
            lib/rubocop/cop/style/symbol_proc.rb +7/-6
            lib/rubocop/cop/style/top_level_method_definition.rb +2/-2
            lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45/-0
            lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1/-1
            lib/rubocop/cop/style/trailing_method_end_statement.rb +1/-0
            lib/rubocop/cop/style/trailing_underscore_variable.rb +11/-11
            lib/rubocop/cop/style/unless_else.rb +10/-9
            lib/rubocop/cop/style/unless_logical_operators.rb +3/-3
            lib/rubocop/cop/style/while_until_do.rb +7/-0
            lib/rubocop/cop/style/while_until_modifier.rb +16/-0
            lib/rubocop/cop/style/word_array.rb +1/-0
            lib/rubocop/cop/style/yoda_condition.rb +1/-1
            lib/rubocop/cop/style/yoda_expression.rb +1/-1
            lib/rubocop/cop/style/zero_length_predicate.rb +6/-3
            lib/rubocop/cop/team.rb +87/-36
            lib/rubocop/cop/util.rb +2/-3
            lib/rubocop/cop/utils/format_string.rb +10/-0
            lib/rubocop/cop/variable_force.rb +9/-7
            lib/rubocop/cop/variable_force/branch.rb +30/-6
            lib/rubocop/cop/variable_force/variable.rb +1/-1
            lib/rubocop/cops_documentation_generator.rb +4/-4
            lib/rubocop/directive_comment.rb +48/-4
            lib/rubocop/file_patterns.rb +9/-1
            lib/rubocop/formatter.rb +22/-21
            lib/rubocop/formatter/clang_style_formatter.rb +5/-2
            lib/rubocop/formatter/disabled_config_formatter.rb +38/-14
            lib/rubocop/formatter/formatter_set.rb +2/-2
            lib/rubocop/formatter/junit_formatter.rb +1/-1
            lib/rubocop/formatter/simple_text_formatter.rb +0/-2
            lib/rubocop/formatter/tap_formatter.rb +5/-2
            lib/rubocop/formatter/worst_offenders_formatter.rb +1/-1
            lib/rubocop/lsp/diagnostic.rb +18/-33
            lib/rubocop/lsp/routes.rb +42/-6
            lib/rubocop/lsp/runtime.rb +13/-4
            lib/rubocop/lsp/stdin_runner.rb +8/-17
            lib/rubocop/magic_comment.rb +20/-0
            lib/rubocop/options.rb +35/-4
            lib/rubocop/path_util.rb +14/-2
            lib/rubocop/plugin/loader.rb +1/-1
            lib/rubocop/rake_task.rb +1/-1
            lib/rubocop/remote_config.rb +10/-8
            lib/rubocop/result_cache.rb +61/-38
            lib/rubocop/rspec/cop_helper.rb +8/-0
            lib/rubocop/rspec/shared_contexts.rb +39/-5
            lib/rubocop/rspec/support.rb +2/-1
            lib/rubocop/runner.rb +134/-57
            lib/rubocop/server/cache.rb +6/-29
            lib/rubocop/server/core.rb +8/-0
            lib/rubocop/target_finder.rb +17/-10
            lib/rubocop/target_ruby.rb +31/-14
            lib/rubocop/version.rb +21/-3
            lib/ruby_lsp/rubocop/addon.rb +23/-8
            lib/ruby_lsp/rubocop/runtime_adapter.rb +49/-15
  DIFFERENT extra_rdoc_files:
    1.79.2->1.88.0:
      * Changed:
            LICENSE.txt +1/-1
            README.md +2/-2
  DIFFERENT runtime dependencies:
    1.79.2->1.88.0:
      * Updated:
            parallel from: ["~> 1.10"] to: [">= 1.10"]
            rubocop-ast from: [">= 1.46.0", "< 2.0"] to: [">= 1.49.0", "< 2.0"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-emoji 4.0.4 4.2.0

Compared versions: ["4.0.4", "4.2.0"]
  DIFFERENT date:
    4.0.4: 2024-11-19 00:00:00 UTC
    4.2.0: 2025-12-17 00:00:00 UTC
  DIFFERENT description:
    4.0.4: [Emoji 16.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
    4.2.0: [Emoji 17.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
  DIFFERENT required_ruby_version:
    4.0.4: >= 2.5, < 4.0
    4.2.0: >= 2.5
  DIFFERENT version:
    4.0.4: 4.0.4
    4.2.0: 4.2.0
  DIFFERENT files:
    4.0.4->4.2.0:
      * Changed:
            CHANGELOG.md +11/-0
            Gemfile +2/-0
            Gemfile.lock +5/-1
            README.md +4/-4
            Rakefile +1/-1
            lib/unicode/emoji/constants.rb +4/-3
            lib/unicode/emoji/generated/regex.rb +1/-1
            lib/unicode/emoji/generated/regex_basic.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_picto.rb +1/-1
            lib/unicode/emoji/generated/regex_picto_no_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_possible.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_presentation.rb +1/-1
            lib/unicode/emoji/generated/regex_text.rb +1/-1
            lib/unicode/emoji/generated/regex_valid.rb +1/-1
            lib/unicode/emoji/generated/regex_valid_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed_include_text.rb +1/-1
            lib/unicode/emoji/generated_native/regex.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_text.rb +1/-1
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
            unicode-emoji.gemspec +1/-1
  DIFFERENT test_files:
    4.0.4->4.2.0:
      * Changed:
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
  DIFFERENT Gemfile dependencies
    4.0.4->4.2.0:
      * Added:
            mutex_m [">= 0"] (runtime)
            ostruct [">= 0"] (runtime)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-emoji 4.0.4 4.2.0

Diff too large (918698 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff rubocop 1.79.2 1.88.0

Diff too large (818032 chars)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT date:
    3.1.4: 2025-01-13 00:00:00 UTC
    3.2.0: 2025-09-09 00:00:00 UTC
  DIFFERENT description:
    3.1.4: [Unicode 16.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
    3.2.0: [Unicode 17.0.0] Determines the monospace display width of a string using EastAsianWidth.txt, Unicode general category, Emoji specification, and other data.
  DIFFERENT version:
    3.1.4: 3.1.4
    3.2.0: 3.2.0
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
            CHANGELOG.md +8/-0
            README.md +5/-5
            lib/unicode/display_width/constants.rb +2/-2
            lib/unicode/display_width/emoji_support.rb +5/-2
  DIFFERENT extra_rdoc_files:
    3.1.4->3.2.0:
      * Changed:
            README.md +5/-5
            CHANGELOG.md +8/-0
  DIFFERENT runtime dependencies:
    3.1.4->3.2.0:
      * Updated:
            unicode-emoji from: ["~> 4.0", ">= 4.0.4"] to: ["~> 4.1"]

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-display_width 3.1.4 3.2.0

Compared versions: ["3.1.4", "3.2.0"]
  DIFFERENT files:
    3.1.4->3.2.0:
      * Changed:
        CHANGELOG.md
                --- /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.1.4/CHANGELOG.md	2026-06-17 02:37:14.993208667 +0000
                +++ /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.2.0/CHANGELOG.md	2026-06-17 02:37:14.994208679 +0000
                @@ -2,0 +3,8 @@
                +## 3.2.0
                +
                +- Unicode 17.0
                +
                +## 3.1.5
                +
                +- Cache Emoji support level for performance reasons #30, patch by @Earlopain:
                +
        README.md
                --- /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.1.4/README.md	2026-06-17 02:37:14.993208667 +0000
                +++ /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.2.0/README.md	2026-06-17 02:37:14.994208679 +0000
                @@ -3 +3 @@
                -Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth()](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                +Determines the monospace display width of a string in Ruby, which is useful for all kinds of terminal-based applications. The implementation is based on [EastAsianWidth.txt](https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt), the [Emoji specfication](https://www.unicode.org/reports/tr51/) and other data, 100% in Ruby. It does not rely on the OS vendor ([wcwidth](https://github.com/janlelis/wcswidth-ruby)) to provide an up-to-date method for measuring string width in terminals.
                @@ -5 +5 @@
                -Unicode version: **16.0.0** (September 2024)
                +Unicode version: **17.0.0** (September 2025)
                @@ -111,2 +111,2 @@
                -Single Emoji character with Skin Tone Modifier            | 2
                -Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is configured to `:rgi` / `:rgi_at`
                +Single Emoji character with Skin Tone Modifier            | 2 unless Emoji mode is `:none` or `vs16`
                +Skin Tone Modifier used in isolation or with invalid base | 2 if Emoji mode is `:rgi` / `:rgi_at`
                @@ -191 +191 @@
                -- Copyright (c) 2011, 2015-2024 Jan Lelis, https://janlelis.com, released under the MIT
                +- Copyright (c) 2011, 2015-2025 Jan Lelis, https://janlelis.com, released under the MIT
        data/display_width.marshal.gz
                Binary files /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.1.4/data/display_width.marshal.gz and /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.2.0/data/display_width.marshal.gz differ
        lib/unicode/display_width/constants.rb
                --- /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.1.4/lib/unicode/display_width/constants.rb	2026-06-17 02:37:14.993208667 +0000
                +++ /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.2.0/lib/unicode/display_width/constants.rb	2026-06-17 02:37:14.995208690 +0000
                @@ -5,2 +5,2 @@
                -    VERSION = "3.1.4"
                -    UNICODE_VERSION = "16.0.0"
                +    VERSION = "3.2.0"
                +    UNICODE_VERSION = "17.0.0"
        lib/unicode/display_width/emoji_support.rb
                --- /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.1.4/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:37:14.993208667 +0000
                +++ /tmp/d20260617-8428-uyrjm2/unicode-display_width-3.2.0/lib/unicode/display_width/emoji_support.rb	2026-06-17 02:37:14.995208690 +0000
                @@ -1,2 +1 @@
                -# require "rbconfig"
                -# RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # windows
                +# frozen_string_literal: true
                @@ -15,0 +15,4 @@
                +        @recommended ||= _recommended
                +      end
                +
                +      def self._recommended

@github-actions

Copy link
Copy Markdown
Contributor

gem compare unicode-emoji 4.0.4 4.2.0

Compared versions: ["4.0.4", "4.2.0"]
  DIFFERENT date:
    4.0.4: 2024-11-19 00:00:00 UTC
    4.2.0: 2025-12-17 00:00:00 UTC
  DIFFERENT description:
    4.0.4: [Emoji 16.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
    4.2.0: [Emoji 17.0] Provides Unicode Emoji data and regexes, incorporating the latest Unicode and Emoji standards. Includes a categorized list of recommended Emoji.
  DIFFERENT required_ruby_version:
    4.0.4: >= 2.5, < 4.0
    4.2.0: >= 2.5
  DIFFERENT version:
    4.0.4: 4.0.4
    4.2.0: 4.2.0
  DIFFERENT files:
    4.0.4->4.2.0:
      * Changed:
            CHANGELOG.md +11/-0
            Gemfile +2/-0
            Gemfile.lock +5/-1
            README.md +4/-4
            Rakefile +1/-1
            lib/unicode/emoji/constants.rb +4/-3
            lib/unicode/emoji/generated/regex.rb +1/-1
            lib/unicode/emoji/generated/regex_basic.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated/regex_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_picto.rb +1/-1
            lib/unicode/emoji/generated/regex_picto_no_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_possible.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_emoji.rb +1/-1
            lib/unicode/emoji/generated/regex_prop_presentation.rb +1/-1
            lib/unicode/emoji/generated/regex_text.rb +1/-1
            lib/unicode/emoji/generated/regex_valid.rb +1/-1
            lib/unicode/emoji/generated/regex_valid_include_text.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed.rb +1/-1
            lib/unicode/emoji/generated/regex_well_formed_include_text.rb +1/-1
            lib/unicode/emoji/generated_native/regex.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_mqe_uqe.rb +1/-1
            lib/unicode/emoji/generated_native/regex_include_text.rb +1/-1
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
            unicode-emoji.gemspec +1/-1
  DIFFERENT test_files:
    4.0.4->4.2.0:
      * Changed:
            spec/emoji_test_txt_spec.rb +2/-2
            spec/unicode_emoji_spec.rb +7/-2
  DIFFERENT Gemfile dependencies
    4.0.4->4.2.0:
      * Added:
            mutex_m [">= 0"] (runtime)
            ostruct [">= 0"] (runtime)

@github-actions

Copy link
Copy Markdown
Contributor

gem compare --diff unicode-emoji 4.0.4 4.2.0

Diff too large (918640 chars)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies ruby Pull requests that update Ruby code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants