1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:44:39 -07:00

regexp: reject bare ?

Minor cleanup:
  - removed a duplicate test case
  - added a function to remove repeated code
  - for consistency, replaced "return nil" with a panic at an
    unreachable point

Fixes #1428.

R=golang-dev, r, rsc
CC=golang-dev
https://golang.org/cl/4057042
This commit is contained in:
Ben Lynn 2011-01-19 13:47:04 -05:00 committed by Russ Cox
parent 1d1f1192d9
commit eb56a79e99
2 changed files with 24 additions and 29 deletions

View File

@ -38,6 +38,8 @@ type stringError struct {
var bad_re = []stringError{ var bad_re = []stringError{
{`*`, ErrBareClosure}, {`*`, ErrBareClosure},
{`+`, ErrBareClosure},
{`?`, ErrBareClosure},
{`(abc`, ErrUnmatchedLpar}, {`(abc`, ErrUnmatchedLpar},
{`abc)`, ErrUnmatchedRpar}, {`abc)`, ErrUnmatchedRpar},
{`x[a-z`, ErrUnmatchedLbkt}, {`x[a-z`, ErrUnmatchedLbkt},
@ -47,7 +49,6 @@ var bad_re = []stringError{
{`a**`, ErrBadClosure}, {`a**`, ErrBadClosure},
{`a*+`, ErrBadClosure}, {`a*+`, ErrBadClosure},
{`a??`, ErrBadClosure}, {`a??`, ErrBadClosure},
{`*`, ErrBareClosure},
{`\x`, ErrBadBackslash}, {`\x`, ErrBadBackslash},
} }

View File

@ -283,6 +283,24 @@ func escape(c int) int {
return -1 return -1
} }
func (p *parser) checkBackslash() int {
c := p.c()
if c == '\\' {
c = p.nextc()
switch {
case c == endOfFile:
p.error(ErrExtraneousBackslash)
case ispunct(c):
// c is as delivered
case escape(c) >= 0:
c = int(escaped[escape(c)])
default:
p.error(ErrBadBackslash)
}
}
return c
}
func (p *parser) charClass() *instr { func (p *parser) charClass() *instr {
i := newCharClass() i := newCharClass()
cc := i.cclass cc := i.cclass
@ -314,20 +332,8 @@ func (p *parser) charClass() *instr {
return i return i
case '-': // do this before backslash processing case '-': // do this before backslash processing
p.error(ErrBadRange) p.error(ErrBadRange)
case '\\':
c = p.nextc()
switch {
case c == endOfFile:
p.error(ErrExtraneousBackslash)
case ispunct(c):
// c is as delivered
case escape(c) >= 0:
c = int(escaped[escape(c)])
default:
p.error(ErrBadBackslash)
}
fallthrough
default: default:
c = p.checkBackslash()
p.nextc() p.nextc()
switch { switch {
case left < 0: // first of pair case left < 0: // first of pair
@ -345,14 +351,14 @@ func (p *parser) charClass() *instr {
} }
} }
} }
return nil panic("unreachable")
} }
func (p *parser) term() (start, end *instr) { func (p *parser) term() (start, end *instr) {
switch c := p.c(); c { switch c := p.c(); c {
case '|', endOfFile: case '|', endOfFile:
return nil, nil return nil, nil
case '*', '+': case '*', '+', '?':
p.error(ErrBareClosure) p.error(ErrBareClosure)
case ')': case ')':
if p.nlpar == 0 { if p.nlpar == 0 {
@ -407,20 +413,8 @@ func (p *parser) term() (start, end *instr) {
} }
bra.next = start bra.next = start
return bra, ebra return bra, ebra
case '\\':
c = p.nextc()
switch {
case c == endOfFile:
p.error(ErrExtraneousBackslash)
case ispunct(c):
// c is as delivered
case escape(c) >= 0:
c = int(escaped[escape(c)])
default:
p.error(ErrBadBackslash)
}
fallthrough
default: default:
c = p.checkBackslash()
p.nextc() p.nextc()
start = &instr{kind: iChar, char: c} start = &instr{kind: iChar, char: c}
p.re.add(start) p.re.add(start)