Metadata-Version: 2.4
Name: bad_path
Version: 0.1.0
Summary: A Python package to identify potentially dangerous file paths
Author-email: Gavin Burnell <g.burnell@example.com>
License: MIT License
        
        Copyright (c) 2026 Gavin Burnell
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/gb119/bad_path
Project-URL: Documentation, https://gb119.github.io/bad_path/
Project-URL: Repository, https://github.com/gb119/bad_path
Project-URL: Issues, https://github.com/gb119/bad_path/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: sphinx>=7.0; extra == "dev"
Requires-Dist: sphinx-rtd-theme>=1.3; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Dynamic: license-file

# bad_path

[![Tests](https://github.com/gb119/bad_path/actions/workflows/tests.yml/badge.svg)](https://github.com/gb119/bad_path/actions/workflows/tests.yml)
[![Documentation](https://github.com/gb119/bad_path/actions/workflows/docs.yml/badge.svg)](https://gb119.github.io/bad_path/)
[![PyPI version](https://badge.fury.io/py/bad-path.svg)](https://badge.fury.io/py/bad-path)

A Python package to identify potentially dangerous file paths.

## Overview

`bad_path` provides functions to test whether a supplied file path points to a system-sensitive location, taking into account different OS platforms (Windows, macOS, Linux).

## Installation

### From PyPI

```bash
pip install bad_path
```

### From Conda

```bash
conda install -c phygbu bad_path
# or
mamba install -c phygbu bad_path
```

### From Source

```bash
git clone https://github.com/gb119/bad_path.git
cd bad_path
pip install -e .
```

## Quick Start

```python
from bad_path import is_dangerous_path, DangerousPathError

# Check if a path is dangerous
if is_dangerous_path("/etc/passwd"):
    print("Warning: This path points to a sensitive location!")

# Raise an exception for dangerous paths
try:
    is_dangerous_path("/etc/passwd", raise_error=True)
except DangerousPathError as e:
    print(f"Error: {e}")

# Use the PathChecker class for more details
from bad_path import PathChecker

checker = PathChecker("/etc/passwd")
if not checker:
    print(f"Dangerous path detected!")
    print(f"Platform system path: {checker.is_system_path}")
    print(f"User-defined sensitive path: {checker.is_sensitive_path}")

# Check path accessibility
checker = PathChecker("/tmp/myfile.txt")
if checker:
    print("Safe path!")
print(f"Readable: {checker.is_readable}")
print(f"Writable: {checker.is_writable}")
print(f"Creatable: {checker.is_creatable}")
```

## Features

- ✅ Cross-platform support (Windows, macOS, Linux)
- ✅ Simple API for checking dangerous paths
- ✅ Object-oriented `PathChecker` class with detailed information
- ✅ Path accessibility checks (read, write, create permissions)
- ✅ **Invalid character detection** (platform-specific)
- ✅ Customizable error handling
- ✅ Lightweight with no external dependencies
- ✅ Works with both strings and `pathlib.Path` objects
- ✅ User-defined dangerous paths support

## Usage Examples

### Basic Path Checking

```python
from bad_path import is_dangerous_path

# Simple boolean check
if is_dangerous_path("/etc/passwd"):
    print("This is a dangerous system path!")

if not is_dangerous_path("/tmp/myfile.txt"):
    print("Safe to use!")
```

### Checking Path Accessibility

```python
from bad_path import PathChecker

# Check if a file is readable
checker = PathChecker("/etc/passwd")
if checker.is_readable:
    print("File can be read")

# Check if a file is writable
checker = PathChecker("/tmp/test.txt")
if checker.is_writable:
    print("File can be written to")

# Check if a new file can be created
checker = PathChecker("/tmp/newfile.txt")
if checker.is_creatable:
    print("File can be created in this location")
```

### Combining Safety and Accessibility Checks

```python
from bad_path import PathChecker

def safe_to_write(filepath):
    """Check if a path is both safe and writable."""
    checker = PathChecker(filepath)
    
    # PathChecker evaluates to True for safe paths
    if not checker:
        return False  # Dangerous location
    
    # Must be writable or creatable
    return checker.is_writable or checker.is_creatable

# Usage
safe_to_write("/tmp/myfile.txt")  # True - safe and creatable
safe_to_write("/etc/passwd")       # False - dangerous location
```

### Checking for Invalid Characters

```python
from bad_path import PathChecker

# Check if a path contains invalid characters for the platform
checker = PathChecker("/tmp/test\x00file.txt")  # Null byte is invalid on all platforms
print(f"Has invalid characters: {checker.has_invalid_chars}")  # True
print(f"Is safe: {bool(checker)}")  # False - dangerous due to invalid char

# Platform-specific invalid characters:
# - POSIX (Linux): null byte (\0)
# - macOS (Darwin): null byte (\0) and colon (:)
# - Windows: < > : " | ? * and control characters (0-31)
#            Also checks for reserved names: CON, PRN, AUX, NUL, COM1-9, LPT1-9

# Windows example - reserved name check
checker = PathChecker("C:\\tmp\\CON.txt")  # CON is a reserved name
print(f"Has invalid characters: {checker.has_invalid_chars}")  # True on Windows

# Paths ending with space or period are invalid on Windows
checker = PathChecker("C:\\tmp\\file. ")
print(f"Has invalid characters: {checker.has_invalid_chars}")  # True on Windows
```

## Documentation

Full documentation is available at [https://gb119.github.io/bad_path/](https://gb119.github.io/bad_path/)

## Development

For development, install with the optional development dependencies:

```bash
pip install -e ".[dev]"
```

Run tests:

```bash
pytest
```

Build documentation:

```bash
cd docs
make html
```

## License

MIT License - see [LICENSE](LICENSE) file for details.
