This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch edje-vector-intergration
in repository efl.
View the commit online.
commit 76e61838fa601a13d2880ade545dc8e8a479a8ad
Author: [email protected] <[email protected]>
AuthorDate: Thu Apr 30 22:51:47 2026 -0600
edje: fix _edje_vg_node_free arity UB and pre-push polish for vector state animation
CRITICAL FIX: Forward declaration of _edje_vg_node_free in edje_test_vector_states.c
was missing the free_strings parameter added in Phase 8.2 (edje_vg_tree.c line 1947).
Two call sites (lines 383 and 389) passed only one argument, reading undefined stack
garbage into rsi for the second parameter on x86-64. This is undefined behavior that
happened to work because:
1. Tests passed by chance — when free_strings is garbage, bool-cast-to-nonzero often
returns true, which is the correct path for test cleanup.
2. The test doesn't iterate over many different register allocations or architectures
where rsi would have different content.
3. A future compiler optimization or architecture change would flip the coin.
Fixed by updating the forward declaration and both call sites to pass EINA_TRUE
(the correct value for tests that own their allocations).
POLISH — pre-push quality improvements:
1. Added comprehensive roadmap comment to _node_lerp_recursive (~160 lines) breaking
it into four named steps (name-alignment, common props, type-specific, recurse) with
section dividers. Maintainers can now navigate the function's structure without
reading the spec.
2. Added destructive-resolve warning to _edje_vg_tree_resolve_colors header: this
function clears color_class bindings as a side effect (eina_stringshare_del + NULL).
Existing code only calls this on working-tree dups, but the warning prevents future
misuse.
3. Added DBG-level logging on efl_gfx_path_interpolate failure in edje_calc.c at the
transition path call site. The existing comment notes this failure is safe (root
already holds B paths as fallback); the log just makes the topology mismatch
visible during development. Matches the return-checking pattern already used at
the other call site in _edje_vg_tree_to_efl_vg.
Verification: ninja -C build clean rebuild succeeds; all 91 edje_suite tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---
src/lib/edje/edje_calc.c | 7 +++++--
src/lib/edje/edje_vg_tree.c | 22 +++++++++++++++++++++-
src/tests/edje/edje_test_vector_states.c | 6 +++---
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 2b78067557..a74bb49ca6 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -3359,8 +3359,11 @@ _edje_vector_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EIN
already holds B paths (step semantics), so
failure is safe to ignore here. */
if (root && efl_a && efl_b)
- efl_gfx_path_interpolate(root, efl_a, efl_b,
- TO_DOUBLE(pos));
+ {
+ if (!efl_gfx_path_interpolate(root, efl_a, efl_b,
+ TO_DOUBLE(pos)))
+ DBG("efl_gfx_path_interpolate failed (topology mismatch); falling back to B paths.");
+ }
}
}
}
diff --git a/src/lib/edje/edje_vg_tree.c b/src/lib/edje/edje_vg_tree.c
index dd1b8bf5d1..902ae851c7 100644
--- a/src/lib/edje/edje_vg_tree.c
+++ b/src/lib/edje/edje_vg_tree.c
@@ -1155,12 +1155,27 @@ _color_lerp_with_ref(Edje_Vg_Color_Binding *out_cb,
}
static void
+/*
+ * Roadmap (spec §5.1 — name-aligned tree lerp):
+ * 1. Resolve same-named nodes in A and B by walking out's structure
+ * (out is a dup of B, so this is a B-anchored alignment).
+ * 2. For each aligned triple, lerp common properties (color, transform,
+ * visible-flag).
+ * 3. Then dispatch on type for shape/gradient-specific scalar/array lerp.
+ * 4. Recurse into container children regardless of whether this level
+ * was lerped.
+ *
+ * Path geometry is NOT touched here — it is interpolated on the live
+ * Efl_VG via efl_gfx_path_interpolate() at materialize time (edje_calc.c).
+ * out_node already carries B's path string as the step fallback.
+ */
_node_lerp_recursive(Edje_Vg_Node *out_node,
const Edje_Vg_Tree *a, const Edje_Vg_Tree *b,
double pos)
{
if (!out_node) return;
+ /* --- Step 1: resolve aligned A/B counterparts by name ----------------- */
if (out_node->name)
{
Edje_Vg_Node *a_node =
@@ -1184,6 +1199,7 @@ _node_lerp_recursive(Edje_Vg_Node *out_node,
* nodes appear in out and fade out) or a post-process pass that
* synthesises faded versions of a's missing nodes into out. */
+ /* --- Step 2: lerp common properties ---------------------- */
/* Common: color (with stringshare fix-up) */
_color_lerp_with_ref(&out_node->color,
&a_node->color, &b_node->color, pos);
@@ -1196,6 +1212,7 @@ _node_lerp_recursive(Edje_Vg_Node *out_node,
out_node->visible = (pos < 1.0) ? a_node->visible
: b_node->visible;
+ /* --- Step 3: type-specific lerp -------------------------- */
switch (out_node->type)
{
case EDJE_VG_NODE_SHAPE:
@@ -1310,7 +1327,7 @@ _node_lerp_recursive(Edje_Vg_Node *out_node,
/* else: type/parent-path mismatch or missing node — step (B's values). */
}
- /* Recurse into containers regardless of whether we lerped this level. */
+ /* --- Step 4: recurse into container children ------------------------ */
if (out_node->type == EDJE_VG_NODE_CONTAINER)
{
Eina_List *l;
@@ -1897,6 +1914,9 @@ _resolve_node_recursive(Edje_Vg_Node *n, const Edje *ed)
}
}
+/* Destructive: clears every color_class binding (eina_stringshare_del + NULL)
+ * after multiplying its RGBA into the binding. Only call on a working-tree
+ * dup, never on a description's canonical tree. */
EAPI void
_edje_vg_tree_resolve_colors(Edje_Vg_Tree *working, const Edje *ed)
{
diff --git a/src/tests/edje/edje_test_vector_states.c b/src/tests/edje/edje_test_vector_states.c
index 2aa247f1f2..a501ba7f1b 100644
--- a/src/tests/edje/edje_test_vector_states.c
+++ b/src/tests/edje/edje_test_vector_states.c
@@ -53,7 +53,7 @@ Eet_Data_Descriptor *_edje_vg_tree_edd(void);
/* Phase 2 helpers (Task 2.1) */
Edje_Vg_Tree *_edje_vg_tree_new(void);
Edje_Vg_Node *_edje_vg_node_new(Edje_Vg_Node_Type type);
-void _edje_vg_node_free(Edje_Vg_Node *n);
+void _edje_vg_node_free(Edje_Vg_Node *n, Eina_Bool free_strings);
void _edje_vg_container_append(Edje_Vg_Node *parent,
Edje_Vg_Node *child);
Edje_Vg_Node *_edje_vg_tree_node_by_name(const Edje_Vg_Tree *t,
@@ -380,13 +380,13 @@ EFL_START_TEST(edje_vg_tree_helpers_basic)
_edje_vg_tree_free(t);
/* _edje_vg_node_free: NULL-safe. */
- _edje_vg_node_free(NULL);
+ _edje_vg_node_free(NULL, EINA_TRUE);
/* _edje_vg_node_new CONTAINER: correct type. */
Edje_Vg_Node *c = _edje_vg_node_new(EDJE_VG_NODE_CONTAINER);
fail_if(!c);
fail_if(c->type != EDJE_VG_NODE_CONTAINER);
- _edje_vg_node_free(c);
+ _edje_vg_node_free(c, EINA_TRUE);
}
EFL_END_TEST
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.