Bug #17119
closedString#partition and #rpartition return wrong result for Regexp patterns containing /\K/
Description
When the Regexp pattern given to String#partition
and String#rpartition
contain a /\K/
(lookbehind) operator, the methods return strings sliced at incorrect positions.
# expected -- partitioned at "c" following "b"
"abcdbce".partition(/b\Kc/) # => ["ab", "c", "dbce"]
"abcdbce".rpartition(/b\Kc/) # => ["abcdb", "c", "e"]
# actual -- results are not partitions
"abcdbce".partition(/b\Kc/) # => ["a", "c", "cdbce"]
"abcdbce".rpartition(/b\Kc/) # => ["abcd", "c", "ce"]
Updated by hanazuki (Kasumi Hanazuki) almost 4 years ago
Updated by hanazuki (Kasumi Hanazuki) almost 4 years ago
- Status changed from Open to Closed
Applied in changeset git|5d71eed1a7f0a70db013de59cd7e95bdca0d5c0e.
rb_str_{partition,rpartition}_m: Handle /\K/ in pattern
When the pattern given to String#partition and String#rpartition
contain a /\K/ (lookbehind) operator, the methods return strings
sliced at incorrect positions.
# without patch
"abcdbce".partition(/b\Kc/) # => ["a", "c", "cdbce"]
"abcdbce".rpartition(/b\Kc/) # => ["abcd", "c", "ce"]
This patch fixes the problem by using BEG(0) instead of the return
value of rb_reg_search.
# with patch
"abcdbce".partition(/b\Kc/) # => ["ab", "c", "dbce"]
"abcdbce".rpartition(/b\Kc/) # => ["abcdb", "c", "e"]
As a side-effect this patch makes String#partition 2x faster when the
pattern is a costly Regexp by performing Regexp search only once,
which was unexpectedly done twice in the original implementation.
Fixes [Bug #17119]