Tables: names with a hyphen or other operator characters are rejected (#576)
This commit is contained in:
parent
3926d21aa9
commit
8427681d7c
|
|
@ -240,7 +240,7 @@ fn insert_table(s: &mut Session, p: &Json) -> Result<Json> {
|
|||
let name = str_param(p, "name")
|
||||
.map(str::to_string)
|
||||
.unwrap_or_else(|| (1..).map(|n| format!("Table{n}")).find(|n| d.wb.table(n).is_none()).unwrap_or_else(|| "Table".into()));
|
||||
if name.is_empty() || name.contains(' ') || name.chars().next().is_some_and(|c| c.is_ascii_digit()) || CellRef::parse(&name).is_some() {
|
||||
if !valid_table_name(&name) {
|
||||
return Err(EngineError::Other("The name that you entered is not valid.".into()));
|
||||
}
|
||||
if d.wb.table(&name).is_some() || d.wb.names.iter().any(|n| n.name.eq_ignore_ascii_case(&name)) {
|
||||
|
|
@ -448,14 +448,19 @@ fn table_style(s: &mut Session, p: &Json) -> Result<Json> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Table names follow the Microsoft name rules, as the xlsx writer does: letters, digits, `_` and `.`,
|
||||
/// starting with a letter, `_` or `\`. Anything else (a hyphen, say) would read as an operator inside a
|
||||
/// structured reference, and the writer would rename the table on save.
|
||||
fn valid_table_name(name: &str) -> bool {
|
||||
name.starts_with(|c: char| c.is_alphabetic() || c == '_' || c == '\\')
|
||||
&& CellRef::parse(name).is_none()
|
||||
&& name.chars().enumerate().all(|(i, c)| c.is_alphanumeric() || c == '_' || c == '.' || (i == 0 && c == '\\'))
|
||||
}
|
||||
|
||||
fn table_rename(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
let (si, ti) = find_table(s, p)?;
|
||||
let name = str_param(p, "name").ok_or_else(|| bad("table.rename", "missing `name`"))?.to_string();
|
||||
if name.is_empty()
|
||||
|| name.contains(' ')
|
||||
|| name.chars().next().is_some_and(|c| c.is_ascii_digit())
|
||||
|| gridcraft_core::CellRef::parse(&name).is_some()
|
||||
{
|
||||
if !valid_table_name(&name) {
|
||||
return Err(EngineError::Other("The name that you entered is not valid.".into()));
|
||||
}
|
||||
if s.doc()?.wb.table(&name).is_some_and(|x| x != (si, ti)) {
|
||||
|
|
|
|||
|
|
@ -1170,6 +1170,22 @@ fn insert_and_delete_cells_never_shift_part_of_a_table() {
|
|||
assert!(e.to_string().contains("shift cells in a table"), "{e}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_names_with_a_hyphen_are_rejected() {
|
||||
let mut s = Session::new();
|
||||
s.execute("range.setValues", json!({"range": "A1", "values": [["Qty"], [7]]})).unwrap();
|
||||
let e = s.execute("insert.table", json!({"range": "A1:A2", "header": true, "name": "A-B"})).unwrap_err();
|
||||
assert!(e.to_string().contains("not valid"), "{e}");
|
||||
assert!(s.doc().unwrap().wb.table("A-B").is_none());
|
||||
s.execute("insert.table", json!({"range": "A1:A2", "header": true, "name": "Sales"})).unwrap();
|
||||
let e = s.execute("table.rename", json!({"table": "Sales", "name": "A-B"})).unwrap_err();
|
||||
assert!(e.to_string().contains("not valid"), "{e}");
|
||||
assert!(s.doc().unwrap().wb.table("Sales").is_some());
|
||||
assert!(s.execute("table.rename", json!({"table": "Sales", "name": ".AB"})).is_err());
|
||||
s.execute("table.rename", json!({"table": "Sales", "name": "A_B"})).unwrap();
|
||||
assert!(s.doc().unwrap().wb.table("A_B").is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn undo_and_redo_keep_the_watch_window_list() {
|
||||
// Found by the command-sequence fuzzer: the list lives in the workbook but isn't an edit, so
|
||||
|
|
|
|||
Loading…
Reference in New Issue