File: util.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 (251 lines) | stat: -rw-r--r-- 9,349 bytes parent folder | download | duplicates (5)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_UPDATER_UTIL_UTIL_H_
#define CHROME_UPDATER_UTIL_UTIL_H_

#include <cmath>
#include <concepts>
#include <limits>
#include <optional>
#include <ostream>
#include <string>
#include <type_traits>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/types/cxx23_to_underlying.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/updater/tag.h"
#include "chrome/updater/updater_scope.h"
#include "chrome/updater/updater_version.h"

class GURL;

namespace base {

class CommandLine;
class FilePath;

// Enables insertion of optional `base` types. Must be in the `base` namespace
// for insertion into gTest expectations to work.
template <class T>
inline std::ostream& operator<<(std::ostream& os, std::optional<T> opt) {
  if (!opt.has_value()) {
    return os << "std::nullopt";
  }
  return os << opt.value();
}

}  // namespace base

namespace updater {

struct RegistrationRequest;

// Converts an unsigned integral to a signed one. Returns -1 if the value is
// out of the range of the target type.
template <std::unsigned_integral T>
[[nodiscard]] auto ToSignedIntegral(T value) {
  using Result = std::make_signed_t<T>;
  return value <= std::numeric_limits<Result>::max()
             ? static_cast<Result>(value)
             : -1;
}

// Inserts an enum value as the underlying type.
template <typename T>
  requires(std::is_enum_v<T>)
inline std::ostream& operator<<(std::ostream& os, const T& e) {
  return os << base::to_underlying(e);
}

// Returns the versioned install directory under which the program stores its
// executables. For example, on macOS this function may return
// ~/Library/Google/GoogleUpdater/88.0.4293.0 (/Library for system). Does not
// create the directory if it does not exist.
std::optional<base::FilePath> GetVersionedInstallDirectory(
    UpdaterScope scope,
    const base::Version& version);

// Simpler form of GetVersionedInstallDirectory for the currently running
// version of the updater.
std::optional<base::FilePath> GetVersionedInstallDirectory(UpdaterScope scope);

// Returns the base install directory common to all versions of the updater.
// Does not create the directory if it does not exist.
std::optional<base::FilePath> GetInstallDirectory(UpdaterScope scope);

// Returns the path where cached CRX files should be stored, common to all
// versions of the updater. Does not create the directory if it does not exist.
std::optional<base::FilePath> GetCrxCacheDirectory(UpdaterScope scope);

#if BUILDFLAG(IS_MAC)
// For example: ~/Library/Google/GoogleUpdater/88.0.4293.0/GoogleUpdater.app
std::optional<base::FilePath> GetUpdaterAppBundlePath(UpdaterScope scope);
#endif  // BUILDFLAG(IS_MAC)

// For user installations:
// ~/Library/Google/GoogleUpdater/88.0.4293.0/GoogleUpdater.app/Contents/
//    MacOS/GoogleUpdater
// For system installations:
// /Library/Google/GoogleUpdater/88.0.4293.0/GoogleUpdater.app/Contents/
//    MacOS/GoogleUpdater
std::optional<base::FilePath> GetUpdaterExecutablePath(
    UpdaterScope scope,
    const base::Version& version);

// Simpler form of GetUpdaterExecutablePath for the currently running version
// of the updater.
std::optional<base::FilePath> GetUpdaterExecutablePath(UpdaterScope scope);

// Returns a relative path to the executable from GetVersionedInstallDirectory.
// "GoogleUpdater.app/Contents/MacOS/GoogleUpdater" on macOS.
// "updater.exe" on Win.
base::FilePath GetExecutableRelativePath();

// Returns the path to the crashpad database directory. The directory is not
// created if it does not exist.
std::optional<base::FilePath> GetCrashDatabasePath(UpdaterScope scope);

// Returns the path to the crashpad database, creating it if it does not exist.
std::optional<base::FilePath> EnsureCrashDatabasePath(UpdaterScope scope);

// Contains the parsed values from the tag. The tag is provided as a command
// line argument to the `--install` or the `--handoff` switch.
struct TagParsingResult {
  TagParsingResult();
  TagParsingResult(std::optional<tagging::TagArgs> tag_args,
                   tagging::ErrorCode error);
  ~TagParsingResult();
  TagParsingResult(const TagParsingResult&);
  TagParsingResult& operator=(const TagParsingResult&);
  std::optional<tagging::TagArgs> tag_args;
  tagging::ErrorCode error = tagging::ErrorCode::kSuccess;
};

// These functions return {} if there was no tag at all. An error is set if the
// tag fails to parse.
TagParsingResult GetTagArgsForCommandLine(
    const base::CommandLine& command_line);
TagParsingResult GetTagArgs();

std::optional<tagging::AppArgs> GetAppArgs(const std::string& app_id);

std::string GetTagLanguage();

std::string GetDecodedInstallDataFromAppArgs(const std::string& app_id);

std::string GetInstallDataIndexFromAppArgs(const std::string& app_id);

std::optional<base::FilePath> GetLogFilePath(UpdaterScope scope);

// Initializes logging for an executable.
void InitLogging(UpdaterScope updater_scope);

// Returns HTTP user-agent value.
std::string GetUpdaterUserAgent(
    const base::Version& updater_version = base::Version(kUpdaterVersion));

// Returns a new GURL by appending the given query parameter name and the
// value. Unsafe characters in the name and the value are escaped like
// %XX%XX. The original query component is preserved if it's present.
//
// Examples:
//
// AppendQueryParameter(GURL("http://example.com"), "name", "value").spec()
// => "http://example.com?name=value"
// AppendQueryParameter(GURL("http://example.com?x=y"), "name", "value").spec()
// => "http://example.com?x=y&name=value"
GURL AppendQueryParameter(const GURL& url,
                          const std::string& name,
                          const std::string& value);

#if BUILDFLAG(IS_MAC)
// Recursively update the permissions of a path to 0755 or 0644, depending on
// whether the file is already executable (by any user) or is a directory.
// Returns false if and only if there is a failure lstating or setting a
// permission, except for failures to set permissions on symbolic links.
bool SetFilePermissionsRecursive(const base::FilePath& root_path);
#endif  // BUILDFLAG(IS_MAC)

#if BUILDFLAG(IS_WIN)

// Returns the versioned task name prefix in the following format:
// "{ProductName}Task{System/User}{UpdaterVersion}".
// For instance: "ChromiumUpdaterTaskSystem92.0.0.1".
std::wstring GetTaskNamePrefix(
    UpdaterScope scope,
    const base::Version& version = base::Version(kUpdaterVersion));

// Returns the versioned task display name in the following format:
// "{ProductName} Task {System/User} {UpdaterVersion}".
// For instance: "ChromiumUpdater Task System 92.0.0.1".
std::wstring GetTaskDisplayName(
    UpdaterScope scope,
    const base::Version& version = base::Version(kUpdaterVersion));

// Parses the command line string in legacy format into `base::CommandLine`.
// The string must be in format like:
//   program.exe /switch1 value1 /switch2 /switch3 value3
// Returns empty if a Chromium style switch is found.
std::optional<base::CommandLine> CommandLineForLegacyFormat(
    const std::wstring& cmd_string);

// Returns the command line for current process, either in legacy style, or
// in Chromium style.
base::CommandLine GetCommandLineLegacyCompatible();

#endif  // BUILDFLAG(IS_WIN)

// Writes the provided string prefixed with the UTF8 byte order mark to a
// temporary file. The temporary file is created in the specified `directory`.
std::optional<base::FilePath> WriteInstallerDataToTempFile(
    const base::FilePath& directory,
    const std::string& installer_data);

// Creates and starts a thread pool for this process.
void InitializeThreadPool(const char* name);

// Returns whether the user currently running the program is the right user for
// the scope. This can be useful to avoid installing system updaters that are
// owned by non-root accounts, or avoiding the installation of a user level
// updater as root.
bool WrongUser(UpdaterScope scope);

// Returns whether a user has previously accepted a EULA / ToS for at least one
// of the listed apps.
bool EulaAccepted(const std::vector<std::string>& app_ids);

// Imports metadata from legacy updaters.
bool MigrateLegacyUpdaters(
    UpdaterScope scope,
    base::RepeatingCallback<void(const RegistrationRequest&)>
        register_callback);

// Delete everything other than `except` under `except.DirName()`.
[[nodiscard]] bool DeleteExcept(std::optional<base::FilePath> except);

// Returns the quotient of dividing two integer numbers (m/n) rounded up.
template <typename T>
  requires(std::integral<T>)
[[nodiscard]] constexpr T CeilingDivide(T m, T n) {
  return std::ceil(static_cast<double>(m) / n);
}

// Returns a value in the [0, 100] range or -1 if the progress could not
// be computed.
[[nodiscard]] int GetDownloadProgress(int64_t downloaded_bytes,
                                      int64_t total_bytes);

// Returns the absolute path to the enterprise companion app executable bundled
// with the updater.
[[nodiscard]] std::optional<base::FilePath>
GetBundledEnterpriseCompanionExecutablePath(UpdaterScope scope);

}  // namespace updater

#endif  // CHROME_UPDATER_UTIL_UTIL_H_