# Known Bugs and Issues

## Current Version: 1.2.0

This document tracks known bugs, edge cases, and issues in the Iron Vault FSAL.

---

## 🔴 Confirmed Bugs

*No critical bugs currently open.*

---

## 🟠 Edge Cases

### EDGE-001: Symlink to External Target Detected But Message Varies

**Status:** Known Behavior
**Severity:** Low
**Component:** `core/sandbox.py`

**Description:**
When a symlink points outside the sandbox, the error message depends on
whether `resolve()` follows the symlink before or after the sandbox check:

- Sometimes: "Path escapes sandbox: 'link' resolved to /external/path"
- Sometimes: "Symlinks not allowed: 'link'"

**Cause:** Path.resolve() follows symlinks, so the escape is detected before
the explicit symlink check runs.

**Impact:** Inconsistent error messages; security is not affected.

**Workaround:** None needed. Both cases correctly block the access.

---

### EDGE-002: Empty FSAL_ROOT Treated as Unset

**Status:** By Design
**Severity:** Info
**Component:** `core/sandbox.py`

**Description:**
Setting `FSAL_ROOT=""` is treated the same as not setting it, falling through
to CWD fallback in dev mode.

**Impact:** Could be confusing if user intended to set empty string.

---

### EDGE-003: Unicode Normalization Not Enforced

**Status:** Open
**Severity:** Low
**Component:** `core/sandbox.py`

**Description:**
Paths are not Unicode-normalized (NFC/NFD). A file created as `café` (NFD)
may not be found when accessed as `café` (NFC) on some filesystems.

**Affected Platforms:** macOS (HFS+/APFS use NFD normalization)

**Impact:** Potential file-not-found errors on cross-platform usage.

**Potential Fix:**
```python
import unicodedata
path = unicodedata.normalize("NFC", str(path))
```

---

## 🟡 Limitations

### LIM-001: No Support for Very Large Files

**Status:** Known Limitation (Mitigated in 1.2.0)
**Severity:** Medium

**Description:**
All file operations load entire content into memory. For files larger than
available RAM, operations will fail with MemoryError.

**Affected Operations:**
- `read()` - loads entire file
- `write()` - requires base64 of entire file in request body
- `copy()` - may buffer entire file

**Current Limit:** 100MB default via FSAL_MAX_FILE_SIZE (configurable).

**Potential Fix:** Implement streaming for large files.

---

### LIM-002: No File Locking

**Status:** Known Limitation
**Severity:** Medium

**Description:**
Concurrent writes to the same file from multiple requests may result in
unpredictable content if timing overlaps between temp file creation and
rename.

**Impact:** Last writer wins; no coordination between clients.

**Potential Fix:** Implement advisory locking with `fcntl.flock()` or use a
separate locking service.

---

### LIM-003: No Recursive Listing

**Status:** Known Limitation
**Severity:** Low

**Description:**
`/v1/fs/list` only lists immediate children, not recursive tree.

**Workaround:** Client must recursively call list for each subdirectory.

**Potential Fix:** Add `recursive: bool` option to `ListIn`.

---

### LIM-004: Base64 Overhead for Binary Files

**Status:** Known Limitation
**Severity:** Low

**Description:**
Binary files are transferred as base64, adding ~33% overhead to payload size.

**Impact:** Increased bandwidth usage, memory consumption.

**Potential Fix:** Support multipart/form-data for binary uploads, or
chunked transfer encoding.

---

## 🟢 Fixed Issues

### FIXED-001: Test Assertion for Symlink Error Message

**Version Fixed:** 1.0.0
**Original Issue:** Test expected "Symlinks not allowed" but got "Path escapes sandbox"
**Resolution:** Updated test to accept either message since both indicate correct blocking.

---

### FIXED-002: Missing Directory fsync After Atomic Rename (BUG-001)

**Version Fixed:** 1.1.0
**Original Issue:** `atomic_write()` fsynced file content but not parent directory
**Resolution:** Added `os.fsync(dir_fd)` after `os.replace()` to persist directory entry

---

### FIXED-003: Token Comparison Timing Attack (BUG-002)

**Version Fixed:** 1.1.0
**Original Issue:** Token comparison used `!=` allowing timing attacks
**Resolution:** Changed to `hmac.compare_digest()` for constant-time comparison

---

### FIXED-004: SandboxViolation Caught by except OSError

**Version Fixed:** 1.2.0
**Original Issue:** `SandboxViolation` inherits from `PermissionError` → `OSError`, 
                   causing the symlink check to silently catch and swallow the exception
**Resolution:** Added explicit `except SandboxViolation: raise` before `except OSError`

---

### FIXED-005: Disk Space Not Checked Before Writes

**Version Fixed:** 1.2.0
**Original Issue:** Writes could fill disk with no warning
**Resolution:** Added `check_disk_space()` with configurable MIN_FREE_DISK_SPACE (100MB default)

---

### FIXED-006: No File Size Limits

**Version Fixed:** 1.2.0
**Original Issue:** Arbitrary large files could cause memory exhaustion
**Resolution:** Added `check_file_size()` with FSAL_MAX_FILE_SIZE env var (100MB default)

---

## Reporting New Issues

When reporting a new issue, please include:

1. **Component:** Which module/file is affected
2. **Steps to Reproduce:** Minimal code or API calls to trigger the issue
3. **Expected Behavior:** What should happen
4. **Actual Behavior:** What actually happens
5. **Environment:** Python version, OS, filesystem type
6. **Severity:** Critical/High/Medium/Low

---

*Last updated: 2026-02-08*
