[go: nahoru, domu]

Change origin.mojom to use url::Origin::Nonce for serializing opaque origins.

This CL is part of adding precursor origin support to url::Origin which
nick@ started in https://crrev.com/c/1028985. It changes the Mojo
representation of url::Origin to use the nonce as an indicator for
whether the origin is opaque or not instead of keeping a boolean.

Bug: 882053
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: If260a09a66cf62b870f15d52f5aabc27a3f73823
Reviewed-on: https://chromium-review.googlesource.com/1227393
Commit-Queue: Nasko Oskov <nasko@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Balazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594911}
diff --git a/services/network/public/cpp/net_ipc_param_traits.cc b/services/network/public/cpp/net_ipc_param_traits.cc
index bf0ac82..8ca5e2e 100644
--- a/services/network/public/cpp/net_ipc_param_traits.cc
+++ b/services/network/public/cpp/net_ipc_param_traits.cc
@@ -485,36 +485,34 @@
 }
 
 void ParamTraits<url::Origin>::Write(base::Pickle* m, const url::Origin& p) {
-  WriteParam(m, p.unique());
-  WriteParam(m, p.scheme());
-  WriteParam(m, p.host());
-  WriteParam(m, p.port());
+  WriteParam(m, p.GetTupleOrPrecursorTupleIfOpaque().scheme());
+  WriteParam(m, p.GetTupleOrPrecursorTupleIfOpaque().host());
+  WriteParam(m, p.GetTupleOrPrecursorTupleIfOpaque().port());
+  WriteParam(m, p.GetNonceForSerialization());
 }
 
 bool ParamTraits<url::Origin>::Read(const base::Pickle* m,
                                     base::PickleIterator* iter,
                                     url::Origin* p) {
-  bool unique;
   std::string scheme;
   std::string host;
   uint16_t port;
-  if (!ReadParam(m, iter, &unique) || !ReadParam(m, iter, &scheme) ||
-      !ReadParam(m, iter, &host) || !ReadParam(m, iter, &port)) {
+  base::Optional<base::UnguessableToken> nonce_if_opaque;
+  if (!ReadParam(m, iter, &scheme) || !ReadParam(m, iter, &host) ||
+      !ReadParam(m, iter, &port) || !ReadParam(m, iter, &nonce_if_opaque)) {
     return false;
   }
 
-  if (unique) {
-    *p = url::Origin();
-  } else {
-    base::Optional<url::Origin> origin =
-        url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(scheme, host,
-                                                                   port);
-    if (!origin.has_value())
-      return false;
+  base::Optional<url::Origin> creation_result =
+      nonce_if_opaque
+          ? url::Origin::UnsafelyCreateOpaqueOriginWithoutNormalization(
+                scheme, host, port, url::Origin::Nonce(*nonce_if_opaque))
+          : url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
+                scheme, host, port);
+  if (!creation_result)
+    return false;
 
-    *p = origin.value();
-  }
-
+  *p = std::move(creation_result.value());
   return true;
 }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/credentialmanager/resources/mock-navigator-credentials.js b/third_party/WebKit/LayoutTests/http/tests/credentialmanager/resources/mock-navigator-credentials.js
index a56c90d..b8d4143 100644
--- a/third_party/WebKit/LayoutTests/http/tests/credentialmanager/resources/mock-navigator-credentials.js
+++ b/third_party/WebKit/LayoutTests/http/tests/credentialmanager/resources/mock-navigator-credentials.js
@@ -32,7 +32,7 @@
       icon: new url.mojom.Url({url: icon}),
       password: stringToMojoString16(password),
       federation: new url.mojom.Origin(
-          {scheme: '', host: '', port: 0, unique: true})
+          {scheme: 'https', host: 'foo.com', port: 443})
     });
   }
 
diff --git a/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h b/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h
index 3785ab7..738b03c 100644
--- a/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h
+++ b/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "url/mojom/origin.mojom-blink.h"
+#include "url/mojom/origin_mojom_traits.h"
 
 namespace mojo {
 
@@ -26,31 +27,38 @@
       const scoped_refptr<const ::blink::SecurityOrigin>& origin) {
     return origin->EffectivePort();
   }
-  static bool unique(
+  static base::Optional<base::UnguessableToken> nonce_if_opaque(
       const scoped_refptr<const ::blink::SecurityOrigin>& origin) {
-    return origin->IsOpaque();
+    if (origin->IsOpaque())
+      return base::UnguessableToken::Create();
+
+    return base::nullopt;
   }
   static bool Read(url::mojom::blink::Origin::DataView data,
                    scoped_refptr<const ::blink::SecurityOrigin>* out) {
-    if (data.unique()) {
-      *out = ::blink::SecurityOrigin::CreateUniqueOpaque();
-    } else {
-      WTF::String scheme;
-      WTF::String host;
-      if (!data.ReadScheme(&scheme) || !data.ReadHost(&host))
-        return false;
+    WTF::String scheme;
+    WTF::String host;
+    base::Optional<base::UnguessableToken> nonce_if_opaque;
+    if (!data.ReadScheme(&scheme) || !data.ReadHost(&host) ||
+        !data.ReadNonceIfOpaque(&nonce_if_opaque))
+      return false;
 
-      *out = ::blink::SecurityOrigin::Create(scheme, host, data.port());
+    if (nonce_if_opaque) {
+      *out = blink::SecurityOrigin::CreateUniqueOpaque();
+      return true;
     }
 
-    // If a unique origin was created, but the unique flag wasn't set, then
-    // the values provided to 'create' were invalid.
-    if (!data.unique() && (*out)->IsOpaque())
+    *out = blink::SecurityOrigin::Create(scheme, host, data.port());
+
+    // If an opaque origin was created, but the opaque flag wasn't set, then
+    // the values provided to 'Create' were invalid.
+    if ((*out)->IsOpaque())
       return false;
 
     return true;
   }
 };
-}
+
+}  // namespace mojo
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_STRUCT_TRAITS_H_
diff --git a/url/BUILD.gn b/url/BUILD.gn
index 1365fce..605ee82c 100644
--- a/url/BUILD.gn
+++ b/url/BUILD.gn
@@ -66,6 +66,7 @@
   deps = [
     "//base",
     "//base/third_party/dynamic_annotations",
+    "//ipc:param_traits",
   ]
 
   if (is_win) {
diff --git a/url/mojom/BUILD.gn b/url/mojom/BUILD.gn
index 1f77a2f..55796a9 100644
--- a/url/mojom/BUILD.gn
+++ b/url/mojom/BUILD.gn
@@ -17,6 +17,7 @@
 
   public_deps = [
     ":url_mojom_gurl",
+    "//mojo/public/mojom/base",
   ]
 
   check_includes_blink = false
diff --git a/url/mojom/origin.mojom b/url/mojom/origin.mojom
index 884357ba..5a9e319 100644
--- a/url/mojom/origin.mojom
+++ b/url/mojom/origin.mojom
@@ -4,9 +4,15 @@
 
 module url.mojom;
 
+import "mojo/public/mojom/base/unguessable_token.mojom";
+
 struct Origin {
   string scheme;
   string host;
   uint16 port;
-  bool unique;
+
+  // When a nonce is provided, this origin is opaque. The scheme/host/port do
+  // not need to be valid, but if they are, they identify the tuple origin
+  // from which this opaque origin is derived.
+  mojo_base.mojom.UnguessableToken? nonce_if_opaque;
 };
diff --git a/url/mojom/origin_mojom_traits.h b/url/mojom/origin_mojom_traits.h
index e4482376..ac34fe9 100644
--- a/url/mojom/origin_mojom_traits.h
+++ b/url/mojom/origin_mojom_traits.h
@@ -6,6 +6,8 @@
 #define URL_MOJO_ORIGIN_MOJOM_TRAITS_H_
 
 #include "base/strings/string_piece.h"
+#include "base/unguessable_token.h"
+#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
 #include "url/mojom/origin.mojom.h"
 #include "url/origin.h"
 
@@ -13,27 +15,38 @@
 
 template <>
 struct StructTraits<url::mojom::OriginDataView, url::Origin> {
-  static const std::string& scheme(const url::Origin& r) { return r.scheme(); }
-  static const std::string& host(const url::Origin& r) { return r.host(); }
-  static uint16_t port(const url::Origin& r) { return r.port(); }
-  static bool unique(const url::Origin& r) { return r.unique(); }
+  static const std::string& scheme(const url::Origin& r) {
+    return r.GetTupleOrPrecursorTupleIfOpaque().scheme();
+  }
+  static const std::string& host(const url::Origin& r) {
+    return r.GetTupleOrPrecursorTupleIfOpaque().host();
+  }
+  static uint16_t port(const url::Origin& r) {
+    return r.GetTupleOrPrecursorTupleIfOpaque().port();
+  }
+  static const base::Optional<base::UnguessableToken> nonce_if_opaque(
+      const url::Origin& r) {
+    // TODO(nasko): Consider returning a const reference here.
+    return r.GetNonceForSerialization();
+  }
   static bool Read(url::mojom::OriginDataView data, url::Origin* out) {
-    if (data.unique()) {
-      *out = url::Origin();
-    } else {
-      base::StringPiece scheme, host;
-      if (!data.ReadScheme(&scheme) || !data.ReadHost(&host))
-        return false;
+    base::StringPiece scheme, host;
+    base::Optional<base::UnguessableToken> nonce_if_opaque;
+    if (!data.ReadScheme(&scheme) || !data.ReadHost(&host) ||
+        !data.ReadNonceIfOpaque(&nonce_if_opaque))
+      return false;
 
-      base::Optional<url::Origin> origin =
-          url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
-              scheme, host, data.port());
-      if (!origin.has_value())
-        return false;
+    base::Optional<url::Origin> creation_result =
+        nonce_if_opaque
+            ? url::Origin::UnsafelyCreateOpaqueOriginWithoutNormalization(
+                  scheme, host, data.port(),
+                  url::Origin::Nonce(*nonce_if_opaque))
+            : url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
+                  scheme, host, data.port());
+    if (!creation_result)
+      return false;
 
-      *out = origin.value();
-    }
-
+    *out = std::move(creation_result.value());
     return true;
   }
 };
diff --git a/url/mojom/url_gurl_mojom_traits_unittest.cc b/url/mojom/url_gurl_mojom_traits_unittest.cc
index 69cbbcc..cdacd51 100644
--- a/url/mojom/url_gurl_mojom_traits_unittest.cc
+++ b/url/mojom/url_gurl_mojom_traits_unittest.cc
@@ -80,14 +80,26 @@
   EXPECT_EQ(non_unique, output);
   EXPECT_FALSE(output.unique());
 
-  Origin unique;
-  EXPECT_TRUE(proxy->BounceOrigin(unique, &output));
+  Origin unique1;
+  Origin unique2 = non_unique.DeriveNewOpaqueOrigin();
+  EXPECT_NE(unique1, unique2);
+  EXPECT_NE(unique2, unique1);
+  EXPECT_NE(unique2, non_unique);
+  EXPECT_TRUE(proxy->BounceOrigin(unique1, &output));
   EXPECT_TRUE(output.unique());
+  EXPECT_EQ(unique1, output);
+  Origin output2;
+  EXPECT_TRUE(proxy->BounceOrigin(unique2, &output2));
+  EXPECT_EQ(unique2, output2);
+  EXPECT_NE(unique2, output);
+  EXPECT_NE(unique1, output2);
 
   Origin normalized =
       Origin::CreateFromNormalizedTuple("http", "www.google.com", 80);
+  EXPECT_EQ(normalized, non_unique);
   EXPECT_TRUE(proxy->BounceOrigin(normalized, &output));
   EXPECT_EQ(normalized, output);
+  EXPECT_EQ(non_unique, output);
   EXPECT_FALSE(output.unique());
 }
 
diff --git a/url/origin.h b/url/origin.h
index 5306803..4e1d349 100644
--- a/url/origin.h
+++ b/url/origin.h
@@ -15,6 +15,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/unguessable_token.h"
+#include "ipc/ipc_param_traits.h"
 #include "url/scheme_host_port.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_canon.h"
@@ -28,8 +29,17 @@
 struct FuzzTraits;
 }  // namespace ipc_fuzzer
 
+namespace mojo {
+template <typename DataViewType, typename T>
+struct StructTraits;
+}  // namespace mojo
+
 namespace url {
 
+namespace mojom {
+class OriginDataView;
+}  // namespace mojom
+
 // Per https://html.spec.whatwg.org/multipage/origin.html#origin, an origin is
 // either:
 // - a tuple origin of (scheme, host, port) as described in RFC 6454.
@@ -245,7 +255,9 @@
 
  private:
   friend class OriginTest;
+  friend IPC::ParamTraits<url::Origin>;
   friend struct ipc_fuzzer::FuzzTraits<Origin>;
+  friend struct mojo::StructTraits<url::mojom::OriginDataView, url::Origin>;
   friend URL_EXPORT std::ostream& operator<<(std::ostream& out,
                                              const Origin& origin);