Files
go-jdenticon/jdenticon/validation.go
Kevin McIntyre f1544ef49c
Some checks failed
CI / Test (Go 1.24.x, ubuntu-latest) (push) Successful in 1m53s
CI / Code Quality (push) Failing after 26s
CI / Security Scan (push) Failing after 11s
CI / Test Coverage (push) Successful in 1m13s
CI / Benchmarks (push) Failing after 10m22s
CI / Build CLI (push) Failing after 8s
Benchmarks / Run Benchmarks (push) Failing after 10m13s
Release / Test (push) Successful in 55s
Release / Build (amd64, darwin, ) (push) Failing after 12s
Release / Build (amd64, linux, ) (push) Failing after 6s
Release / Build (amd64, windows, .exe) (push) Failing after 12s
Release / Build (arm64, darwin, ) (push) Failing after 12s
Release / Build (arm64, linux, ) (push) Failing after 12s
Release / Release (push) Has been skipped
CI / Test (Go 1.24.x, macos-latest) (push) Has been cancelled
CI / Test (Go 1.24.x, windows-latest) (push) Has been cancelled
chore: update module path to gitea.dockr.co/kev/go-jdenticon
Move hosting from GitHub to private Gitea instance.
2026-02-10 10:07:57 -05:00

86 lines
2.8 KiB
Go

package jdenticon
import (
"gitea.dockr.co/kev/go-jdenticon/internal/engine"
)
// validation.go contains helper functions for input validation and DoS protection.
// validateInputs performs common validation for input string and size parameters.
// This provides centralized validation logic used across all public API functions.
func validateInputs(input string, size int, config Config) error {
// Validate input string length
if maxLen := config.effectiveMaxInputLength(); maxLen != -1 && len(input) > maxLen {
return NewErrValueTooLarge("InputLength", maxLen, len(input))
}
// Validate that input is not empty
if input == "" {
return NewErrInvalidInput("input", input, "cannot be empty")
}
// Validate base icon size (must be positive)
if size <= 0 {
return ErrInvalidSize(size)
}
// Validate icon size against configured limit
if maxSize := config.effectiveMaxIconSize(); maxSize != -1 && size > maxSize {
return NewErrValueTooLarge("IconSize", maxSize, size)
}
return nil
}
// validateComplexity performs complexity validation for an input string.
// This should be called after basic input validation and hash computation.
func validateComplexity(hash string, config Config) error {
if maxComplexity := config.effectiveMaxComplexity(); maxComplexity != -1 {
// Create a temporary engine generator to calculate complexity
// This is needed to access the CalculateComplexity method
engineConfig := engine.DefaultGeneratorConfig()
engineConfig.ColorConfig = engine.ColorConfig{
IconPadding: config.Padding,
ColorSaturation: config.ColorSaturation,
GrayscaleSaturation: config.GrayscaleSaturation,
ColorLightness: engine.LightnessRange{
Min: config.ColorLightnessRange[0],
Max: config.ColorLightnessRange[1],
},
GrayscaleLightness: engine.LightnessRange{
Min: config.GrayscaleLightnessRange[0],
Max: config.GrayscaleLightnessRange[1],
},
Hues: config.HueRestrictions,
BackColor: nil, // Not needed for complexity calculation
}
tempGenerator, err := engine.NewGeneratorWithConfig(engineConfig)
if err != nil {
return err
}
complexity, err := tempGenerator.CalculateComplexity(hash)
if err != nil {
return err
}
if complexity > maxComplexity {
return NewErrComplexityLimitExceeded(maxComplexity, complexity, hash)
}
}
return nil
}
// validatePNGSize performs additional validation for PNG functions that use supersampling.
// This checks the effective size (size * supersampling) against configured limits.
func validatePNGSize(size int, config Config) error {
// Check effective size for PNG with supersampling
effectiveSize := size * config.PNGSupersampling
if maxSize := config.effectiveMaxIconSize(); maxSize != -1 && effectiveSize > maxSize {
return NewErrEffectiveSizeTooLarge(maxSize, effectiveSize, size, config.PNGSupersampling)
}
return nil
}