Fix invalid imports in [{..}] form (#3241)

* Fix invalid imports in `[{..}]` form

Before this change, if an import of data that takes the form of a JSON
array of JSON objects results in an error, the import would be re-tried
assuming that each line of the file is a JSON object (the old format).
However, no check was made that the value actually was an object before
casting it to `json::object`, resulting in a segfault.

This adds the check, and handles the failure with a useful error message
(from the first attempt to parse the file).
This commit is contained in:
Dustin J. Mitchell 2024-01-25 08:01:20 -05:00 committed by GitHub
parent 5b5a7a37c0
commit 83bbe4ec37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 7 deletions

View file

@ -133,7 +133,7 @@ int CmdImport::import (const std::string& input)
}
// If an exception is caught, then it is because the free-form JSON
// objects/array above failed to parse. This is an indication that the input
// objects/array above failed to parse. This may be an indication that the input
// is an old-style line-by-line set of JSON objects, because both an array of
// objects, and a single object have failed to parse..
//
@ -142,19 +142,30 @@ int CmdImport::import (const std::string& input)
// { ... }
catch (std::string& e)
{
// Make a very cursory check for the old-style format.
if (input[0] != '{') {
throw e;
}
// Read the entire file, so that errors do not result in a partial import.
std::vector<std::unique_ptr<json::object>> objects;
for (auto& line : split (input, '\n'))
{
if (line.length ())
{
json::value* root = json::parse (line);
if (root)
{
importSingleTask ((json::object*) root);
++count;
delete root;
}
if (root && root->type () == json::j_object)
objects.push_back (std::unique_ptr<json::object> ((json::object *)root));
else
throw format ("Invalid JSON: {1}", line);
}
}
// Import the tasks.
for (auto& root : objects) {
importSingleTask (root.get());
++count;
}
}
return count;