| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/common/extension_api.h" | 5 #include "extensions/common/extension_api.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 std::unique_ptr<base::ListValue> LoadSchemaList( | 48 std::unique_ptr<base::ListValue> LoadSchemaList( |
| 49 const std::string& name, | 49 const std::string& name, |
| 50 const base::StringPiece& schema) { | 50 const base::StringPiece& schema) { |
| 51 std::string error_message; | 51 std::string error_message; |
| 52 std::unique_ptr<base::Value> result(base::JSONReader::ReadAndReturnError( | 52 std::unique_ptr<base::Value> result(base::JSONReader::ReadAndReturnError( |
| 53 schema, | 53 schema, |
| 54 base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN, // options | 54 base::JSON_PARSE_RFC | base::JSON_DETACHABLE_CHILDREN, // options |
| 55 NULL, // error code | 55 NULL, // error code |
| 56 &error_message)); | 56 &error_message)); |
| 57 | 57 |
| 58 #if DCHECK_IS_ON() | 58 // Tracking down http://crbug.com/121424 |
| 59 // |schema| comes from JSON hard-coded to the Chrome binary, so in principle | 59 char buf[128]; |
| 60 // failure to parse indicates we generated corrupted JSON, but in practice | 60 base::snprintf(buf, arraysize(buf), "%s: (%d) '%s'", |
| 61 // corruption of the Chrome binary (e.g. disk errors) can also break it. | 61 name.c_str(), |
| 62 // See http://crbug.com/121424. | 62 result.get() ? result->GetType() : -1, |
| 63 if (!result || !result->IsType(base::Value::TYPE_LIST)) { | 63 error_message.c_str()); |
| 64 char buf[128]; | |
| 65 base::snprintf(buf, arraysize(buf), "%s: (%d) '%s'", name.c_str(), | |
| 66 result.get() ? result->GetType() : -1, | |
| 67 error_message.c_str()); | |
| 68 | 64 |
| 69 DCHECK(result) << "JSON parse failed: " << buf; | 65 CHECK(result.get()) << error_message << " for schema " << schema; |
| 70 DCHECK(result->IsType(base::Value::TYPE_LIST)) << "JSON wrong type: " | 66 CHECK(result->IsType(base::Value::TYPE_LIST)) << " for schema " << schema; |
| 71 << buf; | |
| 72 } | |
| 73 #endif // DCHECK_IS_ON() | |
| 74 | |
| 75 // From() returns null if passed a null or non-list value. | |
| 76 return base::ListValue::From(std::move(result)); | 67 return base::ListValue::From(std::move(result)); |
| 77 } | 68 } |
| 78 | 69 |
| 79 const base::DictionaryValue* FindListItem(const base::ListValue* list, | 70 const base::DictionaryValue* FindListItem(const base::ListValue* list, |
| 80 const std::string& property_name, | 71 const std::string& property_name, |
| 81 const std::string& property_value) { | 72 const std::string& property_value) { |
| 82 for (size_t i = 0; i < list->GetSize(); ++i) { | 73 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 83 const base::DictionaryValue* item = NULL; | 74 const base::DictionaryValue* item = NULL; |
| 84 CHECK(list->GetDictionary(i, &item)) | 75 CHECK(list->GetDictionary(i, &item)) |
| 85 << property_value << "/" << property_name; | 76 << property_value << "/" << property_name; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 g_shared_instance_for_test = testing_api; | 207 g_shared_instance_for_test = testing_api; |
| 217 } | 208 } |
| 218 | 209 |
| 219 ExtensionAPI::OverrideSharedInstanceForTest::~OverrideSharedInstanceForTest() { | 210 ExtensionAPI::OverrideSharedInstanceForTest::~OverrideSharedInstanceForTest() { |
| 220 g_shared_instance_for_test = original_api_; | 211 g_shared_instance_for_test = original_api_; |
| 221 } | 212 } |
| 222 | 213 |
| 223 void ExtensionAPI::LoadSchema(const std::string& name, | 214 void ExtensionAPI::LoadSchema(const std::string& name, |
| 224 const base::StringPiece& schema) { | 215 const base::StringPiece& schema) { |
| 225 std::unique_ptr<base::ListValue> schema_list(LoadSchemaList(name, schema)); | 216 std::unique_ptr<base::ListValue> schema_list(LoadSchemaList(name, schema)); |
| 226 if (!schema_list) | |
| 227 return; | |
| 228 | |
| 229 std::string schema_namespace; | 217 std::string schema_namespace; |
| 230 extensions::ExtensionsClient* extensions_client = | 218 extensions::ExtensionsClient* extensions_client = |
| 231 extensions::ExtensionsClient::Get(); | 219 extensions::ExtensionsClient::Get(); |
| 232 DCHECK(extensions_client); | 220 DCHECK(extensions_client); |
| 233 while (!schema_list->empty()) { | 221 while (!schema_list->empty()) { |
| 234 std::unique_ptr<base::DictionaryValue> schema; | 222 std::unique_ptr<base::DictionaryValue> schema; |
| 235 { | 223 { |
| 236 std::unique_ptr<base::Value> val; | 224 std::unique_ptr<base::Value> val; |
| 237 schema_list->Erase(schema_list->begin(), &val); | 225 schema_list->Erase(schema_list->begin(), &val); |
| 238 schema = base::DictionaryValue::From(std::move(val)); | 226 schema = base::DictionaryValue::From(std::move(val)); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 LoadSchema(maybe_schema_resource->first, | 324 LoadSchema(maybe_schema_resource->first, |
| 337 ReadFromResource(maybe_schema_resource->second)); | 325 ReadFromResource(maybe_schema_resource->second)); |
| 338 } else if (default_configuration_initialized_ && | 326 } else if (default_configuration_initialized_ && |
| 339 extensions_client->IsAPISchemaGenerated(api_name)) { | 327 extensions_client->IsAPISchemaGenerated(api_name)) { |
| 340 LoadSchema(api_name, extensions_client->GetAPISchema(api_name)); | 328 LoadSchema(api_name, extensions_client->GetAPISchema(api_name)); |
| 341 } else { | 329 } else { |
| 342 return NULL; | 330 return NULL; |
| 343 } | 331 } |
| 344 | 332 |
| 345 maybe_schema = schemas_.find(api_name); | 333 maybe_schema = schemas_.find(api_name); |
| 346 // If the schema failed to load then return null for it, rather than | 334 CHECK(schemas_.end() != maybe_schema); |
| 347 // crashing, so that the browser can be notified of the problem. | |
| 348 // See http://crbug.com/121424. | |
| 349 if (schemas_.end() == maybe_schema) | |
| 350 return NULL; | |
| 351 | |
| 352 result = maybe_schema->second.get(); | 335 result = maybe_schema->second.get(); |
| 353 } | 336 } |
| 354 | 337 |
| 355 if (!child_name.empty()) | 338 if (!child_name.empty()) |
| 356 result = GetSchemaChild(result, child_name); | 339 result = GetSchemaChild(result, child_name); |
| 357 | 340 |
| 358 return result; | 341 return result; |
| 359 } | 342 } |
| 360 | 343 |
| 361 Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) { | 344 Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 return result; | 383 return result; |
| 401 } | 384 } |
| 402 | 385 |
| 403 size_t last_dot_index = api_name_candidate.rfind('.'); | 386 size_t last_dot_index = api_name_candidate.rfind('.'); |
| 404 if (last_dot_index == std::string::npos) | 387 if (last_dot_index == std::string::npos) |
| 405 break; | 388 break; |
| 406 | 389 |
| 407 api_name_candidate = api_name_candidate.substr(0, last_dot_index); | 390 api_name_candidate = api_name_candidate.substr(0, last_dot_index); |
| 408 } | 391 } |
| 409 | 392 |
| 410 if (child_name) | 393 *child_name = ""; |
| 411 *child_name = ""; | |
| 412 | |
| 413 return std::string(); | 394 return std::string(); |
| 414 } | 395 } |
| 415 | 396 |
| 416 } // namespace extensions | 397 } // namespace extensions |
| OLD | NEW |