Merge pull request #142 from cie/alexmiller/clicrash

Make fdbcli gracefully handle malformed and partial command errors.
This commit is contained in:
A.J. Beamon 2017-08-22 09:05:47 -07:00 committed by GitHub Enterprise
commit ae56d8e111
1 changed files with 25 additions and 15 deletions

View File

@ -2217,35 +2217,45 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
state UID randomID = g_random->randomUniqueID();
TraceEvent(SevInfo, "CLICommandLog", randomID).detail("command", printable(StringRef(line)));
bool err, partial;
state std::vector<std::vector<StringRef>> parsed = parseLine(line, err, partial);
if (err) {
LogCommand(line, randomID, "ERROR: malformed escape sequence");
is_error = true;
continue;
}
if (partial) {
LogCommand(line, randomID, "ERROR: unterminated quote");
is_error = true;
continue;
bool malformed, partial;
state std::vector<std::vector<StringRef>> parsed = parseLine(line, malformed, partial);
if (malformed) LogCommand(line, randomID, "ERROR: malformed escape sequence");
if (partial) LogCommand(line, randomID, "ERROR: unterminated quote");
if (malformed || partial) {
if (parsed.size() > 0) {
// Denote via a special token that the command was a parse failure.
auto& last_command = parsed.back();
last_command.insert(last_command.begin(), StringRef((const uint8_t*)"parse_error", strlen("parse_error")));
}
}
state bool multi = parsed.size() > 1;
is_error = false;
state std::vector<std::vector<StringRef>>::iterator iter;
for (iter = parsed.begin(); iter != parsed.end(); ++iter) {
state std::vector<StringRef> tokens = *iter;
if (opt.exec.present() && is_error) {
if (is_error) {
printf("WARNING: the previous command failed, the remaining commands will not be executed.\n");
return 1;
break;
}
is_error = false;
if (!tokens.size())
continue;
if (tokencmp(tokens[0], "parse_error")) {
printf("ERROR: Command failed to completely parse.\n");
if (tokens.size() > 1) {
printf("ERROR: Not running partial or malformed command:");
for (auto t = tokens.begin() + 1; t != tokens.end(); ++t)
printf(" %s", formatStringRef(*t, true).c_str());
printf("\n");
}
is_error = true;
continue;
}
if (multi) {
printf(">>>");
for (auto t = tokens.begin(); t != tokens.end(); ++t)