validation

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 11, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

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

View Source
const (
	ChangeTypeAdded    = "added"
	ChangeTypeModified = "modified"
	ChangeTypeDeleted  = "deleted"
)

Change type constants.

Variables

View Source
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

func IsNullByte(err error) bool

IsNullByte returns true if the error indicates a null byte was found.

func IsPathTraversal

func IsPathTraversal(err error) bool

IsPathTraversal returns true if the error indicates a path traversal attempt.

func IsSizeLimit

func IsSizeLimit(err error) bool

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 DiffFile

type DiffFile struct {
	OldPath   string
	NewPath   string
	Hunks     []DiffHunk
	IsNew     bool
	IsDeleted bool
}

DiffFile represents a single file in a diff.

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.

func (*DiffParser) ParseDiff

func (p *DiffParser) ParseDiff(patch string) ([]DiffFile, error)

ParseDiff parses a unified diff into structured data.

Inputs

  • patch: The unified diff string.

Outputs

  • []DiffFile: Parsed diff files.
  • error: Non-nil if patch format is invalid.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL