| Index: trunk/src/chrome/installer/util/google_update_util.cc
|
| ===================================================================
|
| --- trunk/src/chrome/installer/util/google_update_util.cc (revision 285705)
|
| +++ trunk/src/chrome/installer/util/google_update_util.cc (working copy)
|
| @@ -4,19 +4,28 @@
|
|
|
| #include "chrome/installer/util/google_update_util.h"
|
|
|
| +#include <algorithm>
|
| +#include <map>
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| #include "base/command_line.h"
|
| +#include "base/environment.h"
|
| #include "base/file_util.h"
|
| #include "base/files/file_path.h"
|
| #include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "base/path_service.h"
|
| #include "base/process/kill.h"
|
| #include "base/process/launch.h"
|
| #include "base/strings/string16.h"
|
| +#include "base/strings/string_split.h"
|
| #include "base/time/time.h"
|
| #include "base/win/registry.h"
|
| #include "base/win/scoped_handle.h"
|
| #include "base/win/win_util.h"
|
| #include "base/win/windows_version.h"
|
| +#include "chrome/installer/launcher_support/chrome_launcher_support.h"
|
| #include "chrome/installer/util/browser_distribution.h"
|
| #include "chrome/installer/util/google_update_constants.h"
|
| #include "chrome/installer/util/google_update_settings.h"
|
| @@ -32,6 +41,9 @@
|
|
|
| const int kGoogleUpdateTimeoutMs = 20 * 1000;
|
|
|
| +const char kEnvVariableUntrustedData[] = "GoogleUpdateUntrustedData";
|
| +const int kUntrustedDataMaxLength = 4096;
|
| +
|
| // Returns true if Google Update is present at the given level.
|
| bool IsGoogleUpdatePresent(bool system_install) {
|
| // Using the existence of version key in the registry to decide.
|
| @@ -108,6 +120,73 @@
|
| return success;
|
| }
|
|
|
| +bool IsNotPrintable(unsigned char c) {
|
| + return c < 32 || c >= 127;
|
| +}
|
| +
|
| +// Returns whether or not |s| consists of printable characters.
|
| +bool IsStringPrintable(const std::string& s) {
|
| + return std::find_if(s.begin(), s.end(), IsNotPrintable) == s.end();
|
| +}
|
| +
|
| +bool IsIllegalUntrustedDataKeyChar(unsigned char c) {
|
| + return !(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' ||
|
| + c >= '0' && c <= '9' || c == '-' || c == '_' || c == '$');
|
| +}
|
| +
|
| +// Returns true if |key| from untrusted data is valid.
|
| +bool IsUntrustedDataKeyValid(const std::string& key) {
|
| + return std::find_if(key.begin(), key.end(), IsIllegalUntrustedDataKeyChar)
|
| + == key.end();
|
| +}
|
| +
|
| +// Parses |data_string| as key-value pairs and overwrites |untrusted_data| with
|
| +// the result. Returns true if the data could be parsed.
|
| +bool ParseUntrustedData(
|
| + const std::string& data_string,
|
| + std::map<std::string, std::string>* untrusted_data) {
|
| + DCHECK(untrusted_data);
|
| + if (data_string.length() > kUntrustedDataMaxLength ||
|
| + !IsStringPrintable(data_string)) {
|
| + LOG(ERROR) << "Invalid value in untrusted data string.";
|
| + return false;
|
| + }
|
| +
|
| + VLOG(1) << "Untrusted data string: " << data_string;
|
| +
|
| + std::vector<std::pair<std::string, std::string> > kv_pairs;
|
| + if (!base::SplitStringIntoKeyValuePairs(data_string, '=', '&', &kv_pairs)) {
|
| + LOG(ERROR) << "Failed to parse untrusted data: " << data_string;
|
| + return false;
|
| + }
|
| +
|
| + untrusted_data->clear();
|
| + std::vector<std::pair<std::string, std::string> >::const_iterator it;
|
| + for (it = kv_pairs.begin(); it != kv_pairs.end(); ++it) {
|
| + const std::string& key(it->first);
|
| + // TODO(huangs): URL unescape |value|.
|
| + const std::string& value(it->second);
|
| + if (IsUntrustedDataKeyValid(key) && IsStringPrintable(value))
|
| + (*untrusted_data)[key] = value;
|
| + else
|
| + LOG(ERROR) << "Illegal character found in untrusted data.";
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// Reads and parses untrusted data passed from Google Update as key-value
|
| +// pairs, then overwrites |untrusted_data_map| with the result.
|
| +// Returns true if data are successfully read.
|
| +bool GetGoogleUpdateUntrustedData(
|
| + std::map<std::string, std::string>* untrusted_data) {
|
| + scoped_ptr<base::Environment> env(base::Environment::Create());
|
| + std::string data_string;
|
| + if (!env || !env->GetVar(kEnvVariableUntrustedData, &data_string))
|
| + return false;
|
| +
|
| + return ParseUntrustedData(data_string, untrusted_data);
|
| +}
|
| +
|
| } // namespace
|
|
|
| bool EnsureUserLevelGoogleUpdatePresent() {
|
| @@ -187,4 +266,25 @@
|
| }
|
| }
|
|
|
| +std::string GetUntrustedDataValue(const std::string& key) {
|
| + std::map<std::string, std::string> untrusted_data;
|
| + if (GetGoogleUpdateUntrustedData(&untrusted_data)) {
|
| + std::map<std::string, std::string>::const_iterator data_it(
|
| + untrusted_data.find(key));
|
| + if (data_it != untrusted_data.end())
|
| + return data_it->second;
|
| + }
|
| +
|
| + return std::string();
|
| +}
|
| +
|
| +std::string GetUntrustedDataValueFromTag(const std::string& tag,
|
| + const std::string& key) {
|
| + std::map<std::string, std::string> untrusted_data;
|
| + if (ParseUntrustedData(tag, &untrusted_data))
|
| + return untrusted_data[key];
|
| +
|
| + return std::string();
|
| +}
|
| +
|
| } // namespace google_update
|
|
|