Skip to content

Commit

Permalink
Fixes #1200: change default for "Escape slash" to true for 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jan 23, 2024
1 parent 86faf57 commit d4e9457
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 51 deletions.
64 changes: 20 additions & 44 deletions src/main/java/tools/jackson/core/io/CharTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public final class CharTypes
* Lookup table used for determining which output characters in
* 7-bit ASCII range need to be quoted.
*/
protected final static int[] sOutputEscapes128;
protected final static int[] sOutputEscapes128NoSlash;
static {
int[] table = new int[128];
// Control chars need generic escape sequence
Expand All @@ -170,16 +170,16 @@ public final class CharTypes
table[0x0C] = 'f';
table[0x0A] = 'n';
table[0x0D] = 'r';
sOutputEscapes128 = table;
sOutputEscapes128NoSlash = table;
}

/**
* Lookup table same as {@link #sOutputEscapes128} except that
* Lookup table same as {@link #sOutputEscapes128NoSlash} except that
* forward slash ('/') is also escaped
*/
protected final static int[] sOutputEscapes128WithSlash;
static {
sOutputEscapes128WithSlash = Arrays.copyOf(sOutputEscapes128, sOutputEscapes128.length);
sOutputEscapes128WithSlash = Arrays.copyOf(sOutputEscapes128NoSlash, sOutputEscapes128NoSlash.length);
sOutputEscapes128WithSlash['/'] = '/';
}

Expand Down Expand Up @@ -220,23 +220,7 @@ public final class CharTypes
*
* @return 128-entry {@code int[]} that contains escape definitions
*/
public static int[] get7BitOutputEscapes() { return sOutputEscapes128; }

/**
* Alternative to {@link #get7BitOutputEscapes()} when a non-standard quote character
* is used.
*
* @param quoteChar Character used for quoting textual values and property names;
* usually double-quote but sometimes changed to single-quote (apostrophe)
*
* @return 128-entry {@code int[]} that contains escape definitions
*/
public static int[] get7BitOutputEscapes(int quoteChar) {
if (quoteChar == '"') {
return sOutputEscapes128;
}
return AltEscapes.instance.escapesFor(quoteChar);
}
public static int[] get7BitOutputEscapes() { return sOutputEscapes128WithSlash; }

/**
* Alternative to {@link #get7BitOutputEscapes()} when either a non-standard
Expand All @@ -255,7 +239,7 @@ public static int[] get7BitOutputEscapes(int quoteChar, boolean escapeSlash) {
if (escapeSlash) {
return sOutputEscapes128WithSlash;
}
return sOutputEscapes128;
return sOutputEscapes128NoSlash;
}
return AltEscapes.instance.escapesFor(quoteChar, escapeSlash);
}
Expand Down Expand Up @@ -283,7 +267,7 @@ public static char hexToChar(int ch)
* @param content Unescaped String value to append with escaping applied
*/
public static void appendQuoted(StringBuilder sb, String content) {
final int[] escCodes = sOutputEscapes128;
final int[] escCodes = sOutputEscapes128WithSlash;
final int escLen = escCodes.length;
for (int i = 0, len = content.length(); i < len; ++i) {
char c = content.charAt(i);
Expand Down Expand Up @@ -330,35 +314,27 @@ public static byte[] copyHexBytes(boolean uppercase) {
private static class AltEscapes {
public final static AltEscapes instance = new AltEscapes();

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

// @since 2.17
private int[][] _altEscapesWithSlash = 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;
}

// @since 2.17
public int[] escapesFor(int quoteChar, boolean escapeSlash)
{
if (!escapeSlash) {
return escapesFor(quoteChar);
}
int[] esc = _altEscapesWithSlash[quoteChar];
int[] esc = escapeSlash
? _altEscapesWithSlash[quoteChar]
: _altEscapesNoSlash[quoteChar];
if (esc == null) {
esc = escapesFor(quoteChar);
esc['/'] = '/';
esc = escapeSlash
? sOutputEscapes128WithSlash
: sOutputEscapes128NoSlash;
esc = Arrays.copyOf(esc, esc.length);
_altEscapesWithSlash[quoteChar] = esc;
if (escapeSlash) {
_altEscapesWithSlash[quoteChar] = esc;
} else {
_altEscapesNoSlash[quoteChar] = esc;
}
}
return esc;
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/tools/jackson/core/json/JsonWriteFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,9 @@ public enum JsonWriteFeature
/**
* Feature that specifies whether {@link JsonGenerator} should escape forward slashes.
* <p>
* Feature is disabled by default for Jackson 2.x version, and enabled by default in Jackson 3.0.
*
* @since 2.17
* Feature is enabled by default in Jackson 3.0 (was disabled in 2.x).
*/
ESCAPE_FORWARD_SLASHES(false),
ESCAPE_FORWARD_SLASHES(true),

;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,28 @@
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.ObjectWriteContext;
import tools.jackson.core.json.JsonFactory;
import tools.jackson.core.json.JsonGeneratorBase;
import tools.jackson.core.json.JsonWriteFeature;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* @since 2.17
*/
public class JsonWriteFeatureEscapeForwardSlashTest
{
@Test
public void testDefaultSettings() {
JsonFactory jsonF = new JsonFactory();
assertTrue(jsonF.isEnabled(JsonWriteFeature.ESCAPE_FORWARD_SLASHES));
try (JsonGeneratorBase g = (JsonGeneratorBase) jsonF.createGenerator(ObjectWriteContext.empty(),
new StringWriter())) {
assertTrue(g.isEnabled(JsonWriteFeature.ESCAPE_FORWARD_SLASHES));
}
try (JsonGeneratorBase g = (JsonGeneratorBase) jsonF.createGenerator(ObjectWriteContext.empty(),
new ByteArrayOutputStream())) {
assertTrue(g.isEnabled(JsonWriteFeature.ESCAPE_FORWARD_SLASHES));
}
}

@Test
public void testDontEscapeForwardSlash() throws Exception {
final JsonFactory jsonF = JsonFactory.builder()
Expand Down

0 comments on commit d4e9457

Please sign in to comment.