public string MapPathVirtualToPhysical(string virtualPath) { if (virtualPath._IsEmpty()) { return(""); } // virtualPath must be UNIX-style absolute path // / // /abc/def // /abc/def/ // /abc/def/readme.txt // /abc/def/../readme.txt // /abc/def/../../readme.txt // /abc/def/../../../readme.txt virtualPath = PathParser.NormalizeDirectorySeparatorAndCheckIfAbsolutePath(virtualPath); // remove any dangerous relative directory strings // / ----> / (unchanged) // /abc/def ----> /abc/def (unchanged) // /abc/def/ ----> /abc/def (the last '/' is removed) // /abc/def/readme.txt ----> /abc/def/readme.txt (unchanged) // /abc/def/../readme.txt ----> /abc/readme.txt (normalized for security) // /abc/def/../../readme.txt ----> /readme.txt (normalized for security) // /abc/def/../../../readme.txt ----> /readme.txt (normalized for security) virtualPath = PathParser.NormalizeUnixStylePathWithRemovingRelativeDirectoryElements(virtualPath); // remove the first letter if (virtualPath.Length == 0 || virtualPath[0] != '/') { throw new MapPathException($"The normalized virtual path \"{virtualPath}\" does not an absolute path."); } virtualPath = virtualPath.Substring(1); // the contents of virtualPath: // '' (empty) - representing the root directory // readme.txt // abc/def // abc/def/readme.txt // converting the naming convention virtualPath = PathParser.ConvertDirectorySeparatorToOtherSystem(virtualPath, UnderlayPathParser); // the contents of virtualPath: // '' (empty) - representing the root directory // readme.txt // abc\def // abc\def\readme.txt // Make sure the path is not an absolute if (PathParser.IsAbsolutePath(virtualPath, true)) { throw new MapPathException($"The virtualPath \"{virtualPath}\" must not be an absolute path here."); } // delegating to the derive class string physicalPath = MapPathVirtualToPhysicalImpl(virtualPath); // the contents of physicalPath: // c:\view_root // c:\view_root\readme.txt // c:\view_root\abc\def // c:\view_root\abc\def\readme.txt return(physicalPath); }