Files
exoplasim/web/tests/filebase-path-guard.php

53 lines
2.1 KiB
PHP

<?php
require __DIR__.'/bootstrap.php';
require_once __DIR__.'/../lib/filebase.class.php';
function test_fail($message)
{
fwrite(STDERR, "FAIL: {$message}\n");
exit(1);
}
function test_assert($condition, $message)
{
if(!$condition)
test_fail($message);
echo "ok - {$message}\n";
}
function test_throws(callable $fn, $message)
{
try {
$fn();
} catch(InvalidArgumentException $e) {
echo "ok - {$message}\n";
return;
}
test_fail($message);
}
$root = sys_get_temp_dir().'/web-app-starter-filebase-'.bin2hex(random_bytes(4)).'/';
$GLOBALS['config']['filebase']['path'] = $root;
Filebase::write_data('docs', 'bucket-one/nested', 'meta', array('title' => 'safe needle'));
$filename = Filebase::get_data_filename('docs', 'bucket-one/nested', 'meta');
test_assert(str_starts_with($filename, $root.'docs/'), 'data filename stays inside configured filebase root');
test_assert(Filebase::read_data('docs', 'bucket-one/nested', 'meta')['title'] === 'safe needle', 'nested bucket data round-trips');
test_assert(Filebase::list_bucket('docs', 'bucket-one/nested') === array('meta.json'), 'list_bucket uses PHP directory listing');
test_assert(Filebase::search_bucket('docs', 'bucket-one/nested', 'needle') === array('meta'), 'search_bucket finds matching JSON without shell grep');
test_throws(function() { Filebase::get_data_filename('docs', '../escape', 'meta'); }, 'bucket path traversal is rejected');
test_throws(function() { Filebase::get_data_filename('../docs', 'bucket', 'meta'); }, 'class path traversal is rejected');
test_throws(function() { Filebase::get_data_filename('docs', 'bucket', '../meta'); }, 'type path traversal is rejected');
$escape_dir = $root.'escape-marker';
@mkdir($escape_dir, 0774, true);
file_put_contents($escape_dir.'/keep.txt', 'keep');
Filebase::delete_bucket('docs', 'bucket-one/nested');
test_assert(!file_exists($root.'docs/ne/bucket-one/nested'), 'delete_bucket removes the selected bucket');
test_assert(file_exists($escape_dir.'/keep.txt'), 'delete_bucket does not remove sibling paths outside the bucket');
Filebase::delete_directory($root);
echo "All Filebase path guard tests passed.\n";