Skip to content

Conversation

sangwoo108
Copy link
Collaborator

Resolves

@sangwoo108 sangwoo108 added the CI/skip Do not run CI builds (except noplatform) label Oct 20, 2025
tree_tabs_enabled_.Init(
brave_tabs::kTreeTabsEnabled, prefs,
base::BindRepeating(&BraveTabContainer::UpdateLayoutOrientation,
base::Unretained(this)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reported by reviewdog 🐶
[semgrep] base::Unretained is most of the time unrequited, and a weak reference is better suited for secure coding.
Consider swapping Unretained for a weak reference.
base::Unretained usage may be acceptable when a callback owner is guaranteed
to be destroyed with the object base::Unretained is pointing to, for example:

- PrefChangeRegistrar
- base::*Timer
- mojo::Receiver
- any other class member destroyed when the class is deallocated


Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/chromium-uaf.yaml


Cc @thypon @goodov

Comment on lines 51 to 55
// Returns tree height that the `tab` at the given index belongs to.
int GetTreeHeightOfTab(int index) const;

// Returns tree node level of the `tab` at the given index.
int GetTreeNodeLevel(int index) const;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge these into TreeTabVisual(int index) ?

void BraveTabStripModel::BuildTreeTabs() {
CHECK(base::FeatureList::IsEnabled(tabs::features::kBraveTreeTab));
CHECK(!in_tree_mode_);
CHECK(!contents_data()->in_tree_tab_mode());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need TreeTabModel

Comment on lines +19 to +27
void set_use_vertical_tabs(bool vertical) { \
use_vertical_tabs_ = vertical; \
} \
void set_tab_strip(TabStrip* tab_strip) { \
tab_strip_ = tab_strip; \
} \
void set_use_tree_tabs(bool tree) { \
use_tree_tabs_ = tree; \
} \
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a good ideal - having many conditionals would be painful

Comment on lines +23 to +26
void set_in_tree_tab_mode(bool in_tree_tab_mode) {
in_tree_tab_mode_ = in_tree_tab_mode;
}
bool in_tree_tab_mode() const { return in_tree_tab_mode_; }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a good idea to have these here.

Comment on lines +29 to +48
void AddTabRecursive(std::unique_ptr<TabInterface> tab,
size_t index,
std::optional<tab_groups::TabGroupId> new_group_id,
bool new_pinned_state,
TabInterface* opener) override;
void MoveTabRecursive(size_t initial_index,
size_t final_index,
std::optional<tab_groups::TabGroupId> new_group_id,
bool new_pinned_state) override;
void MoveTabsRecursive(
const std::vector<int>& tab_indices,
size_t destination_index,
std::optional<tab_groups::TabGroupId> new_group_id,
bool new_pinned_state,
const std::set<TabCollection::Type>& retain_collection_types) override;
std::unique_ptr<TabInterface> RemoveTabAtIndexRecursive(
size_t index) override;
std::unique_ptr<TabInterface> RemoveTabRecursive(
TabInterface* tab,
bool close_empty_group_collection) override;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These only should route events to delegate or some other classes.

// and insert it into target collection. The target collection can be another
// TreeTabNode in case new tab has opener relationship with the previous tab.
// Otherwise, the target collection can be anything but pinned collection.
class BraveTabStripCollection : public TabStripCollection {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the responsibility of this class is to make a room for doing some actions in a certain evetns.

Comment on lines +44 to +56
if (delegate->IsNormalWindow()) {
tree_tabs_enabled_.Init(
brave_tabs::kTreeTabsEnabled, profile->GetPrefs(),
base::BindRepeating(&BraveTabStripModel::OnTreeTabRelatedPrefChanged,
base::Unretained(this)));
vertical_tabs_enabled_.Init(
brave_tabs::kVerticalTabsEnabled, profile->GetPrefs(),
base::BindRepeating(&BraveTabStripModel::OnTreeTabRelatedPrefChanged,
base::Unretained(this)));
OnTreeTabRelatedPrefChanged();
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These also should be responsibility of other class.

This commit introduces core functionality for the Tree Tabs feature, enabling
tab creation and node wrapping capabilities when adding new tabs.

Key changes:
- Added tab creation logic with proper node wrapping in tree structure
- When adding a new tab with a opener tab and the opener tab is the
  previous tab, the new tab's node will be set as a child of the opener
  tab's node.
- In this way, we'll have a tree structure like below when we open
  multiple tabs with the previous tab as opener sequentially:
```
    - Tab 1
      - Tab 2
        - Tab 3
          - Tab 4
```
This node will hold metadata about tree tab's node such as level and height.
base::BindRepeating(&TreeTabNode::OnWillDetach, base::Unretained(this)));
will_detach_tab_subscription_ =
current_tab_->RegisterWillDetach(base::BindRepeating(
&TreeTabNodeTabCollection::OnWillDetach, base::Unretained(this)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reported by reviewdog 🐶
[semgrep] base::Unretained is most of the time unrequited, and a weak reference is better suited for secure coding.
Consider swapping Unretained for a weak reference.
base::Unretained usage may be acceptable when a callback owner is guaranteed
to be destroyed with the object base::Unretained is pointing to, for example:

- PrefChangeRegistrar
- base::*Timer
- mojo::Receiver
- any other class member destroyed when the class is deallocated


Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/chromium-uaf.yaml


Cc @thypon @goodov


const TreeTabNodeTabCollection* TreeTabNodeTabCollection::GetTopLevelAncestor()
const {
return const_cast<TreeTabNodeTabCollection*>(this)->GetTopLevelAncestor();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reported by reviewdog 🐶
[semgrep] Avoid const_cast to remove const, except when implementing non-const getters in terms of const getters.

Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/const_cast.yaml


Cc @bridiver @cdesouza-chromium

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/skip Do not run CI builds (except noplatform) needs-security-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants