Skip to content

Commit

Permalink
Add explicit support for floats in JsonWriter. (#2130)
Browse files Browse the repository at this point in the history
This avoids floats being treated as doubles and having an unwarranted level of precision.

Fixes #1127.
  • Loading branch information
Capstan committed Jun 8, 2022
1 parent 15b9fa9 commit 96ab171
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
19 changes: 19 additions & 0 deletions gson/src/main/java/com/google/gson/stream/JsonWriter.java
Expand Up @@ -490,6 +490,25 @@ public JsonWriter value(Boolean value) throws IOException {
return this;
}

/**
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Float#isNaN() NaNs} or {@link Float#isInfinite()
* infinities}.
* @return this writer.
* @throws IllegalArgumentException if the value is NaN or Infinity and this writer is not {@link
* #setLenient(boolean) lenient}.
*/
public JsonWriter value(float value) throws IOException {
writeDeferredName();
if (!lenient && (Float.isNaN(value) || Float.isInfinite(value))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
beforeValue();
out.append(Float.toString(value));
return this;
}

/**
* Encodes {@code value}.
*
Expand Down
66 changes: 66 additions & 0 deletions gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
Expand Up @@ -172,6 +172,30 @@ public void testJsonValue() throws IOException {
assertEquals("{\"a\":{\"b\":true},\"c\":1}", stringWriter.toString());
}

public void testNonFiniteFloats() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
try {
jsonWriter.value(Float.NaN);
fail();
} catch (IllegalArgumentException expected) {
assertEquals("Numeric values must be finite, but was NaN", expected.getMessage());
}
try {
jsonWriter.value(Float.NEGATIVE_INFINITY);
fail();
} catch (IllegalArgumentException expected) {
assertEquals("Numeric values must be finite, but was -Infinity", expected.getMessage());
}
try {
jsonWriter.value(Float.POSITIVE_INFINITY);
fail();
} catch (IllegalArgumentException expected) {
assertEquals("Numeric values must be finite, but was Infinity", expected.getMessage());
}
}

public void testNonFiniteDoubles() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
Expand Down Expand Up @@ -226,6 +250,18 @@ public void testNonFiniteNumbers() throws IOException {
}
}

public void testNonFiniteFloatsWhenLenient() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setLenient(true);
jsonWriter.beginArray();
jsonWriter.value(Float.NaN);
jsonWriter.value(Float.NEGATIVE_INFINITY);
jsonWriter.value(Float.POSITIVE_INFINITY);
jsonWriter.endArray();
assertEquals("[NaN,-Infinity,Infinity]", stringWriter.toString());
}

public void testNonFiniteDoublesWhenLenient() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
Expand All @@ -251,6 +287,36 @@ public void testNonFiniteNumbersWhenLenient() throws IOException {
assertEquals("[NaN,-Infinity,Infinity,Infinity]", stringWriter.toString());
}

public void testFloats() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.beginArray();
jsonWriter.value(-0.0f);
jsonWriter.value(1.0f);
jsonWriter.value(Float.MAX_VALUE);
jsonWriter.value(Float.MIN_VALUE);
jsonWriter.value(0.0f);
jsonWriter.value(-0.5f);
jsonWriter.value(2.2250739E-38f);
jsonWriter.value(3.723379f);
jsonWriter.value((float) Math.PI);
jsonWriter.value((float) Math.E);
jsonWriter.endArray();
jsonWriter.close();
assertEquals(
"[-0.0,"
+ "1.0,"
+ "3.4028235E38,"
+ "1.4E-45,"
+ "0.0,"
+ "-0.5,"
+ "2.2250739E-38,"
+ "3.723379,"
+ "3.1415927,"
+ "2.7182817]",
stringWriter.toString());
}

public void testDoubles() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
Expand Down

0 comments on commit 96ab171

Please sign in to comment.