ArrayIndexOutOfBoundsException on JsonWriter.HTML_SAFE_REPLACEMENT_CHARS
- Dominant language
- Java
- Stars
- 24.2k
- Forks
- 4.5k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 12
Description
Version: 2.8.5
Hello, I'm an Android Developer and my application uses gson to make objects to JSON strings. A very strange crash is reported from the users and I can't understand why, so I need your help to figure out. Here is the call-stack of the crash:
```
Fatal Exception: java.lang.ArrayIndexOutOfBoundsException
length=0; index=78
com.google.gson.stream.JsonWriter.string (SourceFile:573)
com.google.gson.stream.JsonWriter.writeDeferredName (SourceFile:402)
com.google.gson.stream.JsonWriter.nullValue (SourceFile:448)
com.google.gson.stream.internal.bind.ObjectTypeAdapter.write (SourceFile:96)
com.google.gson.stream.internal.bind.TypeAdapterRuntimeTypeWrapper.write (SourceFile:69)
com.google.gson.stream.internal.bind.MapTypeAdapterFactory$Adapter.write (SourceFile:208)
com.google.gson.stream.internal.bind.MapTypeAdapterFactory$Adapter.write (SourceFile:145)
com.google.gson.Gson.toJson (SourceFile:704)
com.google.gson.Gson.toJson (SourceFile:683)
com.google.gson.Gson.toJson (SourceFile:638)
com.google.gson.Gson.toJson (SourceFile:618)
{ myCode }
java.lang.Thread.run (Thread.java:764)
```
I traced the call-stack and found [the 573 line of `JsonWriter`](https://github.com/google/gson/blob/9d44cbc19a73b45971c4ecb33c8d34d673afa210/gson/src/main/java/com/google/gson/stream/JsonWriter.java#L573):
```java
private void string(String value) throws IOException {
String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
out.write("\"");
int last = 0;
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
String replacement;
if (c < 128) {
replacement = replacements[c]; // 573
if (replacement == null) {
continue;
}
} else if (c == '\u2028') {
```
The value of `c` is `78` which means `'N'` and `replacements` array can be `HTML_SAFE_REPLACEMENT_CHARS` or `HTML_SAFE_REPLACEMENT_CHARS`.
Because the value of `htmlSafe` is `true` in default, `replacements` may be `HTML_SAFE_REPLACEMENT_CHARS`.
The array is defined and initialized [at the start of this `JsonWriter` class](https://github.com/google/gson/blob/9d44cbc19a73b45971c4ecb33c8d34d673afa210/gson/src/main/java/com/google/gson/stream/JsonWriter.java#L143):
```java
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++) {
REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int) i);
}
REPLACEMENT_CHARS['"'] = "\\\"";
REPLACEMENT_CHARS['\\'] = "\\\\";
REPLACEMENT_CHARS['\t'] = "\\t";
REPLACEMENT_CHARS['\b'] = "\\b";
REPLACEMENT_CHARS['\n'] = "\\n";
REPLACEMENT_CHARS['\r'] = "\\r";
REPLACEMENT_CHARS['\f'] = "\\f";
HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
}
```
So if the length of this array is zero, it means that the static block is not run. Yes, [it may mean that the `JsonWriter` class is loaded but not initialized](https://stackoverflow.com/a/18979222). However, it's constructor had been called in the [`Gson.newJsonWriter()`](https://github.com/google/gson/blob/9d44cbc19a73b45971c4ecb33c8d34d673afa210/gson/src/main/java/com/google/gson/Gson.java#L749) function, which is called at [the 682 line of Gson](https://github.com/google/gson/blob/9d44cbc19a73b45971c4ecb33c8d34d673afa210/gson/src/main/java/com/google/gson/Gson.java#L682) that the program must have passed by.
Now I am very confused. Is it can actually happen?
Contributor guide
Assessment
This issue has not been assessed yet.