forked from external/yambar
yml: fix crash when referencing a nonn-existent anchor
This commit is contained in:
parent
74043d0e6d
commit
1a7b00054f
1 changed files with 39 additions and 6 deletions
45
yml.c
45
yml.c
|
@ -12,6 +12,7 @@
|
||||||
enum yml_error {
|
enum yml_error {
|
||||||
YML_ERR_NONE,
|
YML_ERR_NONE,
|
||||||
YML_ERR_DUPLICATE_KEY,
|
YML_ERR_DUPLICATE_KEY,
|
||||||
|
YML_ERR_INVALID_ANCHOR,
|
||||||
YML_ERR_UNKNOWN,
|
YML_ERR_UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,7 +274,8 @@ post_process(struct yml_node *node)
|
||||||
static const char *
|
static const char *
|
||||||
format_error(enum yml_error err,
|
format_error(enum yml_error err,
|
||||||
const struct yml_node *parent,
|
const struct yml_node *parent,
|
||||||
const struct yml_node *node)
|
const struct yml_node *node,
|
||||||
|
const char *anchor)
|
||||||
{
|
{
|
||||||
static char err_str[512];
|
static char err_str[512];
|
||||||
|
|
||||||
|
@ -314,6 +316,26 @@ format_error(enum yml_error err,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case YML_ERR_INVALID_ANCHOR:
|
||||||
|
if (parent->parent != NULL && parent->parent->type == DICT) {
|
||||||
|
tll_foreach(parent->parent->dict.pairs, pair) {
|
||||||
|
if (pair->item.value != parent)
|
||||||
|
continue;
|
||||||
|
if (pair->item.key->type != SCALAR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
snprintf(err_str, sizeof(err_str),
|
||||||
|
"%s: invalid anchor: %s",
|
||||||
|
pair->item.key->scalar.value,
|
||||||
|
anchor != NULL ? anchor : "<unknown>");
|
||||||
|
return err_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(err_str, sizeof(err_str), "invalid anchor: %s",
|
||||||
|
anchor != NULL ? anchor : "<unknown>");
|
||||||
|
break;
|
||||||
|
|
||||||
case YML_ERR_UNKNOWN:
|
case YML_ERR_UNKNOWN:
|
||||||
snprintf(err_str, sizeof(err_str), "unknown error");
|
snprintf(err_str, sizeof(err_str), "unknown error");
|
||||||
break;
|
break;
|
||||||
|
@ -385,7 +407,8 @@ yml_load(FILE *yml, char **error)
|
||||||
indent -= 2;
|
indent -= 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case YAML_ALIAS_EVENT:
|
case YAML_ALIAS_EVENT: {
|
||||||
|
bool got_match = false;
|
||||||
for (size_t i = 0; i < root->root.anchor_count; i++) {
|
for (size_t i = 0; i < root->root.anchor_count; i++) {
|
||||||
const struct anchor_map *map = &root->root.anchors[i];
|
const struct anchor_map *map = &root->root.anchors[i];
|
||||||
|
|
||||||
|
@ -397,14 +420,23 @@ yml_load(FILE *yml, char **error)
|
||||||
|
|
||||||
enum yml_error err = add_node(n, clone, event.start_mark);
|
enum yml_error err = add_node(n, clone, event.start_mark);
|
||||||
if (err != YML_ERR_NONE) {
|
if (err != YML_ERR_NONE) {
|
||||||
error_str = format_error(err, n, clone);
|
error_str = format_error(err, n, clone, NULL);
|
||||||
yml_destroy(clone);
|
yml_destroy(clone);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
got_match = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!got_match) {
|
||||||
|
error_str = format_error(
|
||||||
|
YML_ERR_INVALID_ANCHOR, n, NULL,
|
||||||
|
(const char *)event.data.alias.anchor);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YAML_SCALAR_EVENT: {
|
case YAML_SCALAR_EVENT: {
|
||||||
struct yml_node *new_scalar = calloc(1, sizeof(*new_scalar));
|
struct yml_node *new_scalar = calloc(1, sizeof(*new_scalar));
|
||||||
|
@ -414,7 +446,7 @@ yml_load(FILE *yml, char **error)
|
||||||
|
|
||||||
enum yml_error err = add_node(n, new_scalar, event.start_mark);
|
enum yml_error err = add_node(n, new_scalar, event.start_mark);
|
||||||
if (err != YML_ERR_NONE) {
|
if (err != YML_ERR_NONE) {
|
||||||
error_str = format_error(err, n, new_scalar);
|
error_str = format_error(err, n, new_scalar, NULL);
|
||||||
yml_destroy(new_scalar);
|
yml_destroy(new_scalar);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -434,7 +466,7 @@ yml_load(FILE *yml, char **error)
|
||||||
|
|
||||||
enum yml_error err = add_node(n, new_list, event.start_mark);
|
enum yml_error err = add_node(n, new_list, event.start_mark);
|
||||||
if (err != YML_ERR_NONE) {
|
if (err != YML_ERR_NONE) {
|
||||||
error_str = format_error(err, n, new_list);
|
error_str = format_error(err, n, new_list, NULL);
|
||||||
yml_destroy(new_list);
|
yml_destroy(new_list);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -462,7 +494,7 @@ yml_load(FILE *yml, char **error)
|
||||||
|
|
||||||
enum yml_error err = add_node(n, new_dict, event.start_mark);
|
enum yml_error err = add_node(n, new_dict, event.start_mark);
|
||||||
if (err != YML_ERR_NONE) {
|
if (err != YML_ERR_NONE) {
|
||||||
error_str = format_error(err, n, new_dict);
|
error_str = format_error(err, n, new_dict, NULL);
|
||||||
yml_destroy(new_dict);
|
yml_destroy(new_dict);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -477,6 +509,7 @@ yml_load(FILE *yml, char **error)
|
||||||
}
|
}
|
||||||
|
|
||||||
case YAML_MAPPING_END_EVENT:
|
case YAML_MAPPING_END_EVENT:
|
||||||
|
assert(!n->dict.next_is_value);
|
||||||
indent -= 2;
|
indent -= 2;
|
||||||
assert(n->parent != NULL);
|
assert(n->parent != NULL);
|
||||||
n = n->parent;
|
n = n->parent;
|
||||||
|
|
Loading…
Add table
Reference in a new issue