diff --git a/CHANGELOG.md b/CHANGELOG.md index 762c37b..48373d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,12 +50,15 @@ * i3/sway: regression; persistent workspaces shown twice ([#253][253]). * pipewire: use roundf instead of ceilf for more accuracy ([#262][262]) +* Crash when a yaml anchor has a value to already exists in the target + yaml node ([#286][286]). [239]: https://codeberg.org/dnkl/yambar/issues/239 [241]: https://codeberg.org/dnkl/yambar/issues/241 [251]: https://codeberg.org/dnkl/yambar/pulls/251 [253]: https://codeberg.org/dnkl/yambar/issues/253 [262]: https://codeberg.org/dnkl/yambar/issues/262 +[286]: https://codeberg.org/dnkl/yambar/issues/286 ### Security diff --git a/yml.c b/yml.c index b3f3d42..a81bdad 100644 --- a/yml.c +++ b/yml.c @@ -237,12 +237,15 @@ post_process(struct yml_node *node, char **error) .key = vv_it->item.key, .value = vv_it->item.value, }; - /* TODO: handle this. Is it an error? Or - * should we replace the existing key/value - * pair */ - assert(!dict_has_key(node, vv_it->item.key)); - tll_push_back(node->dict.pairs, p); + if (dict_has_key(node, vv_it->item.key)) { + /* Prefer value in target dictionary, over the + * value from the anchor */ + yml_destroy(vv_it->item.key); + yml_destroy(vv_it->item.value); + } else { + tll_push_back(node->dict.pairs, p); + } } /* Destroy list, but don't free (since its nodes @@ -274,11 +277,14 @@ post_process(struct yml_node *node, char **error) .value = v_it->item.value, }; - /* TODO: handle this. Is it an error? Or should we - * replace the existing key/value pair */ - assert(!dict_has_key(node, v_it->item.key)); - - tll_push_back(node->dict.pairs, p); + if (dict_has_key(node, v_it->item.key)) { + /* Prefer value in target dictionary, over the + * value from the anchor */ + yml_destroy(v_it->item.key); + yml_destroy(v_it->item.value); + } else { + tll_push_back(node->dict.pairs, p); + } } /* Destroy list here, *without* freeing nodes (since