| Index: chrome/common/extensions/update_manifest.cc
|
| diff --git a/chrome/common/extensions/update_manifest.cc b/chrome/common/extensions/update_manifest.cc
|
| deleted file mode 100644
|
| index 0ed653ff76a8e32288b96c9bef31027a41ad2324..0000000000000000000000000000000000000000
|
| --- a/chrome/common/extensions/update_manifest.cc
|
| +++ /dev/null
|
| @@ -1,285 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/common/extensions/update_manifest.h"
|
| -
|
| -#include <algorithm>
|
| -
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/version.h"
|
| -#include "libxml/tree.h"
|
| -#include "third_party/libxml/chromium/libxml_utils.h"
|
| -
|
| -static const char* kExpectedGupdateProtocol = "2.0";
|
| -static const char* kExpectedGupdateXmlns =
|
| - "http://www.google.com/update2/response";
|
| -
|
| -UpdateManifest::Result::Result()
|
| - : size(0),
|
| - diff_size(0) {}
|
| -
|
| -UpdateManifest::Result::~Result() {}
|
| -
|
| -UpdateManifest::Results::Results() : daystart_elapsed_seconds(kNoDaystart) {}
|
| -
|
| -UpdateManifest::Results::~Results() {}
|
| -
|
| -UpdateManifest::UpdateManifest() {
|
| -}
|
| -
|
| -UpdateManifest::~UpdateManifest() {}
|
| -
|
| -void UpdateManifest::ParseError(const char* details, ...) {
|
| - va_list args;
|
| - va_start(args, details);
|
| -
|
| - if (errors_.length() > 0) {
|
| - // TODO(asargent) make a platform abstracted newline?
|
| - errors_ += "\r\n";
|
| - }
|
| - base::StringAppendV(&errors_, details, args);
|
| - va_end(args);
|
| -}
|
| -
|
| -// Checks whether a given node's name matches |expected_name| and
|
| -// |expected_namespace|.
|
| -static bool TagNameEquals(const xmlNode* node, const char* expected_name,
|
| - const xmlNs* expected_namespace) {
|
| - if (node->ns != expected_namespace) {
|
| - return false;
|
| - }
|
| - return 0 == strcmp(expected_name, reinterpret_cast<const char*>(node->name));
|
| -}
|
| -
|
| -// Returns child nodes of |root| with name |name| in namespace |xml_namespace|.
|
| -static std::vector<xmlNode*> GetChildren(xmlNode* root, xmlNs* xml_namespace,
|
| - const char* name) {
|
| - std::vector<xmlNode*> result;
|
| - for (xmlNode* child = root->children; child != NULL; child = child->next) {
|
| - if (!TagNameEquals(child, name, xml_namespace)) {
|
| - continue;
|
| - }
|
| - result.push_back(child);
|
| - }
|
| - return result;
|
| -}
|
| -
|
| -// Returns the value of a named attribute, or the empty string.
|
| -static std::string GetAttribute(xmlNode* node, const char* attribute_name) {
|
| - const xmlChar* name = reinterpret_cast<const xmlChar*>(attribute_name);
|
| - for (xmlAttr* attr = node->properties; attr != NULL; attr = attr->next) {
|
| - if (!xmlStrcmp(attr->name, name) && attr->children &&
|
| - attr->children->content) {
|
| - return std::string(reinterpret_cast<const char*>(
|
| - attr->children->content));
|
| - }
|
| - }
|
| - return std::string();
|
| -}
|
| -
|
| -// This is used for the xml parser to report errors. This assumes the context
|
| -// is a pointer to a std::string where the error message should be appended.
|
| -static void XmlErrorFunc(void *context, const char *message, ...) {
|
| - va_list args;
|
| - va_start(args, message);
|
| - std::string* error = static_cast<std::string*>(context);
|
| - base::StringAppendV(error, message, args);
|
| - va_end(args);
|
| -}
|
| -
|
| -// Utility class for cleaning up the xml document when leaving a scope.
|
| -class ScopedXmlDocument {
|
| - public:
|
| - explicit ScopedXmlDocument(xmlDocPtr document) : document_(document) {}
|
| - ~ScopedXmlDocument() {
|
| - if (document_)
|
| - xmlFreeDoc(document_);
|
| - }
|
| -
|
| - xmlDocPtr get() {
|
| - return document_;
|
| - }
|
| -
|
| - private:
|
| - xmlDocPtr document_;
|
| -};
|
| -
|
| -// Returns a pointer to the xmlNs on |node| with the |expected_href|, or
|
| -// NULL if there isn't one with that href.
|
| -static xmlNs* GetNamespace(xmlNode* node, const char* expected_href) {
|
| - const xmlChar* href = reinterpret_cast<const xmlChar*>(expected_href);
|
| - for (xmlNs* ns = node->ns; ns != NULL; ns = ns->next) {
|
| - if (ns->href && !xmlStrcmp(ns->href, href)) {
|
| - return ns;
|
| - }
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| -// Helper function that reads in values for a single <app> tag. It returns a
|
| -// boolean indicating success or failure. On failure, it writes a error message
|
| -// into |error_detail|.
|
| -static bool ParseSingleAppTag(xmlNode* app_node, xmlNs* xml_namespace,
|
| - UpdateManifest::Result* result,
|
| - std::string *error_detail) {
|
| - // Read the extension id.
|
| - result->extension_id = GetAttribute(app_node, "appid");
|
| - if (result->extension_id.length() == 0) {
|
| - *error_detail = "Missing appid on app node";
|
| - return false;
|
| - }
|
| -
|
| - // Get the updatecheck node.
|
| - std::vector<xmlNode*> updates = GetChildren(app_node, xml_namespace,
|
| - "updatecheck");
|
| - if (updates.size() > 1) {
|
| - *error_detail = "Too many updatecheck tags on app (expecting only 1).";
|
| - return false;
|
| - }
|
| - if (updates.empty()) {
|
| - *error_detail = "Missing updatecheck on app.";
|
| - return false;
|
| - }
|
| - xmlNode *updatecheck = updates[0];
|
| -
|
| - if (GetAttribute(updatecheck, "status") == "noupdate") {
|
| - return true;
|
| - }
|
| -
|
| - // Find the url to the crx file.
|
| - result->crx_url = GURL(GetAttribute(updatecheck, "codebase"));
|
| - if (!result->crx_url.is_valid()) {
|
| - *error_detail = "Invalid codebase url: '";
|
| - *error_detail += result->crx_url.possibly_invalid_spec();
|
| - *error_detail += "'.";
|
| - return false;
|
| - }
|
| -
|
| - // Get the version.
|
| - result->version = GetAttribute(updatecheck, "version");
|
| - if (result->version.length() == 0) {
|
| - *error_detail = "Missing version for updatecheck.";
|
| - return false;
|
| - }
|
| - Version version(result->version);
|
| - if (!version.IsValid()) {
|
| - *error_detail = "Invalid version: '";
|
| - *error_detail += result->version;
|
| - *error_detail += "'.";
|
| - return false;
|
| - }
|
| -
|
| - // Get the minimum browser version (not required).
|
| - result->browser_min_version = GetAttribute(updatecheck, "prodversionmin");
|
| - if (result->browser_min_version.length()) {
|
| - Version browser_min_version(result->browser_min_version);
|
| - if (!browser_min_version.IsValid()) {
|
| - *error_detail = "Invalid prodversionmin: '";
|
| - *error_detail += result->browser_min_version;
|
| - *error_detail += "'.";
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - // package_hash is optional. It is only required for blacklist. It is a
|
| - // sha256 hash of the package in hex format.
|
| - result->package_hash = GetAttribute(updatecheck, "hash");
|
| -
|
| - int size = 0;
|
| - if (base::StringToInt(GetAttribute(updatecheck, "size"), &size)) {
|
| - result->size = size;
|
| - }
|
| -
|
| - // package_fingerprint is optional. It identifies the package, preferably
|
| - // with a modified sha256 hash of the package in hex format.
|
| - result->package_fingerprint = GetAttribute(updatecheck, "fp");
|
| -
|
| - // Differential update information is optional.
|
| - result->diff_crx_url = GURL(GetAttribute(updatecheck, "codebasediff"));
|
| - result->diff_package_hash = GetAttribute(updatecheck, "hashdiff");
|
| - int sizediff = 0;
|
| - if (base::StringToInt(GetAttribute(updatecheck, "sizediff"), &sizediff)) {
|
| - result->diff_size = sizediff;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -
|
| -bool UpdateManifest::Parse(const std::string& manifest_xml) {
|
| - results_.list.resize(0);
|
| - results_.daystart_elapsed_seconds = kNoDaystart;
|
| - errors_ = "";
|
| -
|
| - if (manifest_xml.length() < 1) {
|
| - ParseError("Empty xml");
|
| - return false;
|
| - }
|
| -
|
| - std::string xml_errors;
|
| - ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc);
|
| -
|
| - // Start up the xml parser with the manifest_xml contents.
|
| - ScopedXmlDocument document(xmlParseDoc(
|
| - reinterpret_cast<const xmlChar*>(manifest_xml.c_str())));
|
| - if (!document.get()) {
|
| - ParseError("%s", xml_errors.c_str());
|
| - return false;
|
| - }
|
| -
|
| - xmlNode *root = xmlDocGetRootElement(document.get());
|
| - if (!root) {
|
| - ParseError("Missing root node");
|
| - return false;
|
| - }
|
| -
|
| - // Look for the required namespace declaration.
|
| - xmlNs* gupdate_ns = GetNamespace(root, kExpectedGupdateXmlns);
|
| - if (!gupdate_ns) {
|
| - ParseError("Missing or incorrect xmlns on gupdate tag");
|
| - return false;
|
| - }
|
| -
|
| - if (!TagNameEquals(root, "gupdate", gupdate_ns)) {
|
| - ParseError("Missing gupdate tag");
|
| - return false;
|
| - }
|
| -
|
| - // Check for the gupdate "protocol" attribute.
|
| - if (GetAttribute(root, "protocol") != kExpectedGupdateProtocol) {
|
| - ParseError("Missing/incorrect protocol on gupdate tag "
|
| - "(expected '%s')", kExpectedGupdateProtocol);
|
| - return false;
|
| - }
|
| -
|
| - // Parse the first <daystart> if it's present.
|
| - std::vector<xmlNode*> daystarts = GetChildren(root, gupdate_ns, "daystart");
|
| - if (!daystarts.empty()) {
|
| - xmlNode* first = daystarts[0];
|
| - std::string elapsed_seconds = GetAttribute(first, "elapsed_seconds");
|
| - int parsed_elapsed = kNoDaystart;
|
| - if (base::StringToInt(elapsed_seconds, &parsed_elapsed)) {
|
| - results_.daystart_elapsed_seconds = parsed_elapsed;
|
| - }
|
| - }
|
| -
|
| - // Parse each of the <app> tags.
|
| - std::vector<xmlNode*> apps = GetChildren(root, gupdate_ns, "app");
|
| - for (unsigned int i = 0; i < apps.size(); i++) {
|
| - Result current;
|
| - std::string error;
|
| - if (!ParseSingleAppTag(apps[i], gupdate_ns, ¤t, &error)) {
|
| - ParseError("%s", error.c_str());
|
| - } else {
|
| - results_.list.push_back(current);
|
| - }
|
| - }
|
| -
|
| - return true;
|
| -}
|
|
|