resolvePath method
Resolves the given path
relative to the currentDirectory.
The resolved path is normalized and checked to ensure it stays within the rootDirectory.
If the path
is absolute and matches part of the currentDirectory, the common prefix is removed.
If the path
is relative, it is resolved relative to the currentDirectory.
Examples:
// Given rootDirectory = '/home/user/project' and currentDirectory = '/home/user/project/subdir'
resolvePath('file.txt'); // Returns: '/home/user/project/subdir/file.txt'
resolvePath('/home/user/project/subdir/file.txt'); // Returns: '/home/user/project/subdir/file.txt'
resolvePath('/home/user'); // Throws FileSystemException (outside root)
resolvePath('../../file.txt'); // Throws FileSystemException (attempt to go above root)
Implementation
@override
String resolvePath(String path) {
// // Convert Windows-style backslashes to forward slashes for consistency
// path = path.replaceAll(r'\', '/');
// If the path is empty or a relative path, append it to the current directory
final effectivePath =
p.isAbsolute(path) ? path : p.join(currentDirectory, path);
// Normalize the path to handle ../, ./, etc.
var virtualPath = p.normalize(effectivePath);
// Handle the case where the root directory is requested
if (virtualPath == rootDirectory) {
return rootDirectory;
}
// Extract the first segment of the path to match against directory mappings
final firstSegment = p.split(virtualPath).firstWhere(
(part) => part.isNotEmpty && part != p.rootPrefix(rootDirectory),
orElse: () => rootDirectory);
// Check if the first segment is mapped to an allowed directory
if (!directoryMappings.containsKey(firstSegment)) {
throw FileSystemException(
"Access denied or directory not found: path requested $path, firstSegment is $firstSegment, directoryMappings $directoryMappings");
}
// Get the mapped directory and construct the remaining path
final mappedDir = directoryMappings[firstSegment]!;
final remainingPath =
p.relative(virtualPath, from: '$rootDirectory$firstSegment');
// Resolve the final path and ensure it is within the allowed directories
final resolvedPath = p.normalize(p.join(mappedDir, remainingPath));
return _resolvePathWithinRoot(resolvedPath);
}