Skip to content

getResourcePaths fails when a META-INF resource has reserved characters in its filename #9972

@wilkinsona

Description

@wilkinsona

Jetty version(s)
12.0.0.beta2

Java version/vendor (use: java -version)

openjdk version "17.0.7" 2023-04-18 LTS
OpenJDK Runtime Environment (build 17.0.7+7-LTS)
OpenJDK 64-Bit Server VM (build 17.0.7+7-LTS, mixed mode, sharing)

OS type/version

macOS 13.4

Description

I'm in the process of upgrading Spring Boot to Jetty 12 and have encountered a problem that's similar to #4033 and #7160. The setup is similar too. There's a jar file that contains a resource named META-INF/resources/nested-reserved-!#\\$%&()*+,:=?@[]-meta-inf-resource.txt and a servlet that's used for testing:

private static final class GetResourcePathsServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		collectResourcePaths("/").forEach(resp.getWriter()::println);
		resp.getWriter().flush();
	}

	private Set<String> collectResourcePaths(String path) {
		Set<String> allResourcePaths = new LinkedHashSet<>();
		Set<String> pathsForPath = getServletContext().getResourcePaths(path);
		if (pathsForPath != null) {
			for (String resourcePath : pathsForPath) {
				allResourcePaths.add(resourcePath);
				allResourcePaths.addAll(collectResourcePaths(resourcePath));
			}
		}
		return allResourcePaths;
	}

}

A request to this servlet fails:

java.lang.NumberFormatException: !hex &
	at org.eclipse.jetty.util.TypeUtil.convertHexDigit(TypeUtil.java:467) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.URIUtil.canonicalPath(URIUtil.java:729) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.URIUtil.canonicalPath(URIUtil.java:667) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletContextHandler$ServletContextApi.getResourcePaths(ServletContextHandler.java:2827) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at com.example.ResourceHandlingApplication$GetResourcePathsServlet.collectResourcePaths(ResourceHandlingApplication.java:81) ~[classes/:na]
	at com.example.ResourceHandlingApplication$GetResourcePathsServlet.collectResourcePaths(ResourceHandlingApplication.java:85) ~[classes/:na]
	at com.example.ResourceHandlingApplication$GetResourcePathsServlet.doGet(ResourceHandlingApplication.java:75) ~[classes/:na]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
	at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:739) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1601) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.0-M1.jar:6.1.0-M1]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-M1.jar:6.1.0-M1]
	at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1573) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:195) ~[jetty-ee10-websocket-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1573) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1534) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletChannel.lambda$handle$0(ServletChannel.java:427) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:684) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:418) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:458) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:504) ~[jetty-security-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:663) ~[jetty-ee10-servlet-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:798) ~[jetty-server-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:611) ~[jetty-server-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.server.Server.handle(Server.java:177) ~[jetty-server-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:617) ~[jetty-server-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:480) ~[jetty-server-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322) ~[jetty-io-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) ~[jetty-io-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) ~[jetty-io-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:473) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:436) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:288) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:196) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149) ~[jetty-util-12.0.0.beta2.jar:12.0.0.beta2]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

The same test succeeds with Jetty 11.

Metadata

Metadata

Assignees

Labels

BugFor general bugs on Jetty side

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions