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
This commit is contained in:
Alexander Udalov
2018-05-25 14:45:22 +02:00
committed by Dmitry Savvinov
parent 61902e1fd5
commit 06d97cce51
5 changed files with 34 additions and 11 deletions
@@ -48,29 +48,36 @@ private fun File.expand(errors: ArgumentParseErrors): List<String> {
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=")