Home | History | Annotate | Download | only in test
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/scoped_vector.h"
      6 #include "chrome/browser/component_updater/update_response.h"
      7 #include "libxml/globals.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace component_updater {
     11 
     12 const char* kValidXml =
     13     "<?xml version='1.0' encoding='UTF-8'?>"
     14     "<response protocol='3.0'>"
     15     " <app appid='12345'>"
     16     "   <updatecheck status='ok'>"
     17     "     <urls>"
     18     "       <url codebase='http://example.com/'/>"
     19     "       <url codebasediff='http://diff.example.com/'/>"
     20     "     </urls>"
     21     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
     22     "       <packages>"
     23     "         <package name='extension_1_2_3_4.crx'/>"
     24     "       </packages>"
     25     "     </manifest>"
     26     "   </updatecheck>"
     27     " </app>"
     28     "</response>";
     29 
     30 const char* valid_xml_with_hash =
     31     "<?xml version='1.0' encoding='UTF-8'?>"
     32     "<response protocol='3.0'>"
     33     " <app appid='12345'>"
     34     "   <updatecheck status='ok'>"
     35     "     <urls>"
     36     "       <url codebase='http://example.com/'/>"
     37     "     </urls>"
     38     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
     39     "       <packages>"
     40     "         <package name='extension_1_2_3_4.crx' hash_sha256='1234'/>"
     41     "       </packages>"
     42     "     </manifest>"
     43     "   </updatecheck>"
     44     " </app>"
     45     "</response>";
     46 
     47 const char* valid_xml_with_invalid_sizes =
     48     "<?xml version='1.0' encoding='UTF-8'?>"
     49     "<response protocol='3.0'>"
     50     " <app appid='12345'>"
     51     "   <updatecheck status='ok'>"
     52     "     <urls>"
     53     "       <url codebase='http://example.com/'/>"
     54     "     </urls>"
     55     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
     56     "       <packages>"
     57     "         <package name='1' size='1234'/>"
     58     "         <package name='2' size='-1234'/>"
     59     "         <package name='3' />"
     60     "         <package name='4' size='-a'/>"
     61     "         <package name='5' size='-123467890123456789'/>"
     62     "         <package name='6' size='123467890123456789'/>"
     63     "       </packages>"
     64     "     </manifest>"
     65     "   </updatecheck>"
     66     " </app>"
     67     "</response>";
     68 
     69 const char* kInvalidValidXmlMissingCodebase =
     70     "<?xml version='1.0' encoding='UTF-8'?>"
     71     "<response protocol='3.0'>"
     72     " <app appid='12345'>"
     73     "   <updatecheck status='ok'>"
     74     "     <urls>"
     75     "       <url codebasediff='http://diff.example.com/'/>"
     76     "     </urls>"
     77     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
     78     "       <packages>"
     79     "         <package namediff='extension_1_2_3_4.crx'/>"
     80     "       </packages>"
     81     "     </manifest>"
     82     "   </updatecheck>"
     83     " </app>"
     84     "</response>";
     85 
     86 const char* kMissingAppId =
     87     "<?xml version='1.0'?>"
     88     "<response protocol='3.0'>"
     89     " <app>"
     90     "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     91     "               version='1.2.3.4' />"
     92     " </app>"
     93     "</response>";
     94 
     95 const char* kInvalidCodebase =
     96     "<?xml version='1.0'?>"
     97     "<response protocol='3.0'>"
     98     " <app appid='12345' status='ok'>"
     99     "  <updatecheck codebase='example.com/extension_1.2.3.4.crx'"
    100     "               version='1.2.3.4' />"
    101     " </app>"
    102     "</response>";
    103 
    104 const char* kMissingVersion =
    105     "<?xml version='1.0'?>"
    106     "<response protocol='3.0'>"
    107     " <app appid='12345' status='ok'>"
    108     "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' />"
    109     " </app>"
    110     "</response>";
    111 
    112 const char* kInvalidVersion =
    113     "<?xml version='1.0'?>"
    114     "<response protocol='3.0'>"
    115     " <app appid='12345' status='ok'>"
    116     "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' "
    117     "               version='1.2.3.a'/>"
    118     " </app>"
    119     "</response>";
    120 
    121 // The v3 version of the protocol is not using namespaces. However, the parser
    122 // must be able to parse responses that include namespaces.
    123 const char* kUsesNamespacePrefix =
    124     "<?xml version='1.0' encoding='UTF-8'?>"
    125     "<g:response xmlns='http://www.google.com/update2/response' protocol='3.0'>"
    126     " <g:app appid='12345'>"
    127     "   <g:updatecheck status='ok'>"
    128     "     <g:urls>"
    129     "       <g:url codebase='http://example.com/'/>"
    130     "     </g:urls>"
    131     "     <g:manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
    132     "       <g:packages>"
    133     "         <g:package name='extension_1_2_3_4.crx'/>"
    134     "       </g:packages>"
    135     "     </g:manifest>"
    136     "   </g:updatecheck>"
    137     " </g:app>"
    138     "</g:response>";
    139 
    140 // Includes unrelated <app> tags from other xml namespaces - this should
    141 // not cause problems.
    142 const char* kSimilarTagnames =
    143     "<?xml version='1.0' encoding='UTF-8'?>"
    144     "<response xmlns:a='http://a' protocol='3.0'>"
    145     " <a:app appid='12345'>"
    146     "   <updatecheck status='ok'>"
    147     "     <urls>"
    148     "       <url codebase='http://example.com/'/>"
    149     "     </urls>"
    150     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
    151     "       <packages>"
    152     "         <package name='extension_1_2_3_4.crx'/>"
    153     "       </packages>"
    154     "     </manifest>"
    155     "   </updatecheck>"
    156     " </a:app>"
    157     " <b:app appid='xyz' xmlns:b='http://b'>"
    158     "   <updatecheck status='noupdate'/>"
    159     " </b:app>"
    160     "</response>";
    161 
    162 // Includes a <daystart> tag.
    163 const char* kWithDaystart =
    164     "<?xml version='1.0' encoding='UTF-8'?>"
    165     "<response protocol='3.0'>"
    166     " <daystart elapsed_seconds='456' />"
    167     " <app appid='12345'>"
    168     "   <updatecheck status='ok'>"
    169     "     <urls>"
    170     "       <url codebase='http://example.com/'/>"
    171     "     </urls>"
    172     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
    173     "       <packages>"
    174     "         <package name='extension_1_2_3_4.crx'/>"
    175     "       </packages>"
    176     "     </manifest>"
    177     "   </updatecheck>"
    178     " </app>"
    179     "</response>";
    180 
    181 // Indicates no updates available - this should not be a parse error.
    182 const char* kNoUpdate =
    183     "<?xml version='1.0' encoding='UTF-8'?>"
    184     "<response protocol='3.0'>"
    185     " <app appid='12345'>"
    186     "  <updatecheck status='noupdate' />"
    187     " </app>"
    188     "</response>";
    189 
    190 // Includes two <app> tags, one with an error.
    191 const char* kTwoAppsOneError =
    192     "<?xml version='1.0' encoding='UTF-8'?>"
    193     "<response protocol='3.0'>"
    194     " <app appid='aaaaaaaa' status='error-unknownApplication'>"
    195     "  <updatecheck status='error-unknownapplication'/>"
    196     " </app>"
    197     " <app appid='bbbbbbbb'>"
    198     "   <updatecheck status='ok'>"
    199     "     <urls>"
    200     "       <url codebase='http://example.com/'/>"
    201     "     </urls>"
    202     "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
    203     "       <packages>"
    204     "         <package name='extension_1_2_3_4.crx'/>"
    205     "       </packages>"
    206     "     </manifest>"
    207     "   </updatecheck>"
    208     " </app>"
    209     "</response>";
    210 
    211 TEST(ComponentUpdaterUpdateResponseTest, TestParser) {
    212   UpdateResponse parser;
    213 
    214   // Test parsing of a number of invalid xml cases
    215   EXPECT_FALSE(parser.Parse(std::string()));
    216   EXPECT_FALSE(parser.errors().empty());
    217 
    218   EXPECT_TRUE(parser.Parse(kMissingAppId));
    219   EXPECT_TRUE(parser.results().list.empty());
    220   EXPECT_FALSE(parser.errors().empty());
    221 
    222   EXPECT_TRUE(parser.Parse(kInvalidCodebase));
    223   EXPECT_TRUE(parser.results().list.empty());
    224   EXPECT_FALSE(parser.errors().empty());
    225 
    226   EXPECT_TRUE(parser.Parse(kMissingVersion));
    227   EXPECT_TRUE(parser.results().list.empty());
    228   EXPECT_FALSE(parser.errors().empty());
    229 
    230   EXPECT_TRUE(parser.Parse(kInvalidVersion));
    231   EXPECT_TRUE(parser.results().list.empty());
    232   EXPECT_FALSE(parser.errors().empty());
    233 
    234   EXPECT_TRUE(parser.Parse(kInvalidValidXmlMissingCodebase));
    235   EXPECT_TRUE(parser.results().list.empty());
    236   EXPECT_FALSE(parser.errors().empty());
    237 
    238   // Parse some valid XML, and check that all params came out as expected
    239   EXPECT_TRUE(parser.Parse(kValidXml));
    240   EXPECT_TRUE(parser.errors().empty());
    241   EXPECT_EQ(1u, parser.results().list.size());
    242   const UpdateResponse::Result* firstResult = &parser.results().list[0];
    243   EXPECT_EQ(1u, firstResult->crx_urls.size());
    244   EXPECT_EQ(GURL("http://example.com/"), firstResult->crx_urls[0]);
    245   EXPECT_EQ(GURL("http://diff.example.com/"), firstResult->crx_diffurls[0]);
    246   EXPECT_EQ("1.2.3.4", firstResult->manifest.version);
    247   EXPECT_EQ("2.0.143.0", firstResult->manifest.browser_min_version);
    248   EXPECT_EQ(1u, firstResult->manifest.packages.size());
    249   EXPECT_EQ("extension_1_2_3_4.crx", firstResult->manifest.packages[0].name);
    250 
    251   // Parse some xml that uses namespace prefixes.
    252   EXPECT_TRUE(parser.Parse(kUsesNamespacePrefix));
    253   EXPECT_TRUE(parser.errors().empty());
    254   EXPECT_TRUE(parser.Parse(kSimilarTagnames));
    255   EXPECT_TRUE(parser.errors().empty());
    256   xmlCleanupGlobals();
    257 
    258   // Parse xml with hash value
    259   EXPECT_TRUE(parser.Parse(valid_xml_with_hash));
    260   EXPECT_TRUE(parser.errors().empty());
    261   EXPECT_FALSE(parser.results().list.empty());
    262   firstResult = &parser.results().list[0];
    263   EXPECT_FALSE(firstResult->manifest.packages.empty());
    264   EXPECT_EQ("1234", firstResult->manifest.packages[0].hash_sha256);
    265 
    266   // Parse xml with package size value
    267   EXPECT_TRUE(parser.Parse(valid_xml_with_invalid_sizes));
    268   EXPECT_TRUE(parser.errors().empty());
    269   EXPECT_FALSE(parser.results().list.empty());
    270   firstResult = &parser.results().list[0];
    271   EXPECT_FALSE(firstResult->manifest.packages.empty());
    272   EXPECT_EQ(1234, firstResult->manifest.packages[0].size);
    273   EXPECT_EQ(-1234, firstResult->manifest.packages[1].size);
    274   EXPECT_EQ(0, firstResult->manifest.packages[2].size);
    275   EXPECT_EQ(0, firstResult->manifest.packages[3].size);
    276   EXPECT_EQ(0, firstResult->manifest.packages[4].size);
    277   EXPECT_EQ(0, firstResult->manifest.packages[5].size);
    278 
    279   // Parse xml with a <daystart> element.
    280   EXPECT_TRUE(parser.Parse(kWithDaystart));
    281   EXPECT_TRUE(parser.errors().empty());
    282   EXPECT_FALSE(parser.results().list.empty());
    283   EXPECT_EQ(parser.results().daystart_elapsed_seconds, 456);
    284 
    285   // Parse a no-update response.
    286   EXPECT_TRUE(parser.Parse(kNoUpdate));
    287   EXPECT_TRUE(parser.errors().empty());
    288   EXPECT_FALSE(parser.results().list.empty());
    289   firstResult = &parser.results().list[0];
    290   EXPECT_EQ(firstResult->extension_id, "12345");
    291   EXPECT_EQ(firstResult->manifest.version, "");
    292 
    293   // Parse xml with one error and one success <app> tag.
    294   EXPECT_TRUE(parser.Parse(kTwoAppsOneError));
    295   EXPECT_FALSE(parser.errors().empty());
    296   EXPECT_EQ(1u, parser.results().list.size());
    297   firstResult = &parser.results().list[0];
    298   EXPECT_EQ(firstResult->extension_id, "bbbbbbbb");
    299 }
    300 
    301 }  // namespace component_updater
    302