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