CVE-2026-2323
Overview
Background
- `views::Label`
- the Views toolkit text control used throughout Chrome’s desktop UI, including the download bubble that shows downloaded filenames.
- `GetBoundedTextSize`
- the
Labelmethod that computes how large the label’s text should be within given bounds; the commit says it is used for multi-line label height. - Baseline height vs. visual height
base_line_heightis the nominal per-line height, whereasfull_text_->GetStringSize()reflects the actual rendered extent, which can be taller for glyphs with large ascenders or descenders.- Download bubble
- the toolbar UI listing recent downloads by filename, where (per the commit) filenames with such characters were vertically cut off.
Root Cause Analysis
In the multi-line branch of Label::GetBoundedTextSize, after size = full_text_->GetStringSize(), the code overwrote the height with GetRequiredLines() * base_line_height whenever base_line_height > 0, discarding the measured string height. For text whose glyphs extend beyond the nominal line box (tall ascenders/descenders, e.g. stacked combining marks or certain scripts), the label was therefore sized too short and the rendered text was clipped. The diff itself is a layout correctness fix; its security relevance comes from the advisory (“Inappropriate implementation in Downloads”) and the commit note that the download bubble vertically truncated filenames, which means the UI could misrepresent what was downloaded (spoofing relevance inferred).
The fix keeps the line-count product only as a minimum, setting the height to std::max(size.height(), min_total_height) so the label is never shorter than its actual rendered text.
Label::GetBoundedTextSize trusted the nominal baseline height instead of the measured text height, so attacker-chosen glyphs could overflow and be clipped; taking the maximum of the two guarantees the full rendered text fits.Attack Path
- Serve a download with a crafted filename a website triggers a download whose filename contains characters with very large ascenders or descenders (filename control by the site is inferred from normal download behavior; not shown in the diff).
- Download bubble lays out the name
the bubble’s multi-line
views::Labelcomputes its height viaGetBoundedTextSizeusingGetRequiredLines() * base_line_height. - Filename rendered clipped the tall glyphs exceed the computed height and are vertically cut off, so the displayed name does not faithfully show the real filename.
- User misled about the file the user may misjudge what was downloaded (e.g. its name or apparent type) before opening it (inferred).
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifui/views/controls/label.cc |
modified |
Files Changed
ash/clipboard/views/clipboard_history_item_view_pixeltest.ccui/views/controls/label.cc
Audit Directions
- Security-sensitive text sized by nominal metricsreview labels showing origins, filenames, extension names or permission subjects for height/width computed from font baseline or average character metrics rather than measured string bounds.
- Clipping and eliding of attacker-controlled stringscheck that truncation in download, permission and dialog UI preserves the security-relevant part (e.g. the extension or eTLD+1) and cannot be manipulated by combining marks or unusual scripts.
- Pixel-test coverage with adversarial glyphsadd rendering tests for stacked diacritics and tall-script filenames in download and security UI to catch clipping regressions.
Patch
From 62c1a660407ec8f7589a271587ffee39bc215751 Mon Sep 17 00:00:00 2001
From: David Yeung <dayeung@chromium.org>
Date: Mon, 15 Dec 2025 19:00:09 -0800
Subject: [PATCH] Fix Multiline label height for glyphs w/ high ascenders and descenders
Label::GetBoundedTextSize calculated the text height solely based on the
baseline height. This ignored the actual visual height of the rendered
text, causing truncation for strings containing characters with large
ascenders or descenders.
This caused bugs with the DownloadBubble where filenames with special
characters were vertically cut off.
Fix is to use the maximum between the text's visual height and the
baseline height.
https://screenshot.googleplex.com/9DZJj79aNFGHccv
Ash pixel test label was also adjusted because of the change. No major
visual changes, just slight visual offset. Instead of triaging, ash
pixel tests require updating the revision number.
Fixed: 467442136
Change-Id: Id0a8b2e95353896e44800801fa508f4e17b7a3f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7256959
Reviewed-by: David Black <dmblack@google.com>
Reviewed-by: Keren Zhu <kerenzhu@chromium.org>
Reviewed-by: Andrew Xu <andrewxu@google.com>
Commit-Queue: David Black <dmblack@google.com>
Auto-Submit: David Yeung <dayeung@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1559108}
---
diff --git a/ash/clipboard/views/clipboard_history_item_view_pixeltest.cc b/ash/clipboard/views/clipboard_history_item_view_pixeltest.cc
index a59b475..0dcf831 100644
--- a/ash/clipboard/views/clipboard_history_item_view_pixeltest.cc
+++ b/ash/clipboard/views/clipboard_history_item_view_pixeltest.cc
@@ -63,14 +63,14 @@
clipboard_history_util::kBitmapItemView);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"bitmap_item_view",
- /*revision_number=*/1, bitmap_contents));
+ /*revision_number=*/2, bitmap_contents));
// Press the tab key to focus on the delete button.
GetEventGenerator()->PressAndReleaseKey(ui::VKEY_TAB, ui::EF_NONE);
EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
"bitmap_item_view_with_delete_button",
- /*revision_number=*/1, bitmap_contents));
+ /*revision_number=*/2, bitmap_contents));
}
} // namespace ash
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index 0c5bb34..2c1b9783 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -1422,8 +1422,9 @@
size = full_text_->GetStringSize();
if (base_line_height > 0) {
- size.set_height(base::checked_cast<int>(GetRequiredLines()) *
- base_line_height);
+ const int min_total_height =
+ base::checked_cast<int>(GetRequiredLines()) * base_line_height;
+ size.set_height(std::max(size.height(), min_total_height));
}
}
Original Bug Report
when the filename contains a very long with special character can break/remove the extension of file in download buble
VULNERABILITY DETAILS this bug almost simillar of https://issues.chromium.org/issues/423956129 (this happened on extension dialog)
when the filename contains a very long filename with the addition (꧁ᬊᬁ ᬊ᭄꧂ツ) this can break/remove the extension of file in download buble (normally when using long filename without ꧂ it still show the extension of file. but when using ꧁ᬊᬁ it can break the text),so that it leads to spoof.
Steps to reproduce:
- Open spooffile.html
- click on spoof file button (for spoof)
VERSION Chrome Version 145.0.7571.0 (Official Build) canary (64-bit) Operating System: Windows 11
REPRODUCTION CASE Please include a demonstration of the security bug, such as an attached HTML or binary file that reproduces the bug when loaded in Chrome. PLEASE make the file as small as possible and remove any content not required to demonstrate the bug, or any personal or confidential information.
Please attach files directly, not in zip or other archive formats, and if you’ve created a demonstration site please also attach the files needed to reproduce the demonstration locally.
FOR CRASHES, PLEASE INCLUDE THE FOLLOWING ADDITIONAL INFORMATION Type of crash: [tab, browser, etc.] Crash State: [see link above: stack trace with symbols, registers, exception record] Client ID (if relevant): [see link above]
CREDIT INFORMATION Externally reported security bugs may appear in Chrome release notes. If this bug is included, how would you like to be credited? Reporter credit: [goes here]