- Added comprehensive bounds checking to prevent buffer overruns in multicall parsing - Implemented graduated validation system (Strict/Moderate/Permissive) to reduce false positives - Added LRU caching system for address validation with 10-minute TTL - Enhanced ABI decoder with missing Universal Router and Arbitrum-specific DEX signatures - Fixed duplicate function declarations and import conflicts across multiple files - Added error recovery mechanisms with multiple fallback strategies - Updated tests to handle new validation behavior for suspicious addresses - Fixed parser test expectations for improved validation system - Applied gofmt formatting fixes to ensure code style compliance - Fixed mutex copying issues in monitoring package by introducing MetricsSnapshot - Resolved critical security vulnerabilities in heuristic address extraction - Progress: Updated TODO audit from 10% to 35% complete 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
344 lines
7.0 KiB
Go
344 lines
7.0 KiB
Go
package security
|
|
|
|
import (
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
func TestSafeUint64ToUint32(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input uint64
|
|
expected uint32
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "zero value",
|
|
input: 0,
|
|
expected: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "small positive value",
|
|
input: 1000,
|
|
expected: 1000,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "max uint32 value",
|
|
input: math.MaxUint32,
|
|
expected: math.MaxUint32,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "overflow value",
|
|
input: math.MaxUint32 + 1,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "large overflow value",
|
|
input: math.MaxUint64,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result, err := SafeUint64ToUint32(tt.input)
|
|
|
|
if tt.expectError {
|
|
if err == nil {
|
|
t.Errorf("SafeUint64ToUint32(%d) expected error but got none", tt.input)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("SafeUint64ToUint32(%d) unexpected error: %v", tt.input, err)
|
|
}
|
|
if result != tt.expected {
|
|
t.Errorf("SafeUint64ToUint32(%d) = %d, want %d", tt.input, result, tt.expected)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSafeUint64ToInt64(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input uint64
|
|
expected int64
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "zero value",
|
|
input: 0,
|
|
expected: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "small positive value",
|
|
input: 1000,
|
|
expected: 1000,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "max int64 value",
|
|
input: math.MaxInt64,
|
|
expected: math.MaxInt64,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "overflow value",
|
|
input: math.MaxInt64 + 1,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "max uint64 value",
|
|
input: math.MaxUint64,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result, err := SafeUint64ToInt64(tt.input)
|
|
|
|
if tt.expectError {
|
|
if err == nil {
|
|
t.Errorf("SafeUint64ToInt64(%d) expected error but got none", tt.input)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("SafeUint64ToInt64(%d) unexpected error: %v", tt.input, err)
|
|
}
|
|
if result != tt.expected {
|
|
t.Errorf("SafeUint64ToInt64(%d) = %d, want %d", tt.input, result, tt.expected)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSafeUint64ToUint32WithDefault(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input uint64
|
|
defaultValue uint32
|
|
expected uint32
|
|
}{
|
|
{
|
|
name: "valid value",
|
|
input: 1000,
|
|
defaultValue: 500,
|
|
expected: 1000,
|
|
},
|
|
{
|
|
name: "overflow uses default",
|
|
input: math.MaxUint32 + 1,
|
|
defaultValue: 500,
|
|
expected: 500,
|
|
},
|
|
{
|
|
name: "max valid value",
|
|
input: math.MaxUint32,
|
|
defaultValue: 500,
|
|
expected: math.MaxUint32,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := SafeUint64ToUint32WithDefault(tt.input, tt.defaultValue)
|
|
if result != tt.expected {
|
|
t.Errorf("SafeUint64ToUint32WithDefault(%d, %d) = %d, want %d",
|
|
tt.input, tt.defaultValue, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSafeAddUint64(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
a uint64
|
|
b uint64
|
|
expected uint64
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "small values",
|
|
a: 100,
|
|
b: 200,
|
|
expected: 300,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "zero addition",
|
|
a: 1000,
|
|
b: 0,
|
|
expected: 1000,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "overflow case",
|
|
a: math.MaxUint64,
|
|
b: 1,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "near max valid",
|
|
a: math.MaxUint64 - 1,
|
|
b: 1,
|
|
expected: math.MaxUint64,
|
|
expectError: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result, err := SafeAddUint64(tt.a, tt.b)
|
|
|
|
if tt.expectError {
|
|
if err == nil {
|
|
t.Errorf("SafeAddUint64(%d, %d) expected error but got none", tt.a, tt.b)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("SafeAddUint64(%d, %d) unexpected error: %v", tt.a, tt.b, err)
|
|
}
|
|
if result != tt.expected {
|
|
t.Errorf("SafeAddUint64(%d, %d) = %d, want %d", tt.a, tt.b, result, tt.expected)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSafeMultiplyUint64(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
a uint64
|
|
b uint64
|
|
expected uint64
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "small values",
|
|
a: 100,
|
|
b: 200,
|
|
expected: 20000,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "zero multiplication",
|
|
a: 1000,
|
|
b: 0,
|
|
expected: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "one multiplication",
|
|
a: 1000,
|
|
b: 1,
|
|
expected: 1000,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "overflow case",
|
|
a: math.MaxUint64,
|
|
b: 2,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "large values overflow",
|
|
a: math.MaxUint64 / 2,
|
|
b: 3,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result, err := SafeMultiplyUint64(tt.a, tt.b)
|
|
|
|
if tt.expectError {
|
|
if err == nil {
|
|
t.Errorf("SafeMultiplyUint64(%d, %d) expected error but got none", tt.a, tt.b)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("SafeMultiplyUint64(%d, %d) unexpected error: %v", tt.a, tt.b, err)
|
|
}
|
|
if result != tt.expected {
|
|
t.Errorf("SafeMultiplyUint64(%d, %d) = %d, want %d", tt.a, tt.b, result, tt.expected)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSafeSubtractUint64(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
a uint64
|
|
b uint64
|
|
expected uint64
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "normal subtraction",
|
|
a: 1000,
|
|
b: 200,
|
|
expected: 800,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "zero result",
|
|
a: 1000,
|
|
b: 1000,
|
|
expected: 0,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "underflow case",
|
|
a: 100,
|
|
b: 200,
|
|
expected: 0,
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "subtract zero",
|
|
a: 1000,
|
|
b: 0,
|
|
expected: 1000,
|
|
expectError: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result, err := SafeSubtractUint64(tt.a, tt.b)
|
|
|
|
if tt.expectError {
|
|
if err == nil {
|
|
t.Errorf("SafeSubtractUint64(%d, %d) expected error but got none", tt.a, tt.b)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("SafeSubtractUint64(%d, %d) unexpected error: %v", tt.a, tt.b, err)
|
|
}
|
|
if result != tt.expected {
|
|
t.Errorf("SafeSubtractUint64(%d, %d) = %d, want %d", tt.a, tt.b, result, tt.expected)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|