#include "components/autofill/content/renderer/form_autofill_util.h"
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/check_deref.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/debug/crash_logging.h"
#include "base/feature_list.h"
#include "base/i18n/case_conversion.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/autofill/content/renderer/timing.h"
#include "components/autofill/core/common/autocomplete_parsing_util.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/field_data_manager.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "components/autofill/core/common/unique_ids.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_autofill_state.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_element_collection.h"
#include "third_party/blink/public/web/web_form_control_element.h"
#include "third_party/blink/public/web/web_form_element.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_label_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_option_element.h"
#include "third_party/blink/public/web/web_remote_frame.h"
#include "third_party/blink/public/web/web_select_element.h"
#include "third_party/blink/public/web/web_select_list_element.h"
#include "third_party/re2/src/re2/re2.h"
WebAutofillState;
WebDocument;
WebElement;
WebElementCollection;
WebFormControlElement;
WebFormElement;
WebFrame;
WebInputElement;
WebLabelElement;
WebLocalFrame;
WebNode;
WebOptionElement;
WebSelectElement;
WebSelectListElement;
WebString;
WebVector;
namespace autofill::form_util {
struct ShadowFieldData { … };
namespace {
LabelSource;
constexpr int kMaxLengthForSingleButtonTitle = …;
constexpr int kMaxLengthForAllButtonTitles = …;
constexpr size_t kMaxShadowLevelsUp = …;
const char* const kButtonFeatures[] = …;
constexpr int kFormNeighborNodesToTraverse = …;
constexpr int kMaxConsecutiveInFourDigitCombinationMatches = …;
constexpr size_t kMaxFourDigitCombinationMatches = …;
constexpr std::string_view kAnchor = …;
constexpr std::string_view kAutocomplete = …;
constexpr std::string_view kAriaDescribedBy = …;
constexpr std::string_view kAriaLabel = …;
constexpr std::string_view kAriaLabelledBy = …;
constexpr std::string_view kBold = …;
constexpr std::string_view kBreak = …;
constexpr std::string_view kButton = …;
constexpr std::string_view kClass = …;
constexpr std::string_view kColspan = …;
constexpr std::string_view kDefinitionDescriptionTag = …;
constexpr std::string_view kDefinitionTermTag = …;
constexpr std::string_view kDiv = …;
constexpr std::string_view kFieldset = …;
constexpr std::string_view kFont = …;
constexpr std::string_view kFor = …;
constexpr std::string_view kForm = …;
constexpr std::string_view kFormControlSelector = …;
constexpr std::string_view kId = …;
constexpr std::string_view kIframe = …;
constexpr std::string_view kImage = …;
constexpr std::string_view kInput = …;
constexpr std::string_view kLabel = …;
constexpr std::string_view kListItem = …;
constexpr std::string_view kMeta = …;
constexpr std::string_view kName = …;
constexpr std::string_view kNoScript = …;
constexpr std::string_view kOption = …;
constexpr std::string_view kParagraph = …;
constexpr std::string_view kPlaceholder = …;
constexpr std::string_view kRole = …;
constexpr std::string_view kScript = …;
constexpr std::string_view kSpan = …;
#if BUILDFLAG(IS_ANDROID)
constexpr std::string_view kSrc = "src";
#endif
constexpr std::string_view kStrong = …;
constexpr std::string_view kSubmit = …;
constexpr std::string_view kTable = …;
constexpr std::string_view kTableCell = …;
constexpr std::string_view kTableHeader = …;
constexpr std::string_view kTableRow = …;
constexpr std::string_view kTitle = …;
constexpr std::string_view kType = …;
constexpr std::string_view kValue = …;
template <const std::string_view& string>
const WebString& GetWebString() { … }
template <const std::string_view& tag_name>
bool HasTagName(const WebElement& element) { … }
template <const std::string_view& tag_name>
bool HasTagName(const WebNode& node) { … }
template <const std::string_view& attribute>
bool HasAttribute(const WebElement& element) { … }
template <const std::string_view& attribute>
WebString GetAttribute(const WebElement& element) { … }
std::u16string GetFormIdentifier(const WebFormElement& form) { … }
WebNode NextWebNode(const WebNode& current_node, bool forward) { … }
bool IsTextInput(const WebInputElement& element) { … }
bool IsSelectElement(const WebFormControlElement& element) { … }
bool IsSelectListElement(const WebFormControlElement& element) { … }
bool IsSelectOrSelectListElement(const WebFormControlElement& element) { … }
bool IsTextInput(const WebFormControlElement& element) { … }
bool IsMonthInput(const WebInputElement& element) { … }
bool IsCheckableElement(const WebFormControlElement& element) { … }
bool IsCheckableElement(const WebElement& element) { … }
bool IsTraversableContainerElement(const WebNode& node) { … }
bool IsWebElementEmpty(const WebElement& root) { … }
size_t CalculateTableCellColumnSpan(const WebElement& element) { … }
const std::u16string CombineAndCollapseWhitespace(const std::u16string& prefix,
const std::u16string& suffix,
bool force_whitespace) { … }
std::u16string FindChildTextInner(const WebNode& node,
int depth,
const std::set<WebNode>& divs_to_skip) { … }
std::u16string FindChildTextWithIgnoreList(
const WebNode& node,
const std::set<WebNode>& divs_to_skip) { … }
struct InferredLabel { … };
std::optional<InferredLabel> InferLabelFromSibling(
const WebFormControlElement& element,
bool forward) { … }
void AddButtonTitleToList(std::u16string title,
mojom::ButtonTitleType button_type,
ButtonTitleList* list) { … }
bool AttributeHasButtonFeature(const WebString& attribute) { … }
bool ElementAttributesHasButtonFeature(const WebElement& element) { … }
void FindElementsWithButtonFeatures(const WebElementCollection& elements,
mojom::ButtonTitleType button_type,
bool extract_value_attribute,
ButtonTitleList* list) { … }
std::vector<WebElement> GetWebElementsFromIdList(const WebDocument& document,
const WebString& id_list) { … }
std::u16string CoalesceTextByIdList(const WebDocument& document,
const WebString& id_list) { … }
std::u16string GetAriaLabel(const WebDocument& document,
const WebElement& element) { … }
std::u16string GetAriaDescription(const WebDocument& document,
const WebElement& element) { … }
std::optional<InferredLabel> InferLabelFromPrevious(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromNext(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromPlaceholder(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromAriaLabel(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromOverlayingSuccessor(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromValueAttribute(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromTableColumn(const WebNode& cell) { … }
std::optional<InferredLabel> InferLabelFromTableRow(const WebNode& cell) { … }
std::optional<InferredLabel> InferLabelFromDivTable(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelFromDefinitionList(const WebNode& dd) { … }
std::optional<InferredLabel> InferLabelFromAncestors(
const WebFormControlElement& element) { … }
std::optional<InferredLabel> InferLabelForElement(
const WebFormControlElement& element) { … }
void InferLabelForElements(
base::span<const WebFormControlElement> control_elements,
std::vector<FormFieldData>& fields) { … }
void RemoveDuplicatesAndLimitTotalLength(ButtonTitleList* result) { … }
ButtonTitleList InferButtonTitlesForForm(const WebFormElement& web_form) { … }
WebVector<WebElement> GetListItemsForSelectOrSelectList(
const WebFormControlElement& element) { … }
void FilterOptionElementsAndGetOptionStrings(
const WebVector<WebElement>& option_elements,
std::vector<SelectOption>* options) { … }
bool ShouldSkipFillField(const FormFieldData::FillData& field,
const WebFormControlElement& element) { … }
void FillFormField(const FormFieldData::FillData& data,
bool is_initiating_node,
WebFormControlElement& field,
FieldDataManager& field_data_manager) { … }
void PreviewFormField(const FormFieldData::FillData& data,
WebFormControlElement& field,
FieldDataManager& field_data_manager) { … }
struct CompareByRendererId { … };
FormFieldData* SearchForFormControlByName(
const std::u16string& field_name,
base::span<const std::pair<FormFieldData*, ShadowFieldData>> fields,
LabelSource& label_source) { … }
void MatchLabelsAndFields(const WebDocument& root,
base::span<FormFieldData> fields,
std::vector<ShadowFieldData> shadow_fields) { … }
bool IsAdIframe(const WebElement& element) { … }
bool IsWebElementVisible(const WebElement& element) { … }
WebFormElement GetClosestAncestorFormElement(WebNode n) { … }
bool IsDOMPredecessor(const WebNode& x,
const WebNode& y,
const WebNode& ancestor_hint) { … }
bool IsVisibleIframe(const WebElement& element) { … }
bool IsRelevantChildFrame(const WebElement& element) { … }
std::vector<WebElement> GetIframeElements(const WebDocument& document,
const WebFormElement& form_element) { … }
bool ScriptModifiedUsernameOrCreditCardNumberAcceptable(
const std::u16string& value,
const std::u16string& typed_value,
const FieldDataManager& field_data_manager) { … }
uint64_t GetMaxLength(const WebFormControlElement& element) { … }
void GetDataListSuggestions(const WebInputElement& element,
std::vector<SelectOption>* options) { … }
bool HasFormAncestor(WebNode node) { … }
std::vector<WebFormControlElement> GetOwnedFormControls(
const WebDocument& document,
const WebFormElement& form_element) { … }
void WebFormControlElementToFormField(
const WebFormElement& form_element,
const WebFormControlElement& element,
const FieldDataManager* field_data_manager,
DenseSet<ExtractOption> extract_options,
FormFieldData* field,
ShadowFieldData* shadow_data) { … }
#if BUILDFLAG(IS_ANDROID)
bool IsLikelyCaptchaIframe(const WebElement& element) {
static constexpr std::string_view kCaptcha = "captcha";
return GetAttribute<kSrc>(element).Find(kCaptcha) != std::string::npos ||
GetAttribute<kTitle>(element).Find(kCaptcha) != std::string::npos ||
GetAttribute<kId>(element).Find(kCaptcha) != std::string::npos ||
GetAttribute<kName>(element).Find(kCaptcha) != std::string::npos;
}
#endif
std::optional<FormData> ExtractFormDataWithFieldsAndFrames(
const WebDocument& document,
const WebFormElement& form_element,
const FieldDataManager& field_data_manager,
DenseSet<ExtractOption> extract_options) { … }
}
InferredLabel::InferredLabel(std::u16string label, LabelSource source)
: … { … }
std::optional<InferredLabel> InferredLabel::BuildIfValid(std::u16string label,
LabelSource source) { … }
std::string GetAutocompleteAttribute(const WebElement& element) { … }
std::optional<FormData> ExtractFormData(
const WebDocument& document,
const WebFormElement& form_element,
const FieldDataManager& field_data_manager,
const CallTimerState& timer_state,
DenseSet<ExtractOption> extract_options) { … }
GURL GetCanonicalActionForForm(const WebFormElement& form) { … }
bool IsTextAreaElement(const WebFormControlElement& element) { … }
bool IsTextAreaElementOrTextInput(const WebFormControlElement& element) { … }
bool IsAutofillableInputElement(const WebInputElement& element) { … }
bool IsAutofillableElement(const WebFormControlElement& element) { … }
FormControlType ToAutofillFormControlType(blink::mojom::FormControlType type) { … }
bool IsCheckable(FormControlType form_control_type) { … }
bool IsWebauthnTaggedElement(const WebFormControlElement& element) { … }
bool IsElementEditable(const WebInputElement& element) { … }
bool IsWebElementFocusableForAutofill(const WebElement& element) { … }
FormRendererId GetFormRendererId(const WebElement& e) { … }
FieldRendererId GetFieldRendererId(const WebElement& e) { … }
base::i18n::TextDirection GetTextDirectionForElement(
const WebFormControlElement& element) { … }
std::vector<WebFormControlElement> GetOwnedAutofillableFormControls(
const WebDocument& document,
const WebFormElement& form_element) { … }
WebFormElement GetOwningForm(const WebFormControlElement& form_control) { … }
std::optional<std::pair<FormData, raw_ref<const FormFieldData>>>
FindFormAndFieldForFormControlElement(
const WebFormControlElement& element,
const FieldDataManager& field_data_manager,
const CallTimerState& timer_state,
DenseSet<ExtractOption> extract_options) { … }
std::optional<FormData> FindFormForContentEditable(
const WebElement& content_editable) { … }
std::vector<std::pair<FieldRef, WebAutofillState>> ApplyFieldsAction(
const WebDocument& document,
base::span<const FormFieldData::FillData> fields,
mojom::FormActionType action_type,
mojom::ActionPersistence action_persistence,
FieldDataManager& field_data_manager) { … }
void ClearPreviewedElements(
base::span<std::pair<WebFormControlElement, WebAutofillState>>
previewed_elements) { … }
bool IsOwnedByFrame(const WebNode& node, content::RenderFrame* frame) { … }
bool MaybeWasOwnedByFrame(const WebNode& node, content::RenderFrame* frame) { … }
bool IsWebpageEmpty(const WebLocalFrame* frame) { … }
std::u16string FindChildText(const WebNode& node) { … }
ButtonTitleList GetButtonTitles(const WebFormElement& web_form,
ButtonTitlesCache* button_titles_cache) { … }
WebFormElement GetFormByRendererId(FormRendererId form_renderer_id) { … }
WebFormControlElement GetFormControlByRendererId(
FieldRendererId queried_form_control) { … }
WebElement GetContentEditableByRendererId(FieldRendererId field_renderer_id) { … }
void TraverseDomForFourDigitCombinations(
const WebDocument& document,
base::OnceCallback<void(const std::vector<std::string>&)>
potential_matches) { … }
std::u16string GetAriaLabelForTesting(
const WebDocument& document,
const WebElement& element) { … }
std::u16string GetAriaDescriptionForTesting(
const WebDocument& document,
const WebElement& element) { … }
void InferLabelForElementsForTesting(
base::span<const blink::WebFormControlElement> control_elements,
std::vector<FormFieldData>& fields) { … }
std::vector<blink::WebFormControlElement>
GetOwnedFormControlsForTesting(
const blink::WebDocument& document,
const blink::WebFormElement& form_element) { … }
WebNode NextWebNodeForTesting(
const WebNode& current_node,
bool forward) { … }
std::u16string FindChildTextWithIgnoreListForTesting(
const WebNode& node,
const std::set<WebNode>& divs_to_skip) { … }
bool IsWebElementVisibleForTesting(const WebElement& element) { … }
bool IsVisibleIframeForTesting(
const WebElement& iframe_element) { … }
WebFormElement GetClosestAncestorFormElementForTesting(WebNode n) { … }
bool IsDOMPredecessorForTesting(const WebNode& x,
const WebNode& y,
const WebNode& ancestor_hint) { … }
uint64_t GetMaxLengthForTesting(
const WebFormControlElement& element) { … }
void WebFormControlElementToFormFieldForTesting(
const WebFormElement& form_element,
const WebFormControlElement& element,
const FieldDataManager* field_data_manager,
DenseSet<ExtractOption> extract_options,
FormFieldData* field) { … }
void GetDataListSuggestionsForTesting(
const WebInputElement& element,
std::vector<SelectOption>* options) { … }
}