Home | History | Annotate | Download | only in permissions
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/command_line.h"
      6 #include "base/json/json_file_value_serializer.h"
      7 #include "base/logging.h"
      8 #include "base/path_service.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "chrome/common/chrome_paths.h"
     11 #include "chrome/common/chrome_switches.h"
     12 #include "chrome/common/extensions/extension_test_util.h"
     13 #include "chrome/common/extensions/features/feature_channel.h"
     14 #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
     15 #include "chrome/common/extensions/permissions/permission_message_util.h"
     16 #include "chrome/common/extensions/permissions/socket_permission.h"
     17 #include "extensions/common/error_utils.h"
     18 #include "extensions/common/extension.h"
     19 #include "extensions/common/permissions/permission_message_provider.h"
     20 #include "extensions/common/permissions/permission_set.h"
     21 #include "extensions/common/permissions/permissions_data.h"
     22 #include "extensions/common/permissions/permissions_info.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 
     25 using extension_test_util::LoadManifest;
     26 
     27 namespace extensions {
     28 
     29 namespace {
     30 
     31 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
     32   int schemes = URLPattern::SCHEME_ALL;
     33   extent->AddPattern(URLPattern(schemes, pattern));
     34 }
     35 
     36 size_t IndexOf(const std::vector<base::string16>& warnings,
     37                const std::string& warning) {
     38   for (size_t i = 0; i < warnings.size(); ++i) {
     39     if (warnings[i] == ASCIIToUTF16(warning))
     40       return i;
     41   }
     42 
     43   return warnings.size();
     44 }
     45 
     46 bool Contains(const std::vector<base::string16>& warnings,
     47               const std::string& warning) {
     48   return IndexOf(warnings, warning) != warnings.size();
     49 }
     50 
     51 }  // namespace
     52 
     53 // Tests GetByID.
     54 TEST(PermissionsTest, GetByID) {
     55   PermissionsInfo* info = PermissionsInfo::GetInstance();
     56   APIPermissionSet apis = info->GetAll();
     57   for (APIPermissionSet::const_iterator i = apis.begin();
     58        i != apis.end(); ++i) {
     59     EXPECT_EQ(i->id(), i->info()->id());
     60   }
     61 }
     62 
     63 // Tests that GetByName works with normal permission names and aliases.
     64 TEST(PermissionsTest, GetByName) {
     65   PermissionsInfo* info = PermissionsInfo::GetInstance();
     66   EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
     67   EXPECT_EQ(APIPermission::kManagement,
     68             info->GetByName("management")->id());
     69   EXPECT_FALSE(info->GetByName("alsdkfjasldkfj"));
     70 }
     71 
     72 TEST(PermissionsTest, GetAll) {
     73   size_t count = 0;
     74   PermissionsInfo* info = PermissionsInfo::GetInstance();
     75   APIPermissionSet apis = info->GetAll();
     76   for (APIPermissionSet::const_iterator api = apis.begin();
     77        api != apis.end(); ++api) {
     78     // Make sure only the valid permission IDs get returned.
     79     EXPECT_NE(APIPermission::kInvalid, api->id());
     80     EXPECT_NE(APIPermission::kUnknown, api->id());
     81     count++;
     82   }
     83   EXPECT_EQ(count, info->get_permission_count());
     84 }
     85 
     86 TEST(PermissionsTest, GetAllByName) {
     87   std::set<std::string> names;
     88   names.insert("background");
     89   names.insert("management");
     90 
     91   // This is an alias of kTab
     92   names.insert("windows");
     93 
     94   // This unknown name should get dropped.
     95   names.insert("sdlkfjasdlkfj");
     96 
     97   APIPermissionSet expected;
     98   expected.insert(APIPermission::kBackground);
     99   expected.insert(APIPermission::kManagement);
    100   expected.insert(APIPermission::kTab);
    101 
    102   EXPECT_EQ(expected,
    103             PermissionsInfo::GetInstance()->GetAllByName(names));
    104 }
    105 
    106 // Tests that the aliases are properly mapped.
    107 TEST(PermissionsTest, Aliases) {
    108   PermissionsInfo* info = PermissionsInfo::GetInstance();
    109   // tabs: tabs, windows
    110   std::string tabs_name = "tabs";
    111   EXPECT_EQ(tabs_name, info->GetByID(APIPermission::kTab)->name());
    112   EXPECT_EQ(APIPermission::kTab, info->GetByName("tabs")->id());
    113   EXPECT_EQ(APIPermission::kTab, info->GetByName("windows")->id());
    114 
    115   // unlimitedStorage: unlimitedStorage, unlimited_storage
    116   std::string storage_name = "unlimitedStorage";
    117   EXPECT_EQ(storage_name, info->GetByID(
    118       APIPermission::kUnlimitedStorage)->name());
    119   EXPECT_EQ(APIPermission::kUnlimitedStorage,
    120             info->GetByName("unlimitedStorage")->id());
    121   EXPECT_EQ(APIPermission::kUnlimitedStorage,
    122             info->GetByName("unlimited_storage")->id());
    123 }
    124 
    125 TEST(PermissionsTest, EffectiveHostPermissions) {
    126   scoped_refptr<Extension> extension;
    127   scoped_refptr<const PermissionSet> permissions;
    128 
    129   extension = LoadManifest("effective_host_permissions", "empty.json");
    130   permissions = extension->GetActivePermissions();
    131   EXPECT_EQ(0u,
    132             PermissionsData::GetEffectiveHostPermissions(extension.get())
    133                 .patterns().size());
    134   EXPECT_FALSE(
    135       permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
    136   EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
    137 
    138   extension = LoadManifest("effective_host_permissions", "one_host.json");
    139   permissions = extension->GetActivePermissions();
    140   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
    141       GURL("http://www.google.com")));
    142   EXPECT_FALSE(permissions->HasEffectiveAccessToURL(
    143       GURL("https://www.google.com")));
    144   EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
    145 
    146   extension = LoadManifest("effective_host_permissions",
    147                            "one_host_wildcard.json");
    148   permissions = extension->GetActivePermissions();
    149   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
    150   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
    151       GURL("http://foo.google.com")));
    152   EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
    153 
    154   extension = LoadManifest("effective_host_permissions", "two_hosts.json");
    155   permissions = extension->GetActivePermissions();
    156   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
    157       GURL("http://www.google.com")));
    158   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
    159       GURL("http://www.reddit.com")));
    160   EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
    161 
    162   extension = LoadManifest("effective_host_permissions",
    163                            "https_not_considered.json");
    164   permissions = extension->GetActivePermissions();
    165   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
    166   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://google.com")));
    167   EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
    168 
    169   extension = LoadManifest("effective_host_permissions",
    170                            "two_content_scripts.json");
    171   permissions = extension->GetActivePermissions();
    172   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://google.com")));
    173   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
    174       GURL("http://www.reddit.com")));
    175   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(
    176       GURL("http://news.ycombinator.com")));
    177   EXPECT_FALSE(permissions->HasEffectiveAccessToAllHosts());
    178 
    179   extension = LoadManifest("effective_host_permissions", "all_hosts.json");
    180   permissions = extension->GetActivePermissions();
    181   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
    182   EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
    183   EXPECT_TRUE(
    184       permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
    185   EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
    186 
    187   extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
    188   permissions = extension->GetActivePermissions();
    189   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
    190   EXPECT_TRUE(
    191       permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
    192   EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
    193 
    194   extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
    195   permissions = extension->GetActivePermissions();
    196   EXPECT_FALSE(permissions->HasEffectiveAccessToURL(GURL("http://test/")));
    197   EXPECT_TRUE(permissions->HasEffectiveAccessToURL(GURL("https://test/")));
    198   EXPECT_TRUE(
    199       permissions->HasEffectiveAccessToURL(GURL("http://www.google.com")));
    200   EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
    201 }
    202 
    203 TEST(PermissionsTest, ExplicitAccessToOrigin) {
    204   APIPermissionSet apis;
    205   ManifestPermissionSet manifest_permissions;
    206   URLPatternSet explicit_hosts;
    207   URLPatternSet scriptable_hosts;
    208 
    209   AddPattern(&explicit_hosts, "http://*.google.com/*");
    210   // The explicit host paths should get set to /*.
    211   AddPattern(&explicit_hosts, "http://www.example.com/a/particular/path/*");
    212 
    213   scoped_refptr<PermissionSet> perm_set = new PermissionSet(
    214       apis, manifest_permissions, explicit_hosts, scriptable_hosts);
    215   ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
    216       GURL("http://www.google.com/")));
    217   ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
    218       GURL("http://test.google.com/")));
    219   ASSERT_TRUE(perm_set->HasExplicitAccessToOrigin(
    220       GURL("http://www.example.com")));
    221   ASSERT_TRUE(perm_set->HasEffectiveAccessToURL(
    222       GURL("http://www.example.com")));
    223   ASSERT_FALSE(perm_set->HasExplicitAccessToOrigin(
    224       GURL("http://test.example.com")));
    225 }
    226 
    227 TEST(PermissionsTest, CreateUnion) {
    228   APIPermission* permission = NULL;
    229 
    230   ManifestPermissionSet manifest_permissions;
    231   APIPermissionSet apis1;
    232   APIPermissionSet apis2;
    233   APIPermissionSet expected_apis;
    234 
    235   URLPatternSet explicit_hosts1;
    236   URLPatternSet explicit_hosts2;
    237   URLPatternSet expected_explicit_hosts;
    238 
    239   URLPatternSet scriptable_hosts1;
    240   URLPatternSet scriptable_hosts2;
    241   URLPatternSet expected_scriptable_hosts;
    242 
    243   URLPatternSet effective_hosts;
    244 
    245   scoped_refptr<PermissionSet> set1;
    246   scoped_refptr<PermissionSet> set2;
    247   scoped_refptr<PermissionSet> union_set;
    248 
    249   const APIPermissionInfo* permission_info =
    250     PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
    251   permission = permission_info->CreateAPIPermission();
    252   {
    253     scoped_ptr<base::ListValue> value(new base::ListValue());
    254     value->Append(
    255         base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
    256     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    257     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    258     if (!permission->FromValue(value.get())) {
    259       NOTREACHED();
    260     }
    261   }
    262 
    263   // Union with an empty set.
    264   apis1.insert(APIPermission::kTab);
    265   apis1.insert(APIPermission::kBackground);
    266   apis1.insert(permission->Clone());
    267   expected_apis.insert(APIPermission::kTab);
    268   expected_apis.insert(APIPermission::kBackground);
    269   expected_apis.insert(permission);
    270 
    271   AddPattern(&explicit_hosts1, "http://*.google.com/*");
    272   AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
    273   AddPattern(&effective_hosts, "http://*.google.com/*");
    274 
    275   set1 = new PermissionSet(apis1, manifest_permissions,
    276                            explicit_hosts1, scriptable_hosts1);
    277   set2 = new PermissionSet(apis2, manifest_permissions,
    278                            explicit_hosts2, scriptable_hosts2);
    279   union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
    280   EXPECT_TRUE(set1->Contains(*set2.get()));
    281   EXPECT_TRUE(set1->Contains(*union_set.get()));
    282   EXPECT_FALSE(set2->Contains(*set1.get()));
    283   EXPECT_FALSE(set2->Contains(*union_set.get()));
    284   EXPECT_TRUE(union_set->Contains(*set1.get()));
    285   EXPECT_TRUE(union_set->Contains(*set2.get()));
    286 
    287   EXPECT_FALSE(union_set->HasEffectiveFullAccess());
    288   EXPECT_EQ(expected_apis, union_set->apis());
    289   EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
    290   EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
    291   EXPECT_EQ(expected_explicit_hosts, union_set->effective_hosts());
    292 
    293   // Now use a real second set.
    294   apis2.insert(APIPermission::kTab);
    295   apis2.insert(APIPermission::kProxy);
    296   apis2.insert(APIPermission::kClipboardWrite);
    297   apis2.insert(APIPermission::kPlugin);
    298 
    299   permission = permission_info->CreateAPIPermission();
    300   {
    301     scoped_ptr<base::ListValue> value(new base::ListValue());
    302     value->Append(
    303         base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
    304     value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
    305     if (!permission->FromValue(value.get())) {
    306       NOTREACHED();
    307     }
    308   }
    309   apis2.insert(permission);
    310 
    311   expected_apis.insert(APIPermission::kTab);
    312   expected_apis.insert(APIPermission::kProxy);
    313   expected_apis.insert(APIPermission::kClipboardWrite);
    314   expected_apis.insert(APIPermission::kPlugin);
    315 
    316   permission = permission_info->CreateAPIPermission();
    317   {
    318     scoped_ptr<base::ListValue> value(new base::ListValue());
    319     value->Append(
    320         base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
    321     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    322     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    323     value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
    324     if (!permission->FromValue(value.get())) {
    325       NOTREACHED();
    326     }
    327   }
    328   // Insert a new permission socket permisssion which will replace the old one.
    329   expected_apis.insert(permission);
    330 
    331   AddPattern(&explicit_hosts2, "http://*.example.com/*");
    332   AddPattern(&scriptable_hosts2, "http://*.google.com/*");
    333   AddPattern(&expected_explicit_hosts, "http://*.example.com/*");
    334   AddPattern(&expected_scriptable_hosts, "http://*.google.com/*");
    335 
    336   URLPatternSet::CreateUnion(
    337       explicit_hosts2, scriptable_hosts2, &effective_hosts);
    338 
    339   set2 = new PermissionSet(apis2, manifest_permissions,
    340                            explicit_hosts2, scriptable_hosts2);
    341   union_set = PermissionSet::CreateUnion(set1.get(), set2.get());
    342 
    343   EXPECT_FALSE(set1->Contains(*set2.get()));
    344   EXPECT_FALSE(set1->Contains(*union_set.get()));
    345   EXPECT_FALSE(set2->Contains(*set1.get()));
    346   EXPECT_FALSE(set2->Contains(*union_set.get()));
    347   EXPECT_TRUE(union_set->Contains(*set1.get()));
    348   EXPECT_TRUE(union_set->Contains(*set2.get()));
    349 
    350   EXPECT_TRUE(union_set->HasEffectiveFullAccess());
    351   EXPECT_TRUE(union_set->HasEffectiveAccessToAllHosts());
    352   EXPECT_EQ(expected_apis, union_set->apis());
    353   EXPECT_EQ(expected_explicit_hosts, union_set->explicit_hosts());
    354   EXPECT_EQ(expected_scriptable_hosts, union_set->scriptable_hosts());
    355   EXPECT_EQ(effective_hosts, union_set->effective_hosts());
    356 }
    357 
    358 TEST(PermissionsTest, CreateIntersection) {
    359   APIPermission* permission = NULL;
    360 
    361   ManifestPermissionSet manifest_permissions;
    362   APIPermissionSet apis1;
    363   APIPermissionSet apis2;
    364   APIPermissionSet expected_apis;
    365 
    366   URLPatternSet explicit_hosts1;
    367   URLPatternSet explicit_hosts2;
    368   URLPatternSet expected_explicit_hosts;
    369 
    370   URLPatternSet scriptable_hosts1;
    371   URLPatternSet scriptable_hosts2;
    372   URLPatternSet expected_scriptable_hosts;
    373 
    374   URLPatternSet effective_hosts;
    375 
    376   scoped_refptr<PermissionSet> set1;
    377   scoped_refptr<PermissionSet> set2;
    378   scoped_refptr<PermissionSet> new_set;
    379 
    380   const APIPermissionInfo* permission_info =
    381     PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
    382 
    383   // Intersection with an empty set.
    384   apis1.insert(APIPermission::kTab);
    385   apis1.insert(APIPermission::kBackground);
    386   permission = permission_info->CreateAPIPermission();
    387   {
    388     scoped_ptr<base::ListValue> value(new base::ListValue());
    389     value->Append(
    390         base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
    391     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    392     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    393     if (!permission->FromValue(value.get())) {
    394       NOTREACHED();
    395     }
    396   }
    397   apis1.insert(permission);
    398 
    399   AddPattern(&explicit_hosts1, "http://*.google.com/*");
    400   AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
    401 
    402   set1 = new PermissionSet(apis1, manifest_permissions,
    403                            explicit_hosts1, scriptable_hosts1);
    404   set2 = new PermissionSet(apis2, manifest_permissions,
    405                            explicit_hosts2, scriptable_hosts2);
    406   new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
    407   EXPECT_TRUE(set1->Contains(*new_set.get()));
    408   EXPECT_TRUE(set2->Contains(*new_set.get()));
    409   EXPECT_TRUE(set1->Contains(*set2.get()));
    410   EXPECT_FALSE(set2->Contains(*set1.get()));
    411   EXPECT_FALSE(new_set->Contains(*set1.get()));
    412   EXPECT_TRUE(new_set->Contains(*set2.get()));
    413 
    414   EXPECT_TRUE(new_set->IsEmpty());
    415   EXPECT_FALSE(new_set->HasEffectiveFullAccess());
    416   EXPECT_EQ(expected_apis, new_set->apis());
    417   EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
    418   EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
    419   EXPECT_EQ(expected_explicit_hosts, new_set->effective_hosts());
    420 
    421   // Now use a real second set.
    422   apis2.insert(APIPermission::kTab);
    423   apis2.insert(APIPermission::kProxy);
    424   apis2.insert(APIPermission::kClipboardWrite);
    425   apis2.insert(APIPermission::kPlugin);
    426   permission = permission_info->CreateAPIPermission();
    427   {
    428     scoped_ptr<base::ListValue> value(new base::ListValue());
    429     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    430     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    431     value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
    432     if (!permission->FromValue(value.get())) {
    433       NOTREACHED();
    434     }
    435   }
    436   apis2.insert(permission);
    437 
    438   expected_apis.insert(APIPermission::kTab);
    439   permission = permission_info->CreateAPIPermission();
    440   {
    441     scoped_ptr<base::ListValue> value(new base::ListValue());
    442     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    443     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    444     if (!permission->FromValue(value.get())) {
    445       NOTREACHED();
    446     }
    447   }
    448   expected_apis.insert(permission);
    449 
    450   AddPattern(&explicit_hosts2, "http://*.example.com/*");
    451   AddPattern(&explicit_hosts2, "http://*.google.com/*");
    452   AddPattern(&scriptable_hosts2, "http://*.google.com/*");
    453   AddPattern(&expected_explicit_hosts, "http://*.google.com/*");
    454 
    455   effective_hosts.ClearPatterns();
    456   AddPattern(&effective_hosts, "http://*.google.com/*");
    457 
    458   set2 = new PermissionSet(apis2, manifest_permissions,
    459                            explicit_hosts2, scriptable_hosts2);
    460   new_set = PermissionSet::CreateIntersection(set1.get(), set2.get());
    461 
    462   EXPECT_TRUE(set1->Contains(*new_set.get()));
    463   EXPECT_TRUE(set2->Contains(*new_set.get()));
    464   EXPECT_FALSE(set1->Contains(*set2.get()));
    465   EXPECT_FALSE(set2->Contains(*set1.get()));
    466   EXPECT_FALSE(new_set->Contains(*set1.get()));
    467   EXPECT_FALSE(new_set->Contains(*set2.get()));
    468 
    469   EXPECT_FALSE(new_set->HasEffectiveFullAccess());
    470   EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
    471   EXPECT_EQ(expected_apis, new_set->apis());
    472   EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
    473   EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
    474   EXPECT_EQ(effective_hosts, new_set->effective_hosts());
    475 }
    476 
    477 TEST(PermissionsTest, CreateDifference) {
    478   APIPermission* permission = NULL;
    479 
    480   ManifestPermissionSet manifest_permissions;
    481   APIPermissionSet apis1;
    482   APIPermissionSet apis2;
    483   APIPermissionSet expected_apis;
    484 
    485   URLPatternSet explicit_hosts1;
    486   URLPatternSet explicit_hosts2;
    487   URLPatternSet expected_explicit_hosts;
    488 
    489   URLPatternSet scriptable_hosts1;
    490   URLPatternSet scriptable_hosts2;
    491   URLPatternSet expected_scriptable_hosts;
    492 
    493   URLPatternSet effective_hosts;
    494 
    495   scoped_refptr<PermissionSet> set1;
    496   scoped_refptr<PermissionSet> set2;
    497   scoped_refptr<PermissionSet> new_set;
    498 
    499   const APIPermissionInfo* permission_info =
    500     PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
    501 
    502   // Difference with an empty set.
    503   apis1.insert(APIPermission::kTab);
    504   apis1.insert(APIPermission::kBackground);
    505   permission = permission_info->CreateAPIPermission();
    506   {
    507     scoped_ptr<base::ListValue> value(new base::ListValue());
    508     value->Append(
    509        base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
    510     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    511     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    512     if (!permission->FromValue(value.get())) {
    513       NOTREACHED();
    514     }
    515   }
    516   apis1.insert(permission);
    517 
    518   AddPattern(&explicit_hosts1, "http://*.google.com/*");
    519   AddPattern(&scriptable_hosts1, "http://www.reddit.com/*");
    520 
    521   set1 = new PermissionSet(apis1, manifest_permissions,
    522                            explicit_hosts1, scriptable_hosts1);
    523   set2 = new PermissionSet(apis2, manifest_permissions,
    524                            explicit_hosts2, scriptable_hosts2);
    525   new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
    526   EXPECT_EQ(*set1.get(), *new_set.get());
    527 
    528   // Now use a real second set.
    529   apis2.insert(APIPermission::kTab);
    530   apis2.insert(APIPermission::kProxy);
    531   apis2.insert(APIPermission::kClipboardWrite);
    532   apis2.insert(APIPermission::kPlugin);
    533   permission = permission_info->CreateAPIPermission();
    534   {
    535     scoped_ptr<base::ListValue> value(new base::ListValue());
    536     value->Append(
    537         base::Value::CreateStringValue("tcp-connect:*.example.com:80"));
    538     value->Append(base::Value::CreateStringValue("udp-send-to::8899"));
    539     if (!permission->FromValue(value.get())) {
    540       NOTREACHED();
    541     }
    542   }
    543   apis2.insert(permission);
    544 
    545   expected_apis.insert(APIPermission::kBackground);
    546   permission = permission_info->CreateAPIPermission();
    547   {
    548     scoped_ptr<base::ListValue> value(new base::ListValue());
    549     value->Append(base::Value::CreateStringValue("udp-bind::8080"));
    550     value->Append(base::Value::CreateStringValue("udp-send-to::8888"));
    551     if (!permission->FromValue(value.get())) {
    552       NOTREACHED();
    553     }
    554   }
    555   expected_apis.insert(permission);
    556 
    557   AddPattern(&explicit_hosts2, "http://*.example.com/*");
    558   AddPattern(&explicit_hosts2, "http://*.google.com/*");
    559   AddPattern(&scriptable_hosts2, "http://*.google.com/*");
    560   AddPattern(&expected_scriptable_hosts, "http://www.reddit.com/*");
    561 
    562   effective_hosts.ClearPatterns();
    563   AddPattern(&effective_hosts, "http://www.reddit.com/*");
    564 
    565   set2 = new PermissionSet(apis2, manifest_permissions,
    566                            explicit_hosts2, scriptable_hosts2);
    567   new_set = PermissionSet::CreateDifference(set1.get(), set2.get());
    568 
    569   EXPECT_TRUE(set1->Contains(*new_set.get()));
    570   EXPECT_FALSE(set2->Contains(*new_set.get()));
    571 
    572   EXPECT_FALSE(new_set->HasEffectiveFullAccess());
    573   EXPECT_FALSE(new_set->HasEffectiveAccessToAllHosts());
    574   EXPECT_EQ(expected_apis, new_set->apis());
    575   EXPECT_EQ(expected_explicit_hosts, new_set->explicit_hosts());
    576   EXPECT_EQ(expected_scriptable_hosts, new_set->scriptable_hosts());
    577   EXPECT_EQ(effective_hosts, new_set->effective_hosts());
    578 
    579   // |set3| = |set1| - |set2| --> |set3| intersect |set2| == empty_set
    580   set1 = PermissionSet::CreateIntersection(new_set.get(), set2.get());
    581   EXPECT_TRUE(set1->IsEmpty());
    582 }
    583 
    584 TEST(PermissionsTest, IsPrivilegeIncrease) {
    585   const struct {
    586     const char* base_name;
    587     bool expect_increase;
    588   } kTests[] = {
    589     { "allhosts1", false },  // all -> all
    590     { "allhosts2", false },  // all -> one
    591     { "allhosts3", true },  // one -> all
    592     { "hosts1", false },  // http://a,http://b -> http://a,http://b
    593     { "hosts2", true },  // http://a,http://b -> https://a,http://*.b
    594     { "hosts3", false },  // http://a,http://b -> http://a
    595     { "hosts4", true },  // http://a -> http://a,http://b
    596     { "hosts5", false },  // http://a,b,c -> http://a,b,c + https://a,b,c
    597     { "hosts6", false },  // http://a.com -> http://a.com + http://a.co.uk
    598     { "permissions1", false },  // tabs -> tabs
    599     { "permissions2", true },  // tabs -> tabs,bookmarks
    600     { "permissions3", true },  // http://a -> http://a,tabs
    601     { "permissions5", true },  // bookmarks -> bookmarks,history
    602     { "equivalent_warnings", false },  // tabs --> tabs, webNavigation
    603 #if !defined(OS_CHROMEOS)  // plugins aren't allowed in ChromeOS
    604     { "permissions4", false },  // plugin -> plugin,tabs
    605     { "plugin1", false },  // plugin -> plugin
    606     { "plugin2", false },  // plugin -> none
    607     { "plugin3", true },  // none -> plugin
    608 #endif
    609     { "storage", false },  // none -> storage
    610     { "notifications", false },  // none -> notifications
    611     { "platformapp1", false },  // host permissions for platform apps
    612     { "platformapp2", true },  // API permissions for platform apps
    613     { "media_galleries1", true },  // all -> read|all
    614     { "media_galleries2", true },  // read|all -> read|delete|copyTo|all
    615     { "media_galleries3", true },  // all -> read|delete|all
    616     { "media_galleries4", false },  // read|all -> all
    617     { "media_galleries5", false },  // read|copyTo|delete|all -> read|all
    618     { "media_galleries6", false },  // read|all -> read|all
    619     { "media_galleries7", true },  // read|delete|all -> read|copyTo|delete|all
    620     { "sockets1", true },  // none -> tcp:*:*
    621     { "sockets2", false },  // tcp:*:* -> tcp:*:*
    622     { "sockets3", true },  // tcp:a.com:80 -> tcp:*:*
    623   };
    624 
    625   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
    626     scoped_refptr<Extension> old_extension(
    627         LoadManifest("allow_silent_upgrade",
    628                      std::string(kTests[i].base_name) + "_old.json"));
    629     scoped_refptr<Extension> new_extension(
    630         LoadManifest("allow_silent_upgrade",
    631                      std::string(kTests[i].base_name) + "_new.json"));
    632 
    633     EXPECT_TRUE(new_extension.get()) << kTests[i].base_name << "_new.json";
    634     if (!new_extension.get())
    635       continue;
    636 
    637     scoped_refptr<const PermissionSet> old_p(
    638         old_extension->GetActivePermissions());
    639     scoped_refptr<const PermissionSet> new_p(
    640         new_extension->GetActivePermissions());
    641     Manifest::Type extension_type = old_extension->GetType();
    642 
    643     bool increased = PermissionMessageProvider::Get()->IsPrivilegeIncrease(
    644         old_p.get(), new_p.get(), extension_type);
    645     EXPECT_EQ(kTests[i].expect_increase, increased) << kTests[i].base_name;
    646   }
    647 }
    648 
    649 TEST(PermissionsTest, PermissionMessages) {
    650   // Ensure that all permissions that needs to show install UI actually have
    651   // strings associated with them.
    652   APIPermissionSet skip;
    653 
    654   // These are considered "nuisance" or "trivial" permissions that don't need
    655   // a prompt.
    656   skip.insert(APIPermission::kActiveTab);
    657   skip.insert(APIPermission::kAdView);
    658   skip.insert(APIPermission::kAlarms);
    659   skip.insert(APIPermission::kAlwaysOnTopWindows);
    660   skip.insert(APIPermission::kAppCurrentWindowInternal);
    661   skip.insert(APIPermission::kAppRuntime);
    662   skip.insert(APIPermission::kAppWindow);
    663   skip.insert(APIPermission::kAudio);
    664   skip.insert(APIPermission::kBrowsingData);
    665   skip.insert(APIPermission::kCastStreaming);
    666   skip.insert(APIPermission::kContextMenus);
    667   skip.insert(APIPermission::kDiagnostics);
    668   skip.insert(APIPermission::kDns);
    669   skip.insert(APIPermission::kDownloadsShelf);
    670   skip.insert(APIPermission::kFontSettings);
    671   skip.insert(APIPermission::kFullscreen);
    672   skip.insert(APIPermission::kGcm);
    673   skip.insert(APIPermission::kIdle);
    674   skip.insert(APIPermission::kIdltest);
    675   skip.insert(APIPermission::kLogPrivate);
    676   skip.insert(APIPermission::kNotification);
    677   skip.insert(APIPermission::kPointerLock);
    678   skip.insert(APIPermission::kPower);
    679   skip.insert(APIPermission::kPushMessaging);
    680   skip.insert(APIPermission::kSessions);
    681   skip.insert(APIPermission::kStorage);
    682   skip.insert(APIPermission::kSystemCpu);
    683   skip.insert(APIPermission::kSystemDisplay);
    684   skip.insert(APIPermission::kSystemMemory);
    685   skip.insert(APIPermission::kSystemNetwork);
    686   skip.insert(APIPermission::kSystemStorage);
    687   skip.insert(APIPermission::kTts);
    688   skip.insert(APIPermission::kUnlimitedStorage);
    689   skip.insert(APIPermission::kWebView);
    690   skip.insert(APIPermission::kOverrideEscFullscreen);
    691 
    692   // TODO(erikkay) add a string for this permission.
    693   skip.insert(APIPermission::kBackground);
    694 
    695   skip.insert(APIPermission::kClipboardWrite);
    696 
    697   // The cookie permission does nothing unless you have associated host
    698   // permissions.
    699   skip.insert(APIPermission::kCookie);
    700 
    701   // These are warned as part of host permission checks.
    702   skip.insert(APIPermission::kDeclarativeContent);
    703   skip.insert(APIPermission::kPageCapture);
    704   skip.insert(APIPermission::kProxy);
    705   skip.insert(APIPermission::kTabCapture);
    706   skip.insert(APIPermission::kWebRequest);
    707   skip.insert(APIPermission::kWebRequestBlocking);
    708 
    709   // This permission requires explicit user action (context menu handler)
    710   // so we won't prompt for it for now.
    711   skip.insert(APIPermission::kFileBrowserHandler);
    712 
    713   // These permissions require explicit user action (configuration dialog)
    714   // so we don't prompt for them at install time.
    715   skip.insert(APIPermission::kMediaGalleries);
    716 
    717   // If you've turned on the experimental command-line flag, we don't need
    718   // to warn you further.
    719   skip.insert(APIPermission::kExperimental);
    720 
    721   // The Identity API has its own server-driven permission prompts.
    722   skip.insert(APIPermission::kIdentity);
    723 
    724   // These are private.
    725   skip.insert(APIPermission::kAutoTestPrivate);
    726   skip.insert(APIPermission::kBookmarkManagerPrivate);
    727   skip.insert(APIPermission::kBrailleDisplayPrivate);
    728   skip.insert(APIPermission::kCast);
    729   skip.insert(APIPermission::kCastStreaming);
    730   skip.insert(APIPermission::kChromeosInfoPrivate);
    731   skip.insert(APIPermission::kCloudPrintPrivate);
    732   skip.insert(APIPermission::kCommandLinePrivate);
    733   skip.insert(APIPermission::kDeveloperPrivate);
    734   skip.insert(APIPermission::kDial);
    735   skip.insert(APIPermission::kDownloadsInternal);
    736   skip.insert(APIPermission::kEchoPrivate);
    737   skip.insert(APIPermission::kEnterprisePlatformKeysPrivate);
    738   skip.insert(APIPermission::kFeedbackPrivate);
    739   skip.insert(APIPermission::kFileBrowserHandlerInternal);
    740   skip.insert(APIPermission::kFileBrowserPrivate);
    741   skip.insert(APIPermission::kFirstRunPrivate);
    742   skip.insert(APIPermission::kIdentityPrivate);
    743   skip.insert(APIPermission::kInfobars);
    744   skip.insert(APIPermission::kInputMethodPrivate);
    745   skip.insert(APIPermission::kMediaGalleriesPrivate);
    746   skip.insert(APIPermission::kMediaPlayerPrivate);
    747   skip.insert(APIPermission::kMetricsPrivate);
    748   skip.insert(APIPermission::kMDns);
    749   skip.insert(APIPermission::kPreferencesPrivate);
    750   skip.insert(APIPermission::kPrincipalsPrivate);
    751   skip.insert(APIPermission::kImageWriterPrivate);
    752   skip.insert(APIPermission::kRtcPrivate);
    753   skip.insert(APIPermission::kStreamsPrivate);
    754   skip.insert(APIPermission::kSystemPrivate);
    755   skip.insert(APIPermission::kTabCaptureForTab);
    756   skip.insert(APIPermission::kTerminalPrivate);
    757   skip.insert(APIPermission::kVirtualKeyboardPrivate);
    758   skip.insert(APIPermission::kWallpaperPrivate);
    759   skip.insert(APIPermission::kWebRequestInternal);
    760   skip.insert(APIPermission::kWebrtcAudioPrivate);
    761   skip.insert(APIPermission::kWebrtcLoggingPrivate);
    762   skip.insert(APIPermission::kWebstorePrivate);
    763 
    764   // Warned as part of host permissions.
    765   skip.insert(APIPermission::kDevtools);
    766 
    767   // Platform apps.
    768   skip.insert(APIPermission::kBluetooth);
    769   skip.insert(APIPermission::kFileSystem);
    770   skip.insert(APIPermission::kFileSystemProvider);
    771   skip.insert(APIPermission::kFileSystemRetainEntries);
    772   skip.insert(APIPermission::kSocket);
    773   skip.insert(APIPermission::kUsbDevice);
    774 
    775   PermissionsInfo* info = PermissionsInfo::GetInstance();
    776   APIPermissionSet permissions = info->GetAll();
    777   for (APIPermissionSet::const_iterator i = permissions.begin();
    778        i != permissions.end(); ++i) {
    779     const APIPermissionInfo* permission_info = i->info();
    780     EXPECT_TRUE(permission_info != NULL);
    781 
    782     if (skip.count(i->id())) {
    783       EXPECT_EQ(PermissionMessage::kNone, permission_info->message_id())
    784           << "unexpected message_id for " << permission_info->name();
    785     } else {
    786       EXPECT_NE(PermissionMessage::kNone, permission_info->message_id())
    787           << "missing message_id for " << permission_info->name();
    788     }
    789   }
    790 }
    791 
    792 TEST(PermissionsTest, FileSystemPermissionMessages) {
    793   APIPermissionSet api_permissions;
    794   api_permissions.insert(APIPermission::kFileSystemWrite);
    795   api_permissions.insert(APIPermission::kFileSystemDirectory);
    796   scoped_refptr<PermissionSet> permissions(
    797       new PermissionSet(api_permissions, ManifestPermissionSet(),
    798                         URLPatternSet(), URLPatternSet()));
    799   PermissionMessages messages =
    800       PermissionMessageProvider::Get()->GetPermissionMessages(
    801           permissions, Manifest::TYPE_PLATFORM_APP);
    802   ASSERT_EQ(2u, messages.size());
    803   std::sort(messages.begin(), messages.end());
    804   std::set<PermissionMessage::ID> ids;
    805   for (PermissionMessages::const_iterator it = messages.begin();
    806        it != messages.end(); ++it) {
    807     ids.insert(it->id());
    808   }
    809   EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemDirectory));
    810   EXPECT_TRUE(ContainsKey(ids, PermissionMessage::kFileSystemWrite));
    811 }
    812 
    813 TEST(PermissionsTest, HiddenFileSystemPermissionMessages) {
    814   APIPermissionSet api_permissions;
    815   api_permissions.insert(APIPermission::kFileSystemWrite);
    816   api_permissions.insert(APIPermission::kFileSystemDirectory);
    817   api_permissions.insert(APIPermission::kFileSystemWriteDirectory);
    818   scoped_refptr<PermissionSet> permissions(
    819       new PermissionSet(api_permissions, ManifestPermissionSet(),
    820                         URLPatternSet(), URLPatternSet()));
    821   PermissionMessages messages =
    822       PermissionMessageProvider::Get()->GetPermissionMessages(
    823           permissions, Manifest::TYPE_PLATFORM_APP);
    824   ASSERT_EQ(1u, messages.size());
    825   EXPECT_EQ(PermissionMessage::kFileSystemWriteDirectory, messages[0].id());
    826 }
    827 
    828 TEST(PermissionsTest, MergedFileSystemPermissionComparison) {
    829   APIPermissionSet write_api_permissions;
    830   write_api_permissions.insert(APIPermission::kFileSystemWrite);
    831   scoped_refptr<PermissionSet> write_permissions(
    832       new PermissionSet(write_api_permissions, ManifestPermissionSet(),
    833                         URLPatternSet(), URLPatternSet()));
    834 
    835   APIPermissionSet directory_api_permissions;
    836   directory_api_permissions.insert(APIPermission::kFileSystemDirectory);
    837   scoped_refptr<PermissionSet> directory_permissions(
    838       new PermissionSet(directory_api_permissions, ManifestPermissionSet(),
    839                         URLPatternSet(), URLPatternSet()));
    840 
    841   APIPermissionSet write_directory_api_permissions;
    842   write_directory_api_permissions.insert(
    843       APIPermission::kFileSystemWriteDirectory);
    844   scoped_refptr<PermissionSet> write_directory_permissions(
    845       new PermissionSet(write_directory_api_permissions,
    846                         ManifestPermissionSet(),
    847                         URLPatternSet(),
    848                         URLPatternSet()));
    849 
    850   const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
    851   EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions,
    852                                              write_permissions,
    853                                              Manifest::TYPE_PLATFORM_APP));
    854   EXPECT_FALSE(provider->IsPrivilegeIncrease(write_directory_permissions,
    855                                              directory_permissions,
    856                                              Manifest::TYPE_PLATFORM_APP));
    857   EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions,
    858                                             directory_permissions,
    859                                             Manifest::TYPE_PLATFORM_APP));
    860   EXPECT_TRUE(provider->IsPrivilegeIncrease(write_permissions,
    861                                             write_directory_permissions,
    862                                             Manifest::TYPE_PLATFORM_APP));
    863   EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions,
    864                                             write_permissions,
    865                                             Manifest::TYPE_PLATFORM_APP));
    866   EXPECT_TRUE(provider->IsPrivilegeIncrease(directory_permissions,
    867                                             write_directory_permissions,
    868                                             Manifest::TYPE_PLATFORM_APP));
    869 }
    870 
    871 TEST(PermissionsTest, GetWarningMessages_ManyHosts) {
    872   scoped_refptr<Extension> extension;
    873 
    874   extension = LoadManifest("permissions", "many-hosts.json");
    875   std::vector<base::string16> warnings =
    876       PermissionsData::GetPermissionMessageStrings(extension.get());
    877   ASSERT_EQ(1u, warnings.size());
    878   EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
    879             UTF16ToUTF8(warnings[0]));
    880 }
    881 
    882 TEST(PermissionsTest, GetWarningMessages_Plugins) {
    883   scoped_refptr<Extension> extension;
    884   scoped_refptr<PermissionSet> permissions;
    885 
    886   extension = LoadManifest("permissions", "plugins.json");
    887   std::vector<base::string16> warnings =
    888       PermissionsData::GetPermissionMessageStrings(extension.get());
    889 // We don't parse the plugins key on Chrome OS, so it should not ask for any
    890   // permissions.
    891 #if defined(OS_CHROMEOS)
    892   ASSERT_EQ(0u, warnings.size());
    893 #else
    894   ASSERT_EQ(1u, warnings.size());
    895   EXPECT_EQ("Access all data on your computer and the websites you visit",
    896             UTF16ToUTF8(warnings[0]));
    897 #endif
    898 }
    899 
    900 TEST(PermissionsTest, GetWarningMessages_AudioVideo) {
    901   // Both audio and video present.
    902   scoped_refptr<Extension> extension =
    903       LoadManifest("permissions", "audio-video.json");
    904   const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
    905   PermissionSet* set =
    906       const_cast<PermissionSet*>(
    907           extension->GetActivePermissions().get());
    908   std::vector<base::string16> warnings =
    909       provider->GetWarningMessages(set, extension->GetType());
    910   EXPECT_FALSE(Contains(warnings, "Use your microphone"));
    911   EXPECT_FALSE(Contains(warnings, "Use your camera"));
    912   EXPECT_TRUE(Contains(warnings, "Use your microphone and camera"));
    913   size_t combined_index = IndexOf(warnings, "Use your microphone and camera");
    914   size_t combined_size = warnings.size();
    915 
    916   // Just audio present.
    917   set->apis_.erase(APIPermission::kVideoCapture);
    918   warnings = provider->GetWarningMessages(set, extension->GetType());
    919   EXPECT_EQ(combined_size, warnings.size());
    920   EXPECT_EQ(combined_index, IndexOf(warnings, "Use your microphone"));
    921   EXPECT_FALSE(Contains(warnings, "Use your camera"));
    922   EXPECT_FALSE(Contains(warnings, "Use your microphone and camera"));
    923 
    924   // Just video present.
    925   set->apis_.erase(APIPermission::kAudioCapture);
    926   set->apis_.insert(APIPermission::kVideoCapture);
    927   warnings = provider->GetWarningMessages(set, extension->GetType());
    928   EXPECT_EQ(combined_size, warnings.size());
    929   EXPECT_FALSE(Contains(warnings, "Use your microphone"));
    930   EXPECT_FALSE(Contains(warnings, "Use your microphone and camera"));
    931   EXPECT_TRUE(Contains(warnings, "Use your camera"));
    932 }
    933 
    934 TEST(PermissionsTest, GetWarningMessages_DeclarativeWebRequest) {
    935   // Test that if the declarativeWebRequest permission is present
    936   // in combination with all hosts permission, then only the warning
    937   // for host permissions is shown, because that covers the use of
    938   // declarativeWebRequest.
    939 
    940   // Until Declarative Web Request is in stable, let's make sure it is enabled
    941   // on the current channel.
    942   ScopedCurrentChannel sc(chrome::VersionInfo::CHANNEL_CANARY);
    943 
    944   // First verify that declarativeWebRequest produces a message when host
    945   // permissions do not cover all hosts.
    946   scoped_refptr<Extension> extension =
    947       LoadManifest("permissions", "web_request_com_host_permissions.json");
    948   const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
    949   const PermissionSet* set = extension->GetActivePermissions().get();
    950   std::vector<base::string16> warnings =
    951       provider->GetWarningMessages(set, extension->GetType());
    952   EXPECT_TRUE(Contains(warnings, "Block parts of web pages"));
    953   EXPECT_FALSE(Contains(warnings, "Access your data on all websites"));
    954 
    955   // Now verify that declarativeWebRequest does not produce a message when host
    956   // permissions do cover all hosts.
    957   extension =
    958       LoadManifest("permissions", "web_request_all_host_permissions.json");
    959   set = extension->GetActivePermissions().get();
    960   warnings = provider->GetWarningMessages(set, extension->GetType());
    961   EXPECT_FALSE(Contains(warnings, "Block parts of web pages"));
    962   EXPECT_TRUE(Contains(warnings, "Access your data on all websites"));
    963 }
    964 
    965 TEST(PermissionsTest, GetWarningMessages_Serial) {
    966   scoped_refptr<Extension> extension =
    967       LoadManifest("permissions", "serial.json");
    968 
    969   EXPECT_TRUE(extension->is_platform_app());
    970   EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSerial));
    971   std::vector<base::string16> warnings =
    972       PermissionsData::GetPermissionMessageStrings(extension.get());
    973   EXPECT_TRUE(
    974       Contains(warnings, "Use serial devices attached to your computer"));
    975   ASSERT_EQ(1u, warnings.size());
    976 }
    977 
    978 TEST(PermissionsTest, GetWarningMessages_Socket_AnyHost) {
    979   ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
    980 
    981   scoped_refptr<Extension> extension =
    982       LoadManifest("permissions", "socket_any_host.json");
    983   EXPECT_TRUE(extension->is_platform_app());
    984   EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
    985   std::vector<base::string16> warnings =
    986       PermissionsData::GetPermissionMessageStrings(extension.get());
    987   EXPECT_EQ(1u, warnings.size());
    988   EXPECT_TRUE(Contains(warnings, "Exchange data with any computer "
    989                                  "on the local network or internet"));
    990 }
    991 
    992 TEST(PermissionsTest, GetWarningMessages_Socket_OneDomainTwoHostnames) {
    993   ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
    994 
    995   scoped_refptr<Extension> extension =
    996       LoadManifest("permissions", "socket_one_domain_two_hostnames.json");
    997   EXPECT_TRUE(extension->is_platform_app());
    998   EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
    999   std::vector<base::string16> warnings =
   1000       PermissionsData::GetPermissionMessageStrings(extension.get());
   1001 
   1002   // Verify the warnings, including support for unicode characters, the fact
   1003   // that domain host warnings come before specific host warnings, and the fact
   1004   // that domains and hostnames are in alphabetical order regardless of the
   1005   // order in the manifest file.
   1006   EXPECT_EQ(2u, warnings.size());
   1007   if (warnings.size() > 0)
   1008     EXPECT_EQ(warnings[0],
   1009               UTF8ToUTF16("Exchange data with any computer in the domain "
   1010                           "example.org"));
   1011   if (warnings.size() > 1)
   1012     EXPECT_EQ(warnings[1],
   1013               UTF8ToUTF16("Exchange data with the computers named: "
   1014                           "b\xC3\xA5r.example.com foo.example.com"));
   1015                           // "\xC3\xA5" = UTF-8 for lowercase A with ring above
   1016 }
   1017 
   1018 TEST(PermissionsTest, GetWarningMessages_Socket_TwoDomainsOneHostname) {
   1019   ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
   1020 
   1021   scoped_refptr<Extension> extension =
   1022       LoadManifest("permissions", "socket_two_domains_one_hostname.json");
   1023   EXPECT_TRUE(extension->is_platform_app());
   1024   EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSocket));
   1025   std::vector<base::string16> warnings =
   1026       PermissionsData::GetPermissionMessageStrings(extension.get());
   1027 
   1028   // Verify the warnings, including the fact that domain host warnings come
   1029   // before specific host warnings and the fact that domains and hostnames are
   1030   // in alphabetical order regardless of the order in the manifest file.
   1031   EXPECT_EQ(2u, warnings.size());
   1032   if (warnings.size() > 0)
   1033     EXPECT_EQ(warnings[0],
   1034               UTF8ToUTF16("Exchange data with any computer in the domains: "
   1035                            "example.com foo.example.org"));
   1036   if (warnings.size() > 1)
   1037     EXPECT_EQ(warnings[1],
   1038               UTF8ToUTF16("Exchange data with the computer named "
   1039                            "bar.example.org"));
   1040 }
   1041 
   1042 TEST(PermissionsTest, GetWarningMessages_PlatformApppHosts) {
   1043   scoped_refptr<Extension> extension;
   1044 
   1045   extension = LoadManifest("permissions", "platform_app_hosts.json");
   1046   EXPECT_TRUE(extension->is_platform_app());
   1047   std::vector<base::string16> warnings =
   1048       PermissionsData::GetPermissionMessageStrings(extension.get());
   1049   ASSERT_EQ(0u, warnings.size());
   1050 
   1051   extension = LoadManifest("permissions", "platform_app_all_urls.json");
   1052   EXPECT_TRUE(extension->is_platform_app());
   1053   warnings = PermissionsData::GetPermissionMessageStrings(extension.get());
   1054   ASSERT_EQ(0u, warnings.size());
   1055 }
   1056 
   1057 TEST(PermissionsTest, GetDistinctHosts) {
   1058   URLPatternSet explicit_hosts;
   1059   std::set<std::string> expected;
   1060   expected.insert("www.foo.com");
   1061   expected.insert("www.bar.com");
   1062   expected.insert("www.baz.com");
   1063 
   1064   {
   1065     SCOPED_TRACE("no dupes");
   1066 
   1067     // Simple list with no dupes.
   1068     explicit_hosts.AddPattern(
   1069         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
   1070     explicit_hosts.AddPattern(
   1071         URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/path"));
   1072     explicit_hosts.AddPattern(
   1073         URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
   1074     EXPECT_EQ(expected,
   1075               permission_message_util::GetDistinctHosts(
   1076                   explicit_hosts, true, true));
   1077   }
   1078 
   1079   {
   1080     SCOPED_TRACE("two dupes");
   1081 
   1082     // Add some dupes.
   1083     explicit_hosts.AddPattern(
   1084         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
   1085     explicit_hosts.AddPattern(
   1086         URLPattern(URLPattern::SCHEME_HTTP, "http://www.baz.com/path"));
   1087     EXPECT_EQ(expected,
   1088               permission_message_util::GetDistinctHosts(
   1089                   explicit_hosts, true, true));
   1090   }
   1091 
   1092   {
   1093     SCOPED_TRACE("schemes differ");
   1094 
   1095     // Add a pattern that differs only by scheme. This should be filtered out.
   1096     explicit_hosts.AddPattern(
   1097         URLPattern(URLPattern::SCHEME_HTTPS, "https://www.bar.com/path"));
   1098     EXPECT_EQ(expected,
   1099               permission_message_util::GetDistinctHosts(
   1100                   explicit_hosts, true, true));
   1101   }
   1102 
   1103   {
   1104     SCOPED_TRACE("paths differ");
   1105 
   1106     // Add some dupes by path.
   1107     explicit_hosts.AddPattern(
   1108         URLPattern(URLPattern::SCHEME_HTTP, "http://www.bar.com/pathypath"));
   1109     EXPECT_EQ(expected,
   1110               permission_message_util::GetDistinctHosts(
   1111                   explicit_hosts, true, true));
   1112   }
   1113 
   1114   {
   1115     SCOPED_TRACE("subdomains differ");
   1116 
   1117     // We don't do anything special for subdomains.
   1118     explicit_hosts.AddPattern(
   1119         URLPattern(URLPattern::SCHEME_HTTP, "http://monkey.www.bar.com/path"));
   1120     explicit_hosts.AddPattern(
   1121         URLPattern(URLPattern::SCHEME_HTTP, "http://bar.com/path"));
   1122 
   1123     expected.insert("monkey.www.bar.com");
   1124     expected.insert("bar.com");
   1125 
   1126     EXPECT_EQ(expected,
   1127               permission_message_util::GetDistinctHosts(
   1128                   explicit_hosts, true, true));
   1129   }
   1130 
   1131   {
   1132     SCOPED_TRACE("RCDs differ");
   1133 
   1134     // Now test for RCD uniquing.
   1135     explicit_hosts.AddPattern(
   1136         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
   1137     explicit_hosts.AddPattern(
   1138         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
   1139     explicit_hosts.AddPattern(
   1140         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.de/path"));
   1141     explicit_hosts.AddPattern(
   1142         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca.us/path"));
   1143     explicit_hosts.AddPattern(
   1144         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
   1145     explicit_hosts.AddPattern(
   1146         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com.my/path"));
   1147 
   1148     // This is an unknown RCD, which shouldn't be uniqued out.
   1149     explicit_hosts.AddPattern(
   1150         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
   1151     // But it should only occur once.
   1152     explicit_hosts.AddPattern(
   1153         URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.xyzzy/path"));
   1154 
   1155     expected.insert("www.foo.xyzzy");
   1156 
   1157     EXPECT_EQ(expected,
   1158               permission_message_util::GetDistinctHosts(
   1159                   explicit_hosts, true, true));
   1160   }
   1161 
   1162   {
   1163     SCOPED_TRACE("wildcards");
   1164 
   1165     explicit_hosts.AddPattern(
   1166         URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
   1167 
   1168     expected.insert("*.google.com");
   1169 
   1170     EXPECT_EQ(expected,
   1171               permission_message_util::GetDistinctHosts(
   1172                   explicit_hosts, true, true));
   1173   }
   1174 
   1175   {
   1176     SCOPED_TRACE("scriptable hosts");
   1177 
   1178     APIPermissionSet empty_perms;
   1179     explicit_hosts.ClearPatterns();
   1180     URLPatternSet scriptable_hosts;
   1181     expected.clear();
   1182 
   1183     explicit_hosts.AddPattern(
   1184         URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com/*"));
   1185     scriptable_hosts.AddPattern(
   1186         URLPattern(URLPattern::SCHEME_HTTP, "http://*.example.com/*"));
   1187 
   1188     expected.insert("*.google.com");
   1189     expected.insert("*.example.com");
   1190 
   1191     scoped_refptr<PermissionSet> perm_set(new PermissionSet(
   1192         empty_perms, ManifestPermissionSet(),
   1193         explicit_hosts, scriptable_hosts));
   1194     EXPECT_EQ(expected,
   1195               permission_message_util::GetDistinctHosts(
   1196                   perm_set->effective_hosts(), true, true));
   1197   }
   1198 
   1199   {
   1200     // We don't display warnings for file URLs because they are off by default.
   1201     SCOPED_TRACE("file urls");
   1202 
   1203     explicit_hosts.ClearPatterns();
   1204     expected.clear();
   1205 
   1206     explicit_hosts.AddPattern(
   1207         URLPattern(URLPattern::SCHEME_FILE, "file:///*"));
   1208 
   1209     EXPECT_EQ(expected,
   1210               permission_message_util::GetDistinctHosts(
   1211                   explicit_hosts, true, true));
   1212   }
   1213 }
   1214 
   1215 TEST(PermissionsTest, GetDistinctHosts_ComIsBestRcd) {
   1216   URLPatternSet explicit_hosts;
   1217   explicit_hosts.AddPattern(
   1218       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
   1219   explicit_hosts.AddPattern(
   1220       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
   1221   explicit_hosts.AddPattern(
   1222       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
   1223   explicit_hosts.AddPattern(
   1224       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
   1225   explicit_hosts.AddPattern(
   1226       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
   1227   explicit_hosts.AddPattern(
   1228       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.com/path"));
   1229 
   1230   std::set<std::string> expected;
   1231   expected.insert("www.foo.com");
   1232   EXPECT_EQ(expected,
   1233             permission_message_util::GetDistinctHosts(
   1234                 explicit_hosts, true, true));
   1235 }
   1236 
   1237 TEST(PermissionsTest, GetDistinctHosts_NetIs2ndBestRcd) {
   1238   URLPatternSet explicit_hosts;
   1239   explicit_hosts.AddPattern(
   1240       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
   1241   explicit_hosts.AddPattern(
   1242       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
   1243   explicit_hosts.AddPattern(
   1244       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
   1245   explicit_hosts.AddPattern(
   1246       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.net/path"));
   1247   explicit_hosts.AddPattern(
   1248       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
   1249   // No http://www.foo.com/path
   1250 
   1251   std::set<std::string> expected;
   1252   expected.insert("www.foo.net");
   1253   EXPECT_EQ(expected,
   1254             permission_message_util::GetDistinctHosts(
   1255                 explicit_hosts, true, true));
   1256 }
   1257 
   1258 TEST(PermissionsTest, GetDistinctHosts_OrgIs3rdBestRcd) {
   1259   URLPatternSet explicit_hosts;
   1260   explicit_hosts.AddPattern(
   1261       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
   1262   explicit_hosts.AddPattern(
   1263       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.org/path"));
   1264   explicit_hosts.AddPattern(
   1265       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
   1266   // No http://www.foo.net/path
   1267   explicit_hosts.AddPattern(
   1268       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
   1269   // No http://www.foo.com/path
   1270 
   1271   std::set<std::string> expected;
   1272   expected.insert("www.foo.org");
   1273   EXPECT_EQ(expected,
   1274             permission_message_util::GetDistinctHosts(
   1275                 explicit_hosts, true, true));
   1276 }
   1277 
   1278 TEST(PermissionsTest, GetDistinctHosts_FirstInListIs4thBestRcd) {
   1279   URLPatternSet explicit_hosts;
   1280   explicit_hosts.AddPattern(
   1281       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.ca/path"));
   1282   // No http://www.foo.org/path
   1283   explicit_hosts.AddPattern(
   1284       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.co.uk/path"));
   1285   // No http://www.foo.net/path
   1286   explicit_hosts.AddPattern(
   1287       URLPattern(URLPattern::SCHEME_HTTP, "http://www.foo.jp/path"));
   1288   // No http://www.foo.com/path
   1289 
   1290   std::set<std::string> expected;
   1291   expected.insert("www.foo.ca");
   1292   EXPECT_EQ(expected,
   1293             permission_message_util::GetDistinctHosts(
   1294                 explicit_hosts, true, true));
   1295 }
   1296 
   1297 TEST(PermissionsTest, IsHostPrivilegeIncrease) {
   1298   Manifest::Type type = Manifest::TYPE_EXTENSION;
   1299   const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
   1300   ManifestPermissionSet empty_manifest_permissions;
   1301   URLPatternSet elist1;
   1302   URLPatternSet elist2;
   1303   URLPatternSet slist1;
   1304   URLPatternSet slist2;
   1305   scoped_refptr<PermissionSet> set1;
   1306   scoped_refptr<PermissionSet> set2;
   1307   APIPermissionSet empty_perms;
   1308   elist1.AddPattern(
   1309       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
   1310   elist1.AddPattern(
   1311       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
   1312 
   1313   // Test that the host order does not matter.
   1314   elist2.AddPattern(
   1315       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
   1316   elist2.AddPattern(
   1317       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/path"));
   1318 
   1319   set1 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1320                            elist1, slist1);
   1321   set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1322                            elist2, slist2);
   1323 
   1324   EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
   1325   EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
   1326 
   1327   // Test that paths are ignored.
   1328   elist2.ClearPatterns();
   1329   elist2.AddPattern(
   1330       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/*"));
   1331   set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1332                            elist2, slist2);
   1333   EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
   1334   EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
   1335 
   1336   // Test that RCDs are ignored.
   1337   elist2.ClearPatterns();
   1338   elist2.AddPattern(
   1339       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com.hk/*"));
   1340   set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1341                            elist2, slist2);
   1342   EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
   1343   EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
   1344 
   1345   // Test that subdomain wildcards are handled properly.
   1346   elist2.ClearPatterns();
   1347   elist2.AddPattern(
   1348       URLPattern(URLPattern::SCHEME_HTTP, "http://*.google.com.hk/*"));
   1349   set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1350                            elist2, slist2);
   1351   EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type));
   1352   // TODO(jstritar): Does not match subdomains properly. http://crbug.com/65337
   1353   // EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
   1354 
   1355   // Test that different domains count as different hosts.
   1356   elist2.ClearPatterns();
   1357   elist2.AddPattern(
   1358       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/path"));
   1359   elist2.AddPattern(
   1360       URLPattern(URLPattern::SCHEME_HTTP, "http://www.example.org/path"));
   1361   set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1362                            elist2, slist2);
   1363   EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type));
   1364   EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
   1365 
   1366   // Test that different subdomains count as different hosts.
   1367   elist2.ClearPatterns();
   1368   elist2.AddPattern(
   1369       URLPattern(URLPattern::SCHEME_HTTP, "http://mail.google.com/*"));
   1370   set2 = new PermissionSet(empty_perms, empty_manifest_permissions,
   1371                            elist2, slist2);
   1372   EXPECT_TRUE(provider->IsPrivilegeIncrease(set1, set2, type));
   1373   EXPECT_TRUE(provider->IsPrivilegeIncrease(set2, set1, type));
   1374 
   1375   // Test that platform apps do not have host permissions increases.
   1376   type = Manifest::TYPE_PLATFORM_APP;
   1377   EXPECT_FALSE(provider->IsPrivilegeIncrease(set1, set2, type));
   1378   EXPECT_FALSE(provider->IsPrivilegeIncrease(set2, set1, type));
   1379 }
   1380 
   1381 TEST(PermissionsTest, GetAPIsAsStrings) {
   1382   APIPermissionSet apis;
   1383   URLPatternSet empty_set;
   1384 
   1385   apis.insert(APIPermission::kProxy);
   1386   apis.insert(APIPermission::kBackground);
   1387   apis.insert(APIPermission::kNotification);
   1388   apis.insert(APIPermission::kTab);
   1389 
   1390   scoped_refptr<PermissionSet> perm_set = new PermissionSet(
   1391       apis, ManifestPermissionSet(), empty_set, empty_set);
   1392   std::set<std::string> api_names = perm_set->GetAPIsAsStrings();
   1393 
   1394   // The result is correct if it has the same number of elements
   1395   // and we can convert it back to the id set.
   1396   EXPECT_EQ(4u, api_names.size());
   1397   EXPECT_EQ(apis,
   1398             PermissionsInfo::GetInstance()->GetAllByName(api_names));
   1399 }
   1400 
   1401 TEST(PermissionsTest, IsEmpty) {
   1402   APIPermissionSet empty_apis;
   1403   URLPatternSet empty_extent;
   1404 
   1405   scoped_refptr<PermissionSet> empty = new PermissionSet();
   1406   EXPECT_TRUE(empty->IsEmpty());
   1407   scoped_refptr<PermissionSet> perm_set;
   1408 
   1409   perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
   1410                                empty_extent, empty_extent);
   1411   EXPECT_TRUE(perm_set->IsEmpty());
   1412 
   1413   APIPermissionSet non_empty_apis;
   1414   non_empty_apis.insert(APIPermission::kBackground);
   1415   perm_set = new PermissionSet(non_empty_apis, ManifestPermissionSet(),
   1416                                empty_extent, empty_extent);
   1417   EXPECT_FALSE(perm_set->IsEmpty());
   1418 
   1419   // Try non standard host
   1420   URLPatternSet non_empty_extent;
   1421   AddPattern(&non_empty_extent, "http://www.google.com/*");
   1422 
   1423   perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
   1424                                non_empty_extent, empty_extent);
   1425   EXPECT_FALSE(perm_set->IsEmpty());
   1426 
   1427   perm_set = new PermissionSet(empty_apis, ManifestPermissionSet(),
   1428                                empty_extent, non_empty_extent);
   1429   EXPECT_FALSE(perm_set->IsEmpty());
   1430 }
   1431 
   1432 TEST(PermissionsTest, ImpliedPermissions) {
   1433   URLPatternSet empty_extent;
   1434   APIPermissionSet apis;
   1435   apis.insert(APIPermission::kWebRequest);
   1436   apis.insert(APIPermission::kFileBrowserHandler);
   1437   EXPECT_EQ(2U, apis.size());
   1438 
   1439   scoped_refptr<PermissionSet> perm_set;
   1440   perm_set = new PermissionSet(apis, ManifestPermissionSet(),
   1441                                empty_extent, empty_extent);
   1442   EXPECT_EQ(4U, perm_set->apis().size());
   1443 }
   1444 
   1445 TEST(PermissionsTest, SyncFileSystemPermission) {
   1446   scoped_refptr<Extension> extension = LoadManifest(
   1447       "permissions", "sync_file_system.json");
   1448   APIPermissionSet apis;
   1449   apis.insert(APIPermission::kSyncFileSystem);
   1450   EXPECT_TRUE(extension->is_platform_app());
   1451   EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kSyncFileSystem));
   1452   std::vector<base::string16> warnings =
   1453       PermissionsData::GetPermissionMessageStrings(extension.get());
   1454   EXPECT_TRUE(Contains(warnings, "Store data in your Google Drive account"));
   1455   ASSERT_EQ(1u, warnings.size());
   1456 }
   1457 
   1458 // Make sure that we don't crash when we're trying to show the permissions
   1459 // even though chrome://thumb (and everything that's not chrome://favicon with
   1460 // a chrome:// scheme) is not a valid permission.
   1461 // More details here: crbug/246314.
   1462 TEST(PermissionsTest, ChromeURLs) {
   1463   URLPatternSet allowed_hosts;
   1464   allowed_hosts.AddPattern(
   1465       URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/"));
   1466   allowed_hosts.AddPattern(
   1467       URLPattern(URLPattern::SCHEME_ALL, "chrome://favicon/"));
   1468   allowed_hosts.AddPattern(
   1469       URLPattern(URLPattern::SCHEME_ALL, "chrome://thumb/"));
   1470   scoped_refptr<PermissionSet> permissions(
   1471       new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
   1472                         allowed_hosts, URLPatternSet()));
   1473   PermissionMessageProvider::Get()->
   1474       GetPermissionMessages(permissions, Manifest::TYPE_EXTENSION);
   1475 }
   1476 
   1477 TEST(PermissionsTest, IsPrivilegeIncrease_DeclarativeWebRequest) {
   1478   scoped_refptr<Extension> extension(
   1479       LoadManifest("permissions", "permissions_all_urls.json"));
   1480   scoped_refptr<const PermissionSet> permissions(
   1481       extension->GetActivePermissions());
   1482 
   1483   scoped_refptr<Extension> extension_dwr(
   1484       LoadManifest("permissions", "web_request_all_host_permissions.json"));
   1485   scoped_refptr<const PermissionSet> permissions_dwr(
   1486       extension_dwr->GetActivePermissions());
   1487 
   1488   EXPECT_FALSE(PermissionMessageProvider::Get()->
   1489                    IsPrivilegeIncrease(permissions.get(),
   1490                                        permissions_dwr.get(),
   1491                                        extension->GetType()));
   1492 }
   1493 
   1494 }  // namespace extensions
   1495