Skip to content

TextCLI: overly strict delimiter checks reject valid single-value input; silent truncation on out-of-BMP zero-length chars #63

Description

@N0153128
  1. contains(",") guard rejects valid single-item input.
    Both -us and -zlc gate their parsing on value.contains(","), throwing IllegalArgumentException if no comma is present. This incorrectly rejects the common single-value case:
    - -us blob: → throws, even though it's a single valid scheme
    - -zlc 0x200C → throws, even though it's a single valid codepoint

String.split(",") already handles a comma-less string safely, returning a one-element array — so the guard doesn't protect anything meaningful and should be dropped (or replaced with a check that actually validates
format, e.g. hex-prefix / non-empty, rather than delimiter presence).
2. Silent truncation on out-of-BMP codepoints in -zlc.
.map(hex -> (char) Integer.decode(hex).intValue()) casts directly to char with no bounds check. A hex value above 0xFFFF (e.g. 0x1F600) is silently truncated rather than rejected — it becomes a different, unintended
character instead of raising an error. TextConfig.ControlCharactersRange already enforces an explicit rangeEnd > 0xFFFF guard for the analogous control-character case; -zlc should get equivalent validation before or
during the cast.
3. -ccr's Integer.decode() calls lack try/catch.
Every other colon/comma-delimited numeric CLI param in the codebase (VideoCLI's -mvsff, -mvbr, -mabrfv, -masr) wraps its parse in try/catch and rethrows a clean IllegalArgumentException on
NumberFormatException/ArrayIndexOutOfBoundsException. -ccr's Integer.decode(...) calls (TextCLI.java lines ~133–134) don't follow this convention — a malformed hex literal will leak a raw exception instead of a clean CLI
error.

Suggested fix shape: drop the contains(",") gate on -us/-zlc (rely on split alone), add an explicit bounds check (or try/catch around the cast) for -zlc, and wrap -ccr's decode calls in try/catch matching the VideoCLI
pattern.

Acceptance Criteria:

  • -us blob: (single scheme, no comma) succeeds and adds blob: to the existing default schemes rather than throwing.
  • -us data:,blob:,file: (multiple schemes) still succeeds and adds all three, as it does today.
  • -zlc 0x200C (single codepoint, no comma) succeeds and adds the character rather than throwing.
  • -zlc 0x200C,0x2060 (multiple codepoints) still succeeds and adds both, as it does today.
  • -zlc 0x1F600 (codepoint above 0xFFFF) throws a clean IllegalArgumentException describing the out-of-range value, instead of silently truncating to a different character.
  • -ccr 0xZZZZ:0x001F (malformed hex literal) throws a clean IllegalArgumentException, not a raw NumberFormatException.
  • -ccr 0x001F (missing : separator) throws a clean IllegalArgumentException, not a raw ArrayIndexOutOfBoundsException.
  • Existing default behavior for all three flags when omitted entirely (no -us/-zlc/-ccr passed) is unchanged — no exception, defaults apply.
  • No regression in -ccr's currently-working valid-input path (-ccr 0x0000:0x001F still adds the range on top of defaults).

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions