Skip to content

Commit 21f4f05

Browse files
authored
Fix impossible unsigned integer comparisons in Abs() function (#919)
1 parent 3461fbb commit 21f4f05

File tree

2 files changed

+38
-25
lines changed

2 files changed

+38
-25
lines changed

builtin/builtin_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,3 +869,36 @@ func TestBuiltin_recursion_custom_max_depth(t *testing.T) {
869869
require.NoError(t, err)
870870
})
871871
}
872+
873+
func TestAbs_UnsignedIntegers(t *testing.T) {
874+
// Test that abs() correctly handles unsigned integers
875+
// Unsigned integers are always non-negative, so abs() should return them unchanged
876+
tests := []struct {
877+
name string
878+
env map[string]any
879+
expr string
880+
want any
881+
}{
882+
{"uint", map[string]any{"x": uint(42)}, "abs(x)", uint(42)},
883+
{"uint8", map[string]any{"x": uint8(42)}, "abs(x)", uint8(42)},
884+
{"uint16", map[string]any{"x": uint16(42)}, "abs(x)", uint16(42)},
885+
{"uint32", map[string]any{"x": uint32(42)}, "abs(x)", uint32(42)},
886+
{"uint64", map[string]any{"x": uint64(42)}, "abs(x)", uint64(42)},
887+
{"uint zero", map[string]any{"x": uint(0)}, "abs(x)", uint(0)},
888+
{"uint8 zero", map[string]any{"x": uint8(0)}, "abs(x)", uint8(0)},
889+
{"uint16 zero", map[string]any{"x": uint16(0)}, "abs(x)", uint16(0)},
890+
{"uint32 zero", map[string]any{"x": uint32(0)}, "abs(x)", uint32(0)},
891+
{"uint64 zero", map[string]any{"x": uint64(0)}, "abs(x)", uint64(0)},
892+
}
893+
894+
for _, tt := range tests {
895+
t.Run(tt.name, func(t *testing.T) {
896+
program, err := expr.Compile(tt.expr, expr.Env(tt.env))
897+
require.NoError(t, err)
898+
899+
result, err := expr.Run(program, tt.env)
900+
require.NoError(t, err)
901+
assert.Equal(t, tt.want, result)
902+
})
903+
}
904+
}

builtin/lib.go

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -102,35 +102,15 @@ func Abs(x any) any {
102102
return x
103103
}
104104
case uint:
105-
if x < 0 {
106-
return -x
107-
} else {
108-
return x
109-
}
105+
return x
110106
case uint8:
111-
if x < 0 {
112-
return -x
113-
} else {
114-
return x
115-
}
107+
return x
116108
case uint16:
117-
if x < 0 {
118-
return -x
119-
} else {
120-
return x
121-
}
109+
return x
122110
case uint32:
123-
if x < 0 {
124-
return -x
125-
} else {
126-
return x
127-
}
111+
return x
128112
case uint64:
129-
if x < 0 {
130-
return -x
131-
} else {
132-
return x
133-
}
113+
return x
134114
}
135115
panic(fmt.Sprintf("invalid argument for abs (type %T)", x))
136116
}

0 commit comments

Comments
 (0)