Skip to content

fix(#41): validate caller-supplied DirectoryLayer::create prefix - #68

Merged
s2x merged 1 commit into
masterfrom
fix/issue-41-directory-prefix-validation
Jul 4, 2026
Merged

fix(#41): validate caller-supplied DirectoryLayer::create prefix#68
s2x merged 1 commit into
masterfrom
fix/issue-41-directory-prefix-validation

Conversation

@s2x

@s2x s2x commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #41

Summary

DirectoryLayer::create(...,$prefix) previously wrote any caller-supplied
prefix directly into the subdirs index without any conflict check, so a
manual prefix overlapping existing directory metadata or content keys
silently corrupted or overwrote data.

This change routes every caller-supplied prefix through
DirectoryLayer::validateRawPrefix(), which throws DirectoryException
with a printable rendering of the offending key when:

  • the prefix is empty;
  • the node-metadata range under the prefix is not empty;
  • the content-key range under the prefix is not empty.

The check runs inside the transaction before any set() call, so a failed
create leaves no partial state and the same path can be retried via
auto-allocation.

Changes

  • src/Directory/DirectoryLayer.php: Validation logic extracted into a
    private helper validateRawPrefix($rawPrefix,$contentSubspaceKey, $nodeProbe,$contentProbe) so it can be unit-tested in pure PHP
    without needing a live Transaction. The instance-level adapter
    assertValidCallerSuppliedPrefix($tr,$prefix) binds it to live
    FoundationDB probes. Also tightened the existing auto-allocation error
    message ("data" → "directory metadata") for consistency with the
    new explicit-prefix diagnostics.
  • docs/directory-layer.md: Documents the explicit-prefix API and
    the three rejection conditions in a four-row table.
  • CHANGELOG.md: New [Unreleased] entry under Fixed with the
    bug description, the validation contract, and a pointer to the two
    new test files.

Tests

  • tests/Unit/DirectoryPrefixValidationTest.php (20 new tests):
    acceptance boundary (' visited, non-empty prefix accepted, 1-byte
    prefix accepted, binary prefix accepted, content-key composition
    observed at probes), rejection boundaries (empty prefix, metadata
    conflict, content conflict, ordering diagnostic when both conflict),
    error-message printable-rendering across printable, control, ~,
    0xFF, mixed.
  • tests/Integration/DirectoryTest.php (4 new tests):
    end-to-end happy-path with auto-validation free prefix (open
    round-trip, usable for normal CRUD), two-distinct-prefixes
    acceptance, empty-prefix rejection (and no transaction state
    mutated afterwards), explicit-prefix overlapping content keys
    rejected.

All checks green locally:

composer lint   # PHPCS + Rector (dry-run) + PHPStan — `[OK] No errors`
composer test:unit  # OK (400 tests, 838 assertions)

CI will additionally exercise PHP 8.2/8.3/8.4 unit tests plus the
5-node FDB cluster e2e-tests job (which the integration suite
runs).

Caller-supplied prefixes were written directly into the subdirs index
without any conflict check, so a manual prefix overlapping existing
directory metadata or content keys silently corrupted or overwrote data.

Route every caller-supplied prefix through validateRawPrefix() which
throws DirectoryException with a printable rendering of the offending
key when:

- the prefix is empty;
- the node-metadata range under the prefix is not empty;
- the content-key range under the prefix is not empty.

The check runs inside the transaction before any set(), so a failed
create leaves no partial state.
@s2x
s2x merged commit b7a9191 into master Jul 4, 2026
6 checks passed
@s2x
s2x deleted the fix/issue-41-directory-prefix-validation branch July 4, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] DirectoryLayer::create does not validate caller-supplied prefix

1 participant