From 06d97cce510a877d2009e6f490263aaf07cd3821 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 25 May 2018 14:45:22 +0200 Subject: [PATCH] Fix multiple issues when expanding argfiles - treat a contiguous whitespace sequence as a single argument separator, not as several empty-string arguments separated by whitespaces - fix infinite loop when reading unfinished quoted argument - do not attempt to perform escape if the backslash is the last character in the file --- .../preprocessCommandLineArguments.kt | 29 ++++++++++++------- ...rgfileWithUnfinishedQuoteAndEscape.argfile | 7 +++++ .../argfileWithUnfinishedQuoteAndEscape.args | 1 + .../argfileWithUnfinishedQuoteAndEscape.out | 3 ++ .../kotlin/cli/CliTestGenerated.java | 5 ++++ 5 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.argfile create mode 100644 compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args create mode 100644 compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.out diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt index 4fc96e713b5..ed7c8d4574d 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt @@ -48,29 +48,36 @@ private fun File.expand(errors: ArgumentParseErrors): List { private fun Reader.parseNextArgument(): String? { val sb = StringBuilder() - var r: Int = read() - while (r != -1) { - when (r.toChar()) { - WHITESPACE, NEWLINE -> return sb.toString() + var r = nextChar() + while (r != null && (r == WHITESPACE || r == NEWLINE)) { + r = nextChar() + } + + loop@ while (r != null) { + when (r) { + WHITESPACE, NEWLINE -> break@loop QUOTATION_MARK -> consumeRestOfEscapedSequence(sb) - BACKSLASH -> sb.append(read().toChar()) - else -> sb.append(r.toChar()) + BACKSLASH -> nextChar()?.apply(sb::append) + else -> sb.append(r) } - r = read() + r = nextChar() } return sb.toString().takeIf { it.isNotEmpty() } } private fun Reader.consumeRestOfEscapedSequence(sb: StringBuilder) { - var ch = read().toChar() - while (ch != QUOTATION_MARK) { - if (ch == BACKSLASH) sb.append(read().toChar()) else sb.append(ch) - ch = read().toChar() + var ch = nextChar() + while (ch != null && ch != QUOTATION_MARK) { + if (ch == BACKSLASH) nextChar()?.apply(sb::append) else sb.append(ch) + ch = nextChar() } } +private fun Reader.nextChar(): Char? = + read().takeUnless { it == -1 }?.toChar() + private val String.argfilePath: String get() = removePrefix("$EXPERIMENTAL_ARGFILE_ARGUMENT=") diff --git a/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.argfile b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.argfile new file mode 100644 index 00000000000..a8db1aeb820 --- /dev/null +++ b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.argfile @@ -0,0 +1,7 @@ + +$TESTDATA_DIR$/simple.kt -d $TEMP_DIR$ + + + + +-jdk-home "abacaba\ diff --git a/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args new file mode 100644 index 00000000000..25c76a92763 --- /dev/null +++ b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args @@ -0,0 +1 @@ +-Xargfile=$TESTDATA_DIR$/argfileWithUnfinishedQuoteAndEscape.argfile diff --git a/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.out b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.out new file mode 100644 index 00000000000..0b104222847 --- /dev/null +++ b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.out @@ -0,0 +1,3 @@ +error: JDK home directory does not exist: abacaba + +COMPILATION_ERROR diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index 2ea7fbdaa89..ca8f054c10d 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -71,6 +71,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/argfileWithEscaping.args"); } + @TestMetadata("argfileWithUnfinishedQuoteAndEscape.args") + public void testArgfileWithUnfinishedQuoteAndEscape() throws Exception { + runTest("compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args"); + } + @TestMetadata("argumentPassedMultipleTimes.args") public void testArgumentPassedMultipleTimes() throws Exception { runTest("compiler/testData/cli/jvm/argumentPassedMultipleTimes.args");