File: unique_ids.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (177 lines) | stat: -rw-r--r-- 7,382 bytes parent folder | download | duplicates (5)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// 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.

#ifndef COMPONENTS_AUTOFILL_CORE_COMMON_UNIQUE_IDS_H_
#define COMPONENTS_AUTOFILL_CORE_COMMON_UNIQUE_IDS_H_

#include <ostream>
#include <string>
#include <variant>

#include "base/types/id_type.h"
#include "base/types/strong_alias.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"

namespace autofill {

namespace internal {

// TokenType wraps an base::UnguessableToken just like base::TokenType but
// initializes to zero by default. We use it to define our own versions of
// LocalFrameToken and RemoteFrameToken to avoid dependencies on blink here and
// in the mojo code, since iOS depends on this code.
template <typename TokenTypeMarker>
class TokenType
    : public base::StrongAlias<TokenTypeMarker, base::UnguessableToken> {
 public:
  using base::StrongAlias<TokenTypeMarker, base::UnguessableToken>::StrongAlias;
  bool is_empty() const { return this->value().is_empty(); }
  explicit constexpr operator bool() const { return !is_empty(); }
  std::string ToString() const { return this->value().ToString(); }
};

}  // namespace internal

// LocalFrameToken and RemoteFrameToken identify AutofillDrivers and
// AutofillAgents.
//
// TODO(crbug.com/40266699): Implement frame tokens as described below for iOS.
//
// Every pair of associated AutofillAgent and AutofillDriver has a
// LocalFrameToken, which uniquely identifies them and remains stable for their
// lifetime.
//
// In the //content layer, LocalFrameTokens are a secret between the browser
// process and the renderer process hosting the respective AutofillAgent.
// Therefore, cross-process AutofillAgents do not know each other's
// LocalFrameToken.
//
// In such a case, an AutofillAgent A1 refers to another AutofillAgent A2 by
// a RemoteFrameToken. The associated AutofillDriver D1 can obtain the
// LocalFrameToken of A2 and its associated AutofillDriver D2 by calling
// AutofillDriver::Resolve(). RemoteFrameTokens only have weak properties:
//
// 1. Different AutofillAgents may refer to A2 by different RemoteFrameTokens.
//    That is, D1.Resolve(R) == D3.Resolve(R') is possible for distinct
//    RemoteFrameTokens R, R', especially when A1 and A3 are hosted by different
//    renderer processes.
//    Therefore, RemoteFrameTokens are not suitable for discriminating between
//    AutofillAgents and AutofillDrivers in the browser process.
//
// 2. Over time, the same RemoteFrameToken may resolve to different
//    LocalFrameTokens. Suppose a navigation in A2's frame replaces A2 and D2
//    with a new objects AutofillAgent A3 and AutofillDriver D3 (this happens on
//    a renderer process swap, which typically happens on cross-origin
//    navigations). Then A2 and A3 have distinct LocalFrameTokens, but A1 may
//    refer to A3 by the same RemoteFrameToken as it did to A2. That is,
//    D1.Resolve(R) may change over cross-origin navigations.
//    Therefore, AutofillDriver::Resolve() must not be cached.
//
// LocalFrameToken and RemoteFrameToken are Blink and //content layer concepts.
//
// If the //content layer is available, AutofillAgent and AutofillDriver inherit
// their {Local,Remote}FrameToken from blink::Web{Local,Remote}Frame and
// content::RenderFrameHost.
//
// On iOS, AutofillAgent and AutofillDriver inherit their LocalFrameToken from
// web::WebFrame, and RemoteFrameTokens are generated during form extraction.
//
// FrameTokens must not be leaked to renderer processes other than the one
// they originate from. Therefore, Autofill should generally not send
// FrameTokens to any renderer process.
using RemoteFrameToken = internal::TokenType<class RemoteFrameTokenMarker>;
using LocalFrameToken = internal::TokenType<class LocalFrameTokenMarker>;
using FrameToken = std::variant<RemoteFrameToken, LocalFrameToken>;

namespace internal {

#if BUILDFLAG(IS_IOS)
using FormRendererIdType = ::base::IdTypeU32<class FormRendererIdMarker>;
using FieldRendererIdType = ::base::IdTypeU32<class FieldRendererIdMarker>;
#else
using FormRendererIdType = ::base::IdTypeU64<class FormRendererIdMarker>;
using FieldRendererIdType = ::base::IdTypeU64<class FieldRendererIdMarker>;
#endif

}  // namespace internal

// FormRendererId and FieldRendererId uniquely identify a DOM form or field
// element, respectively, among all such elements in one frame.
//
// To uniquely identify forms and fields across frames, see FormGlobalId and
// FieldGlobalId.
//
// As a sentinel value, the FormRendererId of a synthetic form converts to
// `false` (== is_null()). A synthetic form is the collection of form fields
// outside of the scope of any <form> tag in a document.
//
// Since each page can trigger an overflow, security must not rely on their
// uniqueness.
//
// RendererIds are not necessarily persistent across page loads.
//
// The types are defined as subclasses instead of typedefs in order to avoid
// having to define out-of-line constructors in all structs that contain
// renderer IDs.
class FormRendererId : public internal::FormRendererIdType {
  using internal::FormRendererIdType::IdType;
};
class FieldRendererId : public internal::FieldRendererIdType {
  using internal::FieldRendererIdType::IdType;
};

namespace internal {

template <typename RendererId>
struct GlobalId {
  LocalFrameToken frame_token;
  RendererId renderer_id;

  // Not all platforms work with multiple frames and set the
  // FormData::host_frame and FormFieldData::host_frame yet.
  // Therefore, only check |renderer_id|.
  explicit constexpr operator bool() const {
    return static_cast<bool>(renderer_id);
  }

  friend auto operator<=>(const GlobalId<RendererId>& lhs,
                          const GlobalId<RendererId>& rhs) = default;
  friend bool operator==(const GlobalId<RendererId>& lhs,
                         const GlobalId<RendererId>& rhs) = default;
};

}  // namespace internal

// FormGlobalId and FieldGlobalId uniquely identify a DOM form or field
// element, respectively, among all such elements in all frames.
//
// As a sentinel value, the FormRendererId of a synthetic form converts to
// `false`. A synthetic form is the collection of form fields outside of the
// scope of any <form> tag in a page.
//
// GlobalIds are not necessarily persistent across page loads.
//
// Since LocalFrameTokens must not be leaked to renderer processes other than
// the one they originate from, Autofill does not send GlobalIds to any renderer
// process.
//
// TODO(crbug.com/40181498) Move to core/browser.
using FormGlobalId = internal::GlobalId<FormRendererId>;
using FieldGlobalId = internal::GlobalId<FieldRendererId>;

class LogBuffer;

std::ostream& operator<<(std::ostream& os, const FormRendererId& form);
std::ostream& operator<<(std::ostream& os, const FieldRendererId& field);
std::ostream& operator<<(std::ostream& os, const FormGlobalId& form);
std::ostream& operator<<(std::ostream& os, const FieldGlobalId& field);
LogBuffer& operator<<(LogBuffer& buffer, const FormRendererId& form);
LogBuffer& operator<<(LogBuffer& buffer, const FieldRendererId& field);
LogBuffer& operator<<(LogBuffer& buffer, const FormGlobalId& form);
LogBuffer& operator<<(LogBuffer& buffer, const FieldGlobalId& field);

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_COMMON_UNIQUE_IDS_H_