From 9b4484739f23eddb8091d603cb4ab754039df7ec Mon Sep 17 00:00:00 2001 From: Mikhail Dmitrichenko Date: Thu, 25 Jun 2026 18:33:06 +0300 Subject: [PATCH] systemd: fix negative number conversion convertNumber() strips the sign before parsing the numeric value and then applies it back via a multiplier. The negative case uses -11 instead of -1, causing negative values to be converted incorrectly. This is visible for any caller using the signed result directly, and can also produce surprising results for unsigned callers if the multiplication overflows. Use -1 for the negative multiplier. Signed-off-by: Mikhail Dmitrichenko --- pkg/systemd/parser/unitfile.go | 2 +- pkg/systemd/parser/unitfile_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/pkg/systemd/parser/unitfile.go b/pkg/systemd/parser/unitfile.go index 310bb1d328..151dd42332 100644 --- a/pkg/systemd/parser/unitfile.go +++ b/pkg/systemd/parser/unitfile.go @@ -661,7 +661,7 @@ func convertNumber(v string) (int64, error) { v = v[1:] } else if strings.HasPrefix(v, "-") { v = v[1:] - mult = int64(-11) + mult = int64(-1) } switch { diff --git a/pkg/systemd/parser/unitfile_test.go b/pkg/systemd/parser/unitfile_test.go index fff4f4445d..a3eedceea0 100644 --- a/pkg/systemd/parser/unitfile_test.go +++ b/pkg/systemd/parser/unitfile_test.go @@ -371,6 +371,32 @@ func TestLookupQuoteStripping(t *testing.T) { } } +func TestLookupIntParsesSignedNumbers(t *testing.T) { + unit := NewUnitFile() + unit.Add("Service", "Positive", "42") + unit.Add("Service", "ExplicitPositive", "+42") + unit.Add("Service", "Negative", "-42") + unit.Add("Service", "Hex", "0x2a") + unit.Add("Service", "Octal", "052") + + tests := []struct { + key string + expected int64 + }{ + {"Positive", 42}, + {"ExplicitPositive", 42}, + {"Negative", -42}, + {"Hex", 42}, + {"Octal", 42}, + } + + for _, tt := range tests { + t.Run(tt.key, func(t *testing.T) { + assert.Equal(t, tt.expected, unit.LookupInt("Service", tt.key, 0)) + }) + } +} + func FuzzParser(f *testing.F) { for _, sample := range samples { f.Add([]byte(sample))