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

FilterChainContext.toString crashes with NullPointerException #1959

Closed Kuerten closed 7 years ago

Kuerten commented 7 years ago

There is a bug with the toString method of FilterChainContext. This occurrs at least in version 2.4.0-beta8 but upon manual inspection also in branches master and 2.4.x as of today.

To reproduce you can use log level finest and basically any request.

The problem is in these methods https://github.com/javaee/grizzly/blob/2_4_0_beta8/modules/grizzly/src/main/java/org/glassfish/grizzly/filterchain/FilterChainContext.java#L397 and https://github.com/javaee/grizzly/blob/2_4_0_beta8/modules/grizzly/src/main/java/org/glassfish/grizzly/filterchain/FilterChainContext.java#L1069

@SuppressWarnings("unchecked")
    public <T> T getMessage() {
        return (T) message;
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(384);
        sb.append("FilterChainContext [");
        sb.append("connection=").append(getConnection());
        sb.append(", closeable=").append(getCloseable());
        sb.append(", operation=").append(getOperation());
        sb.append(", message=").append(String.valueOf(getMessage()));
        sb.append(", address=").append(getAddress());
        sb.append(']');

        return sb.toString();
    }

There are two overloads of String.valueOf, with Object and char[]. (Java 8) Because of the dangerous unbound generic in getMessage both overloads would seem applicable, however the char[] overload is chosen, probably because it is more specific. See bytecode:

L5
    LINENUMBER 1076 L5
    ALOAD 1: sb
    LDC ", message="
    INVOKEVIRTUAL StringBuilder.append (String) : StringBuilder
    ALOAD 0: this
    INVOKEVIRTUAL FilterChainContext.getMessage () : Object
    CHECKCAST [C
    INVOKESTATIC String.valueOf (char[]) : String
    INVOKEVIRTUAL StringBuilder.append (String) : StringBuilder
    POP

However String.valueOf(char[]) will fail if the result of getMessage is null. Also I would assume a ClassCastException could happen in other cases. This can be fixed by explicitly casting the result to object or ensuring that the correct generics are infered. For completeness, part of the stacktrace, but that does not show the overload.

13:51:09.891 [grizzly-nio-kernel(2) SelectorRunner] WARN  o.g.g.filterchain.DefaultFilterChain - GRIZZLY0013: Exception during FilterChain execution
java.lang.NullPointerException: null
    at java.lang.String.<init>(Unknown Source)
    at java.lang.String.valueOf(Unknown Source)
    at org.glassfish.grizzly.filterchain.FilterChainContext.toString(FilterChainContext.java:1076)