@marcel91200 / caddy Mirror · read-only / commits / fbc88ae2
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 04:45 UTC

internal: fix `MaxSizeSubjectsListForLog` off-by-one when `maxToDisplay` is `0` (#7970)

* internal: fix MaxSizeSubjectsListForLog off-by-one when maxToDisplay is 0 The loop appended before checking the length, so with maxToDisplay=0 one domain leaked into the output before the break check. Reorder so the length check comes first. Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * Update internal/logs.go Co-authored-by: Zen Dodd <mail@steadytao.com> Signed-off-by: Mohammed Al Sahaf <mohammed@caffeinatedwonders.com> * fix doc Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> --------- Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> Signed-off-by: Mohammed Al Sahaf <mohammed@caffeinatedwonders.com> Co-authored-by: Zen Dodd <mail@steadytao.com>

Mohammed Al Sahaf committed Sep 26, 2026 at 11:51 UTC fbc88ae2322082b55aef52e0209a0bc56166eca6
2 files changed +39 -5
internal/logs.go
+5 -5
@@ -2,18 +2,18 @@ package internal
2
3 import "fmt"
4
5 -// MaxSizeSubjectsListForLog returns the keys in the map as a slice of maximum length
6 -// maxToDisplay. It is useful for logging domains being managed, for example, since a
7 -// map is typically needed for quick lookup, but a slice is needed for logging, and this
8 -// can be quite a doozy since there may be a huge amount (hundreds of thousands).
5 +// MaxSizeSubjectsListForLog returns up to maxToDisplay keys from subjects.
6 +// If any keys are omitted, it appends one additional entry summarising the
7 +// omitted count. This bounds the number of subject names placed in the log
8 +// while making truncation explicit.
9 func MaxSizeSubjectsListForLog(subjects map[string]struct{}, maxToDisplay int) []string {
10 numberOfNamesToDisplay := min(len(subjects), maxToDisplay)
11 domainsToDisplay := make([]string, 0, numberOfNamesToDisplay)
12 for domain := range subjects {
13 - domainsToDisplay = append(domainsToDisplay, domain)
13 if len(domainsToDisplay) >= numberOfNamesToDisplay {
14 break
15 }
16 + domainsToDisplay = append(domainsToDisplay, domain)
17 }
18 if len(subjects) > maxToDisplay {
19 domainsToDisplay = append(domainsToDisplay, fmt.Sprintf("(and %d more...)", len(subjects)-maxToDisplay))
internal/logs_test.go new
+34
@@ -0,0 +1,34 @@
1 +// Copyright 2015 Matthew Holt and The Caddy Authors
2 +//
3 +// Licensed under the Apache License, Version 2.0 (the "License");
4 +// you may not use this file except in compliance with the License.
5 +// You may obtain a copy of the License at
6 +//
7 +// http://www.apache.org/licenses/LICENSE-2.0
8 +//
9 +// Unless required by applicable law or agreed to in writing, software
10 +// distributed under the License is distributed on an "AS IS" BASIS,
11 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 +// See the License for the specific language governing permissions and
13 +// limitations under the License.
14 +
15 +package internal
16 +
17 +import "testing"
18 +
19 +// TestMaxSizeSubjectsListForLog_MaxIsZero is the regression test for
20 +// the off-by-one where a domain leaked into the output when maxToDisplay
21 +// was 0.
22 +func TestMaxSizeSubjectsListForLog_MaxIsZero(t *testing.T) {
23 + subjects := map[string]struct{}{
24 + "a.com": {},
25 + "b.com": {},
26 + }
27 + got := MaxSizeSubjectsListForLog(subjects, 0)
28 + if len(got) != 1 {
29 + t.Fatalf("expected only the suffix entry, got %d items: %v", len(got), got)
30 + }
31 + if len(got[0]) < 4 || got[0][:4] != "(and" {
32 + t.Errorf("expected the only entry to be the '(and N more...)' suffix, got %q", got[0])
33 + }
34 +}