~charles/logquery

e9a8326b4a115853828b0add25e34393aa562264 — Charles Daniels 3 years ago 0212c9e
fix a bug which could cause an infinite loop on an improperly terminated quoted string
2 files changed, 51 insertions(+), 0 deletions(-)

M parser/parser.go
M parser/parser_test.go
M parser/parser.go => parser/parser.go +4 -0
@@ 157,6 157,10 @@ func (p *Parser) next() (rune, error) {
// Used by NextRecord to advance to the start of the next line, or EOF. Non-EOF
// errors are propagated.
func (p *Parser) readUntilNewLine() error {
	if p.iseof {
		return nil
	}

	for p.current != '\n' {
		_, err := p.next()
		if err == io.EOF {

M parser/parser_test.go => parser/parser_test.go +47 -0
@@ 61,6 61,53 @@ func Test_MultiLineString(t *testing.T) {
	assert.True(t, IsSyntaxError(err))
}

func Test_MixedQuotes(t *testing.T) {
	// Strings with another quoted string inside should be OK, as long as
	// the outer string is property terminated.

	p, err := NewParserFromString("key=\"abc 'xyz'\"")
	assert.Nil(t, err)

	rec, err := p.NextRecord()
	assert.Nil(t, err)

	expect := map[string]interface{}{
		"key": "abc 'xyz'",
	}
	assert.Equal(t, expect, rec)

	p, err = NewParserFromString("key='abc \"xyz\"'")
	assert.Nil(t, err)

	rec, err = p.NextRecord()
	assert.Nil(t, err)

	expect = map[string]interface{}{
		"key": "abc \"xyz\"",
	}
	assert.Equal(t, expect, rec)

	// It's OK if the inner string isn't quoted propertly
	p, err = NewParserFromString("key=\"abc 'xyz 123\"")
	assert.Nil(t, err)

	rec, err = p.NextRecord()
	assert.Nil(t, err)

	expect = map[string]interface{}{
		"key": "abc 'xyz 123",
	}
	assert.Equal(t, expect, rec)

	// We can't mix the outer quotes though.
	p, err = NewParserFromString("key=\"abc'")
	assert.Nil(t, err)

	rec, err = p.NextRecord()
	assert.NotNil(t, err)
	assert.True(t, IsSyntaxError(err))
}

func Test_IllegalKeys(t *testing.T) {
	// A string with an un-escaped newline in it should be a syntax error.
	p, err := NewParserFromString("'=foo'\n';foo'\n'\"foo'\n\"'\"foo\nfoo")