mirror of
https://github.com/golang/go
synced 2024-11-21 21:54:40 -07:00
regexp: fix prefix bug.
After a prefix match, the old code advanced the length of the prefix. This is incorrect since the full match might begin in the middle of the prefix. (Consider "aaaab+" matching "aaaaaab"). Fixes #1373 R=rsc CC=golang-dev https://golang.org/cl/3795044
This commit is contained in:
parent
c0d0d4ef05
commit
15cb7ed34f
@ -78,6 +78,7 @@ var findTests = []FindTest{
|
|||||||
{`axxb$`, "axxcb", nil},
|
{`axxb$`, "axxcb", nil},
|
||||||
{`data`, "daXY data", build(1, 5, 9)},
|
{`data`, "daXY data", build(1, 5, 9)},
|
||||||
{`da(.)a$`, "daXY data", build(1, 5, 9, 7, 8)},
|
{`da(.)a$`, "daXY data", build(1, 5, 9, 7, 8)},
|
||||||
|
{`zx+`, "zzx", build(1, 1, 3)},
|
||||||
|
|
||||||
// can backslash-escape any punctuation
|
// can backslash-escape any punctuation
|
||||||
{`\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~`,
|
{`\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~`,
|
||||||
|
@ -758,7 +758,6 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// fast check for initial plain substring
|
// fast check for initial plain substring
|
||||||
prefixed := false // has this iteration begun by skipping a prefix?
|
|
||||||
if re.prefix != "" {
|
if re.prefix != "" {
|
||||||
advance := 0
|
advance := 0
|
||||||
if anchored {
|
if anchored {
|
||||||
@ -781,8 +780,7 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
|
|||||||
if advance == -1 {
|
if advance == -1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
pos += advance + len(re.prefix)
|
pos += advance
|
||||||
prefixed = true
|
|
||||||
}
|
}
|
||||||
arena := &matchArena{nil, 2 * (re.nbra + 1)}
|
arena := &matchArena{nil, 2 * (re.nbra + 1)}
|
||||||
for pos <= end {
|
for pos <= end {
|
||||||
@ -790,12 +788,7 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
|
|||||||
// prime the pump if we haven't seen a match yet
|
// prime the pump if we haven't seen a match yet
|
||||||
match := arena.noMatch()
|
match := arena.noMatch()
|
||||||
match.m[0] = pos
|
match.m[0] = pos
|
||||||
if prefixed {
|
s[out] = arena.addState(s[out], re.start.next, false, match, pos, end)
|
||||||
s[out] = arena.addState(s[out], re.prefixStart, true, match, pos, end)
|
|
||||||
prefixed = false // next iteration should start at beginning of machine.
|
|
||||||
} else {
|
|
||||||
s[out] = arena.addState(s[out], re.start.next, false, match, pos, end)
|
|
||||||
}
|
|
||||||
arena.free(match) // if addState saved it, ref was incremented
|
arena.free(match) // if addState saved it, ref was incremented
|
||||||
}
|
}
|
||||||
in, out = out, in // old out state is new in state
|
in, out = out, in // old out state is new in state
|
||||||
|
Loading…
Reference in New Issue
Block a user