From 2ec08610518ea2cdc9a03d8c84d95530eba0365c Mon Sep 17 00:00:00 2001 From: Joe Delly Date: Tue, 24 Mar 2020 13:35:11 -0400 Subject: [PATCH] Fix for exception throw when validating URLs (#7701) --- src/Umbraco.Core/StringExtensions.cs | 15 +++++++++++++++ .../Strings/StringExtensionsTests.cs | 18 ++++++++++++++++++ .../PropertyEditors/UploadFileTypeValidator.cs | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 4451fdbba7..c37f8bdf35 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -79,6 +79,21 @@ namespace Umbraco.Core } + /// + /// Determines the extension of the path or URL + /// + /// + /// Extension of the file + public static string GetFileExtension(this string file) + { + //Find any characters between the last . and the start of a query string or the end of the string + const string pattern = @"(?\.[^\.\?]+)(\?.*|$)"; + var match = Regex.Match(file, pattern); + return match.Success + ? match.Groups["extension"].Value + : string.Empty; + } + /// /// Based on the input string, this will detect if the string is a JS path or a JS snippet. /// If a path cannot be determined, then it is assumed to be a snippet the original text is returned diff --git a/src/Umbraco.Tests/Strings/StringExtensionsTests.cs b/src/Umbraco.Tests/Strings/StringExtensionsTests.cs index 4c365d733f..39ffeed205 100644 --- a/src/Umbraco.Tests/Strings/StringExtensionsTests.cs +++ b/src/Umbraco.Tests/Strings/StringExtensionsTests.cs @@ -70,6 +70,24 @@ namespace Umbraco.Tests.Strings Assert.AreEqual(stripped, result); } + [TestCase("../wtf.js?x=wtf", ".js")] + [TestCase(".htaccess", ".htaccess")] + [TestCase("path/to/file/image.png", ".png")] + [TestCase("c:\\abc\\def\\ghi.jkl", ".jkl")] + [TestCase("/root/folder.name/file.ext", ".ext")] + [TestCase("http://www.domain.com/folder/name/file.txt", ".txt")] + [TestCase("i/don't\\have\\an/extension", "")] + [TestCase("https://some.where/path/to/file.ext?query=this&more=that", ".ext")] + [TestCase("double_query.string/file.ext?query=abc?something.else", ".ext")] + [TestCase("test.tar.gz", ".gz")] + [TestCase("wierd.file,but._legal", "._legal")] + [TestCase("one_char.x", ".x")] + public void Get_File_Extension(string input, string result) + { + var extension = input.GetFileExtension(); + Assert.AreEqual(result, extension); + } + [TestCase("'+alert(1234)+'", "+alert1234+")] [TestCase("'+alert(56+78)+'", "+alert56+78+")] [TestCase("{{file}}", "file")] diff --git a/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs b/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs index 6855ab3bb8..8d7bd29889 100644 --- a/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs +++ b/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.PropertyEditors internal static bool IsValidFileExtension(string fileName) { if (fileName.IndexOf('.') <= 0) return false; - var extension = new FileInfo(fileName).Extension.TrimStart("."); + var extension = fileName.GetFileExtension().TrimStart("."); return Current.Configs.Settings().Content.IsFileAllowedForUpload(extension); } }