Skip to content

Commit

Permalink
cmd/asm: fix potential infinite loop in parser
Browse files Browse the repository at this point in the history
For ARM machines, the assembler supports list of registers
operands such as [R1,R2].

A list missing a ']' results in the parser issuing many errors
and consuming all the tokens. At EOF (i.e. end of the line),
it still loops.

Normally, a counter is maintained to make sure the parser
stops after 10 errors. However, multiple errors occuring on the
same line are simply ignored. Only the first one is reported.
At most one error per line is accounted.

Missing ']' in a register list therefore results in an
infinite loop.

Fixed the parser by explicitly checking for ']' to interrupt
this loops

In the operand tests, also fixed a wrong entry which I think was
not set on purpose (but still led to a successful result).

Fixes #11764

Change-Id: Ie87773388ee0d21b3a2a4cb941d4d911d0230ba4
Reviewed-on: https://go-review.googlesource.com/13920
Reviewed-by: Rob Pike <[email protected]>
  • Loading branch information
dspezia authored and robpike committed Aug 27, 2015
1 parent be33e20 commit 7437e3f
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/cmd/asm/internal/asm/operand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ var amd64OperandTests = []operandTest{
{"x·y+8(SB)", "x.y+8(SB)"},
{"x·y+8(SP)", "x.y+8(SP)"},
{"y+56(FP)", "y+56(FP)"},
{"·AddUint32(SB", "\"\".AddUint32(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·callReflect(SB)", "\"\".callReflect(SB)"},
}

Expand Down Expand Up @@ -288,6 +288,7 @@ var armOperandTests = []operandTest{
{"runtime·_sfloat2(SB)", "runtime._sfloat2(SB)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"(R1, R3)", "(R1, R3)"},
{"[R0,R1,g,R15", ""}, // Issue 11764 - previously asm just hung parsing ']' missing register lists
}

var ppc64OperandTests = []operandTest{
Expand Down
9 changes: 7 additions & 2 deletions src/cmd/asm/internal/asm/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,10 +698,15 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
func (p *Parser) registerList(a *obj.Addr) {
// One range per loop.
var bits uint16
ListLoop:
for {
tok := p.next()
if tok.ScanToken == ']' {
break
switch tok.ScanToken {
case ']':
break ListLoop
case scanner.EOF:
p.errorf("missing ']' in register list")
return
}
lo := p.registerNumber(tok.String())
hi := lo
Expand Down

0 comments on commit 7437e3f

Please sign in to comment.