mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-06 22:40:31 -05: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 {
|
||||
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{}{
|
||||
|
|
Loading…
Reference in a new issue