Safelist distributed web schemes for "registerProtocolHandler"

This CL adds "cabal", "dat", "did", "dweb", "ethereum", "hyper",
"ipfs", "ipns", "ssb" to the safelist of
navigator.registerProtocolHandler. Chrome status entry is [1]
and feature has been discussed in [2] [3] [4] [5]. Currently,
the WHATWG and WPT changes are pending on the Mozilla position
review [6].

[1] https://www.chromestatus.com/feature/4776602869170176
[2] https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/29sFh4tTdcs/K4XroilVBAAJ
[3] https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/7nHTRUP1EGY
[4] https://github.com/whatwg/html/issues/3935
[5] https://github.com/whatwg/html/issues/3998
[6] https://github.com/mozilla/standards-positions/issues/339

Bug: 651311
Change-Id: Iba45706e985015cf86bd80adef990abd0980a638
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2153064
Reviewed-by: Mike West <mkwst@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Commit-Queue: Frédéric Wang <fwang@igalia.com>
Cr-Commit-Position: refs/heads/master@{#799626}
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index 824904da..5093562 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -1070,3 +1070,19 @@
       GURL("chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/test.html")));
   ASSERT_TRUE(registry()->IsHandledProtocol("news"));
 }
+
+// See
+// https://html.spec.whatwg.org/multipage/system-state.html#safelisted-scheme
+TEST_F(ProtocolHandlerRegistryTest, SafelistedSchemes) {
+  std::string schemes[] = {
+      "bitcoin",  "cabal",       "dat",    "did",    "doi",   "dweb",
+      "ethereum", "geo",         "hyper",  "im",     "ipfs",  "ipns",
+      "irc",      "ircs",        "magnet", "mailto", "mms",   "news",
+      "nntp",     "openpgp4fpr", "sip",    "sms",    "smsto", "ssb",
+      "ssh",      "tel",         "urn",    "webcal", "wtai",  "xmpp"};
+  for (auto& scheme : schemes) {
+    registry()->OnAcceptRegisterProtocolHandler(
+        CreateProtocolHandler(scheme, GURL("https://example.com/url=%s")));
+    ASSERT_TRUE(registry()->IsHandledProtocol(scheme));
+  }
+}
diff --git a/chrome/common/custom_handlers/protocol_handler.cc b/chrome/common/custom_handlers/protocol_handler.cc
index 0bd39ad..e6adcc0 100644
--- a/chrome/common/custom_handlers/protocol_handler.cc
+++ b/chrome/common/custom_handlers/protocol_handler.cc
@@ -52,9 +52,11 @@
   // From:
   // https://html.spec.whatwg.org/multipage/system-state.html#safelisted-scheme
   static constexpr const char* const kProtocolSafelist[] = {
-      "bitcoin", "geo",  "im",   "irc",         "ircs", "magnet", "mailto",
-      "mms",     "news", "nntp", "openpgp4fpr", "sip",  "sms",    "smsto",
-      "ssh",     "tel",  "urn",  "webcal",      "wtai", "xmpp"};
+      "bitcoin",  "cabal",       "dat",    "did",    "doi",   "dweb",
+      "ethereum", "geo",         "hyper",  "im",     "ipfs",  "ipns",
+      "irc",      "ircs",        "magnet", "mailto", "mms",   "news",
+      "nntp",     "openpgp4fpr", "sip",    "sms",    "smsto", "ssb",
+      "ssh",      "tel",         "urn",    "webcal", "wtai",  "xmpp"};
   static constexpr const char kWebPrefix[] = "web+";
 
   bool has_web_prefix =
diff --git a/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc b/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
index 361d113..f168e6b7 100644
--- a/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
+++ b/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
@@ -51,9 +51,11 @@
   DEFINE_STATIC_LOCAL(
       HashSet<String>, supported_schemes,
       ({
-          "bitcoin", "geo",  "im",   "irc",         "ircs", "magnet", "mailto",
-          "mms",     "news", "nntp", "openpgp4fpr", "sip",  "sms",    "smsto",
-          "ssh",     "tel",  "urn",  "webcal",      "wtai", "xmpp",
+          "bitcoin",     "cabal",  "dat",    "did",   "dweb", "ethereum",
+          "geo",         "hyper",  "im",     "ipfs",  "ipns", "irc",
+          "ircs",        "magnet", "mailto", "mms",   "news", "nntp",
+          "openpgp4fpr", "sip",    "sms",    "smsto", "ssb",  "ssh",
+          "tel",         "urn",    "webcal", "wtai",  "xmpp",
       }));
   return supported_schemes;
 }
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.tentative.https.html b/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.tentative.https.html
new file mode 100644
index 0000000..0120aaa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol.tentative.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset='utf-8'>
+<title>protocol handlers</title>
+
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+
+<script>
+// This should be merged into protocol.https.html when/if
+// https://github.com/whatwg/html/pull/5482 is approved.
+[
+  'cabal',
+  'dat',
+  'did',
+  'dweb',
+  'ethereum',
+  'hyper',
+  'ipfs',
+  'ipns',
+  'ssb',
+].forEach(scheme => {
+  test(() => {
+    navigator.registerProtocolHandler(scheme, location.href + '/%s', "foo");
+  }, 'registerProtocolHandler: overriding the "' + scheme + '" protocol should work');
+
+  test(() => {
+    navigator.unregisterProtocolHandler(scheme, location.href + '/%s');
+  }, 'unregisterProtocolHandler: overriding the "' + scheme + '" protocol should work');
+});
+</script>