From 108af74b2435ba763fe5028cfb2eb3489cde2543 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Tue, 21 Apr 2026 19:01:23 +0000 Subject: [PATCH] fix: return 'invalid' from Level.String instead of panicking on InvalidLevel Level.String indexed levelNames directly, which is a fixed array keyed by the DebugLevel..FatalLevel block. An InvalidLevel value (-1, e.g. from a zero-value pointer or a failed ParseLevel that the caller did not error-check) therefore sliced levelNames[-1] and produced 'index out of range'. MarshalJSON wraps String, so any JSON encoder touching a Level field that was never explicitly set crashes the host process instead of surfacing a useful error (#75). Bounds-check l against the valid Debug..Fatal span and return 'invalid' for anything outside it. Valid Debug..Fatal values keep their existing names byte-for-byte. Closes #75 Signed-off-by: SAY-5 --- levels.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/levels.go b/levels.go index 7d43a43..f4aba5b 100644 --- a/levels.go +++ b/levels.go @@ -41,6 +41,16 @@ var levelStrings = map[string]Level{ // String implementation. func (l Level) String() string { + // InvalidLevel (-1) and any unknown level above FatalLevel fall + // outside the levelNames array, so unguarded indexing used to + // panic with 'index out of range' whenever a zero-value or + // unexpected Level flowed into String - notably through + // MarshalJSON on a field that was never explicitly set (#75). + // Return "invalid" in those cases instead of crashing; the + // in-range levels still round-trip as before. + if l < DebugLevel || int(l) >= len(levelNames) { + return "invalid" + } return levelNames[l] }