fix(width): validate explicit width-point removal indices
Reapply on current upstream main.
This commit is contained in:
parent
eaf96c60ae
commit
3ce51a3487
|
|
@ -323,10 +323,22 @@ fn width_point_copy(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
fn width_point_remove(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
const C: &str = "stroke.widthPoint.remove";
|
||||
let id = id_param(p, "id").ok_or_else(|| bad(C, "missing id"))?;
|
||||
let mut indices: Vec<usize> = match (p.get("indices").and_then(Value::as_array), p.get("index").and_then(Value::as_u64)) {
|
||||
(Some(a), _) => a.iter().filter_map(Value::as_u64).map(|i| i as usize).collect(),
|
||||
(None, Some(i)) => vec![i as usize],
|
||||
(None, None) => return Err(bad(C, "missing index")),
|
||||
let mut indices: Vec<usize> = match p.get("indices") {
|
||||
Some(Value::Array(values)) => values
|
||||
.iter()
|
||||
.map(|value| {
|
||||
let id = value.as_u64().ok_or_else(|| bad(C, format!("invalid width point index {value}: expected an integer")))?;
|
||||
usize::try_from(id).map_err(|_| bad(C, format!("width point index {id} is out of range")))
|
||||
})
|
||||
.collect::<Result<_>>()?,
|
||||
Some(_) => return Err(bad(C, "indices must be an array of non-negative integers")),
|
||||
None => match p.get("index") {
|
||||
Some(value) => {
|
||||
let id = value.as_u64().ok_or_else(|| bad(C, "index must be a non-negative integer"))?;
|
||||
vec![usize::try_from(id).map_err(|_| bad(C, "index is out of range"))?]
|
||||
}
|
||||
None => return Err(bad(C, "missing index")),
|
||||
},
|
||||
};
|
||||
indices.sort_unstable();
|
||||
indices.dedup();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,31 @@ fn dark(s: &Session, x: u32, y: u32) -> bool {
|
|||
vectorcraft_render::Renderer::new().render(&doc, 200, 200, vectorcraft_geom::Affine::IDENTITY, &opts).pixel(x, y)[0] < 128
|
||||
}
|
||||
|
||||
/// Invalid entries in an explicit multi-point delete must not delete the valid entries.
|
||||
#[test]
|
||||
fn invalid_width_point_indices_leave_the_entire_profile_unchanged() {
|
||||
let (mut s, id) = line_session();
|
||||
set(&mut s, json!({"id": id.0, "t": 0.5, "left": 10, "right": 10}));
|
||||
let before = points(&s, id);
|
||||
let history = s.doc().unwrap().history.undo.len();
|
||||
for bad in [
|
||||
json!({"indices": [1, "bad"]}),
|
||||
json!({"indices": [-1, 1]}),
|
||||
json!({"indices": [1.5, 1]}),
|
||||
json!({"indices": {"point": 1}}),
|
||||
json!({"index": "bad"}),
|
||||
] {
|
||||
let mut params = bad.as_object().unwrap().clone();
|
||||
params.insert("id".into(), json!(id.0));
|
||||
let err = s.execute("stroke.widthPoint.remove", &serde_json::Value::Object(params));
|
||||
assert!(err.is_err(), "accepted malformed width point indices");
|
||||
assert_eq!(points(&s, id), before);
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), history);
|
||||
}
|
||||
s.execute("stroke.widthPoint.remove", &json!({"id": id.0, "indices": [1]})).unwrap();
|
||||
assert_eq!(points(&s, id).len(), before.len() - 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_point_moved_onto_another_makes_a_discontinuous_point_that_renders_a_step() {
|
||||
let (mut s, id) = line_session();
|
||||
|
|
|
|||
Loading…
Reference in New Issue