fileutil

package
v0.75.0 Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: MIT Imports: 8 Imported by: 0

README

fileutil Package

The fileutil package provides utility functions for safe file path validation and common file operations.

Overview

This package focuses on security-conscious file handling: path validation, boundary enforcement, and straightforward file/directory operations. It also provides a cross-platform tar extraction helper.

Public API

Functions
Function Signature Description
ValidateAbsolutePath func(path string) (string, error) Validates that a file path is absolute and safe; rejects empty paths, cleans with filepath.Clean, and verifies the result is absolute
ValidatePathWithinBase func(base, candidate string) error Checks that candidate is located within the base directory tree; resolves symlinks before comparison to prevent traversal and symlink escapes
FileExists func(path string) bool Returns true if path exists and is a regular file (not a directory)
DirExists func(path string) bool Returns true if path exists and is a directory
IsDirEmpty func(path string) bool Returns true if the directory at path contains no entries; also returns true if the directory cannot be read
CopyFile func(src, dst string) error Copies the file at src to dst using buffered I/O; calls Sync on the destination before closing
ExtractFileFromTar func(data []byte, path string) ([]byte, error) Extracts a single file by path from a tar archive; rejects unsafe entry names (absolute or ..-containing paths)

Usage Examples

import "github.com/github/gh-aw/pkg/fileutil"

// Validate and clean a user-supplied path
cleanPath, err := fileutil.ValidateAbsolutePath(userInput)
if err != nil {
    return fmt.Errorf("invalid path: %w", err)
}

// Ensure output path stays within workspace
if err := fileutil.ValidatePathWithinBase("/workspace", outputPath); err != nil {
    return fmt.Errorf("output path escapes workspace: %w", err)
}

// Copy a file
if err := fileutil.CopyFile("source.txt", "destination.txt"); err != nil {
    return fmt.Errorf("copy failed: %w", err)
}

Dependencies

Internal:

  • github.com/github/gh-aw/pkg/logger — debug logging

Design Notes

  • All debug output uses logger.New("fileutil:fileutil") and logger.New("fileutil:tar") and is only emitted when DEBUG=fileutil:*.
  • ValidatePathWithinBase resolves symlinks before comparison, providing defence-in-depth against symlink attacks in addition to the .. checking that ValidateAbsolutePath provides.
  • ExtractFileFromTar rejects path-traversal payloads in both the caller-supplied path and in tar entry names using filepath.IsLocal.

This specification is automatically maintained by the spec-extractor workflow.

Documentation

Overview

Package fileutil provides utility functions for working with file paths and file operations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CopyFile added in v0.47.0

func CopyFile(src, dst string) error

CopyFile copies a file from src to dst using buffered IO.

func DirExists added in v0.47.0

func DirExists(path string) bool

DirExists checks if a directory exists.

func ExtractFileFromTar added in v0.49.0

func ExtractFileFromTar(data []byte, path string) ([]byte, error)

ExtractFileFromTar extracts a single file from a tar archive. Uses Go's standard archive/tar for cross-platform compatibility instead of spawning an external tar process which may not be available on all platforms.

path must be a local, relative path (no absolute paths or ".." components). filepath.IsLocal is used to enforce this for both the search target and each tar entry name, guarding against path-traversal payloads embedded in archives.

func FileExists added in v0.47.0

func FileExists(path string) bool

FileExists checks if a file exists and is not a directory.

func IsDirEmpty added in v0.47.0

func IsDirEmpty(path string) bool

IsDirEmpty checks if a directory is empty.

func ValidateAbsolutePath

func ValidateAbsolutePath(path string) (string, error)

ValidateAbsolutePath validates that a file path is absolute and safe to use. It performs the following security checks:

  • Cleans the path using filepath.Clean to normalize . and .. components
  • Verifies the path is absolute to prevent relative path traversal attacks

Returns the cleaned absolute path if validation succeeds, or an error if:

  • The path is empty
  • The path is relative (not absolute)

This function should be used before any file operations (read, write, stat, etc.) to ensure defense-in-depth security against path traversal vulnerabilities.

Example:

cleanPath, err := fileutil.ValidateAbsolutePath(userInputPath)

if err != nil {
   return fmt.Errorf("invalid path: %w", err)
}

content, err := os.ReadFile(cleanPath)

func ValidatePathWithinBase added in v0.71.5

func ValidatePathWithinBase(base, candidate string) error

ValidatePathWithinBase checks that candidate is located within the base directory tree. Both paths are resolved via filepath.EvalSymlinks (with filepath.Abs as fallback when a path does not yet exist) before comparison, so neither ".." components nor symlinks pointing outside base can be used to escape.

Returns an error when:

  • Either path cannot be resolved to an absolute form.
  • The resolved candidate path starts outside the resolved base directory.

Types

This section is empty.

Jump to

Keyboard shortcuts

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