| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/network/public/cpp/web_sandbox_flags.h" |
| |
| #include <set> |
| #include <vector> |
| |
| #include "base/containers/fixed_flat_map.h" |
| #include "base/strings/string_split.h" |
| #include "base/strings/string_util.h" |
| #include "services/network/public/mojom/web_sandbox_flags.mojom.h" |
| |
| namespace network { |
| |
| using mojom::WebSandboxFlags; |
| namespace { |
| |
| // See: https://infra.spec.whatwg.org/#ascii-whitespace |
| // This is different from: base::kWhitespaceASCII. |
| const char* kHtmlWhitespace = " \n\t\r\f"; |
| |
| WebSandboxFlags ParseWebSandboxToken(std::string_view token) { |
| using enum WebSandboxFlags; |
| static constexpr auto kTokenToWebSandboxFlags = |
| base::MakeFixedFlatMap<std::string_view, WebSandboxFlags>({ |
| {"allow-downloads", kDownloads}, |
| {"allow-forms", kForms}, |
| {"allow-modals", kModals}, |
| {"allow-orientation-lock", kOrientationLock}, |
| {"allow-pointer-lock", kPointerLock}, |
| {"allow-popups", kPopups | kTopNavigationToCustomProtocols}, |
| {"allow-popups-to-escape-sandbox", |
| kPropagatesToAuxiliaryBrowsingContexts}, |
| {"allow-presentation", kPresentationController}, |
| {"allow-same-origin", kOrigin}, |
| {"allow-scripts", kAutomaticFeatures | kScripts}, |
| {"allow-storage-access-by-user-activation", |
| kStorageAccessByUserActivation}, |
| {"allow-top-navigation", |
| kTopNavigation | kTopNavigationToCustomProtocols}, |
| {"allow-top-navigation-by-user-activation", |
| kTopNavigationByUserActivation}, |
| {"allow-top-navigation-to-custom-protocols", |
| kTopNavigationToCustomProtocols}, |
| {"allow-same-site-none-cookies", kAllowSameSiteNoneCookies}, |
| }); |
| |
| std::string lowered_token = base::ToLowerASCII(token); |
| const auto it = kTokenToWebSandboxFlags.find(lowered_token); |
| return it == kTokenToWebSandboxFlags.end() ? kNone : it->second; |
| } |
| |
| } // namespace |
| |
| // See: http://www.w3.org/TR/html5/the-iframe-element.html#attr-iframe-sandbox |
| WebSandboxFlagsParsingResult ParseWebSandboxPolicy( |
| std::string_view input, |
| WebSandboxFlags ignored_flags) { |
| WebSandboxFlagsParsingResult out; |
| out.flags = WebSandboxFlags::kAll; |
| |
| std::vector<std::string_view> error_tokens; |
| for (const auto& token : |
| base::SplitStringPiece(input, kHtmlWhitespace, base::KEEP_WHITESPACE, |
| base::SPLIT_WANT_NONEMPTY)) { |
| WebSandboxFlags flags = ~ParseWebSandboxToken(token); |
| flags |= ignored_flags; |
| out.flags &= flags; |
| if (flags == WebSandboxFlags::kAll) |
| error_tokens.push_back(token); |
| } |
| |
| if (!error_tokens.empty()) { |
| // Some tests expect the order of error tokens to be preserved, while |
| // removing the duplicates: |
| // See /fast/frames/sandboxed-iframe-attribute-parsing-03.html |
| std::set<std::string_view> set; |
| std::erase_if(error_tokens, [&](auto x) { return !set.insert(x).second; }); |
| |
| out.error_message = |
| "'" + base::JoinString(error_tokens, "', '") + |
| (error_tokens.size() > 1 ? "' are invalid sandbox flags." |
| : "' is an invalid sandbox flag."); |
| } |
| |
| return out; |
| } |
| |
| } // namespace network |