blob: 8b75cc49f3cb177b2ef943a635b18350165071c4 [file] [log] [blame]
// Copyright 2018 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/chrome_cleaner/parsers/parser_utils/command_line_arguments_sanitizer.h"
#include <stdio.h>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/chrome_cleaner/os/file_path_sanitization.h"
#include "url/gurl.h"
#include "url/url_util.h"
namespace chrome_cleaner {
namespace {
// It may be possible that the return value of GURL.host() is %-scaped, use
// this function to get the ASCII version.
std::wstring GetUnescapedHost(GURL url) {
std::string url_host = url.host();
url::RawCanonOutputT<wchar_t> unescaped_url_host;
url::DecodeURLEscapeSequences(url_host.c_str(), url_host.length(),
url::DecodeURLMode::kUTF8OrIsomorphic,
&unescaped_url_host);
return std::wstring(unescaped_url_host.data(), unescaped_url_host.length());
}
// Tries to parse the url string using GURL and returns the concatenation of
// the scheme and the host. If the url is not valid it returns the same string
// that was provided. If the url has no scheme, http:// is assumed.
std::wstring SanitizeUrl(const std::wstring& possible_url) {
bool has_scheme = (possible_url.find(L"://") != std::string::npos);
std::wstring scheme = (has_scheme) ? L"" : L"http://";
GURL url(scheme + possible_url);
if (!url.is_valid())
return possible_url;
// If the url we received did not have a scheme and it does not have a
// dot on its host then assume it is a file path and don't sanitize it.
if (!has_scheme && url.host().find(".") == std::string::npos)
return possible_url;
return base::UTF8ToWide(url.scheme()) + L"://" + GetUnescapedHost(url);
}
} // namespace
std::vector<std::wstring> SanitizeArguments(const std::wstring& arguments) {
// We prepend a dummy to the string because it takes the first element as the
// executable path.
const base::CommandLine command_line =
base::CommandLine::FromString(L"dummy " + arguments);
const base::CommandLine::SwitchMap& switches = command_line.GetSwitches();
std::vector<std::wstring> sanitized_arguments;
for (auto it = switches.begin(); it != switches.end(); it++) {
sanitized_arguments.push_back(
L"--" + base::UTF8ToWide(it->first) +
((it->second.empty())
? L""
: L"=" + SanitizePath(base::FilePath(SanitizeUrl(it->second)))));
}
const base::CommandLine::StringVector& vector_arguments =
command_line.GetArgs();
for (const auto& argument : vector_arguments) {
sanitized_arguments.push_back(
SanitizePath(base::FilePath(SanitizeUrl(argument))));
}
return sanitized_arguments;
}
} // namespace chrome_cleaner