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 char *const val)
|
||||||
{
|
{
|
||||||
const size_t el = n->n + 1;
|
const size_t el = n->n + 1;
|
||||||
struct html_attribute *const attrs = realloc(n->attrs,
|
char *const attrdup = strdup(attr), *valdup = NULL;
|
||||||
el * sizeof *n->attrs), *a = 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));
|
fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = &attrs[n->n];
|
struct html_attribute *const a = &attrs[n->n];
|
||||||
*a = (const struct html_attribute){0};
|
|
||||||
|
|
||||||
if (!(a->attr = strdup(attr))
|
*a = (const struct html_attribute)
|
||||||
|| (val && !(a->value = strdup(val))))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: strdup(3): %s\n", __func__, strerror(errno));
|
.attr = attrdup,
|
||||||
free(a->attr);
|
.value = valdup
|
||||||
free(a->value);
|
};
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
n->attrs = attrs;
|
n->attrs = attrs;
|
||||||
n->n = el;
|
n->n = el;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
free(attrdup);
|
||||||
|
free(valdup);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void html_node_add_sibling(struct html_node *const n,
|
void html_node_add_sibling(struct html_node *const n,
|
||||||
|
|
Loading…
Reference in New Issue