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
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/clipboard/url_file_parser.h"
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/span.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
namespace ui::clipboard_util::internal {
std::string ExtractURLFromURLFileContents(std::string_view file_contents) {
// NB: This code is written with the single goal of obvious correctness. It is
// deliberately not optimized by any other measure.
if (file_contents.size() > kMaximumParsableFileSize) {
return {};
}
// Re the file format: The file is in .ini file format, with sections headed
// by bracketed names, each containing key-value pairs separated by an equal
// sign. In a .url file, the URL can be found in the [InternetShortcut]
// section, as the value for the "URL" key.
const std::string kInternetShortcut("[InternetShortcut]");
const std::string kURL("URL=");
// Start by splitting the file content into lines.
std::vector<std::string_view> lines_vector = base::SplitStringPiece(
file_contents, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
base::span<std::string_view> lines(lines_vector);
// Search for the [InternetShortcut] section by discarding lines one by one
// until either the section is found or there are no lines left.
while (!lines.empty() && lines.front() != kInternetShortcut) {
lines = lines.subspan<1>();
}
// At this point, either the section was found or there are no lines left. If
// there are no lines left, there is no URL to find in this file. Return.
if (lines.empty()) {
return {};
}
// This is now the [InternetShortcut] section. Discard that section header.
lines = lines.subspan<1>();
// At this point, examine the lines.
while (!lines.empty()) {
const auto& line = lines.front();
// If the line begins with a [ then a new section has begun, and there is no
// URL to find in this file. Return.
if (line.length() && line[0] == '[') {
return {};
}
// Otherwise, it should be a key-value pair delimited by "=". However,
// splitting on "=" doesn't work because URLs can contain that character, so
// just look for the prefix.
if (line.starts_with(kURL)) {
// Success! Strip off the prefix and return what was found.
return std::string(line.substr(kURL.length()));
}
// Otherwise, this isn't a useful line; discard it and move on.
lines = lines.subspan<1>();
}
// If control has reached here, the file was searched and it contains no URL.
// Return.
return {};
}
} // namespace ui::clipboard_util::internal
|