Merge pull request #87 from battags/CASC-233

CASC-233 ErrorRedirectFilter Can throw Null Pointer Exception
This commit is contained in:
Scott 2014-12-07 12:13:27 -05:00
commit d7ca6a098e
2 changed files with 70 additions and 6 deletions

View File

@ -24,22 +24,22 @@ import java.util.Enumeration;
import java.util.List;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Filters that redirects to the supplied url based on an exception. Exceptions and the urls are configured via
* init filter name/param values.
* <p>
* <p/>
* If there is an exact match the filter uses that value. If there's a non-exact match (i.e. inheritance), then the filter
* uses the last value that matched.
* <p>
* <p/>
* If there is no match it will redirect to a default error page. The default exception is configured via the "defaultErrorRedirectPage" property.
*
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.4
*
*/
public final class ErrorRedirectFilter implements Filter {
@ -58,8 +58,8 @@ public final class ErrorRedirectFilter implements Filter {
final HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
filterChain.doFilter(request, response);
} catch (final ServletException e) {
final Throwable t = e.getCause();
} catch (final Exception e) {
final Throwable t = extractErrorToCompare(e);
ErrorHolder currentMatch = null;
for (final ErrorHolder errorHolder : this.errors) {
if (errorHolder.exactMatch(t)) {
@ -78,6 +78,22 @@ public final class ErrorRedirectFilter implements Filter {
}
}
/**
* Determine which error to use for comparison. If there is an {@link Throwable#getCause()} then that will be used. Otherwise, the original throwable is used.
*
* @param throwable the throwable to look for a root cause.
* @return the throwable to use for comparison. MUST NOT BE NULL.
*/
private Throwable extractErrorToCompare(final Throwable throwable) {
final Throwable cause = throwable.getCause();
if (cause != null) {
return cause;
}
return throwable;
}
public void init(final FilterConfig filterConfig) throws ServletException {
this.defaultErrorRedirectPage = filterConfig.getInitParameter("defaultErrorRedirectPage");

View File

@ -0,0 +1,48 @@
package org.jasig.cas.client.util;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import javax.servlet.FilterChain;
import static org.junit.Assert.*;
public final class ErrorRedirectFilterTests {
private static final String REDIRECT_URL = "/ise.html";
private ErrorRedirectFilter errorRedirectFilter;
private FilterChain filterChain;
@Before
public void setUp() throws Exception {
this.errorRedirectFilter = new ErrorRedirectFilter();
final MockFilterConfig filterConfig = new MockFilterConfig();
filterConfig.addInitParameter(IllegalStateException.class.getName(), REDIRECT_URL);
this.errorRedirectFilter.init(filterConfig);
this.filterChain = new MockFilterChain();
}
@Test
public void noRootCause() throws Exception {
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
// this should be okay as the mock filter chain allows one call
this.errorRedirectFilter.doFilter(request, response, this.filterChain);
// this will fail as the mock filter chain will throw IllegalStateException
this.errorRedirectFilter.doFilter(request, response, this.filterChain);
assertEquals(REDIRECT_URL, response.getRedirectedUrl());
}
}