diff options
author | Tao Bao <tbao@google.com> | 2018-07-16 22:09:59 -0700 |
---|---|---|
committer | Tao Bao <tbao@google.com> | 2018-07-17 12:16:53 -0700 |
commit | 1700cc46b5531499b7b532cda05d442f5f60acd4 (patch) | |
tree | fa668d92873b1f1d1df22bb992610ea53a69ed49 /recovery_main.cpp | |
parent | 624b6b6cd582d4a58f924b3e1677628bd8260349 (diff) |
Fix the arguments passed to getopt_long(3).
The getopt_long(3) implementation in Android (upstream freebsd) expects
a null-terminated array while parsing long options with required args.
if (long_options[match].has_arg == required_argument) {
optarg = nargv[optind++];
}
...
if (long_options[match].has_arg == required_argument && optarg == NULL) {
return (BADARG);
}
This seems to make sense in practice, as getopt(3) takes the first two
arguments of argc and argv that are "as passed to the main() function on
program invocation", and both of C and C++ spec say "the value of
argv[argc] shall be 0".
Prior to the CL, we may run into undefined behavior on malformed input
command line (e.g. missing arg for an option that requires one). This CL
fixes the issue by always appending a nullptr to the argument list (but
without counting that into argc).
Test: Build and boot into recovery with commands.
Change-Id: Ic6c37548f4db2f30aeabd40f387ca916eeca5392
Diffstat (limited to 'recovery_main.cpp')
-rw-r--r-- | recovery_main.cpp | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/recovery_main.cpp b/recovery_main.cpp index 5e82c6c1..c79d7d8d 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -29,7 +29,6 @@ #include <time.h> #include <unistd.h> -#include <algorithm> #include <string> #include <vector> @@ -287,9 +286,7 @@ int main(int argc, char** argv) { has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr; std::vector<std::string> args = get_args(argc, argv); - std::vector<char*> args_to_parse(args.size()); - std::transform(args.cbegin(), args.cend(), args_to_parse.begin(), - [](const std::string& arg) { return const_cast<char*>(arg.c_str()); }); + auto args_to_parse = StringVectorToNullTerminatedArray(args); static constexpr struct option OPTIONS[] = { { "locale", required_argument, nullptr, 0 }, @@ -302,7 +299,7 @@ int main(int argc, char** argv) { int arg; int option_index; - while ((arg = getopt_long(args_to_parse.size(), args_to_parse.data(), "", OPTIONS, + while ((arg = getopt_long(args_to_parse.size() - 1, args_to_parse.data(), "", OPTIONS, &option_index)) != -1) { switch (arg) { case 't': |