Documentation
¶
Overview ¶
Package validation provides input validation for untrusted data.
Description ¶
This package validates untrusted input before processing to prevent security vulnerabilities such as path traversal, command injection, and regex denial of service (ReDoS).
Thread Safety ¶
All validators are stateless and safe for concurrent use.
Index ¶
- Constants
- Variables
- func IsNullByte(err error) bool
- func IsPathTraversal(err error) bool
- func IsSizeLimit(err error) bool
- type ChangedSymbol
- type DiffFile
- type DiffHunk
- type DiffLine
- type DiffParser
- type InputValidator
- func (v *InputValidator) ValidateDiffPatch(patch string) error
- func (v *InputValidator) ValidateFilePath(path string) error
- func (v *InputValidator) ValidateGitArgs(args []string) error
- func (v *InputValidator) ValidateRegexPattern(pattern string) error
- func (v *InputValidator) ValidateSymbolID(id string) error
- type InputValidatorOptions
- type ValidationError
Constants ¶
const ( ChangeTypeAdded = "added" ChangeTypeModified = "modified" ChangeTypeDeleted = "deleted" )
Change type constants.
Variables ¶
var ( // ErrPathTraversal indicates a path traversal attempt was detected. ErrPathTraversal = errors.New("path traversal detected") // ErrNullByte indicates a null byte was found in input. ErrNullByte = errors.New("null byte in input") // ErrSizeLimit indicates input exceeded size limits. ErrSizeLimit = errors.New("input exceeds size limit") // ErrInvalidUTF8 indicates input contains invalid UTF-8. ErrInvalidUTF8 = errors.New("invalid UTF-8 encoding") // ErrShellMetachar indicates shell metacharacters were found. ErrShellMetachar = errors.New("shell metacharacter in input") // ErrReDoS indicates a potential ReDoS pattern was detected. ErrReDoS = errors.New("potential ReDoS pattern") )
Common validation errors for use in error checking.
Functions ¶
func IsNullByte ¶
IsNullByte returns true if the error indicates a null byte was found.
func IsPathTraversal ¶
IsPathTraversal returns true if the error indicates a path traversal attempt.
func IsSizeLimit ¶
IsSizeLimit returns true if the error indicates a size limit was exceeded.
Types ¶
type ChangedSymbol ¶
type ChangedSymbol struct {
// FilePath is the file containing the changed symbol.
FilePath string `json:"file_path"`
// SymbolName is the function/type name if detected.
// Empty if not determinable from context.
SymbolName string `json:"symbol_name,omitempty"`
// ChangeType indicates what happened to the symbol.
// One of: "added", "modified", "deleted".
ChangeType string `json:"change_type"`
// StartLine is the starting line number of the change.
StartLine int `json:"start_line"`
// EndLine is the ending line number of the change.
EndLine int `json:"end_line"`
// Context contains the hunk header context (e.g., function name).
Context string `json:"context,omitempty"`
// AddedLines is the count of lines added.
AddedLines int `json:"added_lines"`
// DeletedLines is the count of lines deleted.
DeletedLines int `json:"deleted_lines"`
}
ChangedSymbol represents a symbol that was modified in a patch.
type DiffHunk ¶
type DiffHunk struct {
OldStart int
OldCount int
NewStart int
NewCount int
Context string // Function/method context from hunk header
Lines []DiffLine
}
DiffHunk represents a single hunk in a diff.
type DiffLine ¶
type DiffLine struct {
Type string // "+", "-", or " "
Content string
OldLine int // 0 if not applicable
NewLine int // 0 if not applicable
}
DiffLine represents a single line in a diff.
type DiffParser ¶
type DiffParser struct {
// contains filtered or unexported fields
}
DiffParser extracts changed symbols from unified diff format.
Description ¶
Parses unified diff patches and identifies which symbols (functions, types, etc.) were modified. This is used by patch validation to analyze the blast radius of proposed changes.
Supported Formats ¶
- Standard unified diff (diff -u)
- Git diff format
Thread Safety ¶
Safe for concurrent use (stateless).
func NewDiffParser ¶
func NewDiffParser(validator *InputValidator) *DiffParser
NewDiffParser creates a new diff parser.
Inputs ¶
- validator: Input validator. If nil, a default is created.
Outputs ¶
- *DiffParser: Ready-to-use parser.
func (*DiffParser) ExtractChangedSymbols ¶
func (p *DiffParser) ExtractChangedSymbols(patch string) ([]ChangedSymbol, error)
ExtractChangedSymbols parses a patch and returns changed symbols.
Description ¶
Parses the unified diff and identifies changed lines, then attempts to determine which symbols were affected based on the hunk context.
Inputs ¶
- patch: The unified diff string.
Outputs ¶
- []ChangedSymbol: List of changed symbols.
- error: Non-nil if patch is invalid.
Example ¶
parser := NewDiffParser(validator)
symbols, err := parser.ExtractChangedSymbols(patchContent)
if err != nil {
return fmt.Errorf("failed to parse patch: %w", err)
}
for _, sym := range symbols {
fmt.Printf("Changed: %s in %s\n", sym.SymbolName, sym.FilePath)
}
func (*DiffParser) GetFilesChanged ¶
func (p *DiffParser) GetFilesChanged(patch string) ([]string, error)
GetFilesChanged returns the list of files affected by the patch.
type InputValidator ¶
type InputValidator struct {
// contains filtered or unexported fields
}
InputValidator validates untrusted input before processing.
Description ¶
Provides validation for file paths, diff patches, symbol identifiers, and regex patterns. All methods are stateless and safe for concurrent use.
Security ¶
- Rejects path traversal attempts
- Enforces size limits to prevent DoS
- Validates UTF-8 encoding
- Prevents shell metacharacter injection
- Detects ReDoS-prone regex patterns
Thread Safety ¶
Safe for concurrent use (stateless).
func NewInputValidator ¶
func NewInputValidator(opts *InputValidatorOptions) *InputValidator
NewInputValidator creates a new InputValidator with the given options.
Description ¶
Creates a validator with configurable limits. If opts is nil, defaults are used.
Inputs ¶
- opts: Configuration options. If nil, defaults are used.
Outputs ¶
- *InputValidator: Ready-to-use validator.
Example ¶
v := NewInputValidator(nil)
if err := v.ValidateFilePath("../../../etc/passwd"); err != nil {
// Handle path traversal attempt
}
func (*InputValidator) ValidateDiffPatch ¶
func (v *InputValidator) ValidateDiffPatch(patch string) error
ValidateDiffPatch validates unified diff format and size.
Description ¶
Validates that a patch string is safe to process. Checks size limits, UTF-8 validity, and basic diff format.
Security ¶
- Enforces size limit (maxPatchLen)
- Validates UTF-8 encoding
- Rejects null bytes
- Validates diff header format
Inputs ¶
- patch: The unified diff string to validate.
Outputs ¶
- error: Non-nil if validation fails.
Example ¶
if err := v.ValidateDiffPatch(patchContent); err != nil {
return fmt.Errorf("invalid patch: %w", err)
}
func (*InputValidator) ValidateFilePath ¶
func (v *InputValidator) ValidateFilePath(path string) error
ValidateFilePath rejects path traversal and excessive length.
Description ¶
Validates that a file path is safe to use. Rejects paths containing "..", null bytes, or excessive length.
Security ¶
- Rejects paths containing ".." (path traversal)
- Rejects paths exceeding maxPathLen
- Rejects null bytes (C-string injection)
- Rejects non-UTF-8 sequences
- Rejects paths starting with ~ (home directory expansion)
Inputs ¶
- path: The file path to validate.
Outputs ¶
- error: Non-nil if validation fails, with details about the failure.
Example ¶
if err := v.ValidateFilePath(userInput); err != nil {
return fmt.Errorf("invalid path: %w", err)
}
func (*InputValidator) ValidateGitArgs ¶
func (v *InputValidator) ValidateGitArgs(args []string) error
ValidateGitArgs validates arguments that will be passed to git commands.
Description ¶
Validates that arguments are safe to pass to git via exec.Command. Rejects shell metacharacters to prevent command injection.
Security ¶
- Rejects empty arguments
- Rejects shell metacharacters
- Rejects null bytes
- Rejects arguments starting with - (flag injection)
Inputs ¶
- args: The git command arguments to validate.
Outputs ¶
- error: Non-nil if any argument fails validation.
Example ¶
if err := v.ValidateGitArgs([]string{"log", "--oneline", filePath}); err != nil {
return fmt.Errorf("invalid git args: %w", err)
}
func (*InputValidator) ValidateRegexPattern ¶
func (v *InputValidator) ValidateRegexPattern(pattern string) error
ValidateRegexPattern validates regex won't cause ReDoS.
Description ¶
Validates that a regex pattern is safe to compile and use. Checks for common patterns that can cause catastrophic backtracking (ReDoS).
Security ¶
- Enforces length limit
- Detects nested quantifiers (a+)+ which cause exponential backtracking
- Detects overlapping alternations
- Validates pattern compiles
Limitations ¶
ReDoS detection is heuristic-based and may have false negatives. For untrusted patterns, consider using RE2 (which has linear time guarantees) or implementing execution timeouts.
Inputs ¶
- pattern: The regex pattern to validate.
Outputs ¶
- error: Non-nil if validation fails or pattern is potentially dangerous.
Example ¶
if err := v.ValidateRegexPattern(userPattern); err != nil {
return fmt.Errorf("invalid regex: %w", err)
}
func (*InputValidator) ValidateSymbolID ¶
func (v *InputValidator) ValidateSymbolID(id string) error
ValidateSymbolID rejects malformed symbol identifiers.
Description ¶
Validates that a symbol ID conforms to expected format and doesn't contain dangerous characters that could cause issues in downstream processing (logging, URLs, etc.).
Security ¶
- Rejects empty strings
- Rejects null bytes
- Rejects shell metacharacters
- Enforces reasonable length limit
- Validates character set
Inputs ¶
- id: The symbol identifier to validate.
Outputs ¶
- error: Non-nil if validation fails.
Example ¶
if err := v.ValidateSymbolID(userInput); err != nil {
return fmt.Errorf("invalid symbol ID: %w", err)
}
type InputValidatorOptions ¶
type InputValidatorOptions struct {
MaxPathLen int // Default: 4096
MaxPatchLen int // Default: 1MB (1<<20)
MaxPatternLen int // Default: 1000
}
InputValidatorOptions configures the InputValidator.
func DefaultInputValidatorOptions ¶
func DefaultInputValidatorOptions() InputValidatorOptions
DefaultInputValidatorOptions returns sensible default options.
type ValidationError ¶
type ValidationError struct {
Field string // The field that failed validation
Value string // The rejected value (truncated for safety)
Reason string // Why validation failed
Details string // Additional details for debugging
}
ValidationError represents a validation failure with context.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error implements the error interface.