mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-31 06:06:48 -06:00
Reject Unicode noncharacters in UNICHAR
This commit is contained in:
@@ -281,7 +281,11 @@ fn unichar(a: &[Arg], _c: &mut dyn Ctx) -> R<Value> {
|
||||
if !(1.0..=1_114_111.0).contains(&n) {
|
||||
return Err(CellError::Value);
|
||||
}
|
||||
match char::from_u32(n as u32) {
|
||||
let cp = n as u32;
|
||||
if (0xFDD0..=0xFDEF).contains(&cp) || cp & 0xFFFE == 0xFFFE {
|
||||
return Err(CellError::NA);
|
||||
}
|
||||
match char::from_u32(cp) {
|
||||
Some(c) => text_val(c.to_string()),
|
||||
None => Err(CellError::NA),
|
||||
}
|
||||
@@ -1181,8 +1185,15 @@ mod tests {
|
||||
close(ev("CODE", vec![t("€")]), 128.0);
|
||||
is_err(ev("CODE", vec![t("")]), CellError::Value);
|
||||
is_text(ev("UNICHAR", vec![n(9731.0)]), "☃");
|
||||
for cp in [0xFDD0, 0xFDEF, 0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, 0x10FFFE, 0x10FFFF] {
|
||||
is_err(ev("UNICHAR", vec![n(f64::from(cp))]), CellError::NA);
|
||||
}
|
||||
for cp in [0xFDCF, 0xFDF0, 0xFFFD, 0x1FFFD] {
|
||||
assert!(matches!(ev("UNICHAR", vec![n(f64::from(cp))]), Value::Text(_)));
|
||||
}
|
||||
close(ev("UNICODE", vec![t("☃")]), 9731.0);
|
||||
is_err(ev("UNICHAR", vec![n(0.0)]), CellError::Value);
|
||||
is_err(ev("UNICHAR", vec![n(1_114_112.0)]), CellError::Value);
|
||||
is_err(ev("UNICHAR", vec![n(55296.0)]), CellError::NA);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Function parity: worksheet functions and formulas
|
||||
|
||||
> **Last reviewed:** 2026-10-15 · **Last updated:** 2026-10-27 · **Change:** minor (ECMA.CEILING listed with USDOLLAR as not on Microsoft's list; earlier: IMSQRT reproduces the stray real part Excel gives for negative reals, and the other IM* differences from Excel are listed; earlier: the LAMBDA row lists the recursion limit and its `#NUM!`, and the error a defined name holding an error gives when called; earlier: number text with accounting parentheses coerces like Excel 365; INDEX with one index on a 2-D reference is #REF! as in Excel; earlier: SUBTOTAL and AGGREGATE cap the cells they visit, #2175) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-31 · **Last updated:** 2026-10-31 · **Change:** minor (UNICHAR returns `#N/A` for Unicode noncharacters, as observed in Excel; earlier: ECMA.CEILING listed with USDOLLAR as not on Microsoft's list; IMSQRT reproduces Excel's stray real part for negative reals) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
|
||||
Excel's worksheet functions, category by category, against GridCraft's function library. Part of
|
||||
[target-app-parity.md](target-app-parity.md); gaps feed [gaps.md](gaps.md).
|
||||
@@ -29,6 +29,8 @@ Excel's worksheet functions, category by category, against GridCraft's function
|
||||
|
||||
## Coverage
|
||||
|
||||
| 2026-10-31 | minor | UNICHAR returns `#N/A` for U+FDD0–U+FDEF and U+FFFE/U+FFFF on every plane; adjacent valid characters and existing invalid-range/surrogate errors remain unchanged, matching Excel |
|
||||
|
||||
**Measured: 513 / 523 by name (98.1%); 504 / 523 working (96.4%).**
|
||||
|
||||
| Category | Excel | Ours | Working | % working | Missing |
|
||||
|
||||
Reference in New Issue
Block a user