markTestSkipped('CACTI_PATH_RRA does not resolve to a directory this process can create fixtures under'); } expect(data_source_path_within_rra(data_source_path_test_base() . '/host_ds.rrd'))->toBeTrue() ->and(data_source_path_within_rra(data_source_path_test_base() . '/1/host_ds.rrd'))->toBeTrue(); }); test('a not-yet-created file under the RRA directory is still contained', function () use ($rra_ready) : void { if (!$rra_ready) { $this->markTestSkipped('CACTI_PATH_RRA does not resolve to a directory this process can create fixtures under'); } expect(data_source_path_within_rra(data_source_path_test_base() . '/1/new_ds.rrd'))->toBeTrue(); }); test('an absolute path elsewhere is rejected', function () : void { expect(data_source_path_within_rra('/var/www/html/cacti/resource/x.php'))->toBeFalse() ->and(data_source_path_within_rra('/tmp/x.rrd'))->toBeFalse(); }); test('traversal out of the RRA directory is rejected', function () : void { expect(data_source_path_within_rra(data_source_path_test_base() . '/../resource/x.rrd'))->toBeFalse() ->and(data_source_path_within_rra(data_source_path_test_base() . '/a/../../etc/x'))->toBeFalse(); }); test('a relative path or a lookalike prefix is rejected', function () : void { expect(data_source_path_within_rra('1/host_ds.rrd'))->toBeFalse() ->and(data_source_path_within_rra(data_source_path_test_base() . '_evil/x.rrd'))->toBeFalse(); }); test('empty and null-byte paths are rejected', function () : void { expect(data_source_path_within_rra(''))->toBeFalse() ->and(data_source_path_within_rra("/tmp/x\0.rrd"))->toBeFalse(); }); test('a symlink pivot below the RRA directory is rejected even for a not-yet-created file', function () use ($rra_ready) : void { if (!$rra_ready) { $this->markTestSkipped('CACTI_PATH_RRA does not resolve to a directory this process can create fixtures under'); } $outside = sys_get_temp_dir() . '/cacti_rra_outside_' . bin2hex(random_bytes(6)); mkdir($outside, 0755, true); $link = data_source_path_test_base() . '/linked'; if (!@symlink($outside, $link)) { $this->markTestSkipped('symlink() is not available in this environment'); } try { expect(data_source_path_within_rra($link . '/escaped.rrd'))->toBeFalse(); } finally { unlink($link); rmdir($outside); } });