lorid

convert chordpro to pdf
git clone git://git.relim.de/lorid.git
Log | Files | Refs | README | LICENSE

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:
Msrc/chordpro.c | 51+++++++++++++++++++++++++++++++++++++++++++++------
Mtest/memory/029.cho | 2++
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>