From c8e8b274f1c0889970219447500e9a53c1816292 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 25 Jun 2019 00:55:27 +0000 Subject: [PATCH] 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 --- lldb/lit/Driver/Inputs/process_attach_pid.in | 2 ++ lldb/lit/Driver/TestProcessAttach.test | 2 ++ lldb/source/Interpreter/Options.cpp | 13 ++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 lldb/lit/Driver/Inputs/process_attach_pid.in create mode 100644 lldb/lit/Driver/TestProcessAttach.test diff --git a/lldb/lit/Driver/Inputs/process_attach_pid.in b/lldb/lit/Driver/Inputs/process_attach_pid.in new file mode 100644 index 000000000000..3d17ceee99ed --- /dev/null +++ b/lldb/lit/Driver/Inputs/process_attach_pid.in @@ -0,0 +1,2 @@ +process attach --pid + diff --git a/lldb/lit/Driver/TestProcessAttach.test b/lldb/lit/Driver/TestProcessAttach.test new file mode 100644 index 000000000000..4e24ebb161b6 --- /dev/null +++ b/lldb/lit/Driver/TestProcessAttach.test @@ -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 diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index 814998ec68fc..bd9b47fadd4f 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -1355,13 +1355,23 @@ llvm::Expected Options::Parse(const Args &args, } } std::vector 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 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 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); }