mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-03 12:03:51 +08:00
#17601: Avoiding exceptions by proactively handling the scenario where the path falls outside of the app directory.
--HG-- branch : 1.x
This commit is contained in:
@@ -99,6 +99,10 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
public IEnumerable<string> ListDirectories(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryFileExists(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Resolve(ILifetimeScope container) {
|
||||
|
||||
@@ -97,6 +97,10 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
public IEnumerable<string> ListDirectories(string path) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryFileExists(string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Resolve(ILifetimeScope container) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
|
||||
namespace Orchard.Tests.FileSystems.VirtualPath {
|
||||
[TestFixture]
|
||||
public class DefaultVirtualPathProviderTests {
|
||||
[Test]
|
||||
public void TryFileExistsTest() {
|
||||
StubDefaultVirtualPathProvider defaultVirtualPathProvider = new StubDefaultVirtualPathProvider();
|
||||
|
||||
Assert.That(defaultVirtualPathProvider.TryFileExists("~\\a.txt"), Is.True);
|
||||
Assert.That(defaultVirtualPathProvider.TryFileExists("~\\..\\a.txt"), Is.False);
|
||||
Assert.That(defaultVirtualPathProvider.TryFileExists("~\\a\\..\\a.txt"), Is.True);
|
||||
Assert.That(defaultVirtualPathProvider.TryFileExists("~\\a\\b\\..\\a.txt"), Is.True);
|
||||
Assert.That(defaultVirtualPathProvider.TryFileExists("~\\a\\b\\..\\..\\a.txt"), Is.True);
|
||||
Assert.That(defaultVirtualPathProvider.TryFileExists("~\\a\\b\\..\\..\\..\\a.txt"), Is.False);
|
||||
}
|
||||
}
|
||||
|
||||
internal class StubDefaultVirtualPathProvider : DefaultVirtualPathProvider {
|
||||
public override bool FileExists(string path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,6 +253,7 @@
|
||||
<Compile Include="FileSystems\LockFile\LockFileManagerTests.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\AssemblyProbingFolderTests.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DependenciesFolderTests.cs" />
|
||||
<Compile Include="FileSystems\VirtualPath\DefaultVirtualPathProviderTests.cs" />
|
||||
<Compile Include="Localization\CultureManagerTests.cs" />
|
||||
<Compile Include="Messaging\MessagingChannelStub.cs" />
|
||||
<Compile Include="Mvc\Html\HtmlHelperExtensionsTests.cs" />
|
||||
|
||||
@@ -79,5 +79,14 @@ namespace Orchard.Tests.Stubs {
|
||||
.Directories
|
||||
.Select(f => Combine(path, f.Name));
|
||||
}
|
||||
|
||||
public bool TryFileExists(string virtualPath) {
|
||||
try {
|
||||
return FileExists(virtualPath);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,7 +203,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
: _virtualPathProvider.Combine(basePath, referenceDescriptor.Path);
|
||||
|
||||
// Attempt to reference the project / library file
|
||||
if (!currentSet.Contains(path) && _virtualPathProvider.FileExists(path)) {
|
||||
if (!string.IsNullOrEmpty(path) && !currentSet.Contains(path) && _virtualPathProvider.TryFileExists(path)) {
|
||||
currentSet.Add(path);
|
||||
|
||||
// In case of project, also reference the source files
|
||||
@@ -212,7 +212,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
|
||||
// Try to also reference any pre-built DLL
|
||||
DependencyDescriptor dependencyDescriptor = _dependenciesFolder.GetDescriptor(_virtualPathProvider.GetDirectoryName(referenceDescriptor.Path));
|
||||
if (dependencyDescriptor != null && _virtualPathProvider.FileExists(dependencyDescriptor.VirtualPath)) {
|
||||
if (dependencyDescriptor != null && _virtualPathProvider.TryFileExists(dependencyDescriptor.VirtualPath)) {
|
||||
currentSet.Add(dependencyDescriptor.VirtualPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ using System.Web.Hosting;
|
||||
|
||||
namespace Orchard.FileSystems.VirtualPath {
|
||||
public class DefaultVirtualPathProvider : IVirtualPathProvider {
|
||||
public string GetDirectoryName(string virtualPath) {
|
||||
public virtual string GetDirectoryName(string virtualPath) {
|
||||
return Path.GetDirectoryName(virtualPath).Replace(Path.DirectorySeparatorChar, '/');
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListFiles(string path) {
|
||||
public virtual IEnumerable<string> ListFiles(string path) {
|
||||
return HostingEnvironment
|
||||
.VirtualPathProvider
|
||||
.GetDirectory(path)
|
||||
@@ -20,7 +20,7 @@ namespace Orchard.FileSystems.VirtualPath {
|
||||
.Select(f => ToAppRelative(f.VirtualPath));
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListDirectories(string path) {
|
||||
public virtual IEnumerable<string> ListDirectories(string path) {
|
||||
return HostingEnvironment
|
||||
.VirtualPathProvider
|
||||
.GetDirectory(path)
|
||||
@@ -29,49 +29,63 @@ namespace Orchard.FileSystems.VirtualPath {
|
||||
.Select(d => ToAppRelative(d.VirtualPath));
|
||||
}
|
||||
|
||||
public string Combine(params string[] paths) {
|
||||
public virtual string Combine(params string[] paths) {
|
||||
return Path.Combine(paths).Replace(Path.DirectorySeparatorChar, '/');
|
||||
}
|
||||
|
||||
public string ToAppRelative(string virtualPath) {
|
||||
public virtual string ToAppRelative(string virtualPath) {
|
||||
return VirtualPathUtility.ToAppRelative(virtualPath);
|
||||
}
|
||||
|
||||
public Stream OpenFile(string virtualPath) {
|
||||
public virtual Stream OpenFile(string virtualPath) {
|
||||
return HostingEnvironment.VirtualPathProvider.GetFile(virtualPath).Open();
|
||||
}
|
||||
|
||||
public StreamWriter CreateText(string virtualPath) {
|
||||
public virtual StreamWriter CreateText(string virtualPath) {
|
||||
return File.CreateText(MapPath(virtualPath));
|
||||
}
|
||||
|
||||
public Stream CreateFile(string virtualPath) {
|
||||
public virtual Stream CreateFile(string virtualPath) {
|
||||
return File.Create(MapPath(virtualPath));
|
||||
}
|
||||
|
||||
public DateTime GetFileLastWriteTimeUtc(string virtualPath) {
|
||||
public virtual DateTime GetFileLastWriteTimeUtc(string virtualPath) {
|
||||
return File.GetLastWriteTimeUtc(MapPath(virtualPath));
|
||||
}
|
||||
|
||||
public string MapPath(string virtualPath) {
|
||||
public virtual string MapPath(string virtualPath) {
|
||||
return HostingEnvironment.MapPath(virtualPath);
|
||||
}
|
||||
|
||||
public bool FileExists(string virtualPath) {
|
||||
public virtual bool FileExists(string virtualPath) {
|
||||
return HostingEnvironment.VirtualPathProvider.FileExists(virtualPath);
|
||||
}
|
||||
|
||||
public virtual bool TryFileExists(string virtualPath) {
|
||||
try {
|
||||
return HostingEnvironment.VirtualPathProvider.FileExists(virtualPath);
|
||||
} catch {
|
||||
// Medium Trust or invalid mappings that fall outside the app folder
|
||||
// Check if the path falls outside the root directory of the app
|
||||
string directoryName = Path.GetDirectoryName(virtualPath);
|
||||
if (CountOccurences(@"\", directoryName.Replace(@"\..", "")) < CountOccurences(@"..", directoryName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return FileExists(virtualPath);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string virtualPath) {
|
||||
public virtual bool DirectoryExists(string virtualPath) {
|
||||
return HostingEnvironment.VirtualPathProvider.DirectoryExists(virtualPath);
|
||||
}
|
||||
|
||||
public void CreateDirectory(string virtualPath) {
|
||||
public virtual void CreateDirectory(string virtualPath) {
|
||||
Directory.CreateDirectory(MapPath(virtualPath));
|
||||
}
|
||||
|
||||
private static int CountOccurences(string needle, string haystack) {
|
||||
return (haystack.Length - haystack.Replace(needle, "").Length) / needle.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ namespace Orchard.FileSystems.VirtualPath {
|
||||
string MapPath(string virtualPath);
|
||||
|
||||
bool FileExists(string virtualPath);
|
||||
bool TryFileExists(string virtualPath);
|
||||
Stream OpenFile(string virtualPath);
|
||||
StreamWriter CreateText(string virtualPath);
|
||||
Stream CreateFile(string virtualPath);
|
||||
|
||||
@@ -17,13 +17,13 @@ namespace Orchard.Utility.Extensions {
|
||||
public static string GetReferenceVirtualPath(this IVirtualPathProvider virtualPathProvider, string basePath, string referenceName, string hintPath) {
|
||||
// Check if hint path is valid
|
||||
if (!string.IsNullOrEmpty(hintPath)) {
|
||||
if (virtualPathProvider.FileExists(virtualPathProvider.Combine(basePath, hintPath)))
|
||||
if (virtualPathProvider.TryFileExists(virtualPathProvider.Combine(basePath, hintPath)))
|
||||
return hintPath;
|
||||
}
|
||||
|
||||
// Fall back to bin directory
|
||||
string relativePath = virtualPathProvider.Combine("bin", referenceName + ".dll");
|
||||
if (virtualPathProvider.FileExists(virtualPathProvider.Combine(basePath, relativePath)))
|
||||
if (virtualPathProvider.TryFileExists(virtualPathProvider.Combine(basePath, relativePath)))
|
||||
return relativePath;
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user