Browse Source

Re-enable support for invalid Expires attributes in MockCookie

Changes introduced in commit 9b2087618b
caused a regression for Cookie support in MockHttpServletResponse.
Specifically, an Expires attribute that cannot be parsed using
`ZonedDateTime.parse()` now results in an exception; whereas,
previously an entry such as `Expires=0` was allowed.

This commit fixes this issue in MockCookie by catching and ignoring any
DateTimeException thrown while attempting to parse an Expires attribute.

Closes gh-23911
pull/27217/head
Sam Brannen 6 years ago
parent
commit
ca3440cb42
  1. 11
      spring-test/src/main/java/org/springframework/mock/web/MockCookie.java
  2. 24
      spring-test/src/test/java/org/springframework/mock/web/MockCookieTests.java
  3. 28
      spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java
  4. 11
      spring-web/src/test/java/org/springframework/mock/web/test/MockCookie.java

11
spring-test/src/main/java/org/springframework/mock/web/MockCookie.java

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.mock.web;
import java.time.DateTimeException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@ -31,6 +32,7 @@ import org.springframework.util.StringUtils; @@ -31,6 +32,7 @@ import org.springframework.util.StringUtils;
*
* @author Vedran Pavic
* @author Juergen Hoeller
* @author Sam Brannen
* @since 5.1
*/
public class MockCookie extends Cookie {
@ -119,8 +121,13 @@ public class MockCookie extends Cookie { @@ -119,8 +121,13 @@ public class MockCookie extends Cookie {
cookie.setMaxAge(Integer.parseInt(extractAttributeValue(attribute, setCookieHeader)));
}
else if (StringUtils.startsWithIgnoreCase(attribute, "Expires")) {
cookie.setExpires(ZonedDateTime.parse(extractAttributeValue(attribute, setCookieHeader),
DateTimeFormatter.RFC_1123_DATE_TIME));
try {
cookie.setExpires(ZonedDateTime.parse(extractAttributeValue(attribute, setCookieHeader),
DateTimeFormatter.RFC_1123_DATE_TIME));
}
catch (DateTimeException ex) {
// ignore invalid date formats
}
}
else if (StringUtils.startsWithIgnoreCase(attribute, "Path")) {
cookie.setPath(extractAttributeValue(attribute, setCookieHeader));

24
spring-test/src/test/java/org/springframework/mock/web/MockCookieTests.java

@ -16,13 +16,13 @@ @@ -16,13 +16,13 @@
package org.springframework.mock.web;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import static org.junit.Assert.*;
/**
@ -84,6 +84,22 @@ public class MockCookieTests { @@ -84,6 +84,22 @@ public class MockCookieTests {
assertEquals("Lax", cookie.getSameSite());
}
@Test
public void parseHeaderWithZeroExpiresAttribute() {
MockCookie cookie = MockCookie.parse("SESSION=123; Expires=0");
assertCookie(cookie, "SESSION", "123");
assertNull(cookie.getExpires());
}
@Test
public void parseHeaderWithBogusExpiresAttribute() {
MockCookie cookie = MockCookie.parse("SESSION=123; Expires=bogus");
assertCookie(cookie, "SESSION", "123");
assertNull(cookie.getExpires());
}
private void assertCookie(MockCookie cookie, String name, String value) {
assertEquals(name, cookie.getName());
assertEquals(value, cookie.getValue());
@ -116,7 +132,7 @@ public class MockCookieTests { @@ -116,7 +132,7 @@ public class MockCookieTests {
public void parseHeaderWithAttributesCaseSensitivity() {
MockCookie cookie = MockCookie.parse("SESSION=123; domain=example.com; max-age=60; " +
"expires=Tue, 8 Oct 2019 19:50:00 GMT; path=/; secure; httponly; samesite=Lax");
assertCookie(cookie, "SESSION", "123");
assertEquals("example.com", cookie.getDomain());
assertEquals(60, cookie.getMaxAge());

28
spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java

@ -351,6 +351,20 @@ public class MockHttpServletResponseTests { @@ -351,6 +351,20 @@ public class MockHttpServletResponseTests {
assertEquals(cookieValue, response.getHeader(HttpHeaders.SET_COOKIE));
}
/**
* @since 5.1.12
*/
@Test
public void setCookieHeaderWithZeroExpiresAttribute() {
String cookieValue = "SESSION=123; Path=/; Max-Age=100; Expires=0";
response.setHeader(HttpHeaders.SET_COOKIE, cookieValue);
assertNumCookies(1);
String header = response.getHeader(HttpHeaders.SET_COOKIE);
assertNotEquals(cookieValue, header);
// We don't assert the actual Expires value since it is based on the current time.
assertTrue(header.startsWith("SESSION=123; Path=/; Max-Age=100; Expires="));
}
@Test
public void addCookieHeader() {
response.addHeader(HttpHeaders.SET_COOKIE, "SESSION=123; Path=/; Secure; HttpOnly; SameSite=Lax");
@ -375,6 +389,20 @@ public class MockHttpServletResponseTests { @@ -375,6 +389,20 @@ public class MockHttpServletResponseTests {
assertEquals(cookieValue, response.getHeader(HttpHeaders.SET_COOKIE));
}
/**
* @since 5.1.12
*/
@Test
public void addCookieHeaderWithZeroExpiresAttribute() {
String cookieValue = "SESSION=123; Path=/; Max-Age=100; Expires=0";
response.addHeader(HttpHeaders.SET_COOKIE, cookieValue);
assertNumCookies(1);
String header = response.getHeader(HttpHeaders.SET_COOKIE);
assertNotEquals(cookieValue, header);
// We don't assert the actual Expires value since it is based on the current time.
assertTrue(header.startsWith("SESSION=123; Path=/; Max-Age=100; Expires="));
}
@Test
public void addCookie() {
MockCookie mockCookie = new MockCookie("SESSION", "123");

11
spring-web/src/test/java/org/springframework/mock/web/test/MockCookie.java

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.mock.web.test;
import java.time.DateTimeException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@ -31,6 +32,7 @@ import org.springframework.util.StringUtils; @@ -31,6 +32,7 @@ import org.springframework.util.StringUtils;
*
* @author Vedran Pavic
* @author Juergen Hoeller
* @author Sam Brannen
* @since 5.1
*/
public class MockCookie extends Cookie {
@ -119,8 +121,13 @@ public class MockCookie extends Cookie { @@ -119,8 +121,13 @@ public class MockCookie extends Cookie {
cookie.setMaxAge(Integer.parseInt(extractAttributeValue(attribute, setCookieHeader)));
}
else if (StringUtils.startsWithIgnoreCase(attribute, "Expires")) {
cookie.setExpires(ZonedDateTime.parse(extractAttributeValue(attribute, setCookieHeader),
DateTimeFormatter.RFC_1123_DATE_TIME));
try {
cookie.setExpires(ZonedDateTime.parse(extractAttributeValue(attribute, setCookieHeader),
DateTimeFormatter.RFC_1123_DATE_TIME));
}
catch (DateTimeException ex) {
// ignore invalid date formats
}
}
else if (StringUtils.startsWithIgnoreCase(attribute, "Path")) {
cookie.setPath(extractAttributeValue(attribute, setCookieHeader));

Loading…
Cancel
Save