Skip to content

Commit 09be59f

Browse files
authored
fix: prevent command parsing panic on non-ascii sheet names (#18)
1 parent 8e00a46 commit 09be59f

4 files changed

Lines changed: 33 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.4.2] - 2026-03-10
11+
12+
### Fixed
13+
14+
- Prevent command parsing from panicking on non-ASCII sheet names such as `:addsheet 测试1`
15+
1016
## [0.4.1] - 2026-03-10
1117

1218
### Fixed
@@ -92,7 +98,8 @@ This is the initial release of excel-cli, a lightweight terminal-based Excel vie
9298
- Copy, cut, and paste functionality with `y`, `d`, and `p` keys
9399
- Support for pipe operator when exporting to JSON
94100

95-
[Unreleased]: https://github.com/fuhan666/excel-cli/compare/v0.4.1...HEAD
101+
[Unreleased]: https://github.com/fuhan666/excel-cli/compare/v0.4.2...HEAD
102+
[0.4.2]: https://github.com/fuhan666/excel-cli/releases/tag/v0.4.2
96103
[0.4.1]: https://github.com/fuhan666/excel-cli/releases/tag/v0.4.1
97104
[0.4.0]: https://github.com/fuhan666/excel-cli/releases/tag/v0.4.0
98105
[0.3.0]: https://github.com/fuhan666/excel-cli/releases/tag/v0.3.0

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "excel-cli"
3-
version = "0.4.1"
3+
version = "0.4.2"
44
edition = "2021"
55
description = "A lightweight terminal-based Excel viewer with Vim-like navigation for viewing, editing, and exporting Excel data to JSON format."
66
license = "MIT"

src/commands/executor.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -366,25 +366,21 @@ impl AppState<'_> {
366366
// Parse a cell reference like "A1", "B10", etc.
367367
fn parse_cell_reference(input: &str) -> Option<(usize, usize)> {
368368
// Cell references should have at least 2 characters (e.g., A1)
369-
if input.len() < 2 {
369+
if input.chars().count() < 2 {
370370
return None;
371371
}
372372

373373
// Find the first digit to separate column and row parts
374-
let mut col_end = 0;
375-
for (i, c) in input.chars().enumerate() {
376-
if c.is_ascii_digit() {
377-
col_end = i;
378-
break;
379-
}
380-
}
374+
let col_end = input
375+
.char_indices()
376+
.find(|(_, c)| c.is_ascii_digit())
377+
.map(|(index, _)| index)?;
381378

382379
if col_end == 0 {
383380
return None; // No digits found
384381
}
385382

386-
let col_part = &input[0..col_end];
387-
let row_part = &input[col_end..];
383+
let (col_part, row_part) = input.split_at(col_end);
388384

389385
// Convert column letters to index
390386
let col = col_name_to_index(&col_part.to_uppercase())?;
@@ -394,3 +390,20 @@ fn parse_cell_reference(input: &str) -> Option<(usize, usize)> {
394390

395391
Some((row, col))
396392
}
393+
394+
#[cfg(test)]
395+
mod tests {
396+
use super::parse_cell_reference;
397+
398+
#[test]
399+
fn parses_valid_cell_references() {
400+
assert_eq!(parse_cell_reference("A1"), Some((1, 1)));
401+
assert_eq!(parse_cell_reference("BC12"), Some((12, 55)));
402+
}
403+
404+
#[test]
405+
fn ignores_commands_with_non_ascii_arguments() {
406+
assert_eq!(parse_cell_reference("addsheet 测试1"), None);
407+
assert_eq!(parse_cell_reference("测试1"), None);
408+
}
409+
}

0 commit comments

Comments
 (0)