google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.13k stars 4.27k forks source link

Can't read multiline string in JSON5 #2682

Closed eitanborisov closed 1 month ago

eitanborisov commented 1 month ago

Gson version

2.11.0.

Java / Android version

OpenJDK 17, 1.8 language level, Kotlin 1.9.20.

Used tools

Description

JSON5 specification supports multiline strings, like that:

'dialogue': "A: Hello!\
B: Hi!"

It's very convenient notation, so I can split the string into multiple lines, ant not to use \n.

But when I try to parse a file that contains such string, I get an exception.

Expected behavior

The string should be read by the parser as a string.

Actual behavior

I get next error: Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Invalid escape sequence at line [DELETED] column [DELETED] path $.

Exception stack trace

Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Invalid escape sequence at line [DELETED] column [DELETED] path $.
See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json
    at com.google.gson.Gson.fromJson(Gson.java:1375)
    at com.google.gson.Gson.fromJson(Gson.java:1262)
    at com.google.gson.Gson.fromJson(Gson.java:1171)
    at com.google.gson.Gson.fromJson(Gson.java:1137)
    at com.[DELETED]
    at com.[DELETED]
    at com.[DELETED]
Caused by: com.google.gson.stream.MalformedJsonException: Invalid escape sequence at line [DELETED] column [DELETED] path $.
See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json
    at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1754)
    at com.google.gson.stream.JsonReader.readEscapeCharacter(JsonReader.java:1744)
    at com.google.gson.stream.JsonReader.nextQuotedValue(JsonReader.java:1103)
    at com.google.gson.stream.JsonReader.nextString(JsonReader.java:907)
    at com.google.gson.internal.bind.ObjectTypeAdapter.readTerminal(ObjectTypeAdapter.java:94)
    at com.google.gson.internal.bind.ObjectTypeAdapter.read(ObjectTypeAdapter.java:116)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:200)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:154)
    at com.google.gson.Gson.fromJson(Gson.java:1361)
    ... 6 more
Marcono1234 commented 1 month ago

Are you sure this is really a \LF[^1] and not something else? Gson's JsonReader in lenient mode (which is the default for Gson) supports unescaped LF and \LF in JSON string values. But it does no support for example \CR.

This works without problems:

String json = "{'dialogue': \"A: Hello!\\\nB: Hi!\"}";
System.out.println(new Gson().fromJson(json, Object.class));

This should be identical to your example (except that extra escaping is needed by Java itself).

Could you please provide a small reproducible code snippet which demonstrates the issue?

Note however that Gson's lenient mode is not the same as JSON5; see the JsonReader#setStrictness documentation for more details about Gson's lenient mode.

[^1]: LF being the character which is represented by a \n. And CR being the character represented by \r.

eitanborisov commented 1 month ago

Are you sure this is really a \LF1 and not something else? Gson's JsonReader in lenient mode (which is the default for Gson) supports unescaped LF and \LF in JSON string values. But it does no support for example \CR.

This works without problems:

String json = "{'dialogue': \"A: Hello!\\\nB: Hi!\"}";
System.out.println(new Gson().fromJson(json, Object.class));

Thank you! It really works!

Marcono1234 commented 1 month ago

Ok, thanks for letting us know! I am going to close this issue then.