Skip to content

Commit 44cb454

Browse files
committed
[GR-38430] Fix String#[Regexp, Integer] when the capture group exists but is not matched
1 parent 505d56f commit 44cb454

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Bug fixes:
1010
* Fix `MatchData#[]` exception when supplying a large negative index along with a length argument (@nirvdrum).
1111
* Fix capacity computation for huge `Hash` (#2635, @eregon).
1212
* Fix aliased methods to return the correct owner when method is from a superclass (@bjfish).
13+
* Fix `String#[Regexp, Integer]` when the capture group exists but is not matched (@eregon).
1314

1415
Compatibility:
1516

src/main/java/org/truffleruby/core/string/StringNodes.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,8 @@ protected Object sliceCapture(VirtualFrame frame, Object string, RubyRegexp rege
818818
@Cached ReadCallerVariablesNode readCallerStorageNode,
819819
@Cached ConditionProfile unsetProfile,
820820
@Cached ConditionProfile sameThreadProfile,
821+
@Cached ConditionProfile notMatchedProfile,
822+
@Cached ConditionProfile captureSetProfile,
821823
@Cached StringDupAsStringInstanceNode dupNode) {
822824
final Object capture = RubyGuards.wasProvided(maybeCapture) ? maybeCapture : 0;
823825
final Object matchStrPair = callNode.call(
@@ -828,13 +830,19 @@ protected Object sliceCapture(VirtualFrame frame, Object string, RubyRegexp rege
828830
capture);
829831

830832
final SpecialVariableStorage variables = readCallerStorageNode.execute(frame);
831-
if (matchStrPair == nil) {
833+
if (notMatchedProfile.profile(matchStrPair == nil)) {
832834
variables.setLastMatch(nil, getContext(), unsetProfile, sameThreadProfile);
833835
return nil;
834836
} else {
835837
final Object[] array = (Object[]) ((RubyArray) matchStrPair).store;
836-
variables.setLastMatch(array[0], getContext(), unsetProfile, sameThreadProfile);
837-
return dupNode.executeDupAsStringInstance(array[1]);
838+
final Object matchData = array[0];
839+
final Object captureStringOrNil = array[1];
840+
variables.setLastMatch(matchData, getContext(), unsetProfile, sameThreadProfile);
841+
if (captureSetProfile.profile(captureStringOrNil != nil)) {
842+
return dupNode.executeDupAsStringInstance(captureStringOrNil);
843+
} else {
844+
return nil;
845+
}
838846
}
839847
}
840848

0 commit comments

Comments
 (0)