commit e9df16d34c35d3675721170d2c893fff5d7df9e4
parent 55a9dde6e44140363323a9946b0d1e5d7ac81aaf
Author: nibo <nibo@relim.de>
Date: Sat, 26 Jul 2025 13:57:47 +0200
Free memory in case of test/memory/019.cho
Diffstat:
24 files changed, 275 insertions(+), 25 deletions(-)
diff --git a/src/chordpro.c b/src/chordpro.c
@@ -4731,30 +4731,23 @@ cho_grid_token_parse(struct ChoContext *ctx, const char *token, bool *err)
static void
cho_songs_close(struct ChoContext *ctx, struct ChoLine ***lines)
{
- if (
- (*lines) &&
- (*lines)[ctx->li] &&
- (*lines)[ctx->li]->items &&
- (*lines)[ctx->li]->items[ctx->lii]
- ) {
- if ((*lines)[ctx->li]->items[ctx->lii]->is_text && (*lines)[ctx->li]->items[ctx->lii]->u.text->text) {
- (*lines)[ctx->li]->items[ctx->lii]->u.text->text = erealloc((*lines)[ctx->li]->items[ctx->lii]->u.text->text, (ctx->te+1) * sizeof(char));
- (*lines)[ctx->li]->items[ctx->lii]->u.text->text[ctx->te] = 0;
- ctx->lii++;
- (*lines)[ctx->li]->items = erealloc((*lines)[ctx->li]->items, (ctx->lii+1) * sizeof(struct ChoLineItem *));
- (*lines)[ctx->li]->items[ctx->lii] = NULL;
- (*lines)[ctx->li]->text_above = erealloc((*lines)[ctx->li]->text_above, (ctx->lia+1) * sizeof(struct ChoLineItemAbove *));
- (*lines)[ctx->li]->text_above[ctx->lia] = NULL;
- ctx->li++;
- *lines = erealloc(*lines, (ctx->li+1) * sizeof(struct ChoLine *));
- (*lines)[ctx->li] = NULL;
- } else {
- cho_line_item_free((*lines)[ctx->li]->items[ctx->lii]);
- free((*lines)[ctx->li]->items);
- free((*lines)[ctx->li]->text_above);
- free((*lines)[ctx->li]);
- (*lines)[ctx->li] = NULL;
- }
+ if (!(*lines)[ctx->li]->items[ctx->lii]->u.text->text && !(*lines)[ctx->li]->text_above) {
+ cho_line_item_free((*lines)[ctx->li]->items[ctx->lii]);
+ free((*lines)[ctx->li]->items);
+ free((*lines)[ctx->li]);
+ (*lines)[ctx->li] = NULL;
+ } else {
+ (*lines)[ctx->li]->items[ctx->lii]->u.text->text = erealloc((*lines)[ctx->li]->items[ctx->lii]->u.text->text, (ctx->te+1) * sizeof(char));
+ (*lines)[ctx->li]->items[ctx->lii]->u.text->text[ctx->te] = 0;
+ ctx->lii++;
+ (*lines)[ctx->li]->items = erealloc((*lines)[ctx->li]->items, (ctx->lii+1) * sizeof(struct ChoLineItem *));
+ (*lines)[ctx->li]->items[ctx->lii] = NULL;
+ ctx->lia++;
+ (*lines)[ctx->li]->text_above = erealloc((*lines)[ctx->li]->text_above, (ctx->lia+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[ctx->li]->text_above[ctx->lia] = NULL;
+ ctx->li++;
+ *lines = erealloc(*lines, (ctx->li+1) * sizeof(struct ChoLine *));
+ (*lines)[ctx->li] = NULL;
}
ctx->songs[ctx->so]->metadata = erealloc(ctx->songs[ctx->so]->metadata, (ctx->m+1) * sizeof(struct ChoMetadata *));
ctx->songs[ctx->so]->metadata[ctx->m] = NULL;
@@ -5852,7 +5845,6 @@ cho_songs_parse(const char *str, const char *chordpro_filepath, struct Config *c
break;
}
cho_log(&ctx, LOG_ERR, "Newline character inside an annotation is invalid.");
- ctx.lia++;
goto ERR;
}
(*lines)[ctx.li]->text_above[ctx.lia]->u.annot->text = erealloc((*lines)[ctx.li]->text_above[ctx.lia]->u.annot->text, (ctx.ann+1) * sizeof(char));
diff --git a/test/memory/001.cho b/test/memory/001.cho
@@ -0,0 +1,13 @@
+# cho_log(&ctx, LOG_ERR, "Tag has to be closed on same line.");
+{t: Tag Has To Be Closed On Same Line}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+<span font_family="Inter">Hello World
+</span>
diff --git a/test/memory/002.cho b/test/memory/002.cho
@@ -0,0 +1,12 @@
+# cho_log(&ctx, LOG_ERR, "Can't close a %s section that wasn't opened earlier.", section_types[directive->stype]);
+{t: 02}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{eoc}
diff --git a/test/memory/003.cho b/test/memory/003.cho
@@ -0,0 +1,12 @@
+# cho_log(&ctx, LOG_ERR, "Directive 'image' has no value.");
+{t: 03}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{image}
diff --git a/test/memory/004.cho b/test/memory/004.cho
@@ -0,0 +1,12 @@
+# cho_log(&ctx, LOG_ERR, "Can't start a new directive if the previous one is not yet closed.");
+{t: 04}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{{sot}
diff --git a/test/memory/004.pdf b/test/memory/004.pdf
Binary files differ.
diff --git a/test/memory/005.cho b/test/memory/005.cho
@@ -0,0 +1,13 @@
+# cho_log(&ctx, LOG_ERR, "Can't have a newline in a directive name.");
+{t: 05}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{start_of_bri
+dge}
diff --git a/test/memory/006.cho b/test/memory/006.cho
@@ -0,0 +1,13 @@
+# cho_log(&ctx, LOG_ERR, "Can't start a new section when the previous one is not yet closed.");
+{t: 06}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{start_of_verse: Verse}
+{start_of_something}
diff --git a/test/memory/006.pdf b/test/memory/006.pdf
Binary files differ.
diff --git a/test/memory/007.cho b/test/memory/007.cho
@@ -0,0 +1,13 @@
+# cho_log(&ctx, LOG_ERR, "A directive that closes a section can't have arguments.");
+{t: 07}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{sog}
+{eog: Something}
diff --git a/test/memory/007.pdf b/test/memory/007.pdf
Binary files differ.
diff --git a/test/memory/008.cho b/test/memory/008.cho
@@ -0,0 +1,12 @@
+# cho_log(&ctx, LOG_ERR, "Preamble directive '%s' can't have a value.", directive_name);
+{t: 08}
+
+{sov: Verse 1}
+Make sure the parser has something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{new_song: argument}
diff --git a/test/memory/009.cho b/test/memory/009.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Font directive '%s' has to contain a positive number.", directive_name);
+{t: 09}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{gridsize: abcd}
diff --git a/test/memory/009.pdf b/test/memory/009.pdf
Binary files differ.
diff --git a/test/memory/010.cho b/test/memory/010.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Font directive '%s' has an invalid value.", directive_name);
+{t: 10}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{tabcolour: halloween}
diff --git a/test/memory/011.cho b/test/memory/011.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Directive 'transpose' has an invalid value.");
+{t: 11}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{transpose: forever}
diff --git a/test/memory/012.cho b/test/memory/012.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Directive '%s' can't have a value.", directive_name);
+{t: 12}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{new_page: with a value}
diff --git a/test/memory/013.cho b/test/memory/013.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Can't start a new directive if the previous one is not yet closed.");
+{t: 13}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{sob: {some}
diff --git a/test/memory/014.cho b/test/memory/014.cho
@@ -0,0 +1,16 @@
+# cho_log(&ctx, LOG_ERR, "Newline character inside a directive value is invalid.");
+{t: 14}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{sob: so
+me}
+
diff --git a/test/memory/015.cho b/test/memory/015.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Directive value can't be greater than 4095 bytes.");
+{t: 15}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+{soc: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}
diff --git a/test/memory/016.cho b/test/memory/016.cho
@@ -0,0 +1,15 @@
+# cho_log(&ctx, LOG_ERR, "Newline character inside a chord is invalid.");
+{t: 16}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+[G
+is]
diff --git a/test/memory/017.cho b/test/memory/017.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Can't start a new chord/annotation if the previous one is not yet closed.");
+{t: 17}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+[C4[]
diff --git a/test/memory/018.cho b/test/memory/018.cho
@@ -0,0 +1,14 @@
+# cho_log(&ctx, LOG_ERR, "Chord can't be greater than %d bytes.", CHORD_LEN-1);
+{t: 18}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+[BBBBBBBBBBBBBBB]
diff --git a/test/memory/019.cho b/test/memory/019.cho
@@ -0,0 +1,15 @@
+# cho_log(&ctx, LOG_ERR, "Newline character inside an annotation is invalid.");
+{t: 19}
+
+{textfont: Open Sans}
+
+{sov: Verse 1}
+Make [A]sure the parser has [E]something
+That it saved in memory
+Only this way we may trigger
+A memory leak
+{eov}
+
+# Now trigger the specific error
+[*some
+thing]