-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Description
Describe the bug
GetResult.fromXContent(XcontentParser parser) throws a NullPointerException if the field "found" is missing.
This is an unexpected exception type for a parsing failure and can be confusing to developers. Other missing fields throw a ParsingException which developers are used to handling.
Related component
Libraries
To Reproduce
Run the following program.
import org.opensearch.action.get.GetResponse;
import org.opensearch.common.xcontent.LoggingDeprecationHandler;
import org.opensearch.common.xcontent.json.JsonXContent;
import org.opensearch.core.common.ParsingException;
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentParser;
import java.io.IOException;
public class ReproTestCase {
public static void main(String... args) {
printExceptionType("{foo}");
printExceptionType("{\"found\":false}");
printExceptionType("{\"_index\":\"foo\",\"_id\":\"bar\"}");
}
static void printExceptionType(String json) {
System.out.println("String to parse: " + json);
try (
XContentParser parser = JsonXContent.jsonXContent
.createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, json)
) {
GetResponse.fromXContent(parser);
} catch (IOException io) {
System.out.println(" Bad JSON, expected IOException: " + io.getMessage());
} catch (ParsingException p) {
System.out.println(" Missing fields, expected ParsingException: " + p.getMessage());
} catch (Exception e) {
System.out.println(" Missing \"found\", unexpected Exception: " + e.getClass() + ", " + e.getMessage());
}
System.out.println();
}
}Output:
String to parse: "{foo}"
Bad JSON, expected IOException: Unexpected character ('f' (code 102)): was expecting double-quote to start field name
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 2]
String to parse: "{"found":false}"
Missing fields, expected ParsingException: Missing required fields [_index,_id]
String to parse: "{"_index":"foo","_id":"bar"}"
Missing "found", unexpected Exception: class java.lang.NullPointerException, null
Expected behavior
Code should either throw a ParsingException for a missing found field, or assume a sensible default (false) if it's omitted.
Additional Details
Additional context
The root cause of the problem is that found is initialized to null here:
| Boolean found = null; |
And then only conditionally initialized:
OpenSearch/server/src/main/java/org/opensearch/index/get/GetResult.java
Lines 372 to 374 in 47feca7
| } else if (FOUND.equals(currentFieldName)) { | |
| found = parser.booleanValue(); | |
| } else { |
This value is passed to the GetResult constructor which expects a primitive boolean for the exists parameter. Unboxing the null Boolean results in the NPE.
Suggested Fix
Option 1: test the value for null before calling the GetResult constructor, and throw a ParsingException.
Option 2: initialize found to false