Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-09-17 22:38:30 +0300
committerHans Goudey <h.goudey@me.com>2022-09-17 22:38:30 +0300
commit8934f00ac5701ea349f2bcccab32e252c79aa730 (patch)
treeba4a990efea94c619d9d7ba68aff528992cafe3b /source/blender/nodes
parent6069cab442045775262691929e85b9c1fb3874dc (diff)
Attributes: Validate some builtin attributes for untrusted inputs
We expect some builtin attributes to have positive values or values within a certain range, but currently there some cases where users can set attributes to arbitrary values: the store named attribute node, and the output attributes of the geometry nodes modifier. The set material index node also needs validation. This patch adds an `AttributeValidator` to the attribute API, which can be used to correct values from these untrusted inputs if necessary. As an alternative to D15548, this approach makes it much easier to understand when validation is being applied, without the need to add arguments to every attribute API method or complicate the virtual array system. Currently validation is provided with a multi-function. That integrates well with the field evaluations that set these values now, but it could be wrapped to be friendlier to other areas of Blender in the future. The Python API is not handled here either. Currently I would prefer to wait until we can integrate the C++ and C attribute APIs better before addressing that. Fixes T100952 Differential Revision: https://developer.blender.org/D15990
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc4
2 files changed, 6 insertions, 2 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
index f6dded56315..bb9ac9b5d4c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
@@ -24,11 +24,13 @@ static void set_material_index_in_component(GeometryComponent &component,
MutableAttributeAccessor attributes = *component.attributes_for_write();
bke::GeometryFieldContext field_context{component, domain};
+ const bke::AttributeValidator validator = attributes.lookup_validator("material_index");
AttributeWriter<int> indices = attributes.lookup_or_add_for_write<int>("material_index", domain);
fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
- evaluator.add_with_destination(index_field, indices.varray);
+ evaluator.add_with_destination(validator.validate_field_if_necessary(index_field),
+ indices.varray);
evaluator.evaluate();
indices.finish();
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
index 2a590f5bf4a..ad31c8a2191 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
@@ -103,6 +103,7 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
const CPPType &type = field.cpp_type();
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
+ const bke::AttributeValidator validator = attributes.lookup_validator(name);
/* Could avoid allocating a new buffer if:
* - We are writing to an attribute that exists already with the correct domain and type.
@@ -110,7 +111,8 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
void *buffer = MEM_mallocN(type.size() * domain_size, __func__);
fn::FieldEvaluator evaluator{field_context, &mask};
- evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_size});
+ evaluator.add_with_destination(validator.validate_field_if_necessary(field),
+ GMutableSpan{type, buffer, domain_size});
evaluator.evaluate();
if (GAttributeWriter attribute = attributes.lookup_for_write(name)) {