Repository: caddyserver/caddy (language: go)

Issue:
fuzz-tokenize: Slice bounds out of range in caddyfile.(*lexer).next
Reported at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61620

Detailed Report: https://oss-fuzz.com/testcase?key=4886037758083072

Project: caddy
Fuzzing Engine: libFuzzer
Fuzz Target: fuzz-tokenize
Job Type: libfuzzer_asan_caddy
Platform Id: linux

Crash Type: Slice bounds out of range
Crash Address: 
Crash State:
  caddyfile.(*lexer).next
  caddyfile.Tokenize
 
Sanitizer: address (ASAN)

Regressed: https://oss-fuzz.com/revisions?job=libfuzzer_asan_caddy&range=202308190620:202308200626

Reproducer Testcase: https://oss-fuzz.com/download?testcase_id=4886037758083072

Stack trace:
```


goroutine 17 [running, locked to thread]:
--
  | github.com/caddyserver/caddy/v2/caddyconfig/caddyfile.(*lexer).next(0x10c00007ad40)
  | github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer.go:158 +0x1cf5
  | github.com/caddyserver/caddy/v2/caddyconfig/caddyfile.Tokenize({0x6020000000b0, 0x3, 0x3}, {0xeffca7, 0x9})
  | github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer.go:63 +0x1b1
  | github.com/caddyserver/caddy/v2/caddyconfig/caddyfile.FuzzTokenize({0x6020000000b0?, 0x0?, 0x1?})
  | github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer_fuzz.go:20 +0x4b
```

[clusterfuzz-testcase-minimized-fuzz-tokenize-4886037758083072.txt](https://github.com/caddyserver/caddy/files/12389311/clusterfuzz-testcase-minimized-fuzz-tokenize-4886037758083072.txt)



Discussion / hints:

Fix patch:
diff --git a/caddyconfig/caddyfile/lexer.go b/caddyconfig/caddyfile/lexer.go
index 6f72b5d7bf4..bfd6c0f50bd 100644
--- a/caddyconfig/caddyfile/lexer.go
+++ b/caddyconfig/caddyfile/lexer.go
@@ -154,6 +154,10 @@ func (l *lexer) next() (bool, error) {
 			// we reset the val because the heredoc is syntax we don't
 			// want to keep.
 			if ch == '\n' {
+				if len(val) == 2 {
+					return false, fmt.Errorf("missing opening heredoc marker on line #%d; must contain only alpha-numeric characters, dashes and underscores; got empty string", l.line)
+				}
+
 				// check if there's too many <
 				if string(val[:3]) == "<<<" {
 					return false, fmt.Errorf("too many '<' for heredoc on line #%d; only use two, for example <<END", l.line)


Test patch:
diff --git a/caddyconfig/caddyfile/lexer_test.go b/caddyconfig/caddyfile/lexer_test.go
index ce2f533d7d8..92acc4da9f3 100644
--- a/caddyconfig/caddyfile/lexer_test.go
+++ b/caddyconfig/caddyfile/lexer_test.go
@@ -409,6 +409,11 @@ EOF same-line-arg
 				},
 			},
 		},
+		{
+			input:        []byte("not-a-heredoc <<\n"),
+			expectErr:    true,
+			errorMessage: "missing opening heredoc marker on line #1; must contain only alpha-numeric characters, dashes and underscores; got empty string",
+		},
 		{
 			input: []byte(`heredoc <<<EOF
 	content