Code: void AXTree::PopulateOrderedSetItems(const AXNode* ordered_set,
                                     const AXNode* local_parent,
                                     std::vector<const AXNode*>& items,
                                     bool node_is_radio_button) const {
  if (!(ordered_set == local_parent)) {
    if (local_parent->data().role == ordered_set->data().role)
      return;
  }

   for (int i = 0; i < local_parent->child_count(); ++i) {
     const AXNode* child = local_parent->GetUnignoredChildAtIndex(i);
 
     if (node_is_radio_button &&
         child->data().role == ax::mojom::Role::kRadioButton)
      items.push_back(child);

    if (!node_is_radio_button && child->SetRoleMatchesItemRole(ordered_set))
      items.push_back(child);

    if (child->data().role == ax::mojom::Role::kGenericContainer ||
        child->data().role == ax::mojom::Role::kIgnored) {
      PopulateOrderedSetItems(ordered_set, child, items, node_is_radio_button);
    }
  }
}

Commit Message: Position info (item n of m) incorrect if hidden focusable items in list

Bug: 836997
Change-Id: I971fa7076f72d51829b36af8e379260d48ca25ec
Reviewed-on: https://chromium-review.googlesource.com/c/1450235
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#628890}
CWE ID: CWE-190
void AXTree::PopulateOrderedSetItems(const AXNode* ordered_set,
                                     const AXNode* local_parent,
                                     std::vector<const AXNode*>& items,
                                     bool node_is_radio_button) const {
  if (!(ordered_set == local_parent)) {
    if (local_parent->data().role == ordered_set->data().role)
      return;
  }

   for (int i = 0; i < local_parent->child_count(); ++i) {
     const AXNode* child = local_parent->GetUnignoredChildAtIndex(i);
 
    // Invisible children should not be counted.
    // However, in the collapsed container case (e.g. a combobox), items can
    // still be chosen/navigated. However, the options in these collapsed
    // containers are historically marked invisible. Therefore, in that case,
    // count the invisible items. Only check 2 levels up, as combobox containers
    // are never higher.
    if (child->data().HasState(ax::mojom::State::kInvisible) &&
        !IsCollapsed(local_parent) && !IsCollapsed(local_parent->parent())) {
      continue;
    }

     if (node_is_radio_button &&
         child->data().role == ax::mojom::Role::kRadioButton)
      items.push_back(child);

    if (!node_is_radio_button && child->SetRoleMatchesItemRole(ordered_set))
      items.push_back(child);

    if (child->data().role == ax::mojom::Role::kGenericContainer ||
        child->data().role == ax::mojom::Role::kIgnored) {
      PopulateOrderedSetItems(ordered_set, child, items, node_is_radio_button);
    }
  }
}
