diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs
index 8378081394..286acf0285 100644
--- a/src/Umbraco.Core/IO/IOHelper.cs
+++ b/src/Umbraco.Core/IO/IOHelper.cs
@@ -177,12 +177,23 @@ namespace Umbraco.Core.IO
/// A value indicating whether the filepath is valid.
internal static bool VerifyEditPath(string filePath, IEnumerable validDirs)
{
+ // this is called from ScriptRepository, PartialViewRepository, etc.
+ // filePath is the fullPath (rooted, filesystem path, can be trusted)
+ // validDirs are virtual paths (eg ~/Views)
+ //
+ // except that for templates, filePath actually is a virtual path
+
+ //TODO
+ // what's below is dirty, there are too many ways to get the root dir, etc.
+ // not going to fix everything today
+
var mappedRoot = MapPath(SystemDirectories.Root);
if (filePath.StartsWith(mappedRoot) == false)
filePath = MapPath(filePath);
- // don't trust what we get, it may contain relative segments
- filePath = Path.GetFullPath(filePath);
+ // yes we can (see above)
+ //// don't trust what we get, it may contain relative segments
+ //filePath = Path.GetFullPath(filePath);
foreach (var dir in validDirs)
{
@@ -190,7 +201,7 @@ namespace Umbraco.Core.IO
if (validDir.StartsWith(mappedRoot) == false)
validDir = MapPath(validDir);
- if (filePath.StartsWith(validDir))
+ if (PathStartsWith(filePath, validDir, Path.DirectorySeparatorChar))
return true;
}
@@ -237,6 +248,16 @@ namespace Umbraco.Core.IO
return true;
}
+ public static bool PathStartsWith(string path, string root, char separator)
+ {
+ // either it is identical to root,
+ // or it is root + separator + anything
+
+ if (path.StartsWith(root, StringComparison.OrdinalIgnoreCase) == false) return false;
+ if (path.Length == root.Length) return true;
+ if (path.Length < root.Length) return false;
+ return path[root.Length] == separator;
+ }
///
/// Returns the path to the root of the application, by getting the path to where the assembly where this
diff --git a/src/Umbraco.Core/IO/PhysicalFileSystem.cs b/src/Umbraco.Core/IO/PhysicalFileSystem.cs
index 79b453e9cb..b801f05b8f 100644
--- a/src/Umbraco.Core/IO/PhysicalFileSystem.cs
+++ b/src/Umbraco.Core/IO/PhysicalFileSystem.cs
@@ -186,14 +186,14 @@ namespace Umbraco.Core.IO
{
// test url
var path = EnsureUrlSeparatorChar(fullPathOrUrl);
- if (PathStartsWith(path, _rootUrl, '/'))
+ if (IOHelper.PathStartsWith(path, _rootUrl, '/'))
return path.Substring(_rootUrl.Length)
.Replace('/', Path.DirectorySeparatorChar)
.TrimStart(Path.DirectorySeparatorChar);
// test path
path = EnsureDirectorySeparatorChar(fullPathOrUrl);
- if (PathStartsWith(path, _rootPath, Path.DirectorySeparatorChar))
+ if (IOHelper.PathStartsWith(path, _rootPath, Path.DirectorySeparatorChar))
return path.Substring(_rootPath.Length)
.TrimStart(Path.DirectorySeparatorChar);
@@ -231,7 +231,7 @@ namespace Umbraco.Core.IO
path = GetRelativePath(path);
// if already a full path, return
- if (PathStartsWith(path, _rootPath, Path.DirectorySeparatorChar))
+ if (IOHelper.PathStartsWith(path, _rootPath, Path.DirectorySeparatorChar))
return path;
// else combine and sanitize, ie GetFullPath will take care of any relative
@@ -243,23 +243,12 @@ namespace Umbraco.Core.IO
// at that point, path is within legal parts of the filesystem, ie we have
// permissions to reach that path, but it may nevertheless be outside of
// our root path, due to relative segments, so better check
- if (PathStartsWith(fpath, _rootPath, Path.DirectorySeparatorChar))
+ if (IOHelper.PathStartsWith(fpath, _rootPath, Path.DirectorySeparatorChar))
return fpath;
throw new FileSecurityException("File '" + opath + "' is outside this filesystem's root.");
}
- private static bool PathStartsWith(string path, string root, char separator)
- {
- // either it is identical to root,
- // or it is root + separator + anything
-
- if (path.StartsWith(root, StringComparison.OrdinalIgnoreCase) == false) return false;
- if (path.Length == root.Length) return true;
- if (path.Length < root.Length) return false;
- return path[root.Length] == separator;
- }
-
public string GetUrl(string path)
{
path = EnsureUrlSeparatorChar(path).Trim('/');
diff --git a/src/Umbraco.Core/Persistence/Repositories/FileRepository.cs b/src/Umbraco.Core/Persistence/Repositories/FileRepository.cs
index 04ac5b6f62..e1e4c3105a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/FileRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/FileRepository.cs
@@ -147,10 +147,6 @@ namespace Umbraco.Core.Persistence.Repositories
protected virtual void PersistUpdatedItem(TEntity entity)
{
- //TODO: A big problem here is if the entities 'Path' changes, if that is the case then
- // we'd need to rename the underlying file, BUT how would we do this since we aren't storing an
- // original path property.
-
using (var stream = GetContentStream(entity.Content))
{
FileSystem.AddFile(entity.Path, stream, true);
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IPartialViewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IPartialViewRepository.cs
index 8ba28eeaee..3fbcdd3283 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IPartialViewRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IPartialViewRepository.cs
@@ -6,5 +6,6 @@ namespace Umbraco.Core.Persistence.Repositories
{
void AddFolder(string folderPath);
void DeleteFolder(string folderPath);
+ bool ValidatePartialView(IPartialView partialView);
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/PartialViewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PartialViewRepository.cs
index 254d2cbc0c..e9352a945f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/PartialViewRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/PartialViewRepository.cs
@@ -24,20 +24,24 @@ namespace Umbraco.Core.Persistence.Repositories
public override IPartialView Get(string id)
{
- if (FileSystem.FileExists(id) == false)
- {
- return null;
- }
-
+ // get the relative path within the filesystem
+ // (though... id should be relative already)
var path = FileSystem.GetRelativePath(id);
+
+ if (FileSystem.FileExists(path) == false)
+ return null;
+
+ // content will be lazy-loaded when required
var created = FileSystem.GetCreated(path).UtcDateTime;
var updated = FileSystem.GetLastModified(path).UtcDateTime;
+ //var content = GetFileContent(path);
- var script = new PartialView(path, file => GetFileContent(file.Path))
+ var view = new PartialView(path, file => GetFileContent(file.OriginalPath))
{
//id can be the hash
Id = path.GetHashCode(),
Key = path.EncodeAsGuid(),
+ //Content = content,
CreateDate = created,
UpdateDate = updated,
VirtualPath = FileSystem.GetUrl(id),
@@ -46,9 +50,9 @@ namespace Umbraco.Core.Persistence.Repositories
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
- script.ResetDirtyProperties(false);
+ view.ResetDirtyProperties(false);
- return script;
+ return view;
}
public override void AddOrUpdate(IPartialView entity)
@@ -61,7 +65,7 @@ namespace Umbraco.Core.Persistence.Repositories
// ensure that from now on, content is lazy-loaded
if (partialView != null && partialView.GetFileContent == null)
- partialView.GetFileContent = file => GetFileContent(file.Path);
+ partialView.GetFileContent = file => GetFileContent(file.OriginalPath);
}
public override IEnumerable GetAll(params string[] ids)
@@ -86,6 +90,29 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
+ private static readonly List ValidExtensions = new List { "cshtml" };
+
+ public virtual bool ValidatePartialView(IPartialView partialView)
+ {
+ // get full path
+ string fullPath;
+ try
+ {
+ // may throw for security reasons
+ fullPath = FileSystem.GetFullPath(partialView.Path);
+ }
+ catch
+ {
+ return false;
+ }
+
+ // validate path & extension
+ var validDir = SystemDirectories.MvcViews;
+ var isValidPath = IOHelper.VerifyEditPath(fullPath, validDir);
+ var isValidExtension = IOHelper.VerifyFileExtension(fullPath, ValidExtensions);
+ return isValidPath && isValidExtension;
+ }
+
///
/// Gets a stream that is used to write to the file
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/ScriptRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ScriptRepository.cs
index e288efdc85..13b2877c50 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ScriptRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ScriptRepository.cs
@@ -38,7 +38,7 @@ namespace Umbraco.Core.Persistence.Repositories
var updated = FileSystem.GetLastModified(path).UtcDateTime;
//var content = GetFileContent(path);
- var script = new Script(path, file => GetFileContent(file.Path))
+ var script = new Script(path, file => GetFileContent(file.OriginalPath))
{
//id can be the hash
Id = path.GetHashCode(),
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Persistence.Repositories
// ensure that from now on, content is lazy-loaded
if (entity.GetFileContent == null)
- entity.GetFileContent = file => GetFileContent(file.Path);
+ entity.GetFileContent = file => GetFileContent(file.OriginalPath);
}
public override IEnumerable