|
1 From 97ec0a816bfe1f8488355b5a6e94907a993b2cc7 Mon Sep 17 00:00:00 2001 |
|
2 From: Didier Spezia <[email protected]> |
|
3 Date: Tue, 25 Aug 2015 16:25:11 +0000 |
|
4 Subject: [PATCH 07/63] [release-branch.go1.5] cmd/asm: fix potential infinite |
|
5 loop in parser |
|
6 |
|
7 For ARM machines, the assembler supports list of registers |
|
8 operands such as [R1,R2]. |
|
9 |
|
10 A list missing a ']' results in the parser issuing many errors |
|
11 and consuming all the tokens. At EOF (i.e. end of the line), |
|
12 it still loops. |
|
13 |
|
14 Normally, a counter is maintained to make sure the parser |
|
15 stops after 10 errors. However, multiple errors occuring on the |
|
16 same line are simply ignored. Only the first one is reported. |
|
17 At most one error per line is accounted. |
|
18 |
|
19 Missing ']' in a register list therefore results in an |
|
20 infinite loop. |
|
21 |
|
22 Fixed the parser by explicitly checking for ']' to interrupt |
|
23 this loops |
|
24 |
|
25 In the operand tests, also fixed a wrong entry which I think was |
|
26 not set on purpose (but still led to a successful result). |
|
27 |
|
28 Fixes #11764 |
|
29 |
|
30 Change-Id: Ie87773388ee0d21b3a2a4cb941d4d911d0230ba4 |
|
31 Reviewed-on: https://go-review.googlesource.com/13920 |
|
32 Reviewed-by: Rob Pike <[email protected]> |
|
33 Reviewed-on: https://go-review.googlesource.com/14225 |
|
34 --- |
|
35 src/cmd/asm/internal/asm/operand_test.go | 3 ++- |
|
36 src/cmd/asm/internal/asm/parse.go | 9 +++++++-- |
|
37 2 files changed, 9 insertions(+), 3 deletions(-) |
|
38 |
|
39 diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go |
|
40 index b9154a9..01335ed 100644 |
|
41 --- a/src/cmd/asm/internal/asm/operand_test.go |
|
42 +++ b/src/cmd/asm/internal/asm/operand_test.go |
|
43 @@ -181,7 +181,7 @@ var amd64OperandTests = []operandTest{ |
|
44 {"x·y+8(SB)", "x.y+8(SB)"}, |
|
45 {"x·y+8(SP)", "x.y+8(SP)"}, |
|
46 {"y+56(FP)", "y+56(FP)"}, |
|
47 - {"·AddUint32(SB", "\"\".AddUint32(SB)"}, |
|
48 + {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, |
|
49 {"·callReflect(SB)", "\"\".callReflect(SB)"}, |
|
50 } |
|
51 |
|
52 @@ -288,6 +288,7 @@ var armOperandTests = []operandTest{ |
|
53 {"runtime·_sfloat2(SB)", "runtime._sfloat2(SB)"}, |
|
54 {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, |
|
55 {"(R1, R3)", "(R1, R3)"}, |
|
56 + {"[R0,R1,g,R15", ""}, // Issue 11764 - previously asm just hung parsing ']' missing register lists |
|
57 } |
|
58 |
|
59 var ppc64OperandTests = []operandTest{ |
|
60 diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go |
|
61 index c07e6f8..6cf50df 100644 |
|
62 --- a/src/cmd/asm/internal/asm/parse.go |
|
63 +++ b/src/cmd/asm/internal/asm/parse.go |
|
64 @@ -698,10 +698,15 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) { |
|
65 func (p *Parser) registerList(a *obj.Addr) { |
|
66 // One range per loop. |
|
67 var bits uint16 |
|
68 +ListLoop: |
|
69 for { |
|
70 tok := p.next() |
|
71 - if tok.ScanToken == ']' { |
|
72 - break |
|
73 + switch tok.ScanToken { |
|
74 + case ']': |
|
75 + break ListLoop |
|
76 + case scanner.EOF: |
|
77 + p.errorf("missing ']' in register list") |
|
78 + return |
|
79 } |
|
80 lo := p.registerNumber(tok.String()) |
|
81 hi := lo |
|
82 -- |
|
83 2.6.1 |
|
84 |