javaee / grizzly

Writing scalable server applications in the Java™ programming language has always been difficult. Before the advent of the Java New I/O API (NIO), thread management issues made it impossible for a server to scale to thousands of users. The Grizzly NIO framework has been designed to help developers to take advantage of the Java™ NIO API.
https://javaee.github.io/grizzly/
Other
222 stars 60 forks source link

HttpServletRequest#getHeader throws StringIndexOutOfBoundsException #1931

Closed tsyamamoto closed 7 years ago

tsyamamoto commented 7 years ago

HttpServletRequest#getHeader throws StringIndexOutOfBoundsException. I think checking empty value is missing.

Sample servlet application: GetHeader.java

import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns={"/test"})
public class GetHeader extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        String str = req.getHeader("");
        res.getWriter().println("str = "+str);
    }
}

server.log of GlassFish 4.1.2

[2017-05-08T08:36:51.861+0900] [glassfish 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=37 _ThreadName=http-listener-1(1)] [timeMillis: 1494200211861] [levelValue: 900] [[
  StandardWrapperValve[test.bas.GetHeader]: Servlet.service() for servlet test.bas.GetHeader threw exception
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.lang.String.charAt(String.java:658)
    at org.glassfish.grizzly.http.HttpHeader.isSpecialHeader(HttpHeader.java:917)
    at org.glassfish.grizzly.http.HttpHeader.handleGetSpecialHeader(HttpHeader.java:893)
    at org.glassfish.grizzly.http.HttpHeader.getHeader(HttpHeader.java:614)
    at org.glassfish.grizzly.http.server.Request.getHeader(Request.java:1625)
    at org.apache.catalina.connector.Request.getHeader(Request.java:2654)
    at org.apache.catalina.connector.RequestFacade.getHeader(RequestFacade.java:716)
    at test.bas.GetHeader.doGet(GetHeader.java:13)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:744)
]]

grizzly\modules\http\src\main\java\org\glassfish\grizzly\http\HttpHeader.java

    protected static boolean isSpecialHeader(final String name) {
        final char c = name.charAt(0);    // StringIndexOutOfBoundsException is thrown if name is empty.
        return (c == 'C' || c == 'c' || c == 'U' || c == 'u');
    }
tsyamamoto commented 7 years ago

I found similar issue.

javax.servlet.http.HttpServletRequest#getHeaders(null) throws NullPointerException.

[2017-05-12T09:58:45.493+0900] [glassfish 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=29 _ThreadName=http-listener-1(1)] [timeMillis: 1494550725493] [levelValue: 900] [[
  StandardWrapperValve[test.bas.GetHeader]: Servlet.service() for servlet test.bas.GetHeader threw exception
java.lang.NullPointerException
    at org.glassfish.grizzly.http.util.ByteChunk.equalsIgnoreCase(ByteChunk.java:974)
    at org.glassfish.grizzly.http.util.ByteChunk.equalsIgnoreCase(ByteChunk.java:742)
    at org.glassfish.grizzly.http.util.DataChunk.equalsIgnoreCase(DataChunk.java:685)
    at org.glassfish.grizzly.http.util.ValuesIterator.findNext(MimeHeaders.java:756)
    at org.glassfish.grizzly.http.util.ValuesIterator.<init>(MimeHeaders.java:749)
    at org.glassfish.grizzly.http.util.MimeHeaders$2.iterator(MimeHeaders.java:374)
    at org.apache.catalina.connector.Request.getHeaders(Request.java:2665)
    at org.apache.catalina.connector.RequestFacade.getHeaders(RequestFacade.java:730)
    at test.bas.GetHeader.doGet(GetHeader.java:51)

In javadoc of servlet api, the behavior of null is not referred. So the behavior of null may be vendor specific. However, getHeader(null) does not throw NullPointerException. So the behavior of getHeaders(null) seems to be a bug,