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