Skip to content

Commit

Permalink
Fixed #549
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 13, 2019
1 parent b1391d3 commit 80ca2ef
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/main/java/com/fasterxml/jackson/core/JsonFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ public static int collectDefaults() {
*<p>
* TODO: should clean up this; looks messy having 2 alternatives
* with not very clear differences.
*
* @since 2.6.0
*
* @since 2.6
*/
protected final transient ByteQuadsCanonicalizer _byteSymbolCanonicalizer = ByteQuadsCanonicalizer.createRoot();

Expand Down
37 changes: 34 additions & 3 deletions src/main/java/com/fasterxml/jackson/core/io/CharTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,7 @@ public final class CharTypes
// 04-Mar-2011, tatu: Used to use "-(i + 1)", replaced with constant
table[i] = CharacterEscapes.ESCAPE_STANDARD;
}
/* Others (and some within that range too) have explicit shorter
* sequences
*/
// Others (and some within that range too) have explicit shorter sequences
table['"'] = '"';
table['\\'] = '\\';
// Escaping of slash is optional, so let's not add it
Expand Down Expand Up @@ -210,6 +208,19 @@ public final class CharTypes
*/
public static int[] get7BitOutputEscapes() { return sOutputEscapes128; }

/**
* Alternative to {@link #get7BitOutputEscapes()} when a non-standard quote character
* is used.
*
* @since 2.10
*/
public static int[] get7BitOutputEscapes(int quoteChar) {
if (quoteChar == '"') {
return sOutputEscapes128;
}
return AltEscapes.instance.escapesFor(quoteChar);
}

public static int charToHex(int ch)
{
return (ch > 127) ? -1 : sHexValues[ch];
Expand Down Expand Up @@ -255,5 +266,25 @@ public static char[] copyHexChars() {
public static byte[] copyHexBytes() {
return (byte[]) HB.clone();
}

// @since 2.10
private static class AltEscapes {
public final static AltEscapes instance = new AltEscapes();

private int[][] _altEscapes = new int[128][];

public int[] escapesFor(int quoteChar) {
int[] esc = _altEscapes[quoteChar];
if (esc == null) {
esc = Arrays.copyOf(sOutputEscapes128, 128);
// Only add escape setting if character does not already have it
if (esc[quoteChar] == 0) {
esc[quoteChar] = CharacterEscapes.ESCAPE_STANDARD;
}
_altEscapes[quoteChar] = esc;
}
return esc;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ public UTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec,
{
super(ctxt, features, codec);
_outputStream = out;
_quoteChar = (byte) quoteChar; // TODO: validate/truncate
_quoteChar = (byte) quoteChar;
if (quoteChar != '"') { // since 2.10
_outputEscapes = CharTypes.get7BitOutputEscapes(quoteChar);
}

_bufferRecyclable = true;
_outputBuffer = ctxt.allocWriteEncodingBuffer();
Expand Down Expand Up @@ -152,7 +155,10 @@ public UTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec,

super(ctxt, features, codec);
_outputStream = out;
_quoteChar = (byte) quoteChar; // TODO: validate/truncate
_quoteChar = (byte) quoteChar;
if (quoteChar != '"') { // since 2.10
_outputEscapes = CharTypes.get7BitOutputEscapes(quoteChar);
}

_bufferRecyclable = bufferRecyclable;
_outputTail = outputOffset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ public WriterBasedJsonGenerator(IOContext ctxt, int features,
_outputBuffer = ctxt.allocConcatBuffer();
_outputEnd = _outputBuffer.length;
_quoteChar = quoteChar;
if (quoteChar != '"') { // since 2.10
_outputEscapes = CharTypes.get7BitOutputEscapes(quoteChar);
}
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ public void testAposQuotingWithCharBased() throws Exception
_writeObject(g, "key", "It's \"fun\"");
g.close();
// should escape apostrophes but not quotes?
assertEquals("{'key':'It\\'s' \"fun\"}", w.toString());
assertEquals("{'key':'It\\u0027s \\\"fun\\\"'}", w.toString());

// with Array
w = new StringWriter();
g = createGenerator(JSON_F, w);
_writeArray(g, "It's a sin");
g.close();
assertEquals("['It\\'s a sin']", w.toString());
assertEquals("['It\\u0027s a sin']", w.toString());
}

public void testAposQuotingWithByteBased() throws Exception
Expand All @@ -96,14 +96,14 @@ public void testAposQuotingWithByteBased() throws Exception
_writeObject(g, "key", "It's \"fun\"");
g.close();
// should escape apostrophes but not quotes?
assertEquals("{'key':'It\\'s' \"fun\"}", out.toString("UTF-8"));
assertEquals("{'key':'It\\u0027s \\\"fun\\\"'}", out.toString("UTF-8"));

// with Array
out = new ByteArrayOutputStream();
g = createGenerator(JSON_F, out);
_writeArray(g, "It's a sin");
g.close();
assertEquals("['It\\'s a sin']", out.toString("UTF-8"));
assertEquals("['It\\u0027s a sin']", out.toString("UTF-8"));
}

private void _writeObject(JsonGenerator g, String key, String value) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package com.fasterxml.jackson.core.json;

import com.fasterxml.jackson.core.BaseTest;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.filter.FilteringGeneratorDelegate;
import com.fasterxml.jackson.core.filter.JsonPointerBasedFilter;
import com.fasterxml.jackson.core.io.IOContext;
Expand Down

0 comments on commit 80ca2ef

Please sign in to comment.