OpenHFT / Chronicle-Wire

A Low Garbage Java Serialisation Library that supports multiple formats
http://chronicle.software
Apache License 2.0
513 stars 123 forks source link

JSONWire backslash escape #300

Closed ctrychta closed 2 years ago

ctrychta commented 3 years ago

I'm trying to use JSONWire and I've found that it doesn't seem to escape backslashes in strings which results in invalid JSON output. Here is an example:

    @Test
    void escape() {
        final Bytes<byte[]> data = Bytes.allocateElasticOnHeap();
        final JSONWire wire = new JSONWire(data, true);
        data.writeUnsignedByte('{');
        wire.write("test").text("a\\b\\c\\d");
        data.writeUnsignedByte('}');
        assertEquals("{\"test\": \"a\\\\b\\\\c\\\\d\"}", data.toString());
    }

Would you be able to take a look and let me know whether I'm using it incorrectly or if this is a bug?

RobAustin commented 2 years ago

I'm not sure I'm seeing the issue here - it works if you double escape it

    @Test
    public void escape() {
        final Bytes<byte[]> data = Bytes.allocateElasticOnHeap();
        final JSONWire wire = new JSONWire(data, true);
        data.writeUnsignedByte('{');
        wire.write("test").text("a\\\\b\\\\c\\\\d");
        data.writeUnsignedByte('}');
        assertEquals("{\"test\":\"a\\\\b\\\\c\\\\d\"}", data.toString());
    }
RobAustin commented 2 years ago

I'll close this for now, but we can re-open if this is an issue.

ctrychta commented 2 years ago

Thank you for taking a look. Just to clarify for myself is the intention of text to take a string and add to it JSON directly no matter which characters it contains? If so, I had a misunderstanding of expecting it to escape any characters if needed so a string could be round tripped through the conversion to and from JSON.

For a little more context it appears the implementation has the logic for escaping with escape0, but does not call it because of the needsQuotesEscaped in JSONWire. If it had some logic like the QUOTE_CHARS test in TextWire then it seems like it would be called.

RobAustin commented 2 years ago

yes the - wire.write("test").text("some data")

is going to write

"test" : "some data" 

in JSON

and whatever you write in text(<string>) you should get back when you call text(). I think it is interesting to see how it handles the end of string delimiter " which has to be written as \"

@Test
public void escape() {
    final Bytes<byte[]> data = Bytes.allocateElasticOnHeap();
    final JSONWire wire = new JSONWire(data, true);
    data.writeUnsignedByte('{');
    wire.write("test").text("\"");
    data.writeUnsignedByte('}');
    Assert.assertEquals("{\"test\":\"\\\"\"}", data.toString());
}