org.apache.rocketmq.shaded.ch.qos.logback.core.helpers.Transform Maven / Gradle / Ivy
/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2015, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package org.apache.rocketmq.shaded.ch.qos.logback.core.helpers;
import java.util.regex.Pattern;
/**
* Utility class for transforming strings.
*
* @author Ceki Gülcü
* @author Michael A. McAngus
*/
public class Transform {
private static final String CDATA_START = "";
private static final String CDATA_PSEUDO_END = "]]>";
private static final String CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START;
private static final int CDATA_END_LEN = CDATA_END.length();
private static final Pattern UNSAFE_XML_CHARS = Pattern.compile("[\u0000-\u0008\u000b\u000c\u000e-\u001f<>&'\"]");
/**
* This method takes a string which may contain HTML tags (ie, <b>,
* <table>, etc) and replaces any '<','>' ... characters with
* respective predefined entity references.
*
* @param input
* The text to be converted.
*/
public static String escapeTags(final String input) {
if (input == null || input.length() == 0 || !UNSAFE_XML_CHARS.matcher(input).find()) {
return input;
}
StringBuffer buf = new StringBuffer(input);
return escapeTags(buf);
}
/**
* This method takes a StringBuilder which may contain HTML tags (ie, <b>,
* <table>, etc) and replaces any '<' and '>' characters with
* respective predefined entity references.
* @param buf StringBuffer to transform
* @return
*/
public static String escapeTags(final StringBuffer buf) {
for (int i = 0; i < buf.length(); i++) {
char ch = buf.charAt(i);
switch (ch) {
case '\t':
case '\n':
case '\r':
// These characters are below '\u0020' but are allowed:
break;
case '&':
buf.replace(i, i + 1, "&");
break;
case '<':
buf.replace(i, i + 1, "<");
break;
case '>':
buf.replace(i, i + 1, ">");
break;
case '"':
buf.replace(i, i + 1, """);
break;
case '\'':
buf.replace(i, i + 1, "'");
break;
default:
if (ch < '\u0020') {
// These characters are not allowed,
// replace them with "Object replacement character":
buf.replace(i, i + 1, "\uFFFD");
}
break;
}
}
return buf.toString();
}
/**
* Ensures that embedded CDEnd strings (]]>) are handled properly within
* message, NDC and throwable tag text.
*
* @param output
* Writer. The initial CDSutart () of
* the CDATA section are the responsibility of the calling method.
*
* @param str
* The String that is inserted into an existing CDATA Section.
*/
public static void appendEscapingCDATA(StringBuilder output, String str) {
if (str == null) {
return;
}
int end = str.indexOf(CDATA_END);
if (end < 0) {
output.append(str);
return;
}
int start = 0;
while (end > -1) {
output.append(str.substring(start, end));
output.append(CDATA_EMBEDED_END);
start = end + CDATA_END_LEN;
if (start < str.length()) {
end = str.indexOf(CDATA_END, start);
} else {
return;
}
}
output.append(str.substring(start));
}
}