commit a8b9e551d166e28462ffde23b465625453aad37d
parent ef0e4bb1432607e0e06379a134100052514e992a
Author: nibo <nibo@relim.de>
Date: Wed, 16 Jul 2025 12:04:56 +0200
Free memory in case of error in src/config.c
Diffstat:
| M | src/config.c | | | 139 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
1 file changed, 87 insertions(+), 52 deletions(-)
diff --git a/src/config.c b/src/config.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <errno.h>
#include <toml.h>
#include "core.h"
#include "config.h"
@@ -307,50 +308,51 @@ config_notes_load(
const char *system
)
{
- struct Note **custom_notes = emalloc(8 * sizeof(struct Note *));
- toml_array_t *arr = toml_table_array(notes, system);
+ struct Note **custom_notes;
+ toml_table_t *note;
+ toml_value_t value;
+ toml_array_t *arr;
+ int arr_len, k;
+ int i = 0;
+
+ custom_notes = emalloc(8 * sizeof(struct Note *));
+ arr = toml_table_array(notes, system);
if (!arr) {
- return NULL;
+ goto ERR;
}
- int arr_len = toml_array_len(arr);
+ arr_len = toml_array_len(arr);
if (arr_len != 7) {
config_log(ctx, LOG_ERR, "[notation_systems]", "Custom notation system '%s' has to have exactly 7 items. For an example see `lorid --print-default-config`.", system);
- free(notes);
- return NULL;
+ goto ERR;
}
- toml_table_t *note;
- toml_value_t value;
- int i;
for (i = 0; i<arr_len; i++) {
note = toml_array_table(arr, i);
- if (note) {
- custom_notes[i] = config_note_new();
- value = toml_table_string(note, "note");
- if (value.ok) {
- custom_notes[i]->note = value.u.s;
- }
- value = toml_table_string(note, "sharp");
- if (value.ok) {
- custom_notes[i]->sharp = value.u.s;
- if (i == 2 || i == 6) {
- config_log(ctx, LOG_ERR, "[notation_systems]", "Custom notation system '%s' can't have sharp value at array index '%d'.", system, i);
- goto CLEAN;
- }
+ custom_notes[i] = config_note_new();
+ value = toml_table_string(note, "note");
+ if (value.ok) {
+ custom_notes[i]->note = value.u.s;
+ }
+ value = toml_table_string(note, "sharp");
+ if (value.ok) {
+ custom_notes[i]->sharp = value.u.s;
+ if (i == 2 || i == 6) {
+ config_log(ctx, LOG_ERR, "[notation_systems]", "Custom notation system '%s' can't have sharp value at array index '%d'.", system, i);
+ goto ERR;
}
- value = toml_table_string(note, "flat");
- if (value.ok) {
- custom_notes[i]->flat = value.u.s;
- if (i == 0 || i == 3) {
- config_log(ctx, LOG_ERR, "[notation_systems]", "Custom notation system '%s' can't have flat value at array index '%d'.", system, i);
- goto CLEAN;
- }
+ }
+ value = toml_table_string(note, "flat");
+ if (value.ok) {
+ custom_notes[i]->flat = value.u.s;
+ if (i == 0 || i == 3) {
+ config_log(ctx, LOG_ERR, "[notation_systems]", "Custom notation system '%s' can't have flat value at array index '%d'.", system, i);
+ goto ERR;
}
}
}
custom_notes[7] = NULL;
return custom_notes;
- CLEAN:
- for (int k=i; k>=0; k--) {
+ ERR:
+ for (k = 0; k<=i; k++) {
config_note_free(custom_notes[k]);
}
free(custom_notes);
@@ -361,6 +363,8 @@ static void
config_notes_print_as_toml(enum NotationSystem system)
{
struct Note *notes;
+ int i;
+
switch (system) {
case NOTATION_SYSTEM_COMMON:
notes = (struct Note *)¬es_common;
@@ -384,7 +388,6 @@ config_notes_print_as_toml(enum NotationSystem system)
return;
}
printf("%s = [\n", config_notation_system_to_config_string(system));
- int i;
for (i = 0; i<7; i++) {
printf("\t{ note = \"%s\",", notes[i].note);
if (notes[i].sharp) {
@@ -431,6 +434,8 @@ void
config_print_default(void)
{
struct Config *config = config_load_default();
+ int i;
+
printf("metadata_separator = \"%s\"\n\n", config->metadata_separator);
printf("[notation_systems]\n");
config_notes_print_as_toml(NOTATION_SYSTEM_COMMON);
@@ -461,8 +466,7 @@ config_print_default(void)
printf("show = %s\n", config->output->toc->show ? "true" : "false");
printf("title = \"%s\"\n\n", config->output->toc->title);
printf("[output.styles]\n");
- int i;
- for (i = 1; i<TEXT_TYPE_LENGTH; i++) {
+ for (i = 0; i<TEXT_TYPE_LENGTH; i++) {
printf("[output.styles.%s]\n\n", text_types[i]);
cho_style_print_as_toml(config->output->styles[i], text_types[i]);
}
@@ -482,6 +486,7 @@ config_load_font(
enum FontWeight weight;
toml_value_t value;
bool error;
+
value = toml_table_string(table, "name");
if (value.ok) {
presence->font.name = true;
@@ -496,6 +501,7 @@ config_load_font(
if (err_buf) {
strcpy((char *)err_buf, "family value is invalid.");
}
+ free(value.u.s);
return false;
} else {
font->family = family;
@@ -510,6 +516,7 @@ config_load_font(
if (err_buf) {
strcpy((char *)err_buf, "style value is invalid.");
}
+ free(value.u.s);
return false;
} else {
font->style = style;
@@ -524,6 +531,7 @@ config_load_font(
if (err_buf) {
strcpy((char *)err_buf, "weight value is invalid.");
}
+ free(value.u.s);
return false;
} else {
font->weight = weight;
@@ -546,11 +554,13 @@ config_load_style(
char (*err_buf)[38]
)
{
- toml_value_t value;
+ bool error;
struct RGBColor *color;
enum LineStyle line_style;
- bool error;
- toml_table_t *font_section = toml_table_table(table, "font");
+ toml_table_t *font_section;
+ toml_value_t value;
+
+ font_section = toml_table_table(table, "font");
if (font_section) {
char err[25];
if (!config_load_font(style->font, font_section, presence, &err)) {
@@ -568,6 +578,7 @@ config_load_style(
style->foreground_color = color;
} else {
strcpy((char *)err_buf, "foreground color value is invalid.");
+ free(value.u.s);
return false;
}
free(value.u.s);
@@ -581,6 +592,7 @@ config_load_style(
style->background_color = color;
} else {
strcpy((char *)err_buf, "background color value is invalid.");
+ free(value.u.s);
return false;
}
free(value.u.s);
@@ -591,6 +603,7 @@ config_load_style(
line_style = cho_linestyle_parse(value.u.s, &error);
if (error) {
strcpy((char *)err_buf, "underline style value is invalid.");
+ free(value.u.s);
return false;
} else {
style->underline_style = line_style;
@@ -606,6 +619,7 @@ config_load_style(
style->underline_color = color;
} else {
strcpy((char *)err_buf, "underline color value is invalid.");
+ free(value.u.s);
return false;
}
free(value.u.s);
@@ -616,6 +630,7 @@ config_load_style(
line_style = cho_linestyle_parse(value.u.s, &error);
if (error) {
strcpy((char *)err_buf, "overline style value is invalid.");
+ free(value.u.s);
return false;
} else {
style->overline_style = line_style;
@@ -631,6 +646,7 @@ config_load_style(
style->overline_color = color;
} else {
strcpy((char *)err_buf, "overline color value is invalid.");
+ free(value.u.s);
return false;
}
free(value.u.s);
@@ -649,6 +665,7 @@ config_load_style(
style->strikethrough_color = color;
} else {
strcpy((char *)err_buf, "strikethrough color value is invalid.");
+ free(value.u.s);
return false;
}
free(value.u.s);
@@ -667,6 +684,7 @@ config_load_style(
style->boxed_color = color;
} else {
strcpy((char *)err_buf, "boxed color value is invalid.");
+ free(value.u.s);
return false;
}
free(value.u.s);
@@ -722,8 +740,7 @@ set_text_style(
)
{
- if (!presence->font.name &&
- text_presence->font.name) {
+ if (!presence->font.name && text_presence->font.name) {
free(style->font->name);
style->font->name = strdup(text_style->font->name);
}
@@ -948,7 +965,8 @@ config_load(toml_table_t *toml, const char *filepath)
if (error) {
LOG_DEBUG("config_instrument_parse failed.");
config_log(&ctx, LOG_ERR, "[output.chord_diagram]", "Unknown instrument '%s'.", value.u.s);
- return NULL;
+ free(value.u.s);
+ goto ERR;
}
config->output->diagram->instrument = instrument;
free(value.u.s);
@@ -961,7 +979,8 @@ config_load(toml_table_t *toml, const char *filepath)
notes = toml_table_table(toml, "notation_systems");
if (!notes) {
config_log(&ctx, LOG_ERR, "[output]", "Custom notation system '%s' has no corresponding definition in [notation_systems]");
- return NULL;
+ free(value.u.s);
+ goto ERR;
}
custom_notes = config_notes_load(&ctx, notes, value.u.s);
if (custom_notes) {
@@ -970,7 +989,8 @@ config_load(toml_table_t *toml, const char *filepath)
} else {
LOG_DEBUG("config_notes_load failed.");
config_log(&ctx, LOG_ERR, "[output]", "Couldn't load custom notation system '%s' from [notation_systems] section.", value.u.s);
- return NULL;
+ free(value.u.s);
+ goto ERR;
}
} else {
config_notes_free(config->output->notes);
@@ -993,7 +1013,8 @@ config_load(toml_table_t *toml, const char *filepath)
align = config_alignment_parse(value.u.s, &error);
if (error) {
LOG_DEBUG("config_alignment_parse failed.");
- return NULL;
+ free(value.u.s);
+ goto ERR;
}
config->output->page_no->align = align;
free(value.u.s);
@@ -1007,6 +1028,7 @@ config_load(toml_table_t *toml, const char *filepath)
struct ChoStyle *style;
struct ChoStylePresence presences[TEXT_TYPE_LENGTH] = {0};
toml_table_t *key;
+
for (i = 0; i<toml_table_len(styles); i++) {
key_name = toml_table_key(styles, i, &unused);
ttype = config_text_type_parse(key_name, &error);
@@ -1021,7 +1043,7 @@ config_load(toml_table_t *toml, const char *filepath)
if (!config_load_style(style, key, &presences[ttype], &err)) {
LOG_DEBUG("config_load_style failed.");
config_log(&ctx, LOG_ERR, toml_section_name, err);
- return NULL;
+ goto ERR;
}
}
}
@@ -1036,6 +1058,7 @@ config_load(toml_table_t *toml, const char *filepath)
toml_table_t *notes;
enum NotationSystem notation_system;
struct Note **custom_notes;
+
value = toml_table_string(chords, "notation_system");
if (value.ok) {
notation_system = config_notation_system_parse(value.u.s);
@@ -1043,7 +1066,8 @@ config_load(toml_table_t *toml, const char *filepath)
notes = toml_table_table(toml, "notation_systems");
if (!notes) {
config_log(&ctx, LOG_ERR, "[parser.chords]", "Custom notation system '%s' has no corresponding definition in [notation_systems].", value.u.s);
- return NULL;
+ free(value.u.s);
+ goto ERR;
}
custom_notes = config_notes_load(&ctx, notes, value.u.s);
if (custom_notes) {
@@ -1052,7 +1076,8 @@ config_load(toml_table_t *toml, const char *filepath)
} else {
LOG_DEBUG("config_notes_load failed.");
config_log(&ctx, LOG_ERR, "[parser.chords]", "Couldn't load custom notation system '%s' from [notation_systems] section.", value.u.s);
- return NULL;
+ free(value.u.s);
+ goto ERR;
}
} else {
config_notes_free(config->parser->notes);
@@ -1073,6 +1098,10 @@ config_load(toml_table_t *toml, const char *filepath)
}
free(ctx.config_filepath);
return config;
+ ERR:
+ free(ctx.config_filepath);
+ config_free(config);
+ return NULL;
}
struct Config *
@@ -1080,10 +1109,12 @@ config_load_from_file(const char *filepath)
{
struct Config *config = NULL;
toml_table_t *table = NULL;
- FILE *fp = fopen(filepath, "r");
+ FILE *fp = NULL;
+
+ fp = fopen(filepath, "r");
if (!fp) {
LOG_DEBUG("fopen failed.");
- // util_log(NULL, 0, LOG_ERR, "Cannot open file '%s'.", filepath);
+ util_log(NULL, 0, LOG_ERR, "Cannot open file '%s': %s", filepath, strerror(errno));
return NULL;
}
char errbuf[200];
@@ -1091,14 +1122,16 @@ config_load_from_file(const char *filepath)
if (!table) {
LOG_DEBUG("toml_parse_file failed.");
util_log(NULL, 0, LOG_ERR, "Config file '%s' is not a valid toml file: %s.", filepath, (char *)&errbuf);
- goto CLEAN;
+ fclose(fp);
+ return NULL;
}
config = config_load(table, filepath);
if (!config) {
LOG_DEBUG("config_load failed.");
- goto CLEAN;
+ fclose(fp);
+ toml_free(table);
+ return NULL;
}
- CLEAN:
toml_free(table);
fclose(fp);
return config;
@@ -1110,6 +1143,7 @@ config_load_from_data(const char *data)
struct Config *config = NULL;
toml_table_t *table = NULL;
char errbuf[200];
+
table = toml_parse((char *)data, (char *)&errbuf, sizeof(errbuf));
if (!table) {
LOG_DEBUG("toml_parse failed.");
@@ -1127,12 +1161,13 @@ config_load_from_data(const char *data)
void
config_free(struct Config *config)
{
+ int i;
+
free(config->metadata_separator);
free(config->output->toc->title);
free(config->output->toc);
free(config->output->chorus->label);
free(config->output->chorus);
- int i;
for (i = 0; i<TEXT_TYPE_LENGTH; i++) {
cho_style_free(config->output->styles[i]);
}