openai / openai/codex

Reverse history search can find a combining mark without showing a highlight

Open
#45,034 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI TUI
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

codex-cli 0.0.0, built from the audited source revision d43f1e7eb27b204fd0e565891869280df3ba2346. Running codex --version on that isolated source build returned codex-cli 0.0.0. No host-installed Codex binary was used.

What subscription do you have?

Not applicable to this local reproduction. No Codex account was logged in or used.

Which model were you using?

Not applicable. No model request was made.

What platform is your computer?

Linux x86_64. This is the sanitized result of uname -mprs; host-specific kernel fields are omitted from the public draft.

What terminal emulator and version are you using (if applicable)?

The reproducer runs as a non-interactive Bash/Cargo process, with no terminal emulator and no multiplexer. It builds the pinned source into a separate temporary target directory and uses a separate CODEX_HOME.

Codex doctor report
not available
What issue are you seeing?

Reverse history search can report a real match while showing no visible
highlight. If a history entry contains a followed by U+0301 COMBINING ACUTE
ACCENT and the query is only U+0301, the matcher returns the byte range of the
mark, 1..3. TextArea then styles that zero-width suffix instead of the visible
cell, so the user cannot see which text matched.

What steps can reproduce the bug?
  1. Put the history entry into the local Codex history.
  2. Press Ctrl-R to open reverse history search.
  3. Enter U+0301 COMBINING ACUTE ACCENT as the search query.
  4. The entry is found, but the visible grapheme has no search highlight.

From this report directory, run:

bash attachments/repro.sh

The wrapper first builds codex-cli from the pinned source revision into
isolated CARGO_HOME and CARGO_TARGET_DIR directories and prints the
matching codex --version. It then runs the local matching and TextArea
style oracle. The wrapper intentionally exits with status 1 when the current
source violates the invariant.

The source-level target check reports:

target ranges=[1..3] expected_visible_range=0..3
target overlay x=1 width=0 visible_cell=false
FAIL combining-mark match is invisible ...
checked=1 failures=1

No account, provider, model request, or host history is used. The repeated-run
output and checksum are in attachments/evidence.log;
runtime details are in attachments/environment.txt.

What is the expected behavior?

Any successful search match should produce a visible highlight. A match that
intersects an extended grapheme should style that complete grapheme, or at
least its visible base cell, rather than styling only a zero-width combining
mark.

Additional information

The audited source revision is
d43f1e7eb27b204fd0e565891869280df3ba2346. Public Codex main was checked
at c4017a87aacc7558002b7cb510025e967c1d765e on 2026-09-12; the relevant
history search, composer, and TextArea files were unchanged. The report is
pinned to the audited revision.

history_search_highlight_ranges calls
case_insensitive_match_ranges and returns its byte ranges directly when a
search has a match:

history_search.rs

The matcher lowercases and folds each Unicode scalar while retaining a
scalar-to-original-byte mapping. A query containing only the combining mark
therefore maps back to the mark's original range, rather than expanding to the
extended grapheme containing the preceding base:

history_search.rs

The composer adds these ranges to the highlight overlays:

chat_composer.rs

TextArea computes the overlay x position from display width before the range
and sends only the overlap bytes to the buffer. For range 1..3, the preceding
a occupies one cell and the styled combining mark has display width zero:

textarea.rs

The search state is therefore correct enough to report a match, but the
highlight contract is not visible for a zero-width component. This is a
rendering/feedback issue, not a history matching or editing failure.

I searched the existing Codex issues and did not find one covering a successful
reverse search whose combining-mark highlight is invisible. Existing reports
#37839 and
#30657 concern grapheme-aware
editing and backspace behavior.

The report artifacts are:

attachments.zip

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run bash attachments/repro.sh first, then read history_search.rs, chat_composer.rs, and textarea.rs at the linked ranges. Trace how the combining-mark match range becomes a TextArea overlay, and use the provided oracle to verify that the á grapheme receives a visible highlight without regressing ordinary matches.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.