html.c: Avoid half-init objects on html_node_add_attr

The previous implementation would leave half-initialised objects if one
of the calls to strdup(3) failed. Now, n->attrs is only modified when
all previous memory allocations were successful.
This commit is contained in:
Xavier Del Campo Romero 2024-02-19 22:49:09 +01:00
parent 6ceae16a20
commit 9d9e0c2979
Signed by: xavi
GPG Key ID: 84FF3612A9BF43F2
1 changed files with 23 additions and 12 deletions

35
html.c
View File

@ -110,30 +110,41 @@ int html_node_add_attr(struct html_node *const n, const char *const attr,
const char *const val)
{
const size_t el = n->n + 1;
struct html_attribute *const attrs = realloc(n->attrs,
el * sizeof *n->attrs), *a = NULL;
char *const attrdup = strdup(attr), *valdup = NULL;
struct html_attribute *attrs = NULL;
if (!attrs)
if (!attrdup)
{
fprintf(stderr, "%s: strdup(3) attr: %s\n", __func__, strerror(errno));
goto failure;
}
else if (val && !(valdup = strdup(val)))
{
fprintf(stderr, "%s: strdup(3) val: %s\n", __func__, strerror(errno));
goto failure;
}
else if (!(attrs = realloc(n->attrs, el * sizeof *attrs)))
{
fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno));
return -1;
}
a = &attrs[n->n];
*a = (const struct html_attribute){0};
struct html_attribute *const a = &attrs[n->n];
if (!(a->attr = strdup(attr))
|| (val && !(a->value = strdup(val))))
*a = (const struct html_attribute)
{
fprintf(stderr, "%s: strdup(3): %s\n", __func__, strerror(errno));
free(a->attr);
free(a->value);
return -1;
}
.attr = attrdup,
.value = valdup
};
n->attrs = attrs;
n->n = el;
return 0;
failure:
free(attrdup);
free(valdup);
return -1;
}
void html_node_add_sibling(struct html_node *const n,