@@ -190,7 +190,7 @@ public String validateClass(Class<?> clz) {
190
190
return error ;
191
191
}
192
192
193
- private AppShellSettings createSettings (String contextPath ) {
193
+ private AppShellSettings createSettings (VaadinRequest request ) {
194
194
AppShellSettings settings = new AppShellSettings ();
195
195
196
196
getAnnotations (Meta .class ).forEach (
@@ -225,7 +225,7 @@ private AppShellSettings createSettings(String contextPath) {
225
225
226
226
Set <String > stylesheets = new LinkedHashSet <>();
227
227
for (StyleSheet sheet : getAnnotations (StyleSheet .class )) {
228
- String href = resolveStyleSheetHref (sheet .value (), contextPath );
228
+ String href = resolveStyleSheetHref (sheet .value (), request );
229
229
if (href != null && !href .isBlank ()) {
230
230
stylesheets .add (href );
231
231
}
@@ -235,41 +235,43 @@ private AppShellSettings createSettings(String contextPath) {
235
235
return settings ;
236
236
}
237
237
238
- private String resolveStyleSheetHref (String href , String contextPath ) {
238
+ private String resolveStyleSheetHref (String href , VaadinRequest request ) {
239
239
if (href == null || href .isBlank ()) {
240
240
return null ;
241
241
}
242
+ if (HandlerHelper
243
+ .isPathUnsafe (href .startsWith ("/" ) ? href : "/" + href )) {
244
+ log .warn (
245
+ "@StyleSheet href containing traversals ('../') are not allowed, ignored: {}" ,
246
+ href );
247
+ return null ;
248
+ }
242
249
href = href .trim ();
243
250
// Accept absolute http(s) URLs unchanged
244
251
String lower = href .toLowerCase ();
245
252
if (lower .startsWith ("http://" ) || lower .startsWith ("https://" )) {
246
253
return href ;
247
254
}
248
- // Accept context-relative URLs: context://path -> /path
249
- String contextProtocol = ApplicationConstants .CONTEXT_PROTOCOL_PREFIX ;
250
- if (lower .startsWith (contextProtocol )) {
251
- String path = href .substring (contextProtocol .length ());
252
- if (!path .startsWith ("/" )) {
253
- path = "/" + path ;
254
- }
255
- if (contextPath != null && !contextPath .isEmpty ()) {
256
- return contextPath + path ;
257
- }
258
- return path ;
259
- }
260
255
// Treat ./ as relative path to static resources location
261
256
if (href .startsWith ("./" )) {
262
257
href = href .substring (2 );
263
258
}
264
259
// Accept bare paths beginning with '/' as-is
265
- href = href .startsWith ("/" ) ? href : "/" + href ;
266
- if (HandlerHelper .isPathUnsafe (href )) {
267
- log .warn (
268
- "@StyleSheet href containing traversals ('../') are not allowed, ignored: "
269
- + href );
270
- return null ;
260
+ if (href .startsWith ("/" )) {
261
+ return href ;
262
+ }
263
+
264
+ String contextPath = request .getContextPath ();
265
+ if (!contextPath .isEmpty ()) {
266
+ String contextProtocol = ApplicationConstants .CONTEXT_PROTOCOL_PREFIX ;
267
+ if (!lower .startsWith (contextProtocol )) {
268
+ // Prepend context protocol so URL is resolved with context path
269
+ href = contextProtocol + href ;
270
+ }
271
271
}
272
- return href ;
272
+ BootstrapHandler .BootstrapUriResolver resolver = new BootstrapHandler .BootstrapUriResolver (
273
+ contextPath + "/" , null );
274
+ return resolver .resolveVaadinUri (href );
273
275
}
274
276
275
277
/**
@@ -283,7 +285,7 @@ private String resolveStyleSheetHref(String href, String contextPath) {
283
285
* The request to handle
284
286
*/
285
287
public void modifyIndexHtml (Document document , VaadinRequest request ) {
286
- AppShellSettings settings = createSettings (request . getContextPath () );
288
+ AppShellSettings settings = createSettings (request );
287
289
if (appShellClass != null ) {
288
290
VaadinService .getCurrent ().getInstantiator ()
289
291
.getOrCreate (appShellClass ).configurePage (settings );
0 commit comments