buffet: Fix crash when CommandInstance::SetResults() is invoked

The crash was a result of use-after-delete in
CloudCommandProxy::OnResultsChanged() where TypedValueToJson returned
std::unique_ptr while the JSON value was set to Dictionary by using
unique_ptr::get() on the temporary. Should have called release()
instead to transfer the ownership to the dictionary.

Added a unit test to buffet/device_registration_info_unittest.cc to
test this specific scenario.

BUG=brillo:770
TEST=`FEATURES=test emerge-link buffet`

Change-Id: I34a28ce610a06f2b77af1cc75e358b3fb3562a13
Reviewed-on: https://chromium-review.googlesource.com/264465
Trybot-Ready: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/utils.cc b/buffet/utils.cc
index 9cd7271..8e29ebe 100644
--- a/buffet/utils.cc
+++ b/buffet/utils.cc
@@ -20,7 +20,6 @@
 
 std::unique_ptr<const base::DictionaryValue> LoadJsonDict(
     const base::FilePath& json_file_path, chromeos::ErrorPtr* error) {
-  std::unique_ptr<const base::DictionaryValue> result;
   std::string json_string;
   if (!base::ReadFileToString(json_file_path, &json_string)) {
     chromeos::errors::system::AddSystemError(error, FROM_HERE, errno);
@@ -28,8 +27,14 @@
                                  kFileReadError,
                                  "Failed to read file '%s'",
                                  json_file_path.value().c_str());
-    return result;
+    return {};
   }
+  return LoadJsonDict(json_string, error);
+}
+
+std::unique_ptr<const base::DictionaryValue> LoadJsonDict(
+    const std::string& json_string, chromeos::ErrorPtr* error) {
+  std::unique_ptr<const base::DictionaryValue> result;
   std::string error_message;
   base::Value* value = base::JSONReader::ReadAndReturnError(
       json_string, base::JSON_PARSE_RFC, nullptr, &error_message);
@@ -37,8 +42,8 @@
     chromeos::Error::AddToPrintf(error, FROM_HERE,
                                  chromeos::errors::json::kDomain,
                                  chromeos::errors::json::kParseError,
-                                 "Error parsing content of JSON file '%s': %s",
-                                 json_file_path.value().c_str(),
+                                 "Error parsing JSON string '%s': %s",
+                                 json_string.c_str(),
                                  error_message.c_str());
     return result;
   }
@@ -48,8 +53,8 @@
     chromeos::Error::AddToPrintf(error, FROM_HERE,
                                  chromeos::errors::json::kDomain,
                                  chromeos::errors::json::kObjectExpected,
-                                 "Content of file '%s' is not a JSON object",
-                                 json_file_path.value().c_str());
+                                 "JSON string '%s' is not a JSON object",
+                                 json_string.c_str());
     return result;
   }
   result.reset(dict_value);