File: safe_manifest_parser.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (151 lines) | stat: -rw-r--r-- 5,344 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_BROWSER_UPDATER_SAFE_MANIFEST_PARSER_H_
#define EXTENSIONS_BROWSER_UPDATER_SAFE_MANIFEST_PARSER_H_

#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/functional/callback_forward.h"
#include "extensions/common/extension_id.h"
#include "url/gurl.h"

namespace extensions {

// Note: enum used for UMA. Do NOT reorder or remove entries.
// 1) Don't forget to update enums.xml (name: ManifestInvalidError) when adding
// new entries.
// 2) Don't forget to update device_management_backend.proto (name:
// ExtensionInstallReportLogEvent::ManifestInvalidError) when adding new
// entries.
// 3) Don't forget to update ConvertManifestInvalidErrorToProto method in
// ExtensionInstallEventLogCollector.
// Some errors are common for the entire fetched update manifest which
// contains manifests of different extensions, while some errors are per
// extension basis.
enum class ManifestInvalidError {
  // Common for the entire fetched manifest, which contains manifests of
  // different extensions.
  XML_PARSING_FAILED = 0,
  INVALID_XLMNS_ON_GUPDATE_TAG = 1,
  MISSING_GUPDATE_TAG = 2,
  INVALID_PROTOCOL_ON_GUPDATE_TAG = 3,
  // Here onwards we have errors corresponding to a single extension.
  MISSING_APP_ID = 4,
  MISSING_UPDATE_CHECK_TAGS = 5,
  MULTIPLE_UPDATE_CHECK_TAGS = 6,
  INVALID_PRODVERSION_MIN = 7,
  EMPTY_CODEBASE_URL = 8,
  INVALID_CODEBASE_URL = 9,
  MISSING_VERSION_FOR_UPDATE_CHECK = 10,
  INVALID_VERSION = 11,
  BAD_UPDATE_SPECIFICATION = 12,
  BAD_APP_STATUS = 13,
  // Maximum histogram value.
  kMaxValue = BAD_APP_STATUS
};

struct ManifestParseFailure {
  ManifestParseFailure();
  ManifestParseFailure(const ManifestParseFailure& other);
  ManifestParseFailure(std::string error_detail, ManifestInvalidError error);
  ~ManifestParseFailure();

  std::string error_detail;
  ManifestInvalidError error;
};

struct UpdateManifestResult {
  UpdateManifestResult();
  UpdateManifestResult(const UpdateManifestResult& other);
  ~UpdateManifestResult();

  ExtensionId extension_id;
  std::string version;
  std::string browser_min_version;
  std::string app_status;

  // Error occurred while parsing manifest.
  std::optional<ManifestParseFailure> parse_error;

  // Attribute for no update: server may provide additional info about why there
  // is no updates, eg. “bandwidth limit” if client is downloading extensions
  // too aggressive.
  std::optional<std::string> info;

  // Indicates the outcome of the update check.
  std::string status;

  // Attributes for the full update.
  GURL crx_url;
  std::string package_hash;
  int size = 0;
  std::string package_fingerprint;

  // Attributes for the differential update.
  GURL diff_crx_url;
  std::string diff_package_hash;
  int diff_size = 0;
};

inline constexpr int kNoDaystart = -1;
struct UpdateManifestResults {
  UpdateManifestResults();
  UpdateManifestResults(const UpdateManifestResults& other);
  UpdateManifestResults& operator=(const UpdateManifestResults& other);
  ~UpdateManifestResults();

  // Group successful items from |update_list| by |extension_id|.
  std::map<std::string, std::vector<const UpdateManifestResult*>>
  GroupSuccessfulByID() const;

  std::vector<UpdateManifestResult> update_list;
  // This will be >= 0, or kNoDaystart if the <daystart> tag was not present.
  int daystart_elapsed_seconds = kNoDaystart;
};

// Parses an update manifest |xml| safely in a utility process and calls
// |callback| with the results, which will be null on failure. Runs on
// the UI thread.
//
// An update manifest looks like this:
//
// <?xml version="1.0" encoding="UTF-8"?>
// <gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
//  <daystart elapsed_seconds="300" />
//  <app appid="12345" status="ok">
//   <updatecheck codebase="http://example.com/extension_1.2.3.4.crx"
//                hash="12345" size="9854" status="ok" version="1.2.3.4"
//                prodversionmin="2.0.143.0"
//                codebasediff="http://example.com/diff_1.2.3.4.crx"
//                hashdiff="123" sizediff="101"
//                fp="1.123" />
//  </app>
// </gupdate>
//
// The <daystart> tag contains a "elapsed_seconds" attribute which refers to
// the server's notion of how many seconds it has been since midnight.
//
// The "appid" attribute of the <app> tag refers to the unique id of the
// extension. The "codebase" attribute of the <updatecheck> tag is the url to
// fetch the updated crx file, and the "prodversionmin" attribute refers to
// the minimum version of the chrome browser that the update applies to.

// The diff data members correspond to the differential update package, if
// a differential update is specified in the response.

// The result of parsing one <app> tag in an xml update check manifest.
using ParseUpdateManifestCallback = base::OnceCallback<void(
    std::unique_ptr<UpdateManifestResults> results,
    const std::optional<ManifestParseFailure>& failure)>;
void ParseUpdateManifest(const std::string& xml,
                         ParseUpdateManifestCallback callback);

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_UPDATER_SAFE_MANIFEST_PARSER_H_