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:
parent
6ceae16a20
commit
9d9e0c2979
35
html.c
35
html.c
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue