Skip to content

Commit 90d0f4a

Browse files
committed
Fix escaping in quoted str
1 parent 7d51f2c commit 90d0f4a

File tree

3 files changed

+84
-42
lines changed

3 files changed

+84
-42
lines changed

dsl/scanners.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -231,22 +231,31 @@ func (s *ScanQuoted) Process() {
231231
}
232232

233233
var e rune = '\\'
234-
escaped := 0
234+
escaped := false
235235
buf := bytes.NewBufferString(string(q))
236236
dataLen := len(tok.File.Data)
237237
for i := tok.Pos + 1; i < dataLen; i++ {
238238
r := rune(tok.File.Data[i])
239239
if r == e {
240-
escaped = (escaped + 1) % 2
241-
if escaped == 1 {
240+
if escaped {
241+
buf.Truncate(buf.Len() - 1)
242+
escaped = false
243+
} else {
244+
buf.WriteRune(r)
245+
escaped = true
242246
continue
243247
}
244248
}
245-
buf.WriteRune(r)
246-
if r == q && escaped == 0 {
247-
break
249+
if r == q {
250+
if escaped {
251+
buf.Truncate(buf.Len() - 1)
252+
} else {
253+
buf.WriteRune(r)
254+
break
255+
}
248256
}
249-
escaped = 0
257+
buf.WriteRune(r)
258+
escaped = false
250259
}
251260
tok.Value = buf.String()
252261
tok.Type = TokenType(tokenType)

dsl/scanners_test.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ func TestScanners(t *testing.T) { //nolint:funlen // table data
243243
hit: true,
244244
value: `"This is an IIP\"`,
245245
},
246+
{
247+
c: "dsl/ScanQuoted",
248+
name: "Should not escape other chars",
249+
set: `"`,
250+
tokType: tokQuotedStr,
251+
data: `"End\r\n" -> IN Foo`,
252+
pos: 0,
253+
hit: true,
254+
value: `"End\r\n"`,
255+
},
246256
{
247257
c: "dsl/ScanQuoted",
248258
name: "Does not work without quote char",
@@ -338,11 +348,8 @@ func runScannersTestCase(t *testing.T, f *goflow.Factory, tc *scannersTestCase)
338348
if !tc.hit {
339349
t.Errorf("Unexpected hit: '%s' at %d", tok.Value, tok.Pos)
340350
}
341-
if tok.Type != tc.tokType {
342-
t.Errorf("Unexpected token type: %s", tok.Type)
343-
}
344-
if tok.Value != tc.value {
345-
t.Errorf("Unexpected token value: '%s'", tok.Value)
351+
if tc.tokType != tok.Type || tc.value != tok.Value || tc.pos != tok.Pos {
352+
t.Errorf("Unexpected token, expected %s '%s', got %s '%s'", tc.tokType, tc.value, tok.Type, tok.Value)
346353
}
347354
}
348355

dsl/tokenizer_test.go

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,46 @@ import (
66
"github.com/trustmaster/goflow"
77
)
88

9-
// StartToken(dsl/StartToken) INIT -> Merge.
9+
type tokenizerTestCase struct {
10+
fbp string
11+
tokens []Token
12+
}
13+
1014
func TestTokenizer(t *testing.T) {
11-
fbpData := "StartToken(dsl/StartToken) INIT -> Merge"
12-
expected := []Token{
13-
{Type: tokNewFile, Pos: 0, Value: "test.fbp"},
14-
{Type: tokIdent, Pos: 0, Value: "StartToken"},
15-
{Type: tokLparen, Pos: 10, Value: "("},
16-
{Type: tokIdent, Pos: 11, Value: "dsl"},
17-
{Type: tokSlash, Pos: 14, Value: "/"},
18-
{Type: tokIdent, Pos: 15, Value: "StartToken"},
19-
{Type: tokRparen, Pos: 25, Value: ")"},
20-
{Type: tokWhitespace, Pos: 26, Value: " "},
21-
{Type: tokIdent, Pos: 27, Value: "INIT"},
22-
{Type: tokWhitespace, Pos: 31, Value: " "},
23-
{Type: tokArrow, Pos: 32, Value: "->"},
24-
{Type: tokWhitespace, Pos: 34, Value: " "},
25-
{Type: tokIdent, Pos: 35, Value: "Merge"},
26-
{Type: tokEOF, Pos: 40, Value: "test.fbp"},
15+
cases := []tokenizerTestCase{
16+
{
17+
fbp: "StartToken(dsl/StartToken) INIT -> Merge",
18+
tokens: []Token{
19+
{Type: tokNewFile, Pos: 0, Value: "test.fbp"},
20+
{Type: tokIdent, Pos: 0, Value: "StartToken"},
21+
{Type: tokLparen, Pos: 10, Value: "("},
22+
{Type: tokIdent, Pos: 11, Value: "dsl"},
23+
{Type: tokSlash, Pos: 14, Value: "/"},
24+
{Type: tokIdent, Pos: 15, Value: "StartToken"},
25+
{Type: tokRparen, Pos: 25, Value: ")"},
26+
{Type: tokWhitespace, Pos: 26, Value: " "},
27+
{Type: tokIdent, Pos: 27, Value: "INIT"},
28+
{Type: tokWhitespace, Pos: 31, Value: " "},
29+
{Type: tokArrow, Pos: 32, Value: "->"},
30+
{Type: tokWhitespace, Pos: 34, Value: " "},
31+
{Type: tokIdent, Pos: 35, Value: "Merge"},
32+
{Type: tokEOF, Pos: 40, Value: "test.fbp"},
33+
},
34+
},
35+
{
36+
fbp: `'\r\n' -> SET ScanEOL`,
37+
tokens: []Token{
38+
{Type: tokNewFile, Pos: 0, Value: "test.fbp"},
39+
{Type: tokQuotedStr, Pos: 0, Value: `'\r\n'`},
40+
{Type: tokWhitespace, Pos: 6, Value: " "},
41+
{Type: tokArrow, Pos: 7, Value: "->"},
42+
{Type: tokWhitespace, Pos: 9, Value: " "},
43+
{Type: tokIdent, Pos: 10, Value: "SET"},
44+
{Type: tokWhitespace, Pos: 13, Value: " "},
45+
{Type: tokIdent, Pos: 14, Value: "ScanEOL"},
46+
{Type: tokEOF, Pos: 21, Value: "test.fbp"},
47+
},
48+
},
2749
}
2850

2951
f := goflow.NewFactory()
@@ -32,18 +54,22 @@ func TestTokenizer(t *testing.T) {
3254
return
3355
}
3456

35-
i, err := f.Create("dsl/Tokenizer")
36-
if err != nil {
37-
t.Error(err)
38-
return
39-
}
57+
for i := range cases {
58+
c := cases[i]
59+
60+
ni, err := f.Create("dsl/Tokenizer")
61+
if err != nil {
62+
t.Error(err)
63+
return
64+
}
4065

41-
n := i.(*goflow.Graph)
66+
n := ni.(*goflow.Graph)
4267

43-
runTokenizerTestCase(t, n, fbpData, expected)
68+
runTokenizerTestCase(t, n, &c)
69+
}
4470
}
4571

46-
func runTokenizerTestCase(t *testing.T, n *goflow.Graph, fbpData string, expected []Token) {
72+
func runTokenizerTestCase(t *testing.T, n *goflow.Graph, c *tokenizerTestCase) {
4773
in := make(chan *File)
4874
out := make(chan Token)
4975

@@ -59,7 +85,7 @@ func runTokenizerTestCase(t *testing.T, n *goflow.Graph, fbpData string, expecte
5985

6086
file := &File{
6187
Name: "test.fbp",
62-
Data: []byte(fbpData),
88+
Data: []byte(c.fbp),
6389
}
6490

6591
wait := goflow.Run(n)
@@ -72,14 +98,14 @@ func runTokenizerTestCase(t *testing.T, n *goflow.Graph, fbpData string, expecte
7298
j := 0
7399

74100
for tok := range out {
75-
if !tokEql(tok, expected[j]) {
76-
t.Errorf("Expected '%s': '%s' at %d, got '%s': '%s' at %d", expected[j].Type, expected[j].Value, expected[j].Pos, tok.Type, tok.Value, tok.Pos)
101+
if !tokEql(tok, c.tokens[j]) {
102+
t.Errorf("Expected '%s': '%s' at %d, got '%s': '%s' at %d", c.tokens[j].Type, c.tokens[j].Value, c.tokens[j].Pos, tok.Type, tok.Value, tok.Pos)
77103
}
78104
j++
79105
}
80106

81-
if j != len(expected) {
82-
t.Errorf("Expected %d tokens, got %d", len(expected), j)
107+
if j != len(c.tokens) {
108+
t.Errorf("Expected %d tokens, got %d", len(c.tokens), j)
83109
}
84110

85111
<-wait

0 commit comments

Comments
 (0)