Index: services/catalog/entry.cc |
diff --git a/services/catalog/entry.cc b/services/catalog/entry.cc |
index 0e58f13ac7a2eaa638e67cb4b1e8fa2981dd22c7..9734f92d3747d72ff660ff32d298e1dd86357504 100644 |
--- a/services/catalog/entry.cc |
+++ b/services/catalog/entry.cc |
@@ -11,89 +11,104 @@ |
namespace catalog { |
namespace { |
-shell::CapabilitySpec BuildCapabilitiesV0(const base::DictionaryValue& value) { |
- shell::CapabilitySpec capabilities; |
- base::DictionaryValue::Iterator it(value); |
- for (; !it.IsAtEnd(); it.Advance()) { |
- const base::ListValue* values = nullptr; |
- CHECK(it.value().GetAsList(&values)); |
- shell::CapabilityRequest spec; |
- for (auto i = values->begin(); i != values->end(); ++i) { |
- shell::Interface interface_name; |
- const base::Value* v = *i; |
- CHECK(v->GetAsString(&interface_name)); |
- spec.interfaces.insert(interface_name); |
- } |
- capabilities.required[it.key()] = spec; |
- } |
- return capabilities; |
-} |
- |
-void ReadStringSet(const base::ListValue& list_value, |
+bool ReadStringSet(const base::ListValue& list_value, |
std::set<std::string>* string_set) { |
DCHECK(string_set); |
for (auto i = list_value.begin(); i != list_value.end(); ++i) { |
std::string value; |
const base::Value* value_value = *i; |
- CHECK(value_value->GetAsString(&value)); |
+ if (!value_value->GetAsString(&value)) { |
+ LOG(ERROR) << "Entry::Deserialize: list member must be a string"; |
+ return false; |
+ } |
string_set->insert(value); |
} |
+ return true; |
} |
-void ReadStringSetFromValue(const base::Value& value, |
+bool ReadStringSetFromValue(const base::Value& value, |
std::set<std::string>* string_set) { |
const base::ListValue* list_value = nullptr; |
- CHECK(value.GetAsList(&list_value)); |
- ReadStringSet(*list_value, string_set); |
+ if (!value.GetAsList(&list_value)) { |
+ LOG(ERROR) << "Entry::Deserialize: Value must be a list."; |
+ return false; |
+ } |
+ return ReadStringSet(*list_value, string_set); |
} |
-void ReadStringSetFromDictionary(const base::DictionaryValue& dictionary, |
+bool ReadStringSetFromDictionary(const base::DictionaryValue& dictionary, |
const std::string& key, |
std::set<std::string>* string_set) { |
const base::ListValue* list_value = nullptr; |
- if (dictionary.HasKey(key)) |
- CHECK(dictionary.GetList(key, &list_value)); |
+ if (dictionary.HasKey(key) && !dictionary.GetList(key, &list_value)) { |
+ LOG(ERROR) << "Entry::Deserialize: " << key << " must be a list."; |
+ return false; |
+ } |
if (list_value) |
- ReadStringSet(*list_value, string_set); |
+ return ReadStringSet(*list_value, string_set); |
+ return true; |
} |
-shell::CapabilitySpec BuildCapabilitiesV1(const base::DictionaryValue& value) { |
- shell::CapabilitySpec capabilities; |
- |
+bool BuildCapabilities(const base::DictionaryValue& value, |
+ shell::CapabilitySpec* capabilities) { |
+ DCHECK(capabilities); |
const base::DictionaryValue* provided_value = nullptr; |
- if (value.HasKey(Store::kCapabilities_ProvidedKey)) { |
- CHECK(value.GetDictionary(Store::kCapabilities_ProvidedKey, |
- &provided_value)); |
+ if (value.HasKey(Store::kCapabilities_ProvidedKey) && |
+ !value.GetDictionary(Store::kCapabilities_ProvidedKey, |
+ &provided_value)) { |
+ LOG(ERROR) << "Entry::Deserialize: " << Store::kCapabilities_ProvidedKey |
+ << " must be a dictionary."; |
+ return false; |
} |
if (provided_value) { |
shell::CapabilityRequest provided; |
base::DictionaryValue::Iterator it(*provided_value); |
for(; !it.IsAtEnd(); it.Advance()) { |
shell::Interfaces interfaces; |
- ReadStringSetFromValue(it.value(), &interfaces); |
- capabilities.provided[it.key()] = interfaces; |
+ if (!ReadStringSetFromValue(it.value(), &interfaces)) { |
+ LOG(ERROR) << "Entry::Deserialize: Invalid interface list in provided " |
+ << " classes dictionary"; |
+ return false; |
+ } |
+ capabilities->provided[it.key()] = interfaces; |
} |
} |
const base::DictionaryValue* required_value = nullptr; |
- if (value.HasKey(Store::kCapabilities_RequiredKey)) { |
- CHECK(value.GetDictionary(Store::kCapabilities_RequiredKey, |
- &required_value)); |
+ if (value.HasKey(Store::kCapabilities_RequiredKey) && |
+ !value.GetDictionary(Store::kCapabilities_RequiredKey, |
+ &required_value)) { |
+ LOG(ERROR) << "Entry::Deserialize: " << Store::kCapabilities_RequiredKey |
+ << " must be a dictionary."; |
+ return false; |
} |
if (required_value) { |
base::DictionaryValue::Iterator it(*required_value); |
for (; !it.IsAtEnd(); it.Advance()) { |
shell::CapabilityRequest spec; |
const base::DictionaryValue* entry_value = nullptr; |
- CHECK(it.value().GetAsDictionary(&entry_value)); |
- ReadStringSetFromDictionary( |
- *entry_value, Store::kCapabilities_ClassesKey, &spec.classes); |
- ReadStringSetFromDictionary( |
- *entry_value, Store::kCapabilities_InterfacesKey, &spec.interfaces); |
- capabilities.required[it.key()] = spec; |
+ if (!it.value().GetAsDictionary(&entry_value)) { |
+ LOG(ERROR) << "Entry::Deserialize: " << Store::kCapabilities_RequiredKey |
+ << " must be a dictionary."; |
+ return false; |
+ } |
+ if (!ReadStringSetFromDictionary( |
+ *entry_value, Store::kCapabilities_ClassesKey, &spec.classes)) { |
+ LOG(ERROR) << "Entry::Deserialize: Invalid classes list in required " |
+ << "capabilities dictionary."; |
+ return false; |
+ } |
+ if (!ReadStringSetFromDictionary(*entry_value, |
+ Store::kCapabilities_InterfacesKey, |
+ &spec.interfaces)) { |
+ LOG(ERROR) << "Entry::Deserialize: Invalid interfaces list in required " |
+ << "capabilities dictionary."; |
+ return false; |
+ } |
+ capabilities->required[it.key()] = spec; |
} |
} |
- return capabilities; |
+ return true; |
} |
} // namespace |
@@ -143,42 +158,71 @@ std::unique_ptr<base::DictionaryValue> Entry::Serialize() const { |
// static |
std::unique_ptr<Entry> Entry::Deserialize(const base::DictionaryValue& value) { |
std::unique_ptr<Entry> entry(new Entry); |
+ |
+ // Manifest version. |
int manifest_version = 0; |
- if (value.HasKey(Store::kManifestVersionKey)) |
- CHECK(value.GetInteger(Store::kManifestVersionKey, &manifest_version)); |
+ if (!value.GetInteger(Store::kManifestVersionKey, &manifest_version)) { |
+ LOG(ERROR) << "Entry::Deserialize: " << Store::kManifestVersionKey |
+ << " must be an integer."; |
+ return nullptr; |
+ } |
+ if (manifest_version != 1) { |
+ LOG(ERROR) << "Entry::Deserialize: Unsupported value of " |
+ << Store::kManifestVersionKey << ":" << manifest_version; |
+ return nullptr; |
+ } |
+ |
+ // Name. |
std::string name_string; |
if (!value.GetString(Store::kNameKey, &name_string)) { |
- LOG(ERROR) << "Entry::Deserialize: dictionary has no name key"; |
+ LOG(ERROR) << "Entry::Deserialize: dictionary has no " |
+ << Store::kNameKey << " key"; |
return nullptr; |
} |
if (!shell::IsValidName(name_string)) { |
- LOG(WARNING) << "Entry::Deserialize: " << name_string << " is not a valid " |
- << "Mojo name"; |
+ LOG(ERROR) << "Entry::Deserialize: " << name_string << " is not a valid " |
+ << "Mojo name"; |
return nullptr; |
} |
entry->set_name(name_string); |
+ |
+ // Process group. |
if (value.HasKey(Store::kQualifierKey)) { |
std::string qualifier; |
- CHECK(value.GetString(Store::kQualifierKey, &qualifier)); |
+ if (!value.GetString(Store::kQualifierKey, &qualifier)) { |
+ LOG(ERROR) << "Entry::Deserialize: " << Store::kQualifierKey << " must " |
+ << "be a string."; |
+ return nullptr; |
+ } |
entry->set_qualifier(qualifier); |
} else { |
entry->set_qualifier(shell::GetNamePath(name_string)); |
} |
+ |
+ // Human-readable name. |
std::string display_name; |
if (!value.GetString(Store::kDisplayNameKey, &display_name)) { |
- LOG(WARNING) << "Entry::Deserialize: dictionary has no display_name key"; |
+ LOG(ERROR) << "Entry::Deserialize: dictionary has no " |
+ << Store::kDisplayNameKey << " key"; |
return nullptr; |
} |
entry->set_display_name(display_name); |
+ |
+ // Capability spec. |
const base::DictionaryValue* capabilities = nullptr; |
if (!value.GetDictionary(Store::kCapabilitiesKey, &capabilities)) { |
- LOG(WARNING) << "Entry::Description: dictionary has no capabilities key"; |
+ LOG(ERROR) << "Entry::Deserialize: dictionary has no " |
+ << Store::kCapabilitiesKey << " key"; |
+ return nullptr; |
+ } |
+ |
+ shell::CapabilitySpec spec; |
+ if (!BuildCapabilities(*capabilities, &spec)) { |
+ LOG(ERROR) << "Entry::Deserialize: failed to build capability spec for " |
+ << entry->name(); |
return nullptr; |
} |
- if (manifest_version == 0) |
- entry->set_capabilities(BuildCapabilitiesV0(*capabilities)); |
- else |
- entry->set_capabilities(BuildCapabilitiesV1(*capabilities)); |
+ entry->set_capabilities(spec); |
if (value.HasKey(Store::kApplicationsKey)) { |
const base::ListValue* applications = nullptr; |