From 359c4f091e293e6f9c4ecb23f00d9a3830c575e8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 30 Apr 2019 18:39:58 +0200 Subject: [PATCH 1/4] Add rejectInvalidCookies flag to CookieLocaleResolver Closes gh-22861 --- .../servlet/i18n/CookieLocaleResolver.java | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java index e4fac7ea78..2f859d4230 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -56,7 +56,7 @@ import org.springframework.web.util.WebUtils; public class CookieLocaleResolver extends CookieGenerator implements LocaleContextResolver { /** - * The name of the request attribute that holds the Locale. + * The name of the request attribute that holds the {@code Locale}. *

Only used for overriding a cookie value if the locale has been * changed in the course of the current request! *

Use {@code RequestContext(Utils).getLocale()} @@ -67,7 +67,7 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte public static final String LOCALE_REQUEST_ATTRIBUTE_NAME = CookieLocaleResolver.class.getName() + ".LOCALE"; /** - * The name of the request attribute that holds the TimeZone. + * The name of the request attribute that holds the {@code TimeZone}. *

Only used for overriding a cookie value if the locale has been * changed in the course of the current request! *

Use {@code RequestContext(Utils).getTimeZone()} @@ -85,6 +85,8 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte private boolean languageTagCompliant = true; + private boolean rejectInvalidCookies = true; + @Nullable private Locale defaultLocale; @@ -128,14 +130,36 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte } /** - * Set a fixed Locale that this resolver will return if no cookie found. + * Specify whether to reject cookies with invalid content (e.g. invalid format). + *

The default is {@code true}. Turn this off for lenient handling of parse + * failures, falling back to the default locale and time zone in such a case. + * @since 5.1.7 + * @see #setDefaultLocale + * @see #setDefaultTimeZone + * @see #determineDefaultLocale + * @see #determineDefaultTimeZone + */ + public void setRejectInvalidCookies(boolean rejectInvalidCookies) { + this.rejectInvalidCookies = rejectInvalidCookies; + } + + /** + * Return whether to reject cookies with invalid content (e.g. invalid format). + * @since 5.1.7 + */ + public boolean isRejectInvalidCookies() { + return this.rejectInvalidCookies; + } + + /** + * Set a fixed locale that this resolver will return if no cookie found. */ public void setDefaultLocale(@Nullable Locale defaultLocale) { this.defaultLocale = defaultLocale; } /** - * Return the fixed Locale that this resolver will return if no cookie found, + * Return the fixed locale that this resolver will return if no cookie found, * if any. */ @Nullable @@ -144,7 +168,7 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte } /** - * Set a fixed TimeZone that this resolver will return if no cookie found. + * Set a fixed time zone that this resolver will return if no cookie found. * @since 4.0 */ public void setDefaultTimeZone(@Nullable TimeZone defaultTimeZone) { @@ -152,7 +176,7 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte } /** - * Return the fixed TimeZone that this resolver will return if no cookie found, + * Return the fixed time zone that this resolver will return if no cookie found, * if any. * @since 4.0 */ @@ -214,16 +238,17 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte } } catch (IllegalArgumentException ex) { - String cookieDescription = "invalid locale cookie '" + cookieName + - "': [" + value + "] due to: " + ex.getMessage(); - if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) { - // Error dispatch: ignore locale/timezone parse exceptions - if (logger.isDebugEnabled()) { - logger.debug("Ignoring " + cookieDescription); - } + if (isRejectInvalidCookies() && + request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) { + throw new IllegalStateException("Encountered invalid locale cookie '" + + cookieName + "': [" + value + "] due to: " + ex.getMessage()); } else { - throw new IllegalStateException("Encountered " + cookieDescription); + // Lenient handling (e.g. error dispatch): ignore locale/timezone parse exceptions + if (logger.isDebugEnabled()) { + logger.debug("Ignoring invalid locale cookie '" + cookieName + + "': [" + value + "] due to: " + ex.getMessage()); + } } } if (logger.isTraceEnabled()) { @@ -320,7 +345,7 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte /** * Determine the default time zone for the given request, - * Called if no TimeZone cookie has been found. + * Called if no time zone cookie has been found. *

The default implementation returns the specified default time zone, * if any, or {@code null} otherwise. * @param request the request to resolve the time zone for From e0423fbdc2ffa16e929d80c4d38ac35803dd843e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 30 Apr 2019 18:42:53 +0200 Subject: [PATCH 2/4] Revise inline comment for logException call Closes gh-22794 --- .../servlet/handler/AbstractHandlerExceptionResolver.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java index 8222bb15de..32e88d04ce 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerExceptionResolver.java @@ -109,7 +109,7 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti * @see java.util.logging.Logger#getLogger(String) */ public void setWarnLogCategory(String loggerName) { - this.warnLogger = !StringUtils.isEmpty(loggerName) ? LogFactory.getLog(loggerName) : null; + this.warnLogger = (!StringUtils.isEmpty(loggerName) ? LogFactory.getLog(loggerName) : null); } /** @@ -138,11 +138,11 @@ public abstract class AbstractHandlerExceptionResolver implements HandlerExcepti prepareResponse(ex, response); ModelAndView result = doResolveException(request, response, handler, ex); if (result != null) { - // Print warn message when warn logger is not enabled... + // Print debug message when warn logger is not enabled. if (logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) { logger.debug("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result)); } - // warnLogger with full stack trace (requires explicit config) + // Explicitly configured warn logger in logException method. logException(ex, request); } return result; From 90d4e9090ca05d48f108b9dccb02bfb3bc9ca974 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 30 Apr 2019 18:43:16 +0200 Subject: [PATCH 3/4] Polishing --- .../web/reactive/function/server/EntityResponse.java | 3 +-- .../web/reactive/function/server/ServerResponse.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java index cedbeb7aa4..ab72a30f5a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java @@ -264,8 +264,7 @@ public interface EntityResponse extends ServerResponse { Builder hint(String key, Object value); /** - * Manipulate serialization hint with the given consumer. - * + * Customize the serialization hints with the given consumer. * @param hintsConsumer a function that consumes the hints * @return this builder * @since 5.1.6 diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java index 78d097a280..286845d9da 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java @@ -377,8 +377,7 @@ public interface ServerResponse { BodyBuilder hint(String key, Object value); /** - * Manipulate serialization hint with the given consumer. - * + * Customize the serialization hints with the given consumer. * @param hintsConsumer a function that consumes the hints * @return this builder * @since 5.1.6 From a8f845c944aa0b709ba8b63c372863f06863e578 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 30 Apr 2019 18:44:08 +0200 Subject: [PATCH 4/4] Upgrade to Checkstyle 8.20 and CGLIB 3.2.11 Includes dependency management plugin 1.0.7. --- build.gradle | 4 ++-- spring-core/spring-core.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index f37b3787b3..e1e045d732 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { // 3rd party plugin repositories can be configured in settings.gradle plugins { - id "io.spring.dependency-management" version "1.0.5.RELEASE" apply false + id "io.spring.dependency-management" version "1.0.7.RELEASE" apply false id "org.jetbrains.kotlin.jvm" version "1.2.71" apply false id "org.jetbrains.dokka" version "0.9.17" id "org.asciidoctor.convert" version "1.5.8" @@ -143,7 +143,7 @@ configure(allprojects) { project -> } checkstyle { - toolVersion = "8.19" + toolVersion = "8.20" configDir = rootProject.file("src/checkstyle") } diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index 698ec19ce1..685f18de2f 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -10,7 +10,7 @@ dependencyManagement { // spring-core includes asm and repackages cglib, inlining both into the spring-core jar. // cglib itself depends on asm and is therefore further transformed by the JarJar task to // depend on org.springframework.asm; this avoids including two different copies of asm. -def cglibVersion = "3.2.10" +def cglibVersion = "3.2.11" def objenesisVersion = "3.0.1" configurations {