Merge branch 'serj-lotutovici-sl/fix_long_parsing'

* serj-lotutovici-sl/fix_long_parsing:
  Fix Long parsing for big values.
This commit is contained in:
jwilson
2017-01-16 13:47:40 -05:00
3 changed files with 33 additions and 38 deletions

View File

@@ -17,6 +17,7 @@ package com.squareup.moshi;
import java.io.EOFException;
import java.io.IOException;
import java.math.BigDecimal;
import okio.Buffer;
import okio.BufferedSource;
import okio.ByteString;
@@ -718,15 +719,11 @@ final class BufferedSourceJsonReader extends JsonReader {
}
peeked = PEEKED_BUFFERED;
double asDouble;
long result;
try {
asDouble = Double.parseDouble(peekedString);
} catch (NumberFormatException e) {
throw new JsonDataException("Expected a long but was " + peekedString
+ " at path " + getPath());
}
long result = (long) asDouble;
if (result != asDouble) { // Make sure no precision was lost casting to 'long'.
BigDecimal asDecimal = new BigDecimal(peekedString);
result = asDecimal.longValueExact();
} catch (NumberFormatException | ArithmeticException e) {
throw new JsonDataException("Expected a long but was " + peekedString
+ " at path " + getPath());
}

View File

@@ -617,11 +617,7 @@ public final class BufferedSourceJsonReaderTest {
}
}
/**
* This test fails because there's no double for 9223372036854775808, and our
* long parsing uses Double.parseDouble() for fractional values.
*/
@Test @Ignore public void peekLargerThanLongMaxValue() throws IOException {
@Test public void peekLargerThanLongMaxValue() throws IOException {
JsonReader reader = newReader("[9223372036854775808]");
reader.setLenient(true);
reader.beginArray();
@@ -633,11 +629,19 @@ public final class BufferedSourceJsonReaderTest {
}
}
/**
* This test fails because there's no double for -9223372036854775809, and our
* long parsing uses Double.parseDouble() for fractional values.
*/
@Test @Ignore public void peekLargerThanLongMinValue() throws IOException {
@Test public void precisionNotDiscarded() throws IOException {
JsonReader reader = newReader("[9223372036854775806.5]");
reader.setLenient(true);
reader.beginArray();
assertThat(reader.peek()).isEqualTo(NUMBER);
try {
reader.nextLong();
fail();
} catch (JsonDataException expected) {
}
}
@Test public void peekLargerThanLongMinValue() throws IOException {
JsonReader reader = newReader("[-9223372036854775809]");
reader.setLenient(true);
reader.beginArray();
@@ -650,11 +654,7 @@ public final class BufferedSourceJsonReaderTest {
assertThat(reader.nextDouble()).isEqualTo(-9223372036854775809d);
}
/**
* This test fails because there's no double for 9223372036854775806, and
* our long parsing uses Double.parseDouble() for fractional values.
*/
@Test @Ignore public void highPrecisionLong() throws IOException {
@Test public void highPrecisionLong() throws IOException {
String json = "[9223372036854775806.000]";
JsonReader reader = newReader(json);
reader.beginArray();

View File

@@ -433,21 +433,19 @@ public final class MoshiTest {
assertThat(adapter.fromJson("9223372036854775807")).isEqualTo(Long.MAX_VALUE);
assertThat(adapter.toJson(Long.MAX_VALUE)).isEqualTo("9223372036854775807");
// TODO: This is a bug?
assertThat(adapter.fromJson("9223372036854775808")).isEqualTo(Long.MAX_VALUE); // wtf?
//try {
// adapter.fromJson("9223372036854775808");
// fail();
//} catch (NumberFormatException expected) {
// assertThat(expected).hasMessage("Expected a long but was 9223372036854775808 at path $");
//}
//
//try {
// adapter.fromJson("-9223372036854775809");
// fail();
//} catch (NumberFormatException expected) {
// assertThat(expected).hasMessage("Expected a long but was -9223372036854775809 at path $");
//}
try {
adapter.fromJson("9223372036854775808");
fail();
} catch (JsonDataException expected) {
assertThat(expected).hasMessage("Expected a long but was 9223372036854775808 at path $");
}
try {
adapter.fromJson("-9223372036854775809");
fail();
} catch (JsonDataException expected) {
assertThat(expected).hasMessage("Expected a long but was -9223372036854775809 at path $");
}
// Nulls not allowed for long.class
try {