Add explicit support for floats in JsonTreeWriter. (#2132)

Follow-up to comments on #2130, which introduced a new override which was not overridden by `JsonTreeWriter`. Also tweaks the doccomments for `float`, `double` and `Number` variants of `JsonWriter.value`.

Supplement to the fix for #1127.
This commit is contained in:
Nathan Herring 2022-06-21 09:50:07 -07:00 committed by GitHub
parent 08d4572fc4
commit d2aee6502b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 7 deletions

View File

@ -170,6 +170,14 @@ public final class JsonTreeWriter extends JsonWriter {
return this; return this;
} }
@Override public JsonWriter value(float value) throws IOException {
if (!isLenient() && (Float.isNaN(value) || Float.isInfinite(value))) {
throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
}
put(new JsonPrimitive(value));
return this;
}
@Override public JsonWriter value(double value) throws IOException { @Override public JsonWriter value(double value) throws IOException {
if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value))) { if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value))) {
throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value); throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);

View File

@ -493,8 +493,9 @@ public class JsonWriter implements Closeable, Flushable {
/** /**
* Encodes {@code value}. * Encodes {@code value}.
* *
* @param value a finite value. May not be {@link Float#isNaN() NaNs} or {@link Float#isInfinite() * @param value a finite value, or if {@link #setLenient(boolean) lenient},
* infinities}. * also {@link Float#isNaN() NaN} or {@link Float#isInfinite()
* infinity}.
* @return this writer. * @return this writer.
* @throws IllegalArgumentException if the value is NaN or Infinity and this writer is not {@link * @throws IllegalArgumentException if the value is NaN or Infinity and this writer is not {@link
* #setLenient(boolean) lenient}. * #setLenient(boolean) lenient}.
@ -512,8 +513,8 @@ public class JsonWriter implements Closeable, Flushable {
/** /**
* Encodes {@code value}. * Encodes {@code value}.
* *
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or * @param value a finite value, or if {@link #setLenient(boolean) lenient},
* {@link Double#isInfinite() infinities}. * also {@link Double#isNaN() NaN} or {@link Double#isInfinite() infinity}.
* @return this writer. * @return this writer.
* @throws IllegalArgumentException if the value is NaN or Infinity and this writer is * @throws IllegalArgumentException if the value is NaN or Infinity and this writer is
* not {@link #setLenient(boolean) lenient}. * not {@link #setLenient(boolean) lenient}.
@ -555,8 +556,8 @@ public class JsonWriter implements Closeable, Flushable {
* Encodes {@code value}. The value is written by directly writing the {@link Number#toString()} * Encodes {@code value}. The value is written by directly writing the {@link Number#toString()}
* result to JSON. Implementations must make sure that the result represents a valid JSON number. * result to JSON. Implementations must make sure that the result represents a valid JSON number.
* *
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or * @param value a finite value, or if {@link #setLenient(boolean) lenient},
* {@link Double#isInfinite() infinities}. * also {@link Double#isNaN() NaN} or {@link Double#isInfinite() infinity}.
* @return this writer. * @return this writer.
* @throws IllegalArgumentException if the value is NaN or Infinity and this writer is * @throws IllegalArgumentException if the value is NaN or Infinity and this writer is
* not {@link #setLenient(boolean) lenient}; or if the {@code toString()} result is not a * not {@link #setLenient(boolean) lenient}; or if the {@code toString()} result is not a

View File

@ -152,17 +152,35 @@ public final class JsonTreeWriterTest extends TestCase {
JsonTreeWriter writer = new JsonTreeWriter(); JsonTreeWriter writer = new JsonTreeWriter();
writer.setLenient(true); writer.setLenient(true);
writer.beginArray(); writer.beginArray();
writer.value(Float.NaN);
writer.value(Float.NEGATIVE_INFINITY);
writer.value(Float.POSITIVE_INFINITY);
writer.value(Double.NaN); writer.value(Double.NaN);
writer.value(Double.NEGATIVE_INFINITY); writer.value(Double.NEGATIVE_INFINITY);
writer.value(Double.POSITIVE_INFINITY); writer.value(Double.POSITIVE_INFINITY);
writer.endArray(); writer.endArray();
assertEquals("[NaN,-Infinity,Infinity]", writer.get().toString()); assertEquals("[NaN,-Infinity,Infinity,NaN,-Infinity,Infinity]", writer.get().toString());
} }
public void testStrictNansAndInfinities() throws IOException { public void testStrictNansAndInfinities() throws IOException {
JsonTreeWriter writer = new JsonTreeWriter(); JsonTreeWriter writer = new JsonTreeWriter();
writer.setLenient(false); writer.setLenient(false);
writer.beginArray(); writer.beginArray();
try {
writer.value(Float.NaN);
fail();
} catch (IllegalArgumentException expected) {
}
try {
writer.value(Float.NEGATIVE_INFINITY);
fail();
} catch (IllegalArgumentException expected) {
}
try {
writer.value(Float.POSITIVE_INFINITY);
fail();
} catch (IllegalArgumentException expected) {
}
try { try {
writer.value(Double.NaN); writer.value(Double.NaN);
fail(); fail();
@ -184,6 +202,21 @@ public final class JsonTreeWriterTest extends TestCase {
JsonTreeWriter writer = new JsonTreeWriter(); JsonTreeWriter writer = new JsonTreeWriter();
writer.setLenient(false); writer.setLenient(false);
writer.beginArray(); writer.beginArray();
try {
writer.value(Float.valueOf(Float.NaN));
fail();
} catch (IllegalArgumentException expected) {
}
try {
writer.value(Float.valueOf(Float.NEGATIVE_INFINITY));
fail();
} catch (IllegalArgumentException expected) {
}
try {
writer.value(Float.valueOf(Float.POSITIVE_INFINITY));
fail();
} catch (IllegalArgumentException expected) {
}
try { try {
writer.value(Double.valueOf(Double.NaN)); writer.value(Double.valueOf(Double.NaN));
fail(); fail();