fix(gradient): reject malformed freeform line index lists
This commit is contained in:
parent
212fb9994a
commit
f5111045a9
|
|
@ -148,9 +148,19 @@ pub(crate) fn parse_freeform(v: &Value) -> std::result::Result<Freeform, String>
|
|||
point_fields(pv, &mut pt, Affine::IDENTITY).map_err(|e| format!("freeform point {i}: {e}"))?;
|
||||
f.points.push(pt);
|
||||
}
|
||||
for l in v.get("lines").and_then(Value::as_array).into_iter().flatten() {
|
||||
let ix = l.as_array().map(|a| a.iter().filter_map(Value::as_u64).map(|i| i as usize).collect()).unwrap_or_default();
|
||||
f.add_line(ix)?;
|
||||
if let Some(lines) = v.get("lines") {
|
||||
let lines = lines.as_array().ok_or("`freeform.lines` must be an array")?;
|
||||
for (line, values) in lines.iter().enumerate() {
|
||||
let values = values.as_array().ok_or_else(|| format!("freeform line {line} must be an array of point indices"))?;
|
||||
let indices: Vec<usize> = values
|
||||
.iter()
|
||||
.map(|v| {
|
||||
let id = v.as_u64().ok_or_else(|| format!("freeform line {line} has a non-integer point index: {v}"))?;
|
||||
usize::try_from(id).map_err(|_| format!("freeform line {line} has an out-of-range point index: {id}"))
|
||||
})
|
||||
.collect::<std::result::Result<_, _>>()?;
|
||||
f.add_line(indices).map_err(|e| format!("freeform line {line}: {e}"))?;
|
||||
}
|
||||
}
|
||||
if let Some(m) = str_param(v, "mode") {
|
||||
f.mode = parse_mode(m)?;
|
||||
|
|
@ -323,3 +333,30 @@ fn get(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
v["selected"] = json!(selected);
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod parse_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn malformed_freeform_lines_are_not_silently_shortened() {
|
||||
let points = json!([
|
||||
{"at": [0, 0], "color": "#ff0000"},
|
||||
{"at": [50, 0], "color": "#00ff00"},
|
||||
{"at": [100, 0], "color": "#0000ff"}
|
||||
]);
|
||||
for lines in [
|
||||
json!([[0, "broken", 2]]),
|
||||
json!([[0, -1, 2]]),
|
||||
json!([[0, 1.5, 2]]),
|
||||
json!([{"points": [0, 1]}]),
|
||||
json!("not an array"),
|
||||
] {
|
||||
let value = json!({"points": points, "lines": lines, "mode": "lines"});
|
||||
assert!(parse_freeform(&value).is_err(), "invalid lines accepted: {value}");
|
||||
}
|
||||
let good = parse_freeform(&json!({"points": points, "lines": [[0, 1, 2]], "mode": "lines"})).unwrap();
|
||||
assert_eq!(good.lines, vec![vec![0, 1, 2]]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue