mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-25 09:18:56 +01:00
Fix parser when address is empty token
Bug detected by go-fuzz (more fuzzing is required; need larger corpus)
This commit is contained in:
parent
8d81ae88da
commit
d8c50264cc
3 changed files with 82 additions and 15 deletions
|
@ -36,6 +36,9 @@ func Load(filename string, input io.Reader) (Group, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if len(serverBlocks) == 0 {
|
||||||
|
return Default()
|
||||||
|
}
|
||||||
|
|
||||||
// Each server block represents one or more servers/addresses.
|
// Each server block represents one or more servers/addresses.
|
||||||
// Iterate each server block and make a config for each one,
|
// Iterate each server block and make a config for each one,
|
||||||
|
|
|
@ -21,8 +21,10 @@ func (p *parser) parseAll() ([]ServerBlock, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return blocks, err
|
return blocks, err
|
||||||
}
|
}
|
||||||
|
if len(p.block.Addresses) > 0 {
|
||||||
blocks = append(blocks, p.block)
|
blocks = append(blocks, p.block)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return blocks, nil
|
return blocks, nil
|
||||||
}
|
}
|
||||||
|
@ -85,6 +87,7 @@ func (p *parser) addresses() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tkn != "" {
|
||||||
// Trailing comma indicates another address will follow, which
|
// Trailing comma indicates another address will follow, which
|
||||||
// may possibly be on the next line
|
// may possibly be on the next line
|
||||||
if tkn[len(tkn)-1] == ',' {
|
if tkn[len(tkn)-1] == ',' {
|
||||||
|
@ -100,6 +103,7 @@ func (p *parser) addresses() error {
|
||||||
return err
|
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
|
// Advance token and possibly break out of loop or return error
|
||||||
hasNext := p.Next()
|
hasNext := p.Next()
|
||||||
|
|
|
@ -61,7 +61,7 @@ func TestParseOneAndImport(t *testing.T) {
|
||||||
|
|
||||||
testParseOne := func(input string) (ServerBlock, error) {
|
testParseOne := func(input string) (ServerBlock, error) {
|
||||||
p := testParser(input)
|
p := testParser(input)
|
||||||
p.Next()
|
p.Next() // parseOne doesn't call Next() to start, so we must
|
||||||
err := p.parseOne()
|
err := p.parseOne()
|
||||||
return p.block, err
|
return p.block, err
|
||||||
}
|
}
|
||||||
|
@ -234,6 +234,10 @@ func TestParseOneAndImport(t *testing.T) {
|
||||||
"dir1": 1,
|
"dir1": 1,
|
||||||
"dir2": 2,
|
"dir2": 2,
|
||||||
}},
|
}},
|
||||||
|
|
||||||
|
{``, false, []Address{}, map[string]int{}},
|
||||||
|
|
||||||
|
{`""`, false, []Address{}, map[string]int{}},
|
||||||
} {
|
} {
|
||||||
result, err := testParseOne(test.input)
|
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() {
|
func setupParseTests() {
|
||||||
// Set up some bogus directives for testing
|
// Set up some bogus directives for testing
|
||||||
ValidDirectives = map[string]struct{}{
|
ValidDirectives = map[string]struct{}{
|
||||||
|
|
Loading…
Reference in a new issue