|  | @@ -15,6 +15,7 @@ import com.fasterxml.jackson.core.JsonParser;
 | 
	
		
			
				|  |  |  import com.fasterxml.jackson.core.JsonProcessingException;
 | 
	
		
			
				|  |  |  import com.fasterxml.jackson.core.JsonToken;
 | 
	
		
			
				|  |  |  import com.fasterxml.jackson.core.exc.InputCoercionException;
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.core.exc.StreamConstraintsException;
 | 
	
		
			
				|  |  |  import com.fasterxml.jackson.core.io.JsonEOFException;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import org.elasticsearch.core.IOUtils;
 | 
	
	
		
			
				|  | @@ -28,6 +29,7 @@ import org.elasticsearch.xcontent.XContentType;
 | 
	
		
			
				|  |  |  import org.elasticsearch.xcontent.provider.XContentParserConfigurationImpl;
 | 
	
		
			
				|  |  |  import org.elasticsearch.xcontent.support.AbstractXContentParser;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.io.CharConversionException;
 | 
	
		
			
				|  |  |  import java.io.IOException;
 | 
	
		
			
				|  |  |  import java.nio.CharBuffer;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -50,20 +52,42 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |          parser.configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, allowDuplicateKeys == false);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static XContentParseException newXContentParseException(JsonProcessingException e) {
 | 
	
		
			
				|  |  | +    private static XContentLocation getLocation(JsonProcessingException e) {
 | 
	
		
			
				|  |  |          JsonLocation loc = e.getLocation();
 | 
	
		
			
				|  |  | -        throw new XContentParseException(new XContentLocation(loc.getLineNr(), loc.getColumnNr()), e.getMessage(), e);
 | 
	
		
			
				|  |  | +        if (loc != null) {
 | 
	
		
			
				|  |  | +            return new XContentLocation(loc.getLineNr(), loc.getColumnNr());
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static XContentParseException newXContentParseException(JsonProcessingException e) {
 | 
	
		
			
				|  |  | +        return new XContentParseException(getLocation(e), e.getMessage(), e);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * Handle parser exception depending on type.
 | 
	
		
			
				|  |  | +     * This converts known exceptions to XContentParseException and rethrows them.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    static IOException handleParserException(IOException e) throws IOException {
 | 
	
		
			
				|  |  | +        switch (e) {
 | 
	
		
			
				|  |  | +            case JsonEOFException eof -> throw new XContentEOFException(getLocation(eof), "Unexpected end of file", e);
 | 
	
		
			
				|  |  | +            case JsonParseException pe -> throw newXContentParseException(pe);
 | 
	
		
			
				|  |  | +            case InputCoercionException ice -> throw newXContentParseException(ice);
 | 
	
		
			
				|  |  | +            case CharConversionException cce -> throw new XContentParseException(null, cce.getMessage(), cce);
 | 
	
		
			
				|  |  | +            case StreamConstraintsException sce -> throw newXContentParseException(sce);
 | 
	
		
			
				|  |  | +            default -> {
 | 
	
		
			
				|  |  | +                return e;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public Token nextToken() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return convertToken(parser.nextToken());
 | 
	
		
			
				|  |  | -        } catch (JsonEOFException e) {
 | 
	
		
			
				|  |  | -            JsonLocation location = e.getLocation();
 | 
	
		
			
				|  |  | -            throw new XContentEOFException(new XContentLocation(location.getLineNr(), location.getColumnNr()), "Unexpected end of file", e);
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -71,8 +95,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public String nextFieldName() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.nextFieldName();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -100,8 +124,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      protected boolean doBooleanValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getBooleanValue();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -112,8 +136,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getText();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -139,8 +163,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public CharBuffer charBuffer() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return CharBuffer.wrap(parser.getTextCharacters(), parser.getTextOffset(), parser.getTextLength());
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -189,8 +213,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public char[] textCharacters() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getTextCharacters();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -198,8 +222,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public int textLength() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getTextLength();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -207,8 +231,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public int textOffset() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getTextOffset();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -216,8 +240,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public Number numberValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getNumberValue();
 | 
	
		
			
				|  |  | -        } catch (InputCoercionException | JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -225,8 +249,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public short doShortValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getShortValue();
 | 
	
		
			
				|  |  | -        } catch (InputCoercionException | JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -234,8 +258,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public int doIntValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getIntValue();
 | 
	
		
			
				|  |  | -        } catch (InputCoercionException | JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -243,8 +267,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public long doLongValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getLongValue();
 | 
	
		
			
				|  |  | -        } catch (InputCoercionException | JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -252,8 +276,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public float doFloatValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getFloatValue();
 | 
	
		
			
				|  |  | -        } catch (InputCoercionException | JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -261,8 +285,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public double doDoubleValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getDoubleValue();
 | 
	
		
			
				|  |  | -        } catch (InputCoercionException | JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -270,8 +294,8 @@ public class JsonXContentParser extends AbstractXContentParser {
 | 
	
		
			
				|  |  |      public byte[] binaryValue() throws IOException {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return parser.getBinaryValue();
 | 
	
		
			
				|  |  | -        } catch (JsonParseException e) {
 | 
	
		
			
				|  |  | -            throw newXContentParseException(e);
 | 
	
		
			
				|  |  | +        } catch (IOException e) {
 | 
	
		
			
				|  |  | +            throw handleParserException(e);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |