Skip to content

Commit

Permalink
Merge pull request #35506 from aloubyansky/config-dump-escaping
Browse files Browse the repository at this point in the history
Properly escape property name and values when dumping app config
  • Loading branch information
gsmet committed Aug 24, 2023
2 parents ca83189 + 9d5a925 commit b254b4c
Showing 1 changed file with 97 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,107 @@ public static void write(Map<String, String> readOptions, ConfigTrackingConfig c
*/
public static void write(Writer writer, String name, String value) throws IOException {
if (value != null) {
// escape the backslash before persisting
value = value.replace("\\", "\\\\");
name = toWritableValue(name, true, true);
value = toWritableValue(value, false, true);
writer.write(name);
writer.write("=");
writer.write(value);
writer.write(System.lineSeparator());
}
}

/*
* Converts unicodes to encoded &#92;uxxxx and escapes
* special characters with a preceding slash
*/

/**
* Escapes characters that are expected to be escaped when {@link java.util.Properties} load
* files from disk.
*
* @param str property name or value
* @param escapeSpace whether to escape a whitespace (should be true for property names)
* @param escapeUnicode whether to converts unicodes to encoded &#92;uxxxx
* @return property name or value that can be written to a file
*/
private static String toWritableValue(String str, boolean escapeSpace, boolean escapeUnicode) {
int len = str.length();
int bufLen = len * 2;
if (bufLen < 0) {
bufLen = Integer.MAX_VALUE;
}
StringBuilder outBuffer = new StringBuilder(bufLen);

for (int x = 0; x < len; x++) {
char aChar = str.charAt(x);
// Handle common case first, selecting largest block that
// avoids the specials below
if ((aChar > 61) && (aChar < 127)) {
if (aChar == '\\') {
outBuffer.append('\\');
outBuffer.append('\\');
continue;
}
outBuffer.append(aChar);
continue;
}
switch (aChar) {
case ' ':
if (x == 0 || escapeSpace) {
outBuffer.append('\\');
}
outBuffer.append(' ');
break;
case '\t':
outBuffer.append('\\');
outBuffer.append('t');
break;
case '\n':
outBuffer.append('\\');
outBuffer.append('n');
break;
case '\r':
outBuffer.append('\\');
outBuffer.append('r');
break;
case '\f':
outBuffer.append('\\');
outBuffer.append('f');
break;
case '=': // Fall through
case ':': // Fall through
case '#': // Fall through
case '!':
outBuffer.append('\\');
outBuffer.append(aChar);
break;
default:
if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode) {
outBuffer.append('\\');
outBuffer.append('u');
outBuffer.append(toHex((aChar >> 12) & 0xF));
outBuffer.append(toHex((aChar >> 8) & 0xF));
outBuffer.append(toHex((aChar >> 4) & 0xF));
outBuffer.append(toHex(aChar & 0xF));
} else {
outBuffer.append(aChar);
}
}
}
return outBuffer.toString();
}

/**
* Convert a nibble to a hex character
*
* @param nibble the nibble to convert.
*/
private static char toHex(int nibble) {
return hexDigit[(nibble & 0xF)];
}

/** A table of hex digits */
private static final char[] hexDigit = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
}

0 comments on commit b254b4c

Please sign in to comment.