Skip to content

Commit b97e7d5

Browse files
committed
Revised CookieLocaleResolver parse exception handling
Issue: SPR-15182 (cherry picked from commit e8776f8)
1 parent 4af6d58 commit b97e7d5

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -190,9 +190,24 @@ private void parseLocaleCookieIfNecessary(HttpServletRequest request) {
190190
localePart = value.substring(0, spaceIndex);
191191
timeZonePart = value.substring(spaceIndex + 1);
192192
}
193-
locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null);
194-
if (timeZonePart != null) {
195-
timeZone = StringUtils.parseTimeZoneString(timeZonePart);
193+
try {
194+
locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null);
195+
if (timeZonePart != null) {
196+
timeZone = StringUtils.parseTimeZoneString(timeZonePart);
197+
}
198+
}
199+
catch (IllegalArgumentException ex) {
200+
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
201+
// Error dispatch: ignore locale/timezone parse exceptions
202+
if (logger.isDebugEnabled()) {
203+
logger.debug("Ignoring invalid locale cookie '" + getCookieName() +
204+
"' with value [" + value + "] due to error dispatch: " + ex.getMessage());
205+
}
206+
}
207+
else {
208+
throw new IllegalStateException("Invalid locale cookie '" + getCookieName() +
209+
"' with value [" + value + "]: " + ex.getMessage());
210+
}
196211
}
197212
if (logger.isDebugEnabled()) {
198213
logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale +

spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/CookieLocaleResolverTests.java

+72-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.Locale;
2020
import java.util.TimeZone;
21+
import javax.servlet.ServletException;
2122
import javax.servlet.http.Cookie;
2223

2324
import org.junit.Test;
@@ -28,6 +29,7 @@
2829
import org.springframework.context.i18n.TimeZoneAwareLocaleContext;
2930
import org.springframework.mock.web.test.MockHttpServletRequest;
3031
import org.springframework.mock.web.test.MockHttpServletResponse;
32+
import org.springframework.web.util.WebUtils;
3133

3234
import static org.junit.Assert.*;
3335

@@ -45,7 +47,6 @@ public void testResolveLocale() {
4547
request.setCookies(cookie);
4648

4749
CookieLocaleResolver resolver = new CookieLocaleResolver();
48-
// yup, koekje is the Dutch name for Cookie ;-)
4950
resolver.setCookieName("LanguageKoekje");
5051
Locale loc = resolver.resolveLocale(request);
5152
assertEquals(loc.getLanguage(), "nl");
@@ -58,7 +59,6 @@ public void testResolveLocaleContext() {
5859
request.setCookies(cookie);
5960

6061
CookieLocaleResolver resolver = new CookieLocaleResolver();
61-
// yup, koekje is the Dutch name for Cookie ;-)
6262
resolver.setCookieName("LanguageKoekje");
6363
LocaleContext loc = resolver.resolveLocaleContext(request);
6464
assertEquals("nl", loc.getLocale().getLanguage());
@@ -73,14 +73,82 @@ public void testResolveLocaleContextWithTimeZone() {
7373
request.setCookies(cookie);
7474

7575
CookieLocaleResolver resolver = new CookieLocaleResolver();
76-
// yup, koekje is the Dutch name for Cookie ;-)
7776
resolver.setCookieName("LanguageKoekje");
7877
LocaleContext loc = resolver.resolveLocaleContext(request);
7978
assertEquals("nl", loc.getLocale().getLanguage());
8079
assertTrue(loc instanceof TimeZoneAwareLocaleContext);
8180
assertEquals(TimeZone.getTimeZone("GMT+1"), ((TimeZoneAwareLocaleContext) loc).getTimeZone());
8281
}
8382

83+
@Test
84+
public void testResolveLocaleContextWithInvalidLocale() {
85+
MockHttpServletRequest request = new MockHttpServletRequest();
86+
Cookie cookie = new Cookie("LanguageKoekje", "n-x GMT+1");
87+
request.setCookies(cookie);
88+
89+
CookieLocaleResolver resolver = new CookieLocaleResolver();
90+
resolver.setCookieName("LanguageKoekje");
91+
try {
92+
resolver.resolveLocaleContext(request);
93+
fail("Should have thrown IllegalStateException");
94+
}
95+
catch (IllegalStateException ex) {
96+
assertTrue(ex.getMessage().contains("LanguageKoekje"));
97+
assertTrue(ex.getMessage().contains("n-x GMT+1"));
98+
}
99+
}
100+
101+
@Test
102+
public void testResolveLocaleContextWithInvalidLocaleOnErrorDispatch() {
103+
MockHttpServletRequest request = new MockHttpServletRequest();
104+
request.addPreferredLocale(Locale.GERMAN);
105+
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, new ServletException());
106+
Cookie cookie = new Cookie("LanguageKoekje", "n-x GMT+1");
107+
request.setCookies(cookie);
108+
109+
CookieLocaleResolver resolver = new CookieLocaleResolver();
110+
resolver.setDefaultTimeZone(TimeZone.getTimeZone("GMT+2"));
111+
resolver.setCookieName("LanguageKoekje");
112+
LocaleContext loc = resolver.resolveLocaleContext(request);
113+
assertEquals(Locale.GERMAN, loc.getLocale());
114+
assertTrue(loc instanceof TimeZoneAwareLocaleContext);
115+
assertEquals(TimeZone.getTimeZone("GMT+2"), ((TimeZoneAwareLocaleContext) loc).getTimeZone());
116+
}
117+
118+
@Test
119+
public void testResolveLocaleContextWithInvalidTimeZone() {
120+
MockHttpServletRequest request = new MockHttpServletRequest();
121+
Cookie cookie = new Cookie("LanguageKoekje", "nl X-MT");
122+
request.setCookies(cookie);
123+
124+
CookieLocaleResolver resolver = new CookieLocaleResolver();
125+
resolver.setCookieName("LanguageKoekje");
126+
try {
127+
resolver.resolveLocaleContext(request);
128+
fail("Should have thrown IllegalStateException");
129+
}
130+
catch (IllegalStateException ex) {
131+
assertTrue(ex.getMessage().contains("LanguageKoekje"));
132+
assertTrue(ex.getMessage().contains("nl X-MT"));
133+
}
134+
}
135+
136+
@Test
137+
public void testResolveLocaleContextWithInvalidTimeZoneOnErrorDispatch() {
138+
MockHttpServletRequest request = new MockHttpServletRequest();
139+
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, new ServletException());
140+
Cookie cookie = new Cookie("LanguageKoekje", "nl X-MT");
141+
request.setCookies(cookie);
142+
143+
CookieLocaleResolver resolver = new CookieLocaleResolver();
144+
resolver.setDefaultTimeZone(TimeZone.getTimeZone("GMT+2"));
145+
resolver.setCookieName("LanguageKoekje");
146+
LocaleContext loc = resolver.resolveLocaleContext(request);
147+
assertEquals("nl", loc.getLocale().getLanguage());
148+
assertTrue(loc instanceof TimeZoneAwareLocaleContext);
149+
assertEquals(TimeZone.getTimeZone("GMT+2"), ((TimeZoneAwareLocaleContext) loc).getTimeZone());
150+
}
151+
84152
@Test
85153
public void testSetAndResolveLocale() {
86154
MockHttpServletRequest request = new MockHttpServletRequest();

0 commit comments

Comments
 (0)