8173807: JShell: control characters should be escaped in String values

Reviewed-by: jlahoda
This commit is contained in:
Robert Field 2017-02-06 09:25:31 -08:00
parent 43593d5bf5
commit c42d389e2d
2 changed files with 70 additions and 3 deletions

View File

@ -28,6 +28,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.stream.IntStream;
import jdk.jshell.spi.ExecutionControl;
import jdk.jshell.spi.SPIResolutionException;
@ -41,6 +42,23 @@ import jdk.jshell.spi.SPIResolutionException;
*/
public class DirectExecutionControl implements ExecutionControl {
private static final String[] charRep;
static {
charRep = new String[256];
for (int i = 0; i < charRep.length; ++i) {
charRep[i] = Character.isISOControl(i)
? String.format("\\%03o", i)
: "" + (char) i;
}
charRep['\b'] = "\\b";
charRep['\t'] = "\\t";
charRep['\n'] = "\\n";
charRep['\f'] = "\\f";
charRep['\r'] = "\\r";
charRep['\\'] = "\\\\";
}
private final LoaderDelegate loaderDelegate;
/**
@ -192,9 +210,26 @@ public class DirectExecutionControl implements ExecutionControl {
if (value == null) {
return "null";
} else if (value instanceof String) {
return "\"" + (String) value + "\"";
return "\"" + ((String) value).codePoints()
.flatMap(cp ->
(cp == '"')
? "\\\"".codePoints()
: (cp < 256)
? charRep[cp].codePoints()
: IntStream.of(cp))
.collect(
StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append)
.toString() + "\"";
} else if (value instanceof Character) {
return "'" + value + "'";
char cp = (char) (Character) value;
return "'" + (
(cp == '\'')
? "\\\'"
: (cp < 256)
? charRep[cp]
: String.valueOf(cp)) + "'";
} else if (value.getClass().isArray()) {
int dims = 0;
Class<?> t = value.getClass();

View File

@ -22,7 +22,7 @@
*/
/*
* @test 8130450 8158906 8154374 8166400 8171892 8173848
* @test 8130450 8158906 8154374 8166400 8171892 8173807 8173848
* @summary simple regression test
* @build KullaTesting TestingInputStream
* @run testng SimpleRegressionTest
@ -191,4 +191,36 @@ public class SimpleRegressionTest extends KullaTesting {
assertEval("new boolean[2][1][3]",
"boolean[2][][] { boolean[1][] { boolean[3] { false, false, false } }, boolean[1][] { boolean[3] { false, false, false } } }");
}
public void testStringRepresentation() {
assertEval("\"A!\\rB!\"",
"\"A!\\rB!\"");
assertEval("\"a\\bB\\tc\\nd\\fe\\rf\\\"g'\\\\h\"",
"\"a\\bB\\tc\\nd\\fe\\rf\\\"g'\\\\h\"");
assertEval("\"\\141\\10B\\11c\\nd\\fe\\15f\\42g\\'\\134h\"",
"\"a\\bB\\tc\\nd\\fe\\rf\\\"g'\\\\h\"");
assertEval("\"1234567890!@#$%^&*()-_=+qwertQWERT,./<>?;:[]{}\"",
"\"1234567890!@#$%^&*()-_=+qwertQWERT,./<>?;:[]{}\"");
assertEval("\"AA\\1\\7\\35\\25\"",
"\"AA\\001\\007\\035\\025\"");
assertEval("\"\"",
"\"\"");
assertEval("(String)null",
"null");
}
public void testCharRepresentation() {
for (String s : new String[]{"'A'", "'Z'", "'0'", "'9'",
"'a'", "'z'", "'*'", "'%'",
"'\\b'", "'\\t'", "'\\n'", "'\\f'", "'\\r'",
"'\"'", "'\\\''", "'\\\\'", "'\\007'", "'\\034'",}) {
assertEval(s, s);
}
assertEval("'\\3'",
"'\\003'");
assertEval("'\\u001D'",
"'\\035'");
assertEval("\"a\\bb\\tc\\nd\\fe\\rf\\\"g'\\\\h\".charAt(1)",
"'\\b'");
}
}