Reapply "Fix a crash in option parsing."

with an additional read-out-of-bounds bugfix applied.

Differential Revision: https://reviews.llvm.org/D63110

llvm-svn: 364260
This commit is contained in:
Adrian Prantl 2019-06-25 00:55:27 +00:00
parent 49885b1245
commit c8e8b274f1
3 changed files with 16 additions and 1 deletions

View File

@ -0,0 +1,2 @@
process attach --pid

View File

@ -0,0 +1,2 @@
# RUN: %lldb -x -b -S %S/Inputs/process_attach_pid.in 2>&1 | FileCheck %s
# CHECK: last option requires an argument

View File

@ -1355,13 +1355,23 @@ llvm::Expected<Args> Options::Parse(const Args &args,
}
}
std::vector<char *> argv = GetArgvForParsing(args);
// If the last option requires an argument but doesn't have one,
// some implementations of getopt_long will still try to read it.
char overflow = 0;
argv.push_back(&overflow);
std::unique_lock<std::mutex> lock;
OptionParser::Prepare(lock);
int val;
while (true) {
int long_options_index = -1;
val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(),
val = OptionParser::Parse(argv.size() - 1, &*argv.begin(), sstr.GetString(),
long_options, &long_options_index);
if ((size_t)OptionParser::GetOptionIndex() > argv.size() - 1) {
error.SetErrorStringWithFormat("last option requires an argument");
break;
}
if (val == -1)
break;
@ -1439,6 +1449,7 @@ llvm::Expected<Args> Options::Parse(const Args &args,
if (error.Fail())
return error.ToError();
argv.pop_back();
argv.erase(argv.begin(), argv.begin() + OptionParser::GetOptionIndex());
return ReconstituteArgsAfterParsing(argv, args);
}