Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions library/src/main/java/com/dslplatform/json/NumberConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -383,48 +383,56 @@ static NumberInfo readLongNumber(final JsonReader reader, final int start) throw
}

public static double deserializeDouble(final JsonReader reader) throws IOException {
if (reader.last() == '"') {
final int position = reader.getCurrentIndex();
final char[] buf = reader.readSimpleQuote();
return parseDoubleGeneric(buf, reader.getCurrentIndex() - position - 1, reader, true);
final boolean withQuotes = reader.last() == '"';
final int start, end;
if (withQuotes) {
final char[] tmp = reader.readSimpleQuote();
start = reader.getTokenStart();
end = reader.getCurrentIndex() - 1;
}
else {
start = reader.scanNumber();
end = reader.getCurrentIndex();
}
final int start = reader.scanNumber();
final int end = reader.getCurrentIndex();
final byte[] buf = reader.buffer;
final byte ch = buf[start];
if (ch == '-') {
return -parseDouble(buf, reader, start, end, 1);
return -parseDouble(buf, reader, start, end, 1, withQuotes);
}
return parseDouble(buf, reader, start, end, 0);
return parseDouble(buf, reader, start, end, 0, withQuotes);
}

private static double parseDouble(final byte[] buf, final JsonReader reader, final int start, final int end, final int offset) throws IOException {
private static double parseDouble(final byte[] buf, final JsonReader reader, final int start, final int end, final int offset, final boolean withQuotes) throws IOException {
if (end - start - offset > reader.doubleLengthLimit) {
if (end == reader.length()) {
final NumberInfo tmp = readLongNumber(reader, start + offset);
return parseDoubleGeneric(tmp.buffer, tmp.length, reader, false);
return parseDoubleGeneric(tmp.buffer, tmp.length, reader, withQuotes);
}
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, false);
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, withQuotes);
}
long value = 0;
byte ch = ' ';
int i = start + offset;
final boolean leadingZero = buf[start + offset] == 48;
final boolean leadingZero = buf[i] == 48;
// Add support for NaN and Infinity now that this method handles quoted values
if (buf[i] == 'N' || buf[i] == 'I') {
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, withQuotes);
}
for (; i < end; i++) {
ch = buf[i];
if (ch == '.' || ch == 'e' || ch == 'E') break;
final int ind = buf[i] - 48;
if (ind < 0 || ind > 9) {
if (leadingZero && i > start + offset + 1) {
numberException(reader, start, end, "Leading zero is not allowed");
numberException(reader, start, end + (withQuotes ? 2 : 0), "Leading zero is not allowed");
}
if (i > start + offset && reader.allWhitespace(i, end)) return value;
numberException(reader, start, end, "Unknown digit", (char)ch);
}
value = (value << 3) + (value << 1) + ind;
}
if (i == start + offset) numberException(reader, start, end, "Digit not found");
else if (leadingZero && ch != '.' && i > start + offset + 1) numberException(reader, start, end, "Leading zero is not allowed");
else if (leadingZero && ch != '.' && i > start + offset + 1) numberException(reader, start, end + (withQuotes ? 2 : 0), "Leading zero is not allowed");
else if (i == end) return value;
else if (ch == '.') {
i++;
Expand All @@ -438,7 +446,7 @@ else if (ch == '.') {
maxLen = i + 15;
ch = buf[i];
if (ch == '0' && end > maxLen) {
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, false);
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, withQuotes);
} else if (ch < '8') {
preciseDividor = 1e14;
expDiff = -1;
Expand Down Expand Up @@ -477,7 +485,7 @@ else if (ch == 'e' || ch == 'E') {
return doubleExponent(reader, value, i - decPos,0, buf, start, end, offset, i);
}
if (reader.doublePrecision == JsonReader.DoublePrecision.HIGH) {
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, false);
return parseDoubleGeneric(reader.prepareBuffer(start + offset, end - start - offset), end - start - offset, reader, withQuotes);
}
int decimals = 0;
final int decLimit = start + offset + 18 < end ? start + offset + 18 : end;
Expand Down Expand Up @@ -1755,4 +1763,4 @@ public static ArrayList<BigDecimal> deserializeDecimalNullableCollection(final J
public static void deserializeDecimalNullableCollection(final JsonReader reader, final Collection<BigDecimal> res) throws IOException {
reader.deserializeNullableCollection(DECIMAL_READER, res);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1563,4 +1563,20 @@ public void testNumberDeserializationWithNewStreamWhenAtBoundaryAndMore() throws

Assert.assertEquals(expected, actual);
}

@Test
public void quotedDoubles() throws IOException {
// setup
final JsonWriter sw = new JsonWriter(null);
final String[] inputs = { "\"104923.87000004\"", "\"0.00230002\"","\"-104923.87000004\"", "\"-0.00230002\"" };
final JsonReader<Object> jr = dslJson.newReader(new byte[0]);
for (String inp : inputs) {
double expected = Double.parseDouble(inp.substring(1, inp.length() - 1));
byte[] bytes = inp.getBytes("UTF-8");
jr.process(bytes, bytes.length);
jr.read();
double number = NumberConverter.deserializeDouble(jr);
Assert.assertEquals(expected, number, 0);
}
}
}