Skip to content

Commit 96ab171

Browse files
authored
Add explicit support for floats in JsonWriter. (#2130)
This avoids floats being treated as doubles and having an unwarranted level of precision. Fixes #1127.
1 parent 15b9fa9 commit 96ab171

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

gson/src/main/java/com/google/gson/stream/JsonWriter.java

+19
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,25 @@ public JsonWriter value(Boolean value) throws IOException {
490490
return this;
491491
}
492492

493+
/**
494+
* Encodes {@code value}.
495+
*
496+
* @param value a finite value. May not be {@link Float#isNaN() NaNs} or {@link Float#isInfinite()
497+
* infinities}.
498+
* @return this writer.
499+
* @throws IllegalArgumentException if the value is NaN or Infinity and this writer is not {@link
500+
* #setLenient(boolean) lenient}.
501+
*/
502+
public JsonWriter value(float value) throws IOException {
503+
writeDeferredName();
504+
if (!lenient && (Float.isNaN(value) || Float.isInfinite(value))) {
505+
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
506+
}
507+
beforeValue();
508+
out.append(Float.toString(value));
509+
return this;
510+
}
511+
493512
/**
494513
* Encodes {@code value}.
495514
*

gson/src/test/java/com/google/gson/stream/JsonWriterTest.java

+66
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,30 @@ public void testJsonValue() throws IOException {
172172
assertEquals("{\"a\":{\"b\":true},\"c\":1}", stringWriter.toString());
173173
}
174174

175+
public void testNonFiniteFloats() throws IOException {
176+
StringWriter stringWriter = new StringWriter();
177+
JsonWriter jsonWriter = new JsonWriter(stringWriter);
178+
jsonWriter.beginArray();
179+
try {
180+
jsonWriter.value(Float.NaN);
181+
fail();
182+
} catch (IllegalArgumentException expected) {
183+
assertEquals("Numeric values must be finite, but was NaN", expected.getMessage());
184+
}
185+
try {
186+
jsonWriter.value(Float.NEGATIVE_INFINITY);
187+
fail();
188+
} catch (IllegalArgumentException expected) {
189+
assertEquals("Numeric values must be finite, but was -Infinity", expected.getMessage());
190+
}
191+
try {
192+
jsonWriter.value(Float.POSITIVE_INFINITY);
193+
fail();
194+
} catch (IllegalArgumentException expected) {
195+
assertEquals("Numeric values must be finite, but was Infinity", expected.getMessage());
196+
}
197+
}
198+
175199
public void testNonFiniteDoubles() throws IOException {
176200
StringWriter stringWriter = new StringWriter();
177201
JsonWriter jsonWriter = new JsonWriter(stringWriter);
@@ -226,6 +250,18 @@ public void testNonFiniteNumbers() throws IOException {
226250
}
227251
}
228252

253+
public void testNonFiniteFloatsWhenLenient() throws IOException {
254+
StringWriter stringWriter = new StringWriter();
255+
JsonWriter jsonWriter = new JsonWriter(stringWriter);
256+
jsonWriter.setLenient(true);
257+
jsonWriter.beginArray();
258+
jsonWriter.value(Float.NaN);
259+
jsonWriter.value(Float.NEGATIVE_INFINITY);
260+
jsonWriter.value(Float.POSITIVE_INFINITY);
261+
jsonWriter.endArray();
262+
assertEquals("[NaN,-Infinity,Infinity]", stringWriter.toString());
263+
}
264+
229265
public void testNonFiniteDoublesWhenLenient() throws IOException {
230266
StringWriter stringWriter = new StringWriter();
231267
JsonWriter jsonWriter = new JsonWriter(stringWriter);
@@ -251,6 +287,36 @@ public void testNonFiniteNumbersWhenLenient() throws IOException {
251287
assertEquals("[NaN,-Infinity,Infinity,Infinity]", stringWriter.toString());
252288
}
253289

290+
public void testFloats() throws IOException {
291+
StringWriter stringWriter = new StringWriter();
292+
JsonWriter jsonWriter = new JsonWriter(stringWriter);
293+
jsonWriter.beginArray();
294+
jsonWriter.value(-0.0f);
295+
jsonWriter.value(1.0f);
296+
jsonWriter.value(Float.MAX_VALUE);
297+
jsonWriter.value(Float.MIN_VALUE);
298+
jsonWriter.value(0.0f);
299+
jsonWriter.value(-0.5f);
300+
jsonWriter.value(2.2250739E-38f);
301+
jsonWriter.value(3.723379f);
302+
jsonWriter.value((float) Math.PI);
303+
jsonWriter.value((float) Math.E);
304+
jsonWriter.endArray();
305+
jsonWriter.close();
306+
assertEquals(
307+
"[-0.0,"
308+
+ "1.0,"
309+
+ "3.4028235E38,"
310+
+ "1.4E-45,"
311+
+ "0.0,"
312+
+ "-0.5,"
313+
+ "2.2250739E-38,"
314+
+ "3.723379,"
315+
+ "3.1415927,"
316+
+ "2.7182817]",
317+
stringWriter.toString());
318+
}
319+
254320
public void testDoubles() throws IOException {
255321
StringWriter stringWriter = new StringWriter();
256322
JsonWriter jsonWriter = new JsonWriter(stringWriter);

0 commit comments

Comments
 (0)