Files
dingtalk-workspace-cli/internal/cli
huwenjiao.hwj 7eb39ad5d6 fix(sheet): narrow the interface_ref carve-out, fail closed on truncated CSV
Two review findings, plus a same-class defect found by sweeping for it.

1. compatibleInterfaceRefRedirect accepted any mcp tool repointing from any
   non-empty interface_ref to any other, as long as no other check for that tool
   failed. Schema shape cannot prove two RPCs share business semantics,
   permissions, error behaviour, or side effects, so that would have let every
   future backend swap bypass the gate it exists to enforce. It is now keyed on
   an explicit reviewedInterfaceRefRedirect allowlist of exact tool + old→new
   pairs, currently holding only the reviewed
   sheet.range_set_style: update_range → set_cell_range migration. Every other
   ref change is reported again.

2. sheet export --export-format csv only printed a stderr warning when
   get_range_as_csv returned hasMore=true, then wrote --output and reported
   success with exit code 0. Automated callers, and anyone not watching stderr,
   would treat an incomplete file as a complete export, and an existing target
   file was overwritten with truncated data. Truncation now fails before the
   write (leaving any existing file untouched) unless --allow-truncated is
   passed; with the opt-in the success line states the data is incomplete.
   --allow-truncated is registered in the reviewed mapping ledger as a local
   policy input.

3. Swept for the same classes and found sheet_dimension.go repeating the
   fmt.Sscanf("%d") prefix-parse hole in three places: insert_dimension,
   delete_dimension, and update_dimension all accepted --length "3x" as 3, so a
   malformed value silently operated on the wrong row/column count — the delete
   direction is not rollbackable. All three now use strconv.Atoi. (Checked and
   cleared: sheet csv-get also surfaces hasMore, but it has no --output and only
   returns the flag in its JSON payload, so it is not the same fail-open shape.)

Tests: allowlist rejection cases (unreviewed target ref, and the same pair on a
tool absent from the allowlist, asserted outside the table so the registration
survives until checkCompatibility runs); truncation fail-closed with a
pre-existing output file asserted byte-for-byte unchanged; --allow-truncated
write-through; and an untruncated read needing no opt-in. Changed-code coverage
stays at 100% (939 statements).
2026-08-07 21:05:47 +08:00
..
2026-03-27 17:55:57 +08:00
2026-03-27 17:55:57 +08:00
2026-03-27 17:55:57 +08:00