Skip to content

feat(input): add mask_on_submit option#138

Merged
jdx merged 4 commits intomainfrom
feat/mask-on-submit
Mar 8, 2026
Merged

feat(input): add mask_on_submit option#138
jdx merged 4 commits intomainfrom
feat/mask-on-submit

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Mar 8, 2026

Summary

  • Add mask_on_submit flag to Input that shows input in cleartext while typing but masks with asterisks after submission
  • Useful for PINs where the user needs to see what they type but the value shouldn't remain visible in terminal scrollback
  • Different from password which masks during typing too

Test plan

  • Manual test: create an input with .mask_on_submit(true), verify text is visible while typing
  • Manual test: after pressing enter, verify the submitted value shows as ****
  • Verify password(true) behavior is unchanged

🤖 Generated with Claude Code


Note

Low Risk
Small, localized change to terminal rendering behavior with added tests; minimal risk aside from potential expectations around how masking appears after submit.

Overview
Adds a new mask_on_submit flag (and builder method) to Input to support post-submit-only masking, intended for cases like PIN entry where terminal scrollback shouldn’t reveal the value.

Updates render_success to mask output based on precedence (password masks with a fixed 12 *, otherwise mask_on_submit masks to input length), and adds unit tests covering masked/empty mask_on_submit output and verifying password success rendering remains consistent.

Written by Cursor Bugbot for commit 0779446. This will update automatically on new commits. Configure here.

Add a new `mask_on_submit` flag that shows input in cleartext while
typing but masks it with asterisks after submission. Useful for PINs
where the user needs to see what they're typing but the value should
not remain visible in terminal scrollback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gemini-code-assist
Copy link
Copy Markdown

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 enhances the Input component by introducing a new masking behavior. It allows for a more nuanced approach to sensitive data entry, where the input is visible to the user as they type but automatically masked once submitted. This improves both usability and security for specific use cases, such as entering PINs, without altering the existing full-masking password functionality.

Highlights

  • New Feature: mask_on_submit option: Introduced a new mask_on_submit boolean field to the Input struct. When enabled, this allows the user to see their input while typing, but masks the value with asterisks after submission. This is distinct from the existing password option, which masks input during typing as well.
  • Enhanced Input Security: This feature provides a practical solution for handling sensitive inputs like PINs, ensuring that the value is not visible in terminal scrollback after submission, while still offering a good user experience during entry.
Changelog
  • src/input.rs
    • Added mask_on_submit field to the Input struct.
    • Initialized mask_on_submit to false in the Input::new constructor.
    • Implemented a new builder method mask_on_submit for setting the field.
    • Updated the documentation for the password field to clarify its behavior.
    • Modified the input rendering logic to apply masking if either password or mask_on_submit is true.
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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

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

Comment thread src/input.rs Outdated
Copy link
Copy Markdown

@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 introduces a mask_on_submit option to the Input component, a useful feature for handling sensitive inputs like PINs. However, the implementation of the masking logic in render_success introduces an information disclosure vulnerability, leaking the length and byte-count of passwords in the terminal scrollback, which is a regression from previous fixed-length masking. The change also contradicts the pull request's own test plan regarding password functionality. A specific suggestion has been provided to address this while preserving the new functionality.

Comment thread src/input.rs Outdated
Comment on lines +729 to +731
if self.password || self.mask_on_submit {
"*".repeat(self.input.len().max(1))
} else {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

The new masking logic in render_success introduces an information disclosure vulnerability, contradicting the test plan's goal of preserving password(true) behavior. Specifically: 1. Password Length Leak: The current implementation leaks the exact password length by using the input's actual length instead of the previous fixed-length mask (12 asterisks). 2. Byte-Count Leak: Using .len() instead of .chars().count() for mask_on_submit reveals information about character types (e.g., multi-byte characters like Emojis). 3. Misleading Empty Input: The .max(1) logic renders an empty input as a single asterisk, which is inconsistent. The logic should differentiate between password and mask_on_submit. For password, a fixed-length mask should be used. For mask_on_submit, .chars().count() should be used for accurate character counting.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 8, 2026

Greptile Summary

This PR adds a mask_on_submit option to Input that keeps typed characters visible while the user is typing but replaces them with asterisks in the post-submit success render — filling the gap between password (masks at all times) and default cleartext.

Key implementation details:

  • New mask_on_submit: bool field on Input, defaulting to false
  • Builder method .mask_on_submit(...) following existing conventions
  • render_success branching: password → 12 asterisks, mask_on_submit"*".repeat(chars().count()), otherwise plaintext
  • render_input is unchanged (only checks self.password), so mask_on_submit input is correctly visible while typing
  • Unicode-safe: uses .chars().count() for the asterisk repeat count, not .len() (byte count)
  • Precedence documented: when both password and mask_on_submit are set, password takes precedence
  • Comprehensive test coverage includes normal input, empty input, and password mode edge cases

Confidence Score: 5/5

  • Safe to merge — well-scoped change with correct implementation, no regressions, and comprehensive test coverage.
  • The PR is a small, localized change to a single file that correctly implements the mask_on_submit feature. The implementation properly handles all cases: password mode maintains the original fixed 12-asterisk display, mask_on_submit correctly uses actual character count without spurious padding, empty input is handled correctly, flag precedence is documented, and all code paths are covered by unit tests. No security, data integrity, or compatibility concerns identified.
  • No files require special attention

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User types input] --> B{password?}
    B -- yes --> C[render_input: mask each char with '*']
    B -- no --> D[render_input: show plaintext]
    C --> E[User submits]
    D --> E
    E --> F[render_success]
    F --> G{password?}
    G -- yes --> H["Display '************' (12 fixed asterisks)"]
    G -- no --> I{mask_on_submit?}
    I -- yes --> J["Display '*' × chars().count()"]
    I -- no --> K[Display plaintext input]
Loading

Last reviewed commit: 0779446

Comment thread src/input.rs Outdated
Comment thread src/input.rs Outdated
Password mode now shows 12 asterisks (original behavior) to avoid
revealing password length. mask_on_submit uses actual input length
without .max(1) so empty input correctly shows nothing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread src/input.rs Outdated
Byte length produces too many asterisks for multi-byte UTF-8 input.
Use character count to match the rest of the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread src/input.rs
Comment thread src/input.rs
Also document that password takes precedence over mask_on_submit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jdx jdx merged commit 23c102a into main Mar 8, 2026
7 checks passed
@jdx jdx deleted the feat/mask-on-submit branch March 8, 2026 20:58
@jdx jdx mentioned this pull request Mar 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant