Skip to content

Commit

Permalink
Revert "Fix json-body not escaped properly" as this produces badly fo…
Browse files Browse the repository at this point in the history
…rmed JSON where there are escaped quotes present. Given the potential for other undiscovered edge-cases, we'll release a patch version without this fix for now"

This reverts commit 1d29977.
  • Loading branch information
tomakehurst committed Feb 19, 2024
1 parent da0d9c4 commit d68e984
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 291 deletions.
28 changes: 0 additions & 28 deletions src/main/java/com/github/tomakehurst/wiremock/common/Json.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public final class Json {

Expand Down Expand Up @@ -122,32 +120,6 @@ public static byte[] toByteArray(Object object) {
}
}

public static byte[] toByteArrayEscaped(JsonNode jsonNode) {
String string = toStringEscaped(jsonNode);
return string != null ? Strings.bytesFromString(string) : new byte[0];
}

public static String toStringEscaped(JsonNode jsonNode) {
if (jsonNode.isValueNode()) {
if (jsonNode.isTextual()) {
return "\"" + jsonNode.asText() + "\"";
} else {
return jsonNode.asText();
}
} else if (jsonNode.isArray()) {
return Stream.generate(jsonNode.elements()::next)
.limit(jsonNode.size())
.map(Json::toStringEscaped)
.collect(Collectors.joining(",", "[", "]"));
} else if (jsonNode.isObject()) {
return Stream.generate(jsonNode.fields()::next)
.limit(jsonNode.size())
.map(field -> "\"" + field.getKey() + "\":" + toStringEscaped(field.getValue()))
.collect(Collectors.joining(",", "{", "}"));
}
return null;
}

public static JsonNode node(String json) {
return read(json, JsonNode.class);
}
Expand Down
37 changes: 10 additions & 27 deletions src/main/java/com/github/tomakehurst/wiremock/http/Body.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@

import static com.github.tomakehurst.wiremock.common.Encoding.decodeBase64;
import static com.github.tomakehurst.wiremock.common.Encoding.encodeBase64;
import static com.github.tomakehurst.wiremock.common.Strings.bytesFromString;
import static com.github.tomakehurst.wiremock.common.Strings.stringFromBytes;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.github.tomakehurst.wiremock.common.ContentTypes;
import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.common.Strings;
import java.util.Arrays;
import java.util.Objects;

Expand All @@ -32,46 +32,33 @@ public class Body {
private final byte[] content;
private final boolean binary;
private final boolean json;
private final JsonNode jsonContent;

public Body(byte[] content) {
this(content, true);
}

public Body(String content) {
this.content = bytesFromString(content);
this.binary = false;
this.json = false;
this.jsonContent = null;
this.content = Strings.bytesFromString(content);
binary = false;
json = false;
}

private Body(byte[] content, boolean binary) {
this.content = content;
this.binary = binary;
this.json = false;
this.jsonContent = null;
json = false;
}

private Body(byte[] content, boolean binary, boolean json) {
if (json) {
JsonNode jsonNode = Json.node(stringFromBytes(content));
this.content = Json.toByteArrayEscaped(jsonNode);
this.binary = binary;
this.json = true;
this.jsonContent = jsonNode;
} else {
this.content = content;
this.binary = binary;
this.json = false;
this.jsonContent = null;
}
this.content = content;
this.binary = binary;
this.json = json;
}

private Body(JsonNode content) {
this.content = Json.toByteArrayEscaped(content);
this.content = Json.toByteArray(content);
binary = false;
json = true;
jsonContent = content;
}

static Body fromBytes(byte[] bytes) {
Expand Down Expand Up @@ -123,11 +110,7 @@ public boolean isBinary() {
}

public JsonNode asJson() {
if (isJson()) {
return jsonContent;
} else {
return Json.node(asString());
}
return Json.node(asString());
}

public boolean isJson() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
import org.hamcrest.TypeSafeMatcher;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

Expand Down Expand Up @@ -704,40 +703,4 @@ private String decompress(byte[] content) {
public static String padRight(String s, int paddingLength) {
return String.format("%1$-" + paddingLength + "s", s);
}

@Nested
class JsonResponseBodyStandaloneAcceptanceTest {

private static final String MAPPING_REQUEST_WITH_JSON_RESPONSE_BODY =
"{\n"
+ " \"metadata\": {\n"
+ " \"description\": \"matches helper example\"\n"
+ " },\n"
+ " \"request\": {\n"
+ " \"method\": \"GET\",\n"
+ " \"urlPattern\": \"/matches/\\\\?string=[^&]+\"\n"
+ " },\n"
+ " \"response\": {\n"
+ " \"status\": 200,\n"
+ " \"headers\": {\n"
+ " \"Content-Type\": \"application/json\"\n"
+ " },\n"
+ " \"transformers\": [\n"
+ " \"response-template\"\n"
+ " ],\n"
+ " \"jsonBody\": {\n"
+ "\"string matches\": \"{{#matches request.query.string 'lor\\\\w+'}}Matched{{/matches}}\"\n"
+ " }\n"
+ " }\n"
+ "}\n";

@Test
void readEscapeSequenceProperly() {
writeMappingFile("test-mapping-1.json", MAPPING_REQUEST_WITH_JSON_RESPONSE_BODY);
startRunner();
assertThat(
testClient.get("/matches/?string=lorem").content(),
is("{\"string matches\":\"Matched\"}"));
}
}
}
78 changes: 0 additions & 78 deletions src/test/java/com/github/tomakehurst/wiremock/http/BodyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,45 +86,6 @@ void constructsFromJson() {
assertThat(body.asBase64(), is(encodeBase64(bytesFromString("1"))));
}

@Test
void mustEscapeWhenConstructedFromJson() {
String jsonString =
"{\n"
+ " \"escape\": [\n"
+ " \"quotation mark : \\\" padding\",\n"
+ " \"reverse solidas : \\\\ padding\",\n"
+ " \"backspace : \\b padding\",\n"
+ " \"formfeed : \\f padding\",\n"
+ " \"newline : \\n padding\",\n"
+ " \"carriage return : \\r padding\",\n"
+ " \"horizontal tab: \\t padding\",\n"
+ " \"hex digit: \\u12ab"
+ " padding\"\n"
+ " ]\n"
+ "}\n";
JsonNode jsonNode = Json.node(jsonString);
String jsonCompressedAndEscaped =
jsonNode
.toString()
.replace("\\\"", "\"")
.replace("\\\\", "\\")
.replace("\\b", "\b")
.replace("\\f", "\f")
.replace("\\n", "\n")
.replace("\\r", "\r")
.replace("\\t", "\t")
.replaceAll("\\\\u12ab", "\u12ab");

Body body = Body.fromOneOf(null, null, jsonNode, "lskdjflsjdflks");

assertThat(body.asString(), is(jsonCompressedAndEscaped));
assertThat(body.isBinary(), is(false));
assertThat(body.asBytes(), is(bytesFromString(jsonCompressedAndEscaped)));
assertThat(body.isJson(), is(true));
assertThat(body.asJson(), is(jsonNode));
assertThat(body.asBase64(), is(encodeBase64(bytesFromString(jsonCompressedAndEscaped))));
}

@Test
void constructsFromBase64() {
String content = "this content";
Expand Down Expand Up @@ -154,45 +115,6 @@ void constructsFromJsonBytes() {
assertThat(body.asBase64(), is(encodeBase64(bytesFromString(jsonString))));
}

@Test
void mustEscapeWhenConstructedFromJsonBytes() {
String jsonString =
"{\n"
+ " \"escape\": [\n"
+ " \"quotation mark : \\\" padding\",\n"
+ " \"reverse solidas : \\\\ padding\",\n"
+ " \"backspace : \\b padding\",\n"
+ " \"formfeed : \\f padding\",\n"
+ " \"newline : \\n padding\",\n"
+ " \"carriage return : \\r padding\",\n"
+ " \"horizontal tab: \\t padding\",\n"
+ " \"hex digit: \\u12ab padding\"\n"
+ " ]\n"
+ "}\n";
byte[] jsonBytes = bytesFromString(jsonString);
JsonNode jsonNode = Json.node(jsonString);
String jsonCompressedAndEscaped =
jsonNode
.toString()
.replace("\\\"", "\"")
.replace("\\\\", "\\")
.replace("\\b", "\b")
.replace("\\f", "\f")
.replace("\\n", "\n")
.replace("\\r", "\r")
.replace("\\t", "\t")
.replaceAll("\\\\u12ab", "\u12ab");

Body body = Body.fromJsonBytes(jsonBytes);

assertThat(body.asString(), is(jsonCompressedAndEscaped));
assertThat(body.isBinary(), is(false));
assertThat(body.asBytes(), is(bytesFromString(jsonCompressedAndEscaped)));
assertThat(body.isJson(), is(true));
assertThat(body.asJson(), is(jsonNode));
assertThat(body.asBase64(), is(encodeBase64(bytesFromString(jsonCompressedAndEscaped))));
}

@Test
void bodyAsJson() {
final JsonNode jsonContent = Json.node("{\"name\":\"wiremock\",\"isCool\":true}");
Expand Down

0 comments on commit d68e984

Please sign in to comment.