From 3aacfc026535fed217f568ca89151a44b2fea3c7 Mon Sep 17 00:00:00 2001 From: Colin Harrington Date: Tue, 20 Dec 2016 17:21:56 -0600 Subject: [PATCH] #10371: Layout resolution fails with the WAR when using relative URIs outside of the /layouts directory --- .../web/sitemesh/GroovyPageLayoutFinder.java | 2 +- .../GroovyPageLayoutFinderSpec.groovy | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 grails-web-sitemesh/src/test/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinderSpec.groovy diff --git a/grails-web-sitemesh/src/main/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinder.java b/grails-web-sitemesh/src/main/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinder.java index d02895988ed..81ad842df80 100644 --- a/grails-web-sitemesh/src/main/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinder.java +++ b/grails-web-sitemesh/src/main/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinder.java @@ -193,7 +193,7 @@ public Decorator getNamedDecorator(HttpServletRequest request, String name, bool View view; try { - view = viewResolver.resolveViewName(GrailsResourceUtils.appendPiecesForUri(LAYOUTS_PATH, name), + view = viewResolver.resolveViewName(GrailsResourceUtils.cleanPath(GrailsResourceUtils.appendPiecesForUri(LAYOUTS_PATH, name)), request.getLocale()); // it's only possible to check that GroovyPageView exists if (viewMustExist && !(view instanceof AbstractGrailsView)) { diff --git a/grails-web-sitemesh/src/test/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinderSpec.groovy b/grails-web-sitemesh/src/test/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinderSpec.groovy new file mode 100644 index 00000000000..4d46696d3e4 --- /dev/null +++ b/grails-web-sitemesh/src/test/groovy/org/grails/web/sitemesh/GroovyPageLayoutFinderSpec.groovy @@ -0,0 +1,54 @@ +/* + * Copyright 2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.grails.web.sitemesh + +import org.grails.web.servlet.view.GrailsViewResolver +import org.springframework.mock.web.MockHttpServletRequest +import spock.lang.Issue +import spock.lang.Specification +import spock.lang.Unroll +import javax.servlet.http.HttpServletRequest + +/** + * @author Colin Harrington + */ +class GroovyPageLayoutFinderSpec extends Specification { + @Issue("https://github.com/grails/grails-core/issues/10371") + @Unroll("Layout name mapping: #layoutName => #expectedPath") + void "testing layout name resolution"() { + given: + GroovyPageLayoutFinder layoutFinder = new GroovyPageLayoutFinder() + HttpServletRequest request = new MockHttpServletRequest() + layoutFinder.viewResolver = Mock(GrailsViewResolver) + when: + layoutFinder.getNamedDecorator(request, layoutName, false) + + then: + 1 * layoutFinder.viewResolver.resolveViewName(expectedPath, Locale.ENGLISH) + notThrown(Exception) + + where: + layoutName | expectedPath + "foo" | "/layouts/foo" + "foo/bar" | "/layouts/foo/bar" + "../foo" | "/foo" + "../foo/bar" | "/foo/bar" + "../../foo" | "/../foo" + "../foo/../../bar" | "/../bar" + "foo/../../bar" | "/bar" + } +}