Preserve UTF-8 content when masking links in JSON payloads

Closes gh-705
This commit is contained in:
Andy Wilkinson
2021-01-08 10:02:54 +00:00
parent 82d8c6387e
commit c3cb7af68a
4 changed files with 46 additions and 11 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.restdocs.operation.preprocess;
import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern;
import org.springframework.http.MediaType;
@@ -38,7 +39,7 @@ class LinkMaskingContentModifier implements ContentModifier {
}
LinkMaskingContentModifier(String mask) {
this.contentModifier = new PatternReplacingContentModifier(LINK_HREF, mask);
this.contentModifier = new PatternReplacingContentModifier(LINK_HREF, mask, StandardCharsets.UTF_8);
}
@Override

View File

@@ -16,6 +16,7 @@
package org.springframework.restdocs.operation.preprocess;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -34,26 +35,40 @@ class PatternReplacingContentModifier implements ContentModifier {
private final String replacement;
private final Charset fallbackCharset;
/**
* Creates a new {@link PatternReplacingContentModifier} that will replace occurrences
* of the given {@code pattern} with the given {@code replacement}.
* of the given {@code pattern} with the given {@code replacement}. The content is
* handled using the charset from its content type. When no content type is specified
* the JVM's {@link Charset#defaultCharset() default charset is used}.
* @param pattern the pattern
* @param replacement the replacement
*/
PatternReplacingContentModifier(Pattern pattern, String replacement) {
this(pattern, replacement, Charset.defaultCharset());
}
/**
* Creates a new {@link PatternReplacingContentModifier} that will replace occurrences
* of the given {@code pattern} with the given {@code replacement}. The content is
* handled using the charset from its content type. When no content type is specified
* the given {@code fallbackCharset} is used.
* @param pattern the pattern
* @param replacement the replacement
* @param fallbackCharset the charset to use as a fallback
*/
PatternReplacingContentModifier(Pattern pattern, String replacement, Charset fallbackCharset) {
this.pattern = pattern;
this.replacement = replacement;
this.fallbackCharset = fallbackCharset;
}
@Override
public byte[] modifyContent(byte[] content, MediaType contentType) {
String original;
if (contentType != null && contentType.getCharset() != null) {
original = new String(content, contentType.getCharset());
}
else {
original = new String(content);
}
Charset charset = (contentType != null && contentType.getCharset() != null) ? contentType.getCharset()
: this.fallbackCharset;
String original = new String(content, charset);
Matcher matcher = this.pattern.matcher(original);
StringBuilder builder = new StringBuilder();
int previous = 0;
@@ -73,7 +88,7 @@ class PatternReplacingContentModifier implements ContentModifier {
if (previous < original.length()) {
builder.append(original.substring(previous));
}
return builder.toString().getBytes();
return builder.toString().getBytes(charset);
}
}