Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/api/declarative/declarative_manifest_data.h" | 5 #include "extensions/common/api/declarative/declarative_manifest_data.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "extensions/common/manifest_constants.h" | 12 #include "extensions/common/manifest_constants.h" |
| 13 | 13 |
| 14 using base::UTF8ToUTF16; | 14 using base::UTF8ToUTF16; |
| 15 using base::StringPrintf; | 15 using base::StringPrintf; |
| 16 | 16 |
| 17 namespace extensions { | 17 namespace extensions { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 const char* ValueTypeToString(const base::Value* value) { | |
| 22 const base::Value::Type type = value->GetType(); | |
| 23 static const char* strings[] = {"null", | |
| 24 "boolean", | |
| 25 "integer", | |
| 26 "double", | |
| 27 "string", | |
| 28 "binary", | |
| 29 "dictionary", | |
| 30 "list"}; | |
| 31 CHECK(static_cast<size_t>(type) < arraysize(strings)); | |
| 32 return strings[type]; | |
| 33 } | |
| 34 | |
| 35 class ErrorBuilder { | 21 class ErrorBuilder { |
| 36 public: | 22 public: |
| 37 explicit ErrorBuilder(base::string16* error) : error_(error) {} | 23 explicit ErrorBuilder(base::string16* error) : error_(error) {} |
| 38 | 24 |
| 39 // Appends a literal string |error|. | 25 // Appends a literal string |error|. |
| 40 void Append(const char* error) { | 26 void Append(const char* error) { |
| 41 if (error_->length()) | 27 if (error_->length()) |
| 42 error_->append(UTF8ToUTF16("; ")); | 28 error_->append(UTF8ToUTF16("; ")); |
| 43 error_->append(UTF8ToUTF16(error)); | 29 error_->append(UTF8ToUTF16(error)); |
| 44 } | 30 } |
| 45 | 31 |
| 46 // Appends a string |error| with the first %s replaced by |sub|. | 32 // Appends a string |error| with the first %s replaced by |sub|. |
| 47 void Append(const char* error, const char* sub) { | 33 void Append(const char* error, const char* sub) { |
| 48 Append(base::StringPrintf(error, sub).c_str()); | 34 Append(base::StringPrintf(error, sub).c_str()); |
| 49 } | 35 } |
| 50 | 36 |
| 51 private: | 37 private: |
| 52 base::string16* error_; | 38 base::string16* error_; |
| 53 DISALLOW_COPY_AND_ASSIGN(ErrorBuilder); | 39 DISALLOW_COPY_AND_ASSIGN(ErrorBuilder); |
| 54 }; | 40 }; |
| 55 | 41 |
| 56 // Converts a rule defined in the manifest into a JSON internal format. The | 42 // Converts a rule defined in the manifest into a JSON internal format. The |
| 57 // difference is that actions and conditions use a "type" key to define the | 43 // difference is that actions and conditions use a "type" key to define the |
| 58 // type of rule/condition, while the internal format uses a "instanceType" key | 44 // type of rule/condition, while the internal format uses a "instanceType" key |
| 59 // for this. This function walks through all the conditions and rules to swap | 45 // for this. This function walks through all the conditions and rules to swap |
| 60 // the manifest key for the internal key. | 46 // the manifest key for the internal key. |
| 61 bool ConvertManifestRule(const linked_ptr<DeclarativeManifestData::Rule>& rule, | 47 bool ConvertManifestRule(const linked_ptr<DeclarativeManifestData::Rule>& rule, |
| 62 ErrorBuilder* error_builder) { | 48 ErrorBuilder* error_builder) { |
| 63 auto convert_list = | 49 auto convert_list = |
| 64 [error_builder](std::vector<std::unique_ptr<base::Value>>& list) { | 50 [error_builder](const std::vector<std::unique_ptr<base::Value>>& list) { |
| 65 for (const std::unique_ptr<base::Value>& value : list) { | 51 for (const std::unique_ptr<base::Value>& value : list) { |
| 66 base::DictionaryValue* dictionary = nullptr; | 52 base::DictionaryValue* dictionary = nullptr; |
| 67 if (!value->GetAsDictionary(&dictionary)) { | 53 if (!value->GetAsDictionary(&dictionary)) { |
| 68 error_builder->Append("expected dictionary, got %s", | 54 error_builder->Append("expected dictionary, got %s", |
| 69 ValueTypeToString(value.get())); | 55 base::Value::GetTypeName(value->GetType())); |
| 70 return false; | 56 return false; |
| 71 } | 57 } |
| 72 std::string type; | 58 std::string type; |
| 73 if (!dictionary->GetString("type", &type)) { | 59 if (!dictionary->GetString("type", &type)) { |
| 74 error_builder->Append("'type' is required and must be a string"); | 60 error_builder->Append("'type' is required and must be a string"); |
| 75 return false; | 61 return false; |
| 76 } | 62 } |
| 77 dictionary->Remove("type", nullptr); | 63 dictionary->Remove("type", nullptr); |
| 78 dictionary->SetString("instanceType", type); | 64 dictionary->SetString("instanceType", type); |
| 79 } | 65 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 // field to indicate the instance type. Instead of adding rules to a | 118 // field to indicate the instance type. Instead of adding rules to a |
| 133 // specific event list, each rule has an "event" field to indicate which | 119 // specific event list, each rule has an "event" field to indicate which |
| 134 // event it applies to. | 120 // event it applies to. |
| 135 // | 121 // |
| 136 ErrorBuilder error_builder(error); | 122 ErrorBuilder error_builder(error); |
| 137 std::unique_ptr<DeclarativeManifestData> result( | 123 std::unique_ptr<DeclarativeManifestData> result( |
| 138 new DeclarativeManifestData()); | 124 new DeclarativeManifestData()); |
| 139 const base::ListValue* list = nullptr; | 125 const base::ListValue* list = nullptr; |
| 140 if (!value.GetAsList(&list)) { | 126 if (!value.GetAsList(&list)) { |
| 141 error_builder.Append("'event_rules' expected list, got %s", | 127 error_builder.Append("'event_rules' expected list, got %s", |
| 142 ValueTypeToString(&value)); | 128 base::Value::GetTypeName(value.GetType())); |
| 143 return std::unique_ptr<DeclarativeManifestData>(); | 129 return std::unique_ptr<DeclarativeManifestData>(); |
| 144 } | 130 } |
| 145 | 131 |
| 146 for (size_t i = 0; i < list->GetSize(); ++i) { | 132 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 147 const base::DictionaryValue* dict = nullptr; | 133 const base::DictionaryValue* dict = nullptr; |
| 148 if (!list->GetDictionary(i, &dict)) { | 134 if (!list->GetDictionary(i, &dict)) { |
|
pneubeck (no reviews)
2016/07/14 18:51:37
this whole block is rather confusing.
maybe change
Lei Zhang
2016/07/15 01:27:18
Sure. You are absolutely right, the else case can'
| |
| 149 const base::Value* value = nullptr; | 135 const base::Value* dict_value = nullptr; |
| 150 if (list->Get(i, &value)) | 136 if (list->Get(i, &dict_value)) { |
| 151 error_builder.Append("expected dictionary, got %s", | 137 error_builder.Append("expected dictionary, got %s", |
| 152 ValueTypeToString(value)); | 138 base::Value::GetTypeName(dict_value->GetType())); |
| 153 else | 139 } else { |
| 154 error_builder.Append("expected dictionary"); | 140 error_builder.Append("expected dictionary"); |
| 141 } | |
| 155 return std::unique_ptr<DeclarativeManifestData>(); | 142 return std::unique_ptr<DeclarativeManifestData>(); |
| 156 } | 143 } |
| 157 std::string event; | 144 std::string event; |
| 158 if (!dict->GetString("event", &event)) { | 145 if (!dict->GetString("event", &event)) { |
| 159 error_builder.Append("'event' is required"); | 146 error_builder.Append("'event' is required"); |
| 160 return std::unique_ptr<DeclarativeManifestData>(); | 147 return std::unique_ptr<DeclarativeManifestData>(); |
| 161 } | 148 } |
| 162 | 149 |
| 163 linked_ptr<Rule> rule(new Rule()); | 150 linked_ptr<Rule> rule(new Rule()); |
| 164 if (!Rule::Populate(*dict, rule.get())) { | 151 if (!Rule::Populate(*dict, rule.get())) { |
| 165 error_builder.Append("rule failed to populate"); | 152 error_builder.Append("rule failed to populate"); |
| 166 return std::unique_ptr<DeclarativeManifestData>(); | 153 return std::unique_ptr<DeclarativeManifestData>(); |
| 167 } | 154 } |
| 168 | 155 |
| 169 if (!ConvertManifestRule(rule, &error_builder)) | 156 if (!ConvertManifestRule(rule, &error_builder)) |
| 170 return std::unique_ptr<DeclarativeManifestData>(); | 157 return std::unique_ptr<DeclarativeManifestData>(); |
| 171 | 158 |
| 172 result->event_rules_map_[event].push_back(rule); | 159 result->event_rules_map_[event].push_back(rule); |
| 173 } | 160 } |
| 174 return result; | 161 return result; |
| 175 } | 162 } |
| 176 | 163 |
| 177 std::vector<linked_ptr<DeclarativeManifestData::Rule>>& | 164 std::vector<linked_ptr<DeclarativeManifestData::Rule>>& |
| 178 DeclarativeManifestData::RulesForEvent(const std::string& event) { | 165 DeclarativeManifestData::RulesForEvent(const std::string& event) { |
| 179 return event_rules_map_[event]; | 166 return event_rules_map_[event]; |
| 180 } | 167 } |
| 181 | 168 |
| 182 } // namespace extensions | 169 } // namespace extensions |
| OLD | NEW |