diff --git a/CHANGELOG.md b/CHANGELOG.md index c312dfb..920bf96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.2] - 2026-03-10 + +### Fixed + +- Prevent command parsing from panicking on non-ASCII sheet names such as `:addsheet 测试1` + ## [0.4.1] - 2026-03-10 ### Fixed @@ -92,7 +98,8 @@ This is the initial release of excel-cli, a lightweight terminal-based Excel vie - Copy, cut, and paste functionality with `y`, `d`, and `p` keys - Support for pipe operator when exporting to JSON -[Unreleased]: https://github.com/fuhan666/excel-cli/compare/v0.4.1...HEAD +[Unreleased]: https://github.com/fuhan666/excel-cli/compare/v0.4.2...HEAD +[0.4.2]: https://github.com/fuhan666/excel-cli/releases/tag/v0.4.2 [0.4.1]: https://github.com/fuhan666/excel-cli/releases/tag/v0.4.1 [0.4.0]: https://github.com/fuhan666/excel-cli/releases/tag/v0.4.0 [0.3.0]: https://github.com/fuhan666/excel-cli/releases/tag/v0.3.0 diff --git a/Cargo.lock b/Cargo.lock index a7ea831..ae70c72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "excel-cli" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "calamine", diff --git a/Cargo.toml b/Cargo.toml index bb033c1..10a0c4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "excel-cli" -version = "0.4.1" +version = "0.4.2" edition = "2021" description = "A lightweight terminal-based Excel viewer with Vim-like navigation for viewing, editing, and exporting Excel data to JSON format." license = "MIT" diff --git a/src/commands/executor.rs b/src/commands/executor.rs index a1bd699..f49ae8d 100644 --- a/src/commands/executor.rs +++ b/src/commands/executor.rs @@ -366,25 +366,21 @@ impl AppState<'_> { // Parse a cell reference like "A1", "B10", etc. fn parse_cell_reference(input: &str) -> Option<(usize, usize)> { // Cell references should have at least 2 characters (e.g., A1) - if input.len() < 2 { + if input.chars().count() < 2 { return None; } // Find the first digit to separate column and row parts - let mut col_end = 0; - for (i, c) in input.chars().enumerate() { - if c.is_ascii_digit() { - col_end = i; - break; - } - } + let col_end = input + .char_indices() + .find(|(_, c)| c.is_ascii_digit()) + .map(|(index, _)| index)?; if col_end == 0 { return None; // No digits found } - let col_part = &input[0..col_end]; - let row_part = &input[col_end..]; + let (col_part, row_part) = input.split_at(col_end); // Convert column letters to index let col = col_name_to_index(&col_part.to_uppercase())?; @@ -394,3 +390,20 @@ fn parse_cell_reference(input: &str) -> Option<(usize, usize)> { Some((row, col)) } + +#[cfg(test)] +mod tests { + use super::parse_cell_reference; + + #[test] + fn parses_valid_cell_references() { + assert_eq!(parse_cell_reference("A1"), Some((1, 1))); + assert_eq!(parse_cell_reference("BC12"), Some((12, 55))); + } + + #[test] + fn ignores_commands_with_non_ascii_arguments() { + assert_eq!(parse_cell_reference("addsheet 测试1"), None); + assert_eq!(parse_cell_reference("测试1"), None); + } +}