diff --git a/samples/ImageSharp.Web.Sample/Pages/Index.cshtml b/samples/ImageSharp.Web.Sample/Pages/Index.cshtml index c492abf..73ad597 100644 --- a/samples/ImageSharp.Web.Sample/Pages/Index.cshtml +++ b/samples/ImageSharp.Web.Sample/Pages/Index.cshtml @@ -52,10 +52,10 @@

- sixlabors.imagesharp.web.svg?width=300 + sixlabors.imagesharp.web.svg?width=300&format=jpg

- +

diff --git a/src/ImageSharp.Web/FormatUtilities.cs b/src/ImageSharp.Web/FormatUtilities.cs index 4e9cba5..928241b 100644 --- a/src/ImageSharp.Web/FormatUtilities.cs +++ b/src/ImageSharp.Web/FormatUtilities.cs @@ -53,12 +53,19 @@ public FormatUtilities(IOptions options) [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetExtensionFromUri(string uri, [NotNullWhen(true)] out string? extension) { + // Attempts to extract a valid image file extension from the URI. + // If the path contains a recognized extension, it is used. + // If the path lacks an extension and a query string is present, + // the method checks for a valid 'format' parameter as a fallback. + // Returns true if a supported extension is found in either location. extension = null; int query = uri.IndexOf('?'); ReadOnlySpan path; if (query > -1) { + path = uri.AsSpan(0, query); + if (uri.Contains(FormatWebProcessor.Format, StringComparison.OrdinalIgnoreCase) && QueryHelpers.ParseQuery(uri[query..]).TryGetValue(FormatWebProcessor.Format, out StringValues ext)) { @@ -68,15 +75,13 @@ public bool TryGetExtensionFromUri(string uri, [NotNullWhen(true)] out string? e { if (extSpan.Equals(e, StringComparison.OrdinalIgnoreCase)) { + // We've found a valid extension in the query. + // Now we need to check the path to see if there is a file extension and validate that. extension = e; - return true; + break; } } - - return false; } - - path = uri.AsSpan(0, query); } else { @@ -92,13 +97,17 @@ public bool TryGetExtensionFromUri(string uri, [NotNullWhen(true)] out string? e { if (pathExtension.Equals(e, StringComparison.OrdinalIgnoreCase)) { - extension = e; + // We've found a valid extension in the path, however we do not + // want to overwrite an existing extension. + extension ??= e; return true; } } + + return false; } - return false; + return extension != null; } /// diff --git a/src/ImageSharp.Web/ImageSharp.Web.csproj b/src/ImageSharp.Web/ImageSharp.Web.csproj index aaf62cc..ccbd034 100644 --- a/src/ImageSharp.Web/ImageSharp.Web.csproj +++ b/src/ImageSharp.Web/ImageSharp.Web.csproj @@ -46,7 +46,7 @@ - + diff --git a/tests/ImageSharp.Web.Tests/Helpers/FormatUtilitiesTests.cs b/tests/ImageSharp.Web.Tests/Helpers/FormatUtilitiesTests.cs index cbc150a..104336d 100644 --- a/tests/ImageSharp.Web.Tests/Helpers/FormatUtilitiesTests.cs +++ b/tests/ImageSharp.Web.Tests/Helpers/FormatUtilitiesTests.cs @@ -46,9 +46,16 @@ public void GetExtensionShouldAcknowledgeQueryStringFormatParameter() } [Fact] - public void GetExtensionShouldRejectInvalidQueryStringFormatParameter() + public void GetExtensionShouldAllowInvalidQueryStringFormatParameterWithValidExtension() { const string uri = "http://www.example.org/some/path/to/image.bmp?width=300&format=invalid"; + Assert.True(FormatUtilities.TryGetExtensionFromUri(uri, out _)); + } + + [Fact] + public void GetExtensionShouldRejectInvalidPathWithValidQueryStringFormatParameter() + { + const string uri = "http://www.example.org/some/path/to/image.svg?width=300&format=jpg"; Assert.False(FormatUtilities.TryGetExtensionFromUri(uri, out _)); } }