aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-02-19 22:49:09 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2024-02-19 22:49:09 +0100
commit9d9e0c2979f43297b2ebbf84f14f064f3f9ced0e (patch)
tree95f89b3c89c1e8bfa8cf75068b06d8f89b6c099f
parent6ceae16a20175edb77fb2ffab0d3d6648d011221 (diff)
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.
-rw-r--r--html.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/html.c b/html.c
index 5a92d77..0277498 100644
--- a/html.c
+++ b/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,