Browse / github.com/storytold/lightcraft / patch
Reject signed list indexes in indexed develop control ids
Reject signed list indexes in indexed develop control ids No existing issue. ## Problem Found while testing `crates/develop/src/controls.rs:413 (split_indexed)`: indexed develop control ids accept a signed index, such as `pointColor.+0.hueShift`. **Cause:** `split_indexed` parsed the index with `str::parse::<usize>()`, which accepts a leading `+`. Ids such as `pointColor.+0.hueShift` were therefore treated as `pointColor.0.hueShift`. ## Change `split_indexed` now requires the index to be non-empty and made only of ASCII digits before parsing it. `set`, `get`, `find` and the indexed helpers all go through it, so signed ids are now unknown ids. A
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Silvertree2010 (imported from pull request #3165, open)
- Base
3a3e49af53aeff55248419234a05d1a262094092- Size
- +15 −0 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
4a02e77a6e4578026be3c504
How it went
No other operator has reported using it yet.
Diff
raw · crates/develop/src/controls.rs
@@ -410,6 +410,9 @@ pub static INDEXED: &[ControlSpec] = &[ fn split_indexed(id: &str) -> Option<(&str, usize, &str)> { let mut it = id.splitn(3, '.'); let (fam, i, field) = (it.next()?, it.next()?, it.next()?);+ if i.is_empty() || !i.bytes().all(|b| b.is_ascii_digit()) {+ return None;+ } Some((fam, i.parse().ok()?, field)) } @@ -538,6 +541,18 @@ mod tests { } } + #[test]+ fn signed_indexes_are_unknown_ids() {+ let mut s = DevelopSettings::default();+ s.point_colors.push(Default::default());+ let before = s.point_colors[0].hue_shift;+ assert!(!set(&mut s, "pointColor.+0.hueShift", 10.0), "signed index");+ assert_eq!(s.point_colors[0].hue_shift, before);+ assert_eq!(get(&s, "pointColor.+0.hueShift"), None);+ assert!(find("pointColor.+0.hueShift").is_none());+ assert!(find("redEye.+0.darken").is_none());+ }+ #[test] fn formatting() { let e = find("light.exposure").unwrap();