Skip to content

Commit 2b2b44e

Browse files
Fixed integer overflow handling in JsonTokenEventHandlerAdaptor (#642)
1 parent 0bd018d commit 2b2b44e

2 files changed

Lines changed: 79 additions & 3 deletions

File tree

httpcore5-jackson2/src/main/java/org/apache/hc/core5/jackson2/JsonTokenEventHandlerAdaptor.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,16 @@ public void accept(final int tokenId, final JsonParser jsonParser) throws IOExce
6767
break;
6868
case JsonTokenId.ID_NUMBER_INT:
6969
final JsonParser.NumberType numberType = jsonParser.getNumberType();
70-
final Number numberValue = jsonParser.getNumberValue();
7170
if (numberType == JsonParser.NumberType.LONG) {
72-
eventHandler.value(numberValue.longValue());
71+
eventHandler.value(jsonParser.getLongValue());
72+
} else if (numberType == JsonParser.NumberType.BIG_INTEGER) {
73+
try {
74+
eventHandler.value(jsonParser.getLongValue());
75+
} catch (final IOException ex) {
76+
throw new IOException("Integer value is out of range for 64-bit signed long: " + jsonParser.getText(), ex);
77+
}
7378
} else {
74-
eventHandler.value(numberValue.intValue());
79+
eventHandler.value(jsonParser.getIntValue());
7580
}
7681
break;
7782
case JsonTokenId.ID_NUMBER_FLOAT:
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* ====================================================================
3+
* Licensed to the Apache Software Foundation (ASF) under one
4+
* or more contributor license agreements. See the NOTICE file
5+
* distributed with this work for additional information
6+
* regarding copyright ownership. The ASF licenses this file
7+
* to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance
9+
* with the License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing,
14+
* software distributed under the License is distributed on an
15+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
* KIND, either express or implied. See the License for the
17+
* specific language governing permissions and limitations
18+
* under the License.
19+
* ====================================================================
20+
*
21+
* This software consists of voluntary contributions made by many
22+
* individuals on behalf of the Apache Software Foundation. For more
23+
* information on the Apache Software Foundation, please see
24+
* <http://www.apache.org/>.
25+
*
26+
*/
27+
package org.apache.hc.core5.jackson2;
28+
29+
import java.io.IOException;
30+
31+
import com.fasterxml.jackson.core.JsonParser;
32+
import com.fasterxml.jackson.core.JsonTokenId;
33+
34+
import org.assertj.core.api.Assertions;
35+
import org.junit.jupiter.api.Test;
36+
import org.mockito.Mockito;
37+
38+
public class JsonTokenEventHandlerAdaptorTest {
39+
40+
@Test
41+
void testIntTokenWithBigIntegerConvertibleToLongUsesLongCallback() throws Exception {
42+
final JsonTokenEventHandler eventHandler = Mockito.mock(JsonTokenEventHandler.class);
43+
final JsonParser jsonParser = Mockito.mock(JsonParser.class);
44+
Mockito.when(jsonParser.getNumberType()).thenReturn(JsonParser.NumberType.BIG_INTEGER);
45+
Mockito.when(jsonParser.getLongValue()).thenReturn(2147483648L);
46+
47+
final JsonTokenEventHandlerAdaptor adaptor = new JsonTokenEventHandlerAdaptor(eventHandler);
48+
adaptor.accept(JsonTokenId.ID_NUMBER_INT, jsonParser);
49+
50+
Mockito.verify(eventHandler).value(2147483648L);
51+
Mockito.verify(eventHandler, Mockito.never()).value(Mockito.anyInt());
52+
Mockito.verifyNoMoreInteractions(eventHandler);
53+
}
54+
55+
@Test
56+
void testIntTokenWithBigIntegerOutOfLongRangeThrowsIOException() throws Exception {
57+
final JsonTokenEventHandler eventHandler = Mockito.mock(JsonTokenEventHandler.class);
58+
final JsonParser jsonParser = Mockito.mock(JsonParser.class);
59+
Mockito.when(jsonParser.getNumberType()).thenReturn(JsonParser.NumberType.BIG_INTEGER);
60+
Mockito.when(jsonParser.getText()).thenReturn("9223372036854775808");
61+
Mockito.when(jsonParser.getLongValue()).thenThrow(new IOException("Numeric value out of range"));
62+
63+
final JsonTokenEventHandlerAdaptor adaptor = new JsonTokenEventHandlerAdaptor(eventHandler);
64+
Assertions.assertThatIOException().isThrownBy(
65+
() -> adaptor.accept(JsonTokenId.ID_NUMBER_INT, jsonParser))
66+
.withMessageContaining("out of range for 64-bit signed long");
67+
68+
Mockito.verifyNoInteractions(eventHandler);
69+
}
70+
71+
}

0 commit comments

Comments
 (0)