Found while reviewing #130 (REPL table/column alignment had the same class of bug).
`apply_string_padding` in `crates/kaish-kernel/src/tools/builtin/format_string.rs` (around line 513-516) computes the padding for `printf`'s `%Ns` width specifier using `val.len()` — UTF-8 byte count, not display width:
```rust
fn apply_string_padding(spec: &FormatSpec, val: &str, output: &mut String) {
let width = spec.width.unwrap_or(0);
if width > val.len() {
let pad_count = width - val.len();
...
```
A CJK or emoji argument to `printf '%10s'` will be over-padded (byte length > display width), misaligning output the same way the REPL's table renderer did pre-#130.
Fix shape: use `unicode_width::UnicodeWidthStr::width()` for the padding calculation, same as #130's fix in `kaish-repl/src/format.rs`. Would need unicode-width as a kaish-kernel dependency (already used by kaish-repl).
Low priority — narrow surface (printf %Ns with non-ASCII args specifically), but same bug class as #130 so worth tracking.
Found while reviewing #130 (REPL table/column alignment had the same class of bug).
`apply_string_padding` in `crates/kaish-kernel/src/tools/builtin/format_string.rs` (around line 513-516) computes the padding for `printf`'s `%Ns` width specifier using `val.len()` — UTF-8 byte count, not display width:
```rust
fn apply_string_padding(spec: &FormatSpec, val: &str, output: &mut String) {
let width = spec.width.unwrap_or(0);
if width > val.len() {
let pad_count = width - val.len();
...
```
A CJK or emoji argument to `printf '%10s'` will be over-padded (byte length > display width), misaligning output the same way the REPL's table renderer did pre-#130.
Fix shape: use `unicode_width::UnicodeWidthStr::width()` for the padding calculation, same as #130's fix in `kaish-repl/src/format.rs`. Would need
unicode-widthas akaish-kerneldependency (already used bykaish-repl).Low priority — narrow surface (
printf %Nswith non-ASCII args specifically), but same bug class as #130 so worth tracking.