commit 6b9e0a31f4ba113e1d99921344c2eab1d28bd3f4
parent ebf7af492cbc57c3bbda7f67a3916f549cde39ff
Author: nibo <nibo@relim.de>
Date: Wed, 30 Jul 2025 20:19:29 +0200
Improve cleaning on error in case of attributes
Diffstat:
2 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/src/chordpro.c b/src/chordpro.c
@@ -4137,6 +4137,15 @@ cho_directive_parse(struct ChoContext *ctx, const char *name)
directive->ttype = TEXT_TYPE_TEXT;
} else
if (
+ !strcmp(name, "end_of_bridge") ||
+ !strcmp(name, "eob")
+ ) {
+ directive->dtype = DIRECTIVE_TYPE_ENVIRONMENT;
+ directive->position = POSITION_END;
+ directive->stype = SECTION_TYPE_BRIDGE;
+ directive->ttype = TEXT_TYPE_TEXT;
+ } else
+ if (
!strcmp(name, "start_of_tab") ||
!strcmp(name, "sot")
) {
@@ -5279,7 +5288,7 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
ctx.th--;
break;
case CHORD_DIRECTIVE_DEFINE:
- cho_log(&ctx, LOG_WARN, "Ignoring chord directive '%s' because it has no value.", directive_name);
+ cho_log(&ctx, LOG_WARN, "Ignoring chord directive '%s' because it has no value.", directive_name);
break;
}
break;
@@ -6246,7 +6255,10 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
} else {
ctx.tags[ctx.ta]->attrs[ctx.at]->name = erealloc(ctx.tags[ctx.ta]->attrs[ctx.at]->name, (ctx.atn+1) * sizeof(char));
ctx.tags[ctx.ta]->attrs[ctx.at]->name[ctx.atn] = 0;
- cho_log(&ctx, LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ cho_log(&ctx, LOG_ERR, "1 Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
}
@@ -6258,11 +6270,23 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
}
ctx.tags[ctx.ta]->attrs[ctx.at]->name = erealloc(ctx.tags[ctx.ta]->attrs[ctx.at]->name, (ctx.atn+1) * sizeof(char));
ctx.tags[ctx.ta]->attrs[ctx.at]->name[ctx.atn] = 0;
- cho_log(&ctx, LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ cho_log(&ctx, LOG_ERR, "2 Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
if (c == '>') {
- if (ctx.tags[ctx.ta]->attrs[ctx.at-1]->value) {
+ if (ctx.tags[ctx.ta]->attrs[ctx.at]->name && !ctx.tags[ctx.ta]->attrs[ctx.at]->value) {
+ ctx.tags[ctx.ta]->attrs[ctx.at]->name = erealloc(ctx.tags[ctx.ta]->attrs[ctx.at]->name, (ctx.atn+1) * sizeof(char));
+ ctx.tags[ctx.ta]->attrs[ctx.at]->name[ctx.atn] = 0;
+ cho_log(&ctx, LOG_ERR, "3 Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
+ goto ERR;
+ }
+ if (ctx.at > 0 && ctx.tags[ctx.ta]->attrs[ctx.at-1]->value) {
cho_tag_attr_free(ctx.tags[ctx.ta]->attrs[ctx.at]);
ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
ctx.atn = 0;
@@ -6314,7 +6338,10 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
ctx.tags[ctx.ta]->attrs[ctx.at]->name = erealloc(ctx.tags[ctx.ta]->attrs[ctx.at]->name, (ctx.atn+1) * sizeof(char));
ctx.tags[ctx.ta]->attrs[ctx.at]->name[ctx.atn] = 0;
ctx.atn = 0;
- cho_log(&ctx, LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ cho_log(&ctx, LOG_ERR, "4 Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
}
@@ -6327,6 +6354,9 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
break;
}
cho_log(&ctx, LOG_ERR, "Newline character inside an tag attribute name is invalid.");
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
ctx.tags[ctx.ta]->attrs[ctx.at]->name = erealloc(ctx.tags[ctx.ta]->attrs[ctx.at]->name, (ctx.atn+1) * sizeof(char));
@@ -6344,15 +6374,24 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
break;
}
cho_log(&ctx, LOG_ERR, "Newline character inside an attribute value is invalid.");
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
if (avs == ATTRIBUTE_VALUE_SYNTAX_UNINITIALIZED) {
if (is_whitespace(c)) {
cho_log(&ctx, LOG_ERR, "Whitespace character after equals sign is invalid.");
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
if (c == '>') {
- cho_log(&ctx, LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ cho_log(&ctx, LOG_ERR, "5 Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
+ ctx.at++;
+ ctx.tags[ctx.ta]->attrs = erealloc(ctx.tags[ctx.ta]->attrs, (ctx.at+1) * sizeof(struct Attr *));
+ ctx.tags[ctx.ta]->attrs[ctx.at] = NULL;
goto ERR;
}
if (c == '\'') {
diff --git a/test/memory/029.cho b/test/memory/029.cho
@@ -1,3 +1,4 @@
+# cho_log(&ctx, LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", ctx.tags[ctx.ta]->attrs[ctx.at]->name, tag_start);
{t: 29}
{textfont: Open Sans}
@@ -10,3 +11,4 @@ A memory leak
{eov}
# Now trigger the specific error
+<span size ></span>