OpenJDK / jdk / jdk12
changeset 43587:6103af590758
8173807: JShell: control characters should be escaped in String values
Reviewed-by: jlahoda
author | rfield |
---|---|
date | Mon, 06 Feb 2017 09:25:31 -0800 |
parents | cc7a4eb79b29 |
children | 6a0e0ea0e93b |
files | langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java langtools/test/jdk/jshell/SimpleRegressionTest.java |
diffstat | 2 files changed, 70 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java Mon Feb 06 09:00:02 2017 -0800 +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java Mon Feb 06 09:25:31 2017 -0800 @@ -28,6 +28,7 @@ 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 @@ */ 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 @@ 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();
--- a/langtools/test/jdk/jshell/SimpleRegressionTest.java Mon Feb 06 09:00:02 2017 -0800 +++ b/langtools/test/jdk/jshell/SimpleRegressionTest.java Mon Feb 06 09:25:31 2017 -0800 @@ -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 @@ 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'"); + } }