summaryrefslogtreecommitdiff
path: root/chromium/third_party
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-07-31 13:49:43 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-05 09:06:37 +0000
commit989a5679948742873fa248c70f1b3fa85c9f5027 (patch)
tree56c0d1f62e443cf6245ddbf64fcbeba30fa57666 /chromium/third_party
parent687e6c44d85e93f8e789e5378779baa624900ba5 (diff)
downloadqtwebengine-chromium-989a5679948742873fa248c70f1b3fa85c9f5027.tar.gz
[Backport] Critical security issue 977057
[Merge to 76] Check AX cache if labelled before fetching labels HTML labelable elements can cause extreme slowness while loading in some cases. We should only call html_element->labels() if the current element is known to have labels (we can check our relationship cache). (cherry picked from commit b90d7299cdc96191d94e1ecfe1a4f82a625531f8) Bug: 977057, 976849 Change-Id: Ia5e0e312b3a5e1d2d2d4cfdc5249f6a58b38147c Commit-Queue: Aaron Leventhal <aleventhal@chromium.org> Reviewed-by: Nektarios Paisios <nektar@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#672099} Reviewed-by: Katie Dektar <katie@chromium.org> Cr-Commit-Position: refs/branch-heads/3809@{#899} Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002} Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/third_party')
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h13
5 files changed, 48 insertions, 5 deletions
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 6f67e81f0b9..9399d5ee150 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2631,7 +2631,9 @@ String AXNodeObject::NativeTextAlternative(
name_sources->back().native_source = kAXTextFromNativeHTMLLabel;
}
- LabelsNodeList* labels = html_element->labels();
+ LabelsNodeList* labels = nullptr;
+ if (AXObjectCache().MayHaveHTMLLabel(*html_element))
+ labels = html_element->labels();
if (labels && labels->length() > 0) {
HeapVector<Member<Element>> label_elements;
for (unsigned label_index = 0; label_index < labels->length();
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 1606304ac1c..1dd58539faa 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -894,6 +894,19 @@ void AXObjectCacheImpl::UpdateAriaOwns(
relation_cache_->UpdateAriaOwns(owner, id_vector, owned_children);
}
+bool AXObjectCacheImpl::MayHaveHTMLLabel(const HTMLElement& elem) {
+ // Return false if this type of element will not accept a <label for> label.
+ if (!elem.IsLabelable())
+ return false;
+
+ // Return true if a <label for> pointed to this element at some point.
+ if (relation_cache_->MayHaveHTMLLabelViaForAttribute(elem))
+ return true;
+
+ // Return true if any amcestor is a label, as in <label><input></label>.
+ return Traversal<HTMLLabelElement>::FirstAncestor(elem);
+}
+
void AXObjectCacheImpl::CheckedStateChanged(Node* node) {
PostNotification(node, ax::mojom::Event::kCheckedStateChanged);
}
@@ -1191,7 +1204,8 @@ void AXObjectCacheImpl::HandleValidationMessageVisibilityChanged(
}
void AXObjectCacheImpl::LabelChanged(Element* element) {
- TextChanged(ToHTMLLabelElement(element)->control());
+ // Will call back to TextChanged() when done updating relation cache.
+ relation_cache_->LabelChanged(element);
}
void AXObjectCacheImpl::InlineTextBoxesUpdated(
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 684b1f4713c..58c7639c3fd 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -221,6 +221,8 @@ class MODULES_EXPORT AXObjectCacheImpl
const Vector<String>& id_vector,
HeapVector<Member<AXObject>>& owned_children);
+ bool MayHaveHTMLLabel(const HTMLElement& elem);
+
// Synchronously returns whether or not we currently have permission to
// call AOM event listeners.
bool CanCallAOMEventListeners() const;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
index c587778440b..5c77eb092c3 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -9,6 +9,8 @@
namespace blink {
+using namespace html_names;
+
AXRelationCache::AXRelationCache(AXObjectCacheImpl* object_cache)
: object_cache_(object_cache) {}
@@ -163,6 +165,14 @@ void AXRelationCache::UpdateAriaOwns(
validated_owned_child_axids);
}
+bool AXRelationCache::MayHaveHTMLLabelViaForAttribute(
+ const HTMLElement& labelable) {
+ const AtomicString& id = labelable.GetIdAttribute();
+ if (id.IsEmpty())
+ return false;
+ return all_previously_seen_label_target_ids_.Contains(id);
+}
+
// Fill source_objects with AXObjects for relations pointing to target.
void AXRelationCache::GetReverseRelated(
Node* target,
@@ -257,8 +267,12 @@ void AXRelationCache::TextChanged(AXObject* object) {
}
void AXRelationCache::LabelChanged(Node* node) {
- if (HTMLElement* control = ToHTMLLabelElement(node)->control())
- TextChanged(Get(control));
+ const AtomicString& id = ToHTMLElement(node)->FastGetAttribute(kForAttr);
+ if (!id.IsEmpty()) {
+ all_previously_seen_label_target_ids_.insert(id);
+ if (HTMLElement* control = ToHTMLLabelElement(node)->control())
+ TextChanged(Get(control));
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
index 6c3af3d9bc4..c843dfe1d5e 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
@@ -35,6 +35,9 @@ class AXRelationCache {
const Vector<String>& id_vector,
HeapVector<Member<AXObject>>& owned_children);
+ // Return true if any label ever pointed to the element via the for attribute.
+ bool MayHaveHTMLLabelViaForAttribute(const HTMLElement&);
+
// Given an element in the DOM tree that was either just added or whose id
// just changed, check to see if another object wants to be its parent due to
// aria-owns. If so, update the tree by calling childrenChanged() on the
@@ -51,6 +54,8 @@ class AXRelationCache {
void UpdateReverseRelations(const AXObject* relation_source,
const Vector<String>& target_ids);
+ void LabelChanged(Node*);
+
private:
// If any object is related to this object via <label for>, aria-owns,
// aria-describedby or aria-labeledby, update the text for the related object.
@@ -87,13 +92,19 @@ class AXRelationCache {
// and fire the appropriate change events.
HashMap<String, HashSet<AXID>> id_attr_to_related_mapping_;
+ // HTML id attributes that at one time havehad a <label for> pointing to it.
+ // IDs are not necessarily removed from this set. It is not necessary to
+ // remove IDs as false positives are ok. Being able to determine that a
+ // labelable element has never had an associated label allows the accessible
+ // name calculation to be optimized.
+ HashSet<AtomicString> all_previously_seen_label_target_ids_;
+
// Helpers that call back into object cache
AXObject* ObjectFromAXID(AXID) const;
AXObject* GetOrCreate(Node*);
AXObject* Get(Node*);
void ChildrenChanged(AXObject*);
void TextChanged(AXObject*);
- void LabelChanged(Node*);
DISALLOW_COPY_AND_ASSIGN(AXRelationCache);
};