Skip to content

Commit

Permalink
Fix MatchData#[index, length] when index is larger than number of mat…
Browse files Browse the repository at this point in the history
…ched values

PullRequest: truffleruby/4290
  • Loading branch information
andrykonchin committed Jun 13, 2024
2 parents 6192d04 + 8a46320 commit 53ab10a
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Bug fixes:
* Fix `IO#{read_nonblock,readpartial,sysread}`, `BasicSocket#{recv,recv_nonblock}`, `{Socket,UDPSocket}#recvfrom_nonblock`, `UnixSocket#recvfrom` and preserve a provided buffer's encoding (#3506, @andrykonchyn).
* Repair `IO#{wait_readable,wait_writable,wait}` to be interruptible (#3504, @andrykonchin).
* Fix Hash value omission for constant names (@andrykonchin).
* Fix `MatchData#[index, length]` when index is larger than number of matched values (@andrykonchin).

Compatibility:

Expand Down
5 changes: 5 additions & 0 deletions spec/ruby/core/matchdata/element_reference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
# negative index is larger than the number of match values
/(.)(.)(\d+)(\d)/.match("THX1138.")[-30, 2].should == nil

# positive index larger than number of match values
/(.)(.)(\d+)(\d)/.match("THX1138.")[5, 2].should == []
/(.)(.)(\d+)(\d)/.match("THX1138.")[6, 2].should == nil
/(.)(.)(\d+)(\d)/.match("THX1138.")[30, 2].should == nil

# length argument larger than number of match values is capped to match value length
/(.)(.)(\d+)(\d)/.match("THX1138.")[3, 10].should == %w|113 8|

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/truffleruby/core/regexp/MatchDataNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ Object getIndex(RubyMatchData matchData, int index, int length,
@Cached @Exclusive InlinedConditionProfile negativeLengthProfile,
@Cached @Shared InlinedConditionProfile normalizedIndexProfile,
@Cached @Exclusive InlinedConditionProfile negativeIndexProfile,
@Cached @Exclusive InlinedConditionProfile tooLargeIndexProfile,
@Cached @Exclusive InlinedConditionProfile tooLargeTotalProfile) {
final Object[] values = getValuesNode.execute(matchData);

Expand All @@ -294,6 +295,10 @@ Object getIndex(RubyMatchData matchData, int index, int length,
}
}

if (tooLargeIndexProfile.profile(this, index > values.length)) {
return nil;
}

int endIndex = index + length;
if (tooLargeTotalProfile.profile(this, endIndex > values.length)) {
endIndex = values.length;
Expand Down
1 change: 0 additions & 1 deletion test/mri/excludes/TestRegexp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
exclude :test_cache_optimization_exponential, "NoMethodError: undefined method `timeout=' for Regexp:Class"
exclude :test_cache_optimization_square, "NoMethodError: undefined method `timeout=' for Regexp:Class"
exclude :test_invalid_free_at_parse_depth_limit_over, "NameError: uninitialized constant Bug"
exclude :test_match_aref, "throws internal exception"
exclude :test_match_without_regexp, "Encoding::CompatibilityError: incompatible encoding regexp match (Shift_JIS regexp with UTF-8 string)"
exclude :test_parse, "Polyglot::ForeignException: invalid group reference 80"
exclude :test_parse_kg, "Polyglot::ForeignException: undefined name <-1> reference"
Expand Down

0 comments on commit 53ab10a

Please sign in to comment.