Pchp.Library.Streams.PhpStream.ResolvePath C# (CSharp) Method

ResolvePath() public static method

Merges the path with the current working directory to get a canonicalized absolute pathname representing the same file.
This method is an analogy of main/safe_mode.c: php_checkuid. Looks for the file in the include_path and checks for open_basedir restrictions.
Security violation - when the target file /// lays outside the tree defined by open_basedir configuration option.
public static ResolvePath ( Context ctx, string &path, StreamWrapper &wrapper, CheckAccessMode mode, CheckAccessOptions options ) : bool
ctx Pchp.Core.Context Current runtime context.
path string An absolute or relative path to a file.
wrapper StreamWrapper The wrapper found for the specified file or null if the path resolution fails.
mode CheckAccessMode The checking mode of the method (file, directory etc.).
options CheckAccessOptions Additional options for the method.
return bool
        public static bool ResolvePath(Context ctx, ref string path, out StreamWrapper wrapper, CheckAccessMode mode, CheckAccessOptions options)
        {
            // Path will contain the absolute path without file:// or the complete URL; filename is the relative path.
            string filename, scheme = GetSchemeInternal(path, out filename);
            wrapper = StreamWrapper.GetWrapper(ctx, scheme, (StreamOptions)options);
            if (wrapper == null) return false;

            if (wrapper.IsUrl)
            {
                // Note: path contains the whole URL, filename the same without the scheme:// portion.
                // What to check more?
            }
            else if (scheme != "php")
            {
                try
                {
                    // Filename contains the original path without the scheme:// portion, check for include path.
                    bool isInclude = false;
                    if ((options & CheckAccessOptions.UseIncludePath) > 0)
                    {
                        isInclude = CheckIncludePath(ctx, filename, ref path);
                    }

                    // Path will now contain an absolute path (either to an include or actual directory).
                    if (!isInclude)
                    {
                        path = Path.GetFullPath(Path.Combine(ctx.WorkingDirectory, filename));
                    }
                }
                catch (System.Exception)
                {
                    if ((options & CheckAccessOptions.Quiet) == 0)
                        PhpException.Throw(PhpError.Warning, ErrResources.stream_filename_invalid, FileSystemUtils.StripPassword(path));
                    return false;
                }

                // NOTE: we should let OS & Security configuration to decide
                //var global_config = Configuration.Global;

                //// Note: extensions check open_basedir too -> double check..
                //if (!global_config.SafeMode.IsPathAllowed(path))
                //{
                //    if ((options & CheckAccessOptions.Quiet) == 0)
                //        PhpException.Throw(PhpError.Warning, ErrResources.open_basedir_effect, path, global_config.SafeMode.GetAllowedPathPrefixesJoin());
                //    return false;
                //}

                // Replace all '/' with '\'.
                // path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                Debug.Assert(
                    path.IndexOf(Path.AltDirectorySeparatorChar) == -1 ||
                    (Path.AltDirectorySeparatorChar == Path.DirectorySeparatorChar),    // on Mono, so ignore it
                    string.Format("'{0}' should not contain '{1}' char.", path, Path.AltDirectorySeparatorChar));

                // The file wrapper expects an absolute path w/o the scheme, others expect the scheme://url.
                if (scheme != "file")
                {
                    path = String.Format("{0}://{1}", scheme, path);
                }
            }

            return true;
        }