Summary
VirtualFilesystemDirect::rmdir() (recursive branch) reaches into vfsStream's private internals via reflection, coupling the package to a specific vfsStream implementation layout.
Where
VirtualFilesystemDirect.php, recursive rmdir():
$child = $this->getDir( $dir );
$dirname = $this->getNonPublicPropertyValue( 'name', vfsStreamAbstractContent::class, $child );
$parent = $this->getParentDir( $dirname, $child );
getParentDir() likewise reads the private parentPath property. Both go through TestCaseTrait::getNonPublicPropertyValue().
Impact
composer.json allows mikey179/vfsstream: ^1.6, so any minor/patch bump can change these private members and silently break recursive directory removal — a core operation the whole filesystem-mock strategy depends on. There is no compile-time signal; it would surface only as failing consumer tests.
Proposed direction
Use vfsStream's public API instead of reflection:
vfsStreamContainer::removeChild() / getChild() for the tree mutation.
- Newer vfsStream exposes
getParent(); where unavailable, derive the parent from the known path rather than reading parentPath.
Goal: no reflection into vfsStream internals, so a vfsStream upgrade can't break recursive delete unnoticed.
Found during an audit of WP Rocket's integration test suite, which depends on this package.
Summary
VirtualFilesystemDirect::rmdir()(recursive branch) reaches into vfsStream's private internals via reflection, coupling the package to a specific vfsStream implementation layout.Where
VirtualFilesystemDirect.php, recursivermdir():getParentDir()likewise reads the privateparentPathproperty. Both go throughTestCaseTrait::getNonPublicPropertyValue().Impact
composer.jsonallowsmikey179/vfsstream: ^1.6, so any minor/patch bump can change these private members and silently break recursive directory removal — a core operation the whole filesystem-mock strategy depends on. There is no compile-time signal; it would surface only as failing consumer tests.Proposed direction
Use vfsStream's public API instead of reflection:
vfsStreamContainer::removeChild()/getChild()for the tree mutation.getParent(); where unavailable, derive the parent from the known path rather than readingparentPath.Goal: no reflection into vfsStream internals, so a vfsStream upgrade can't break recursive delete unnoticed.
Found during an audit of WP Rocket's integration test suite, which depends on this package.