mirror of
https://github.com/TwiN/gatus.git
synced 2026-08-21 14:46:03 +00:00
fix(jsonpath): prevent panic on negative array index (#1703)
A jsonpath condition with a negative array index (e.g. [BODY].data[-1] or [BODY][-1]) reached array[arrayIndex] with a negative index because the len(array) > arrayIndex bounds checks are satisfied by any negative value, causing a 'runtime error: index out of range [-1]' panic. Since condition evaluation runs in the watchdog with no recover(), this would crash the process. Guard against negative indices alongside the existing strconv.Atoi error check so an out-of-range negative index returns nil (treated as an invalid path) instead of panicking. Adds tests for negative indices on keyed arrays, root arrays, and negative-index-followed-by-key. Made by an AI agent (Claude Code, model Claude Opus 4.8). Co-authored-by: TwiN <twin@linux.com>
This commit is contained in:
@@ -87,7 +87,7 @@ func extractValue(currentKey string, value interface{}) interface{} {
|
||||
}
|
||||
}
|
||||
arrayIndex, err := strconv.Atoi(index)
|
||||
if err != nil {
|
||||
if err != nil || arrayIndex < 0 {
|
||||
return nil
|
||||
}
|
||||
currentKeyWithoutIndex := currentKey[:startOfBracket]
|
||||
|
||||
@@ -174,6 +174,38 @@ func TestEval(t *testing.T) {
|
||||
ExpectedOutputLength: 18,
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "negative-index-on-keyed-array",
|
||||
Path: "data[-1]",
|
||||
Data: `{"data": [1, 2, 3]}`,
|
||||
ExpectedOutput: "",
|
||||
ExpectedOutputLength: 0,
|
||||
ExpectedError: true,
|
||||
},
|
||||
{
|
||||
Name: "negative-index-on-root-array",
|
||||
Path: "[-1]",
|
||||
Data: `[1, 2, 3]`,
|
||||
ExpectedOutput: "",
|
||||
ExpectedOutputLength: 0,
|
||||
ExpectedError: true,
|
||||
},
|
||||
{
|
||||
Name: "negative-index-followed-by-key",
|
||||
Path: "data[-1].name",
|
||||
Data: `{"data": [{"name": "value"}]}`,
|
||||
ExpectedOutput: "",
|
||||
ExpectedOutputLength: 0,
|
||||
ExpectedError: true,
|
||||
},
|
||||
{
|
||||
Name: "negative-index-nested-array",
|
||||
Path: "data[0][-1]",
|
||||
Data: `{"data": [[1, 2, 3]]}`,
|
||||
ExpectedOutput: "",
|
||||
ExpectedOutputLength: 0,
|
||||
ExpectedError: true,
|
||||
},
|
||||
}
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.Name, func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user