15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h" 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/common/update_manifest.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml/globals.h" 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kValidXml = 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' prodversionmin='2.0.143.0' />" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *valid_xml_with_hash = 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' prodversionmin='2.0.143.0' " 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" hash='1234'/>" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kMissingAppId = 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app>" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' />" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kInvalidCodebase = 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345' status='ok'>" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='example.com/extension_1.2.3.4.crx'" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' />" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kMissingVersion = 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345' status='ok'>" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' />" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kInvalidVersion = 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345' status='ok'>" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' " 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.a'/>" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kUsesNamespacePrefix = 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<g:gupdate xmlns:g='http://www.google.com/update2/response' protocol='2.0'>" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <g:app appid='12345'>" 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <g:updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' prodversionmin='2.0.143.0' />" 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </g:app>" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</g:gupdate>"; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Includes unrelated <app> tags from other xml namespaces - this should 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not cause problems. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kSimilarTagnames = 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response'" 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" xmlns:a='http://a' protocol='2.0'>" 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <a:app/>" 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <b:app xmlns:b='http://b' />" 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>" 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' prodversionmin='2.0.143.0' />" 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Includes a <daystart> tag. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kWithDaystart = 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <daystart elapsed_seconds='456' />" 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>" 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" version='1.2.3.4' prodversionmin='2.0.143.0' />" 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates no updates available - this should not be a parse error. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kNoUpdate = 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>" 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck status='noupdate' />" 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Includes two <app> tags, one with an error. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kTwoAppsOneError = 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>" 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='aaaaaaaa' status='error-unknownApplication'>" 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck status='error-unknownapplication'/>" 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='bbbbbbbb'>" 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <updatecheck codebase='http://example.com/b_3.1.crx' version='3.1'/>" 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>" 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>"; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExtensionUpdateManifestTest, TestUpdateManifest) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateManifest parser; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test parsing of a number of invalid xml cases 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(parser.Parse(std::string())); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.errors().empty()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kMissingAppId)); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.results().list.empty()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.errors().empty()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kInvalidCodebase)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.results().list.empty()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.errors().empty()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kMissingVersion)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.results().list.empty()); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.errors().empty()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kInvalidVersion)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.results().list.empty()); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.errors().empty()); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse some valid XML, and check that all params came out as expected 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kValidXml)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.errors().empty()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.results().list.empty()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UpdateManifest::Result* firstResult = &parser.results().list.at(0); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(GURL("http://example.com/extension_1.2.3.4.crx"), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstResult->crx_url); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("1.2.3.4", firstResult->version); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("2.0.143.0", firstResult->browser_min_version); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse some xml that uses namespace prefixes. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kUsesNamespacePrefix)); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.errors().empty()); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kSimilarTagnames)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.errors().empty()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlCleanupGlobals(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse xml with hash value 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(valid_xml_with_hash)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.errors().empty()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.results().list.empty()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstResult = &parser.results().list.at(0); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("1234", firstResult->package_hash); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse xml with a <daystart> element. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kWithDaystart)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.errors().empty()); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.results().list.empty()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(parser.results().daystart_elapsed_seconds, 456); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse a no-update response. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kNoUpdate)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.errors().empty()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.results().list.empty()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstResult = &parser.results().list.at(0); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(firstResult->extension_id, "12345"); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(firstResult->version, ""); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse xml with one error and one success <app> tag. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(parser.Parse(kTwoAppsOneError)); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(parser.errors().empty()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, parser.results().list.size()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) firstResult = &parser.results().list.at(0); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(firstResult->extension_id, "bbbbbbbb"); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 188