Skip to content

Commit

Permalink
Fix that "ab" =~ /(?!^a).*b/ didn't match (Issue #44)
Browse files Browse the repository at this point in the history
See also: https://bugs.ruby-lang.org/issues/9728

Optimization for '.*' was wrong. Optimization should be disabled not
only for /(?<=x).*/ but also for /(?!x).*/.
  • Loading branch information
k-takata committed Sep 1, 2014
1 parent 76baf02 commit 15ddec6
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
10 changes: 7 additions & 3 deletions regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4512,6 +4512,9 @@ concat_opt_anc_info(OptAncInfo* to, OptAncInfo* left, OptAncInfo* right,
if (right_len == 0) {
to->right_anchor |= left->right_anchor;
}
else {
to->right_anchor |= (left->right_anchor & ANCHOR_PREC_READ_NOT);
}
}

static int
Expand Down Expand Up @@ -5085,7 +5088,8 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
case ANCHOR_END_BUF:
case ANCHOR_SEMI_END_BUF:
case ANCHOR_END_LINE:
case ANCHOR_LOOK_BEHIND: /* just for (?<=x).* */
case ANCHOR_LOOK_BEHIND: /* just for (?<=x).* */
case ANCHOR_PREC_READ_NOT: /* just for (?!x).* */
add_opt_anc_info(&opt->anc, NANCHOR(node)->type);
break;

Expand All @@ -5108,7 +5112,6 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;

case ANCHOR_PREC_READ_NOT:
case ANCHOR_LOOK_BEHIND_NOT:
break;
}
Expand Down Expand Up @@ -5374,7 +5377,8 @@ set_optimize_info_from_tree(Node* node, regex_t* reg, ScanEnv* scan_env)
ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML |
ANCHOR_LOOK_BEHIND);

reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF);
reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
ANCHOR_PREC_READ_NOT);

if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
reg->anchor_dmin = opt.len.min;
Expand Down
2 changes: 1 addition & 1 deletion regexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -4188,7 +4188,7 @@ onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end,
prev = s;
s += enclen(reg->enc, s);

if ((reg->anchor & ANCHOR_LOOK_BEHIND) == 0) {
if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {
while (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)
&& s < range) {
prev = s;
Expand Down

0 comments on commit 15ddec6

Please sign in to comment.