resolvePath method

  1. @override
String resolvePath(
  1. String path
)
override

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);
}