Commit d8c50264 authored by Matthew Holt's avatar Matthew Holt

Fix parser when address is empty token

Bug detected by go-fuzz (more fuzzing is required; need larger corpus)
parent 8d81ae88
......@@ -36,6 +36,9 @@ func Load(filename string, input io.Reader) (Group, error) {
if err != nil {
return nil, err
}
if len(serverBlocks) == 0 {
return Default()
}
// Each server block represents one or more servers/addresses.
// Iterate each server block and make a config for each one,
......
......@@ -21,7 +21,9 @@ func (p *parser) parseAll() ([]ServerBlock, error) {
if err != nil {
return blocks, err
}
blocks = append(blocks, p.block)
if len(p.block.Addresses) > 0 {
blocks = append(blocks, p.block)
}
}
return blocks, nil
......@@ -85,21 +87,23 @@ func (p *parser) addresses() error {
break
}
// Trailing comma indicates another address will follow, which
// may possibly be on the next line
if tkn[len(tkn)-1] == ',' {
tkn = tkn[:len(tkn)-1]
expectingAnother = true
} else {
expectingAnother = false // but we may still see another one on this line
}
if tkn != "" {
// Trailing comma indicates another address will follow, which
// may possibly be on the next line
if tkn[len(tkn)-1] == ',' {
tkn = tkn[:len(tkn)-1]
expectingAnother = true
} else {
expectingAnother = false // but we may still see another one on this line
}
// Parse and save this address
host, port, err := standardAddress(tkn)
if err != nil {
return err
// Parse and save this address
host, port, err := standardAddress(tkn)
if err != nil {
return err
}
p.block.Addresses = append(p.block.Addresses, Address{host, port})
}
p.block.Addresses = append(p.block.Addresses, Address{host, port})
// Advance token and possibly break out of loop or return error
hasNext := p.Next()
......
......@@ -61,7 +61,7 @@ func TestParseOneAndImport(t *testing.T) {
testParseOne := func(input string) (ServerBlock, error) {
p := testParser(input)
p.Next()
p.Next() // parseOne doesn't call Next() to start, so we must
err := p.parseOne()
return p.block, err
}
......@@ -234,6 +234,10 @@ func TestParseOneAndImport(t *testing.T) {
"dir1": 1,
"dir2": 2,
}},
{``, false, []Address{}, map[string]int{}},
{`""`, false, []Address{}, map[string]int{}},
} {
result, err := testParseOne(test.input)
......@@ -275,6 +279,62 @@ func TestParseOneAndImport(t *testing.T) {
}
}
func TestParseAll(t *testing.T) {
setupParseTests()
testParseAll := func(input string) ([]ServerBlock, error) {
p := testParser(input)
return p.parseAll()
}
for i, test := range []struct {
input string
shouldErr bool
numBlocks int
}{
{`localhost`, false, 1},
{`localhost {
dir1
}`, false, 1},
{`http://localhost https://localhost
dir1 foo bar`, false, 1},
{`http://localhost, https://localhost {
dir1 foo bar
}`, false, 1},
{`http://host1.com,
http://host2.com,
https://host3.com`, false, 1},
{`host1 {
}
host2 {
}`, false, 2},
{`""`, false, 0},
{``, false, 0},
} {
results, err := testParseAll(test.input)
if test.shouldErr && err == nil {
t.Errorf("Test %d: Expected an error, but didn't get one", i)
}
if !test.shouldErr && err != nil {
t.Errorf("Test %d: Expected no error, but got: %v", i, err)
}
if len(results) != test.numBlocks {
t.Errorf("Test %d: Expected %d server blocks, got %d",
i, test.numBlocks, len(results))
continue
}
}
}
func setupParseTests() {
// Set up some bogus directives for testing
ValidDirectives = map[string]struct{}{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment