Skip to content

refactor: consolidate output hygiene into output.rs#527

Merged
jpoehnelt merged 4 commits intomainfrom
fix/output-hygiene
Mar 18, 2026
Merged

refactor: consolidate output hygiene into output.rs#527
jpoehnelt merged 4 commits intomainfrom
fix/output-hygiene

Conversation

@jpoehnelt
Copy link
Member

Summary

Introduce src/output.rs that consolidates terminal sanitization, coloring, and stderr messaging into a single module.

Changes

New output.rs module:

  • sanitize_for_terminal — upgraded to also strip dangerous Unicode (bidi overrides, zero-width chars, directional isolates, line/paragraph separators)
  • reject_dangerous_chars — renamed from reject_control_chars, moved from validate.rs
  • is_dangerous_unicode — shared predicate
  • colorize + stderr_supports_color — moved from error.rs (respects NO_COLOR + TTY detection)
  • status/warn/info — auto-sanitizing stderr helpers for future use

Security fixes:

  • watch.rs:103
  • triage.rs — user --query string now sanitized before printing
  • watch.rs — 3 inline \x1b[...] ANSI codes replaced with colorize() to respect NO_COLOR

Migration:

  • error.rs re-exports sanitize_for_terminal + colorize from output.rs (no caller changes needed)
  • validate.rs re-exports reject_control_chars as alias for reject_dangerous_chars (backwards compatible)

Test results

  • cargo clippy -- -D warnings
  • 724/724 tests pass ✅

Introduce src/output.rs that consolidates:
- sanitize_for_terminal (upgraded: now also strips bidi overrides,
  zero-width chars, directional isolates, line/paragraph separators)
- reject_dangerous_chars (renamed from reject_control_chars)
- is_dangerous_unicode predicate
- colorize + stderr_supports_color (NO_COLOR + TTY detection)
- status/warn/info stderr helpers (auto-sanitize)

Migrate existing callers via re-exports from error.rs and validate.rs.

Fix watch.rs:
- Sanitize raw API error body in eprintln (was high-risk injection vector)
- Replace 3 inline ANSI escape codes with colorize() for NO_COLOR support

Fix triage.rs:
- Sanitize user --query string in no_messages_msg output
@changeset-bot
Copy link

changeset-bot bot commented Mar 17, 2026

🦋 Changeset detected

Latest commit: db5713d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@googleworkspace-bot googleworkspace-bot added area: core Core CLI parsing, commands, error handling, utilities and removed area: http labels Mar 17, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the application's terminal output handling by consolidating all sanitization, coloring, and stderr messaging into a dedicated output.rs module. This change enhances the security posture by preventing various forms of terminal injection and Unicode spoofing, while also improving the user experience through consistent and environment-aware colorization. The refactoring ensures that all untrusted content printed to the terminal is properly sanitized, and existing callers are seamlessly migrated through re-exports.

Highlights

  • Consolidated Output Hygiene Module: A new src/output.rs module was introduced to centralize terminal sanitization, coloring, and stderr messaging functions, improving maintainability and consistency.
  • Enhanced Terminal Sanitization: The sanitize_for_terminal function was upgraded to strip dangerous Unicode characters, including bidi overrides, zero-width characters, directional isolates, and line/paragraph separators, in addition to ASCII control characters.
  • Improved Security for User Input and API Output: Security vulnerabilities were addressed by sanitizing user --query strings in triage.rs and API error bodies in watch.rs before printing them to the terminal, preventing potential escape-sequence injection.
  • Consistent Color Handling: Inline ANSI escape codes in watch.rs were replaced with calls to the new colorize() function, ensuring that terminal coloring respects the NO_COLOR environment variable and TTY detection.
  • Refactored Validation Logic: The reject_control_chars function was moved from validate.rs to output.rs (renamed to reject_dangerous_chars) and re-exported, consolidating character validation logic.
  • New Stderr Helper Functions: New status, warn, and info helper functions were added to output.rs to provide auto-sanitizing stderr output, simplifying future usage.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@googleworkspace-bot googleworkspace-bot added the cla: yes This human has signed the Contributor License Agreement. label Mar 17, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great refactoring that consolidates terminal output-related functionality into a new output.rs module. The changes significantly improve code organization and security by introducing robust sanitization for terminal output, which helps prevent control sequence injection. The added Unicode character filtering is a valuable enhancement. The migration to use the new colorize function correctly respects the NO_COLOR environment variable. I've found one area for improvement in the new reject_dangerous_chars function to make it even more robust.

@github-actions github-actions bot added the gemini: reviewed Gemini Code Assist has reviewed the latest changes label Mar 17, 2026
@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

❌ Patch coverage is 87.16216% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.92%. Comparing base (9c26e3c) to head (db5713d).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/output.rs 91.53% 11 Missing ⚠️
src/helpers/gmail/watch.rs 45.45% 6 Missing ⚠️
src/helpers/gmail/read.rs 50.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #527      +/-   ##
==========================================
+ Coverage   68.10%   68.92%   +0.82%     
==========================================
  Files          40       42       +2     
  Lines       17954    18762     +808     
==========================================
+ Hits        12227    12932     +705     
- Misses       5727     5830     +103     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Update all 10 caller files to import sanitize_for_terminal directly
from crate::output instead of going through crate::error re-exports.
Remove pub(crate) re-exports from error.rs and validate.rs.
@github-actions github-actions bot removed the gemini: reviewed Gemini Code Assist has reviewed the latest changes label Mar 17, 2026
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Address PR review: the manual (c as u32) < 0x20 check missed
C1 control characters (U+0080-U+009F), including CSI (U+009B) which
can inject terminal escape sequences. Using char::is_control() covers
both C0 and C1 ranges.

Add test for CSI rejection.
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great refactoring that consolidates terminal output hygiene into a new output.rs module. The changes significantly improve security by introducing sanitization for user-provided query strings and API error responses, preventing potential terminal injection attacks. The move from raw ANSI escape codes to a centralized colorize function that respects NO_COLOR is also a welcome improvement for correctness and maintainability.

I've found one potential security issue in the new colorize function where the ansi_color parameter is not validated, which could lead to an escape sequence injection if used with untrusted input in the future. My review includes a suggestion to harden this function.

@github-actions github-actions bot added the gemini: reviewed Gemini Code Assist has reviewed the latest changes label Mar 17, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is an excellent refactoring that significantly improves code organization and security by consolidating terminal output sanitization into a new output.rs module. The changes are well-executed, with the new module being comprehensive and well-tested. The security enhancements, such as sanitizing user input and API responses before printing and replacing hardcoded ANSI codes, are crucial improvements. The migration path is also well-designed, ensuring backward compatibility. I have reviewed the changes and found no issues.

Defense-in-depth: only emit ANSI escape codes when ansi_color
contains exclusively ASCII digits. Falls back to plain text if
an invalid color code is passed.
@github-actions github-actions bot removed the gemini: reviewed Gemini Code Assist has reviewed the latest changes label Mar 18, 2026
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a solid refactoring that consolidates terminal output hygiene into a new output.rs module, enhancing both code organization and security. The upgrades to sanitization to cover dangerous Unicode characters and the replacement of hardcoded ANSI codes to respect NO_COLOR environments are excellent improvements. I've identified one high-severity issue in the new is_dangerous_unicode function where its implementation is largely redundant with char::is_control(), leading to inefficiency and misleading documentation. My suggestion simplifies the function to improve clarity and performance. Overall, these are very positive changes.

@github-actions github-actions bot added the gemini: reviewed Gemini Code Assist has reviewed the latest changes label Mar 18, 2026
@jpoehnelt jpoehnelt merged commit 2e909ae into main Mar 18, 2026
38 checks passed
@jpoehnelt jpoehnelt deleted the fix/output-hygiene branch March 18, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: auth area: core Core CLI parsing, commands, error handling, utilities area: http area: skills cla: yes This human has signed the Contributor License Agreement. gemini: reviewed Gemini Code Assist has reviewed the latest changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants