Skip to content

Commit

Permalink
Merge pull request #1958 from bugsnag/PLAT-11342/handle-nan-infinity-…
Browse files Browse the repository at this point in the history
…values

Handle NaN & Infinity values in serialization
  • Loading branch information
lemnik authored Jan 26, 2024
2 parents baf6804 + dcb3b12 commit 59adb78
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 154 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

* Avoid any possibility of multiple conflicting native crash handlers or stack-unwinders running concurrently
[#1960](https://github.com/bugsnag/bugsnag-android/pull/1960)
* Metadata that includes non-finite doubles (NaN, +Infinity, -Infinity) are omitted instead of breaking serialization
[#1958](https://github.com/bugsnag/bugsnag-android/pull/1958)

## 6.1.0 (2023-12-05)

Expand All @@ -16,7 +18,7 @@

### Bug fixes

* Updating existing feature flags no longer causes them to change location.
* Updating existing feature-flags flags no longer causes them to change location.
[#1940](https://github.com/bugsnag/bugsnag-android/pull/1940)
* Fixed possible NDK crash when constructing several concurrent `Client` instances
[#1950](https://github.com/bugsnag/bugsnag-android/pull/1950)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ internal class BugsnagEventMapper(
event.userImpl = convertUser(map.readEntry("user"))

// populate metadata
val metadataMap: Map<String, Map<String, Any?>> = map.readEntry("metaData")
val metadataMap: Map<String, Map<String, Any?>> =
(map["metaData"] as? Map<String, Map<String, Any?>>).orEmpty()
metadataMap.forEach { (key, value) ->
event.addMetadata(key, value)
}

val featureFlagsList: List<Map<String, Any?>> = map.readEntry("featureFlags")
val featureFlagsList: List<Map<String, Any?>> =
(map["featureFlags"] as? List<Map<String, Any?>>).orEmpty()
featureFlagsList.forEach { featureFlagMap ->
event.addFeatureFlag(
featureFlagMap.readEntry("featureFlag"),
Expand All @@ -43,7 +45,8 @@ internal class BugsnagEventMapper(
}

// populate breadcrumbs
val breadcrumbList: List<MutableMap<String, Any?>> = map.readEntry("breadcrumbs")
val breadcrumbList: List<MutableMap<String, Any?>> =
(map["breadcrumbs"] as? List<MutableMap<String, Any?>>).orEmpty()
breadcrumbList.mapTo(event.breadcrumbs) {
Breadcrumb(
convertBreadcrumbInternal(it),
Expand Down Expand Up @@ -226,8 +229,7 @@ internal class BugsnagEventMapper(
is T -> return value
null -> throw IllegalStateException("cannot find json property '$key'")
else -> throw IllegalArgumentException(
"json property '$key' not " +
"of expected type, found ${value.javaClass.name}"
"json property '$key' not of expected type, found ${value.javaClass.name}"
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class JsonWriter implements Closeable, Flushable {
*/
private static final String[] REPLACEMENT_CHARS;
private static final String[] HTML_SAFE_REPLACEMENT_CHARS;

static {
REPLACEMENT_CHARS = new String[128];
for (int i = 0; i <= 0x1f; i++) {
Expand All @@ -165,11 +166,14 @@ class JsonWriter implements Closeable, Flushable {
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
}

/** The output data, containing at most one top-level array or object. */
/**
* The output data, containing at most one top-level array or object.
*/
private final Writer out;

private int[] stack = new int[32];
private int stackSize = 0;

{
push(EMPTY_DOCUMENT);
}
Expand Down Expand Up @@ -337,7 +341,7 @@ private JsonWriter open(int empty, String openBracket) throws IOException {
* given bracket.
*/
private JsonWriter close(int empty, int nonempty, String closeBracket)
throws IOException {
throws IOException {
int context = peek();
if (context != nonempty && context != empty) {
throw new IllegalStateException("Nesting problem.");
Expand Down Expand Up @@ -437,7 +441,7 @@ public JsonWriter jsonValue(String value) throws IOException {
}
writeDeferredName();
beforeValue();
out.append(value);
out.write(value);
return this;
}

Expand Down Expand Up @@ -490,17 +494,18 @@ public JsonWriter value(Boolean value) throws IOException {
/**
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or
* {@link Double#isInfinite() infinities}.
* @param value a finite value.
* @return this writer.
*/
public JsonWriter value(double value) throws IOException {
writeDeferredName();
if (!lenient && (Double.isNaN(value) || Double.isInfinite(value))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
// omit these values instead of attempting to write them
deferredName = null;
} else {
writeDeferredName();
beforeValue();
out.write(Double.toString(value));
}
beforeValue();
out.append(Double.toString(value));
return this;
}

Expand All @@ -520,22 +525,24 @@ public JsonWriter value(long value) throws IOException {
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or
* {@link Double#isInfinite() infinities}.
* {@link Double#isInfinite() infinities}.
* @return this writer.
*/
public JsonWriter value(Number value) throws IOException {
if (value == null) {
return nullValue();
}

writeDeferredName();
String string = value.toString();
if (!lenient
&& (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
&& (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
// omit this value
deferredName = null;
} else {
writeDeferredName();
beforeValue();
out.write(string);
}
beforeValue();
out.append(string);
return this;
}

Expand Down Expand Up @@ -634,7 +641,7 @@ void beforeValue() throws IOException {
case NONEMPTY_DOCUMENT:
if (!lenient) {
throw new IllegalStateException(
"JSON must have only one top-level value.");
"JSON must have only one top-level value.");
}
// fall-through
case EMPTY_DOCUMENT: // first in document
Expand All @@ -647,12 +654,12 @@ void beforeValue() throws IOException {
break;

case NONEMPTY_ARRAY: // another in array
out.append(',');
out.write(',');
newline();
break;

case DANGLING_NAME: // value for name
out.append(separator);
out.write(separator);
replaceTop(NONEMPTY_OBJECT);
break;

Expand Down
Loading

0 comments on commit 59adb78

Please sign in to comment.