From b048c83172f8ae686f3bc0b3a5fc01ff78a8170e Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Wed, 17 Jan 2024 20:13:38 +0100 Subject: [PATCH] Web-Optimized Image Delivery: Sanitize SEO name (#36) --- .../dam/impl/weboptimized/ParameterMap.java | 16 +++++++++++++++- ...WebOptimizedImageDeliveryServiceImplTest.java | 6 +++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/wcm/handler/mediasource/dam/impl/weboptimized/ParameterMap.java b/src/main/java/io/wcm/handler/mediasource/dam/impl/weboptimized/ParameterMap.java index 574e7c60..bded7466 100644 --- a/src/main/java/io/wcm/handler/mediasource/dam/impl/weboptimized/ParameterMap.java +++ b/src/main/java/io/wcm/handler/mediasource/dam/impl/weboptimized/ParameterMap.java @@ -22,6 +22,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; @@ -44,6 +46,8 @@ final class ParameterMap { static final String PARAM_ROTATE = "r"; static final String PARAM_QUALITY = "quality"; + static final Pattern SEO_NAME_FILTER_PATTERN = Pattern.compile("[\\W_]"); + private static final Set SUPPORTED_FORMATS = Set.of( FileExtension.JPEG, FileExtension.PNG, @@ -72,7 +76,7 @@ static Map build(@NotNull Asset asset, @NotNull WebOptimizedImag // please note: AssetDelivery API expects all values as strings Map map = new HashMap<>(); map.put(PARAM_PATH, path); - map.put(PARAM_SEO_NAME, seoName); + map.put(PARAM_SEO_NAME, sanitizeSeoName(seoName)); map.put(PARAM_FORMAT, format); map.put(PARAM_PREFER_WEBP, "true"); if (width != null) { @@ -90,4 +94,14 @@ static Map build(@NotNull Asset asset, @NotNull WebOptimizedImag return map; } + /** + * Sanitizes the SEO name to avoid problems with special characters in URLs. + * @param name Name + * @return Sanitzed name + */ + private static String sanitizeSeoName(String name) { + Matcher matcher = SEO_NAME_FILTER_PATTERN.matcher(name); + return StringUtils.toRootLowerCase(matcher.replaceAll("-")); + } + } diff --git a/src/test/java/io/wcm/handler/mediasource/dam/impl/weboptimized/WebOptimizedImageDeliveryServiceImplTest.java b/src/test/java/io/wcm/handler/mediasource/dam/impl/weboptimized/WebOptimizedImageDeliveryServiceImplTest.java index a7d1aaee..532c34f4 100644 --- a/src/test/java/io/wcm/handler/mediasource/dam/impl/weboptimized/WebOptimizedImageDeliveryServiceImplTest.java +++ b/src/test/java/io/wcm/handler/mediasource/dam/impl/weboptimized/WebOptimizedImageDeliveryServiceImplTest.java @@ -73,13 +73,13 @@ void testGetDeliveryUrl_AssetDeliveryNotPresent() { void testGetDeliveryUrl_AssetDeliveryPresent() { context.registerInjectActivateService(MockAssetDelivery.class); WebOptimizedImageDeliveryService underTest = context.registerInjectActivateService(WebOptimizedImageDeliveryServiceImpl.class); - Asset asset = context.create().asset("/content/dam/test.jpg", 10, 10, ContentType.JPEG); + Asset asset = context.create().asset("/content/dam/Test_1.jpg", 10, 10, ContentType.JPEG); String assetId = MockAssetDelivery.getAssetId(asset); - assertEquals("/asset/delivery/" + assetId + "/test.jpg?preferwebp=true", + assertEquals("/asset/delivery/" + assetId + "/test-1.jpg?preferwebp=true", underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams())); - assertEquals("/asset/delivery/" + assetId + "/test.jpg?c=0%2C0%2C2%2C4&preferwebp=true&r=90&width=10", + assertEquals("/asset/delivery/" + assetId + "/test-1.jpg?c=0%2C0%2C2%2C4&preferwebp=true&r=90&width=10", underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams() .width(10L).cropDimension(new CropDimension(0, 0, 2, 4)).rotation(90))); }