Skip to content

Commit 117d4f5

Browse files
committed
WICKET-7024 URL sanitization for not mounted resources
1 parent 755a63a commit 117d4f5

File tree

6 files changed

+121
-31
lines changed

6 files changed

+121
-31
lines changed

wicket-core-tests/src/test/java/org/apache/wicket/core/request/mapper/TestMapperContext.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public ResourceReferenceRegistry getResourceReferenceRegistry()
126126
private final ResourceReferenceRegistry registry = new ResourceReferenceRegistry()
127127
{
128128
@Override
129-
protected ResourceReference createDefaultResourceReference(Key key)
129+
protected ResourceReference createDefaultResourceReference(Key key, boolean updateCache)
130130
{
131131
// Do not create package resource here because it requires "real" application
132132
return null;

wicket-core-tests/src/test/java/org/apache/wicket/core/request/resource/LessResourceReferenceTest.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@
2929
import org.apache.wicket.markup.html.WebPage;
3030
import org.apache.wicket.mock.MockApplication;
3131
import org.apache.wicket.protocol.http.WebApplication;
32-
import org.apache.wicket.request.resource.CssPackageResource;
33-
import org.apache.wicket.request.resource.CssResourceReference;
34-
import org.apache.wicket.request.resource.PackageResource;
35-
import org.apache.wicket.request.resource.ResourceReference;
36-
import org.apache.wicket.request.resource.ResourceReferenceRegistry;
32+
import org.apache.wicket.request.resource.*;
3733
import org.apache.wicket.util.file.Files;
3834
import org.apache.wicket.util.resource.IResourceStream;
3935
import org.apache.wicket.util.resource.StringResourceStream;
@@ -54,7 +50,7 @@ class LessResourceReferenceTest extends WicketTestCase
5450
* An {@link org.apache.wicket.request.resource.IResourceReferenceFactory} that creates
5551
* LessResourceReference for resources with extension '.less'
5652
*/
57-
static class LessResourceReferenceFactory extends ResourceReferenceRegistry.DefaultResourceReferenceFactory
53+
static class LessResourceReferenceFactory implements IResourceReferenceFactory
5854
{
5955
@Override
6056
public ResourceReference create(ResourceReference.Key key)
@@ -68,7 +64,8 @@ public ResourceReference create(ResourceReference.Key key)
6864
}
6965
else
7066
{
71-
result = super.create(key);
67+
result = new ResourceReferenceRegistry.DefaultResourceReferenceFactory().create(
68+
key);
7269
}
7370
}
7471
return result;

wicket-core-tests/src/test/java/org/apache/wicket/core/request/resource/PackageResourceReferenceTest.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
class PackageResourceReferenceTest extends WicketTestCase
7070
{
7171
private static Class<PackageResourceReferenceTest> scope = PackageResourceReferenceTest.class;
72-
private static final Locale defaultLocale = Locale.CHINA;
72+
private static final Locale defaultLocale = Locale.CHINA;
7373
private static final Locale[] locales = { null, new Locale("en"), new Locale("en", "US") };
7474
private static final String[] styles = { null, "style" };
7575
private static final String[] variations = { null, "var" };
@@ -444,13 +444,15 @@ public void decodeStyleFromUrl()
444444
}
445445

446446
@Test
447-
@Disabled
448447
public void doNotFindResourceInTheCache()
449448
{
450449
IResourceStreamLocator resourceStreamLocator = mock(IResourceStreamLocator.class);
451450
when(resourceStreamLocator.locate(scope, "org/apache/wicket/core/request/resource/a.css",
452451
"yellow", null, defaultLocale, null, false)).thenReturn(
453452
new UrlResourceStream(scope.getResource("a.css")));
453+
when(resourceStreamLocator.locate(scope, "org/apache/wicket/core/request/resource/a.css",
454+
"yellow", null, null, null, false)).thenReturn(
455+
new UrlResourceStream(scope.getResource("a.css")));
454456

455457
tester.getApplication().getResourceSettings()
456458
.setResourceStreamLocator(new CachingResourceStreamLocator(resourceStreamLocator));
@@ -460,8 +462,12 @@ public void doNotFindResourceInTheCache()
460462
tester.executeUrl(
461463
"wicket/resource/org.apache.wicket.core.request.resource.PackageResourceReferenceTest/a.css?-yellow");
462464

465+
// WICKET-7129: proposal to remove the duplicated resource resolution
466+
verify(resourceStreamLocator, times(2)).locate(PackageResourceReferenceTest.class,
467+
"org/apache/wicket/core/request/resource/a.css", "yellow", null, null, null, false);
463468
verify(resourceStreamLocator, times(2)).locate(PackageResourceReferenceTest.class,
464-
"org/apache/wicket/core/request/resource/a.css", "yellow", null, defaultLocale, null, false);
469+
"org/apache/wicket/core/request/resource/a.css", "yellow", null, defaultLocale, null,
470+
false);
465471
}
466472

467473
@Test

wicket-core/src/main/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapper.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,20 @@ public IRequestHandler mapRequest(Request request)
130130

131131
Class<?> scope = resolveClass(className);
132132

133-
// attributes = PackageResource.sanitize(attributes, scope, name.toString());
134-
135133
if (scope != null && scope.getPackage() != null)
136134
{
135+
ResourceReference auxRes = getContext().getResourceReferenceRegistry()
136+
.getResourceReference(scope, name.toString(), attributes.getLocale(),
137+
attributes.getStyle(), attributes.getVariation(), true, true, false);
138+
if (auxRes != null)
139+
{
140+
IResource resource = auxRes.getResource();
141+
if (resource instanceof PackageResource packageResource)
142+
{
143+
attributes = PackageResource.sanitize(attributes, scope, name.toString());
144+
}
145+
}
146+
137147
ResourceReference res = getContext().getResourceReferenceRegistry()
138148
.getResourceReference(scope, name.toString(), attributes.getLocale(),
139149
attributes.getStyle(), attributes.getVariation(), true, true);

wicket-core/src/main/java/org/apache/wicket/request/resource/PackageResource.java

+39-4
Original file line numberDiff line numberDiff line change
@@ -737,15 +737,50 @@ public static boolean exists(final ResourceReference.Key key)
737737
* @param variation
738738
* The component's variation (of the style)
739739
* @return {@code true} if a resource could be loaded, {@code false} otherwise
740+
*
741+
* @deprecated @see {@link PackageResource#exists(Class, String, Locale, String, String, boolean)}
740742
*/
741743
public static boolean exists(final Class<?> scope, final String path, final Locale locale,
742744
final String style, final String variation)
745+
{
746+
return exists(scope, path, locale, style, variation, true);
747+
}
748+
749+
/**
750+
* Checks whether a resource for a given set of criteria exists.
751+
*
752+
* @param scope
753+
* This argument will be used to get the class loader for loading the package
754+
* resource, and to determine what package it is in. Typically this is the class in
755+
* which you call this method
756+
* @param path
757+
* The path to the resource
758+
* @param locale
759+
* The locale of the resource
760+
* @param style
761+
* The style of the resource (see {@link org.apache.wicket.Session})
762+
* @param variation
763+
* The component's variation (of the style)
764+
* @param updateCache
765+
* if the server resource stream reference cache should be updated
766+
* @return {@code true} if a resource could be loaded, {@code false} otherwise
767+
*/
768+
public static boolean exists(final Class<?> scope, final String path, final Locale locale,
769+
final String style, final String variation, final boolean updateCache)
743770
{
744771
String absolutePath = Packages.absolutePath(scope, path);
745-
return Application.get()
746-
.getResourceSettings()
747-
.getResourceStreamLocator()
748-
.locate(scope, absolutePath, style, variation, locale, null, false) != null;
772+
IResourceStreamLocator resourceStreamLocator = Application.get().getResourceSettings()
773+
.getResourceStreamLocator();
774+
if (resourceStreamLocator instanceof CachingResourceStreamLocator cache)
775+
{
776+
return cache.locate(scope, absolutePath, style, variation, locale, null, false,
777+
updateCache) != null;
778+
}
779+
else
780+
{
781+
return resourceStreamLocator.locate(scope, absolutePath, style, variation, locale, null,
782+
false) != null;
783+
}
749784
}
750785

751786
@Override

wicket-core/src/main/java/org/apache/wicket/request/resource/ResourceReferenceRegistry.java

+56-14
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,15 @@ public static class DefaultResourceReferenceFactory implements IResourceReferenc
7474
{
7575
@Override
7676
public ResourceReference create(Key key)
77+
{
78+
return create(key, true);
79+
}
80+
81+
public ResourceReference create(Key key, boolean updateCache)
7782
{
7883
ResourceReference result = null;
79-
if (PackageResource.exists(key))
84+
if (PackageResource.exists(key.getScopeClass(), key.getName(), key.getLocale(),
85+
key.getStyle(), key.getVariation(), updateCache))
8086
{
8187
result = new PackageResourceReference(key);
8288
}
@@ -180,17 +186,28 @@ public final ResourceReference unregisterResourceReference(final Key key)
180186
return removed;
181187
}
182188

189+
/**
190+
* @deprecated @see {@link ResourceReferenceRegistry#getResourceReference(Class, String, Locale, String, String, boolean, boolean, boolean)}
191+
*/
192+
public final ResourceReference getResourceReference(final Class<?> scope, final String name,
193+
final Locale locale, final String style, final String variation, final boolean strict,
194+
final boolean createIfNotFound)
195+
{
196+
return getResourceReference(scope, name, locale, style, variation, strict, createIfNotFound,
197+
true);
198+
}
199+
183200
/**
184201
* Get a resource reference matching the parameters from the registry or if not found and
185202
* requested, create an default resource reference and add it to the registry.
186203
* <p>
187204
* Part of the search is scanning the class (scope) and it's superclass for static
188205
* ResourceReference fields. Found fields get registered automatically (but are different from
189206
* auto-generated ResourceReferences).
190-
*
207+
*
191208
* @see #createDefaultResourceReference(org.apache.wicket.request.resource.ResourceReference.Key)
192209
* @see ClassScanner
193-
*
210+
*
194211
* @param scope
195212
* The scope of resource reference (e.g. the Component's class)
196213
* @param name
@@ -206,16 +223,25 @@ public final ResourceReference unregisterResourceReference(final Key key)
206223
* @param createIfNotFound
207224
* If true a default resource reference is created if no entry can be found in the
208225
* registry. The newly created resource reference will be added to the registry.
226+
* @param updateCache
227+
* If true, the server resource stream reference cache should be updated
209228
* @return Either the resource reference found in the registry or, if requested, a resource
210229
* reference automatically created based on the parameters provided. The automatically
211230
* created resource reference will automatically be added to the registry.
212231
*/
213-
public final ResourceReference getResourceReference(final Class<?> scope, final String name,
214-
final Locale locale, final String style, final String variation, final boolean strict,
215-
final boolean createIfNotFound)
232+
public ResourceReference getResourceReference(Class<?> scope, String name, Locale locale,
233+
String style, String variation, boolean strict, boolean createIfNotFound, boolean updateCache)
216234
{
217235
return getResourceReference(new Key(scope.getName(), name, locale, style, variation),
218-
strict, createIfNotFound);
236+
strict, createIfNotFound, updateCache);
237+
}
238+
239+
/**
240+
* @deprecated @see {@link ResourceReferenceRegistry#getResourceReference(Key, boolean, boolean, boolean)}
241+
*/
242+
public final ResourceReference getResourceReference(final Key key, final boolean strict,
243+
final boolean createIfNotFound){
244+
return getResourceReference(key, strict, createIfNotFound, true);
219245
}
220246

221247
/**
@@ -236,12 +262,14 @@ public final ResourceReference getResourceReference(final Class<?> scope, final
236262
* @param createIfNotFound
237263
* If true a default resource reference is created if no entry can be found in the
238264
* registry. The newly created resource reference will be added to the registry.
265+
* @param strict
266+
* If true, the server resource stream reference cache should be updated
239267
* @return Either the resource reference found in the registry or, if requested, a resource
240268
* reference automatically created based on the parameters provided. The automatically
241269
* created resource reference will automatically be added to the registry.
242270
*/
243271
public final ResourceReference getResourceReference(final Key key, final boolean strict,
244-
final boolean createIfNotFound)
272+
final boolean createIfNotFound, boolean updateCache)
245273
{
246274
ResourceReference resource = _getResourceReference(key.getScope(), key.getName(),
247275
key.getLocale(), key.getStyle(), key.getVariation(), strict);
@@ -262,7 +290,7 @@ public final ResourceReference getResourceReference(final Key key, final boolean
262290
// Still nothing found => Shall a new reference be auto-created?
263291
if ((resource == null) && createIfNotFound)
264292
{
265-
resource = addDefaultResourceReference(key);
293+
resource = addDefaultResourceReference(key, updateCache);
266294
}
267295
}
268296

@@ -334,12 +362,12 @@ private ResourceReference _getResourceReference(final String scope, final String
334362
* the data making up the resource reference
335363
* @return The default resource created
336364
*/
337-
private ResourceReference addDefaultResourceReference(final Key key)
365+
private ResourceReference addDefaultResourceReference(final Key key, final boolean updateCache)
338366
{
339367
// Can be subclassed to create other than PackagedResourceReference
340-
ResourceReference reference = createDefaultResourceReference(key);
368+
ResourceReference reference = createDefaultResourceReference(key, updateCache);
341369

342-
if (reference != null)
370+
if (reference != null && updateCache)
343371
{
344372
// number of RRs which can be auto-added is restricted (cache size). Remove entries, and
345373
// unregister excessive ones, if needed.
@@ -383,6 +411,14 @@ private void enforceAutoAddedCacheSize(int maxSize)
383411
}
384412
}
385413

414+
/**
415+
* @deprecated @see {@link ResourceReferenceRegistry#createDefaultResourceReference(Key, boolean)}
416+
*/
417+
protected ResourceReference createDefaultResourceReference(final Key key)
418+
{
419+
return createDefaultResourceReference(key, true);
420+
}
421+
386422
/**
387423
* Creates a default resource reference in case no registry entry and it was requested to create
388424
* one.
@@ -393,14 +429,20 @@ private void enforceAutoAddedCacheSize(int maxSize)
393429
* the data making up the resource reference
394430
* @return The {@link ResourceReference} created or {@code null} if not successful
395431
*/
396-
protected ResourceReference createDefaultResourceReference(final Key key)
432+
protected ResourceReference createDefaultResourceReference(final Key key, final boolean updateCache)
397433
{
398434
IResourceReferenceFactory factory = getResourceReferenceFactory();
399435
if (factory == null)
400436
{
401437
factory = new DefaultResourceReferenceFactory();
402438
}
403-
return factory.create(key);
439+
if (factory instanceof DefaultResourceReferenceFactory defaultFactory)
440+
{
441+
return defaultFactory.create(key, updateCache);
442+
443+
} else {
444+
return factory.create(key);
445+
}
404446
}
405447

406448
/**

0 commit comments

Comments
 (0)