From 49b55cc69865f1bdb589b6e2eab95ed00d199e3e Mon Sep 17 00:00:00 2001 From: jansupol Date: Thu, 25 Apr 2024 15:34:52 +0200 Subject: [PATCH] Prevent NPE in Jersey Spring RequestContextFilter Signed-off-by: jansupol --- .../spring/scope/RequestContextFilter.java | 6 +- .../SpringRequestContextFilterTest.java | 69 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/SpringRequestContextFilterTest.java diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java index 5ad00d64d6..6a9edaa800 100644 --- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java +++ b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -98,7 +98,9 @@ public void resetAttributes(final ContainerRequestContext requestContext) { final AbstractRequestAttributes attributes = (AbstractRequestAttributes) requestContext.getProperty(REQUEST_ATTRIBUTES_PROPERTY); RequestContextHolder.resetRequestAttributes(); - attributes.requestCompleted(); + if (attributes != null) { + attributes.requestCompleted(); + } } } : EMPTY_ATTRIBUTE_CONTROLLER; } diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/SpringRequestContextFilterTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/SpringRequestContextFilterTest.java new file mode 100644 index 0000000000..7e28b5d8fc --- /dev/null +++ b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/SpringRequestContextFilterTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.server.spring.filter; + +import org.glassfish.jersey.internal.inject.AbstractBinder; +import org.glassfish.jersey.internal.inject.InjectionManager; +import org.glassfish.jersey.internal.inject.Injections; +import org.glassfish.jersey.server.spring.scope.RequestContextFilter; +import org.junit.jupiter.api.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.WebApplicationContext; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class SpringRequestContextFilterTest { + @Test + public void testMissingAttributes() throws IOException { + WebApplicationContext webAppCtx = (WebApplicationContext) Proxy.newProxyInstance( + WebApplicationContext.class.getClassLoader(), + new Class[]{WebApplicationContext.class}, + new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return null; + } + }); + + InjectionManager injectionManager = Injections.createInjectionManager(); + injectionManager.register(new AbstractBinder() { + @Override + protected void configure() { + bind(webAppCtx).to(ApplicationContext.class); + } + }); + injectionManager.completeRegistration(); + + ContainerRequestContext requestContext = (ContainerRequestContext) Proxy.newProxyInstance( + ContainerRequestContext.class.getClassLoader(), + new Class[]{ContainerRequestContext.class}, + new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return null; + } + }); + + RequestContextFilter filter = new RequestContextFilter(injectionManager); + filter.filter(requestContext, (ContainerResponseContext) null); + } +}