forked from external/yambar
yml: don’t crash when (trying to) merge anchors that aren’t dictionaries
Up until now, we only asserted the value being merged in was a dictionary. Now we do a proper check and return a real error message instead. Closes #32
This commit is contained in:
parent
afe22813f3
commit
0855e5ff63
2 changed files with 44 additions and 9 deletions
|
@ -13,6 +13,11 @@
|
||||||
### Deprecated
|
### Deprecated
|
||||||
### Removed
|
### Removed
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
* Crash when merging non-dictionary anchors in the YAML configuration
|
||||||
|
(https://codeberg.org/dnkl/yambar/issues/32).
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
### Contributors
|
### Contributors
|
||||||
|
|
||||||
|
|
48
yml.c
48
yml.c
|
@ -177,13 +177,14 @@ add_anchor(struct yml_node *root, const char *anchor,
|
||||||
root->root.anchor_count++;
|
root->root.anchor_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
post_process(struct yml_node *node)
|
post_process(struct yml_node *node, char **error)
|
||||||
{
|
{
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case ROOT:
|
case ROOT:
|
||||||
if (node->root.root != NULL)
|
if (node->root.root != NULL)
|
||||||
post_process(node->root.root);
|
if (!post_process(node->root.root, error))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCALAR:
|
case SCALAR:
|
||||||
|
@ -192,13 +193,17 @@ post_process(struct yml_node *node)
|
||||||
|
|
||||||
case LIST:
|
case LIST:
|
||||||
tll_foreach(node->list.values, it)
|
tll_foreach(node->list.values, it)
|
||||||
post_process(it->item);
|
if (!post_process(it->item, error))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DICT:
|
case DICT:
|
||||||
tll_foreach(node->dict.pairs, it) {
|
tll_foreach(node->dict.pairs, it) {
|
||||||
post_process(it->item.key);
|
if (!post_process(it->item.key, error) ||
|
||||||
post_process(it->item.value);
|
!post_process(it->item.value, error))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tll_foreach(node->dict.pairs, it) {
|
tll_foreach(node->dict.pairs, it) {
|
||||||
|
@ -214,7 +219,17 @@ post_process(struct yml_node *node)
|
||||||
* e.g. <<: [*foo, *bar]
|
* e.g. <<: [*foo, *bar]
|
||||||
*/
|
*/
|
||||||
tll_foreach(it->item.value->list.values, v_it) {
|
tll_foreach(it->item.value->list.values, v_it) {
|
||||||
assert(v_it->item->type == DICT);
|
if (v_it->item->type != DICT) {
|
||||||
|
int cnt = snprintf(
|
||||||
|
NULL, 0, "%zu:%zu: cannot merge non-dictionary anchor",
|
||||||
|
v_it->item->line, v_it->item->column);
|
||||||
|
*error = malloc(cnt + 1);
|
||||||
|
snprintf(
|
||||||
|
*error, cnt + 1, "%zu:%zu: cannot merge non-dictionary anchor",
|
||||||
|
v_it->item->line, v_it->item->column);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
tll_foreach(v_it->item->dict.pairs, vv_it) {
|
tll_foreach(v_it->item->dict.pairs, vv_it) {
|
||||||
struct dict_pair p = {
|
struct dict_pair p = {
|
||||||
.key = vv_it->item.key,
|
.key = vv_it->item.key,
|
||||||
|
@ -240,7 +255,17 @@ post_process(struct yml_node *node)
|
||||||
* Merge value is a dictionary only
|
* Merge value is a dictionary only
|
||||||
* e.g. <<: *foo
|
* e.g. <<: *foo
|
||||||
*/
|
*/
|
||||||
assert(it->item.value->type == DICT);
|
if (it->item.value->type != DICT) {
|
||||||
|
int cnt = snprintf(
|
||||||
|
NULL, 0, "%zu:%zu: cannot merge non-dictionary anchor",
|
||||||
|
it->item.value->line, it->item.value->column);
|
||||||
|
*error = malloc(cnt + 1);
|
||||||
|
snprintf(
|
||||||
|
*error, cnt + 1, "%zu:%zu: cannot merge non-dictionary anchor",
|
||||||
|
it->item.value->line, it->item.value->column);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
tll_foreach(it->item.value->dict.pairs, v_it) {
|
tll_foreach(it->item.value->dict.pairs, v_it) {
|
||||||
struct dict_pair p = {
|
struct dict_pair p = {
|
||||||
.key = v_it->item.key,
|
.key = v_it->item.key,
|
||||||
|
@ -269,6 +294,8 @@ post_process(struct yml_node *node)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -526,7 +553,10 @@ yml_load(FILE *yml, char **error)
|
||||||
|
|
||||||
yaml_parser_delete(&yaml);
|
yaml_parser_delete(&yaml);
|
||||||
|
|
||||||
post_process(root);
|
if (!post_process(root, error)) {
|
||||||
|
yml_destroy(root);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return root;
|
return root;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
Loading…
Add table
Reference in a new issue