lorid

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

commit 0c3bba0c39399ed5f4beeb9ebb0727dd6d93b329
parent 706b901d7969c3000fac48659de8bb99ff117d62
Author: nibo <nibo@relim.de>
Date:   Mon, 14 Oct 2024 10:55:53 +0200

Add more parser restrictions

Diffstat:
Mchordpro.c | 77++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 48 insertions(+), 29 deletions(-)

diff --git a/chordpro.c b/chordpro.c @@ -333,14 +333,9 @@ cho_log(enum LogLevel level, const char *msg, ...) static inline bool is_whitespace(char c) { - if ( - c == '\t' || - c == '\n' || - c == '\f' || - c == '\r' || - c == ' ' - ) + if (c == '\t' || c == ' ') { return true; + } return false; } @@ -2615,7 +2610,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) char directive_name[128]; char directive_value[128]; char chord[15]; - char tag_begin[6]; + char tag_start[6]; char tag_end[6]; char custom_directive[64]; char *label; @@ -2707,6 +2702,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) te--; break; } + if (ta > -1 && !tags[ta]->is_closed) { + cho_log(LOG_ERR, "Tag has to be closed on same line."); + return NULL; + } songs[so]->sections[se]->lines[li]->lyrics[ly]->text = realloc(songs[so]->sections[se]->lines[li]->lyrics[ly]->text, (te+1) * sizeof(char)); songs[so]->sections[se]->lines[li]->lyrics[ly]->text[te] = 0; if (strlen(songs[so]->sections[se]->lines[li]->lyrics[ly]->text) == 0) { @@ -2966,7 +2965,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) break; } if (buf == '{') { - cho_log(LOG_ERR, "Can't start a new directive if the previous one is not closed yet."); + cho_log(LOG_ERR, "Can't start a new directive if the previous one is not yet closed."); return NULL; } if (buf == '\n') { @@ -3240,7 +3239,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) break; } if (buf == '{') { - cho_log(LOG_ERR, "Can't start a new directive if the previous one is not closed yet."); + cho_log(LOG_ERR, "Can't start a new directive if the previous one is not yet closed."); return NULL; } if (buf == '\n') { @@ -3297,6 +3296,14 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) state = STATE_ANNOTATION; break; } + if (buf == '\n') { + cho_log(LOG_ERR, "Newline character inside a chord is invalid."); + return NULL; + } + if (buf == '[') { + cho_log(LOG_ERR, "Can't start a new chord/annotation if the previous one is not yet closed."); + return NULL; + } if (buf == '<') { if (prev_buf == '[') { songs[so]->sections[se]->lines[li]->text_above = realloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *)); @@ -3338,6 +3345,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) state = STATE_MARKUP_TAG; break; } + if (buf == '\n') { + cho_log(LOG_ERR, "Newline character inside an annotation is invalid."); + return NULL; + } songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text = realloc(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char)); songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text[ann] = buf; ann++; @@ -3345,10 +3356,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) case STATE_MARKUP_TAG_BEGIN: MARKUP_TAG_BEGIN: if (buf == '>') { - tag_begin[t] = 0; + tag_start[t] = 0; t = 0; - tags[ta]->name = strdup(tag_begin); - tag_style = cho_style_parse(tag_begin, NULL, cho_tag_style_inherit(tags, ta-1)); + tags[ta]->name = strdup(tag_start); + tag_style = cho_style_parse(tag_start, NULL, cho_tag_style_inherit(tags, ta-1)); if (!tag_style) { LOG_DEBUG("cho_style_parse failed."); return NULL; @@ -3371,14 +3382,14 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) cho_log(LOG_ERR, "Invalid prev_state '%s'.", state_enums[prev_state]); return NULL; } - memset(tag_begin, 0, strlen(tag_begin)); + memset(tag_start, 0, strlen(tag_start)); state = prev_state; break; } if (is_whitespace(buf)) { - tag_begin[t] = 0; + tag_start[t] = 0; t = 0; - tags[ta]->name = strdup(tag_begin); + tags[ta]->name = strdup(tag_start); tags[ta]->attrs = realloc(tags[ta]->attrs, (at+1) * sizeof(struct Attr *)); tags[ta]->attrs[at] = cho_tag_attr_new(); state = STATE_MARKUP_ATTR_NAME; @@ -3392,7 +3403,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) cho_log(LOG_ERR, "Begin tag name is too long."); return NULL; } - tag_begin[t] = buf; + tag_start[t] = buf; t++; break; case STATE_MARKUP_TAG: @@ -3418,6 +3429,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) state = prev_state; break; } + if (buf == '\n') { + cho_log(LOG_ERR, "Newline character inside a tag name is invalid."); + return NULL; + } if (t == 5) { cho_log(LOG_ERR, "End tag name is too long."); return NULL; @@ -3440,7 +3455,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) } else { tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char)); tags[ta]->attrs[at]->name[atn] = 0; - cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_begin); + cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_start); return NULL; } } @@ -3452,14 +3467,14 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) } tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char)); tags[ta]->attrs[at]->name[atn] = 0; - cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_begin); + cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_start); return NULL; } if (buf == '>') { if (tags[ta]->attrs[at-1]->value) { cho_tag_attr_free(tags[ta]->attrs[at]); tags[ta]->attrs[at] = NULL; - tag_style = cho_style_parse(tag_begin, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1)); + tag_style = cho_style_parse(tag_start, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1)); if (!tag_style) { LOG_DEBUG("cho_style_parse failed."); return NULL; @@ -3483,29 +3498,37 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) return NULL; } at = 0; - memset(tag_begin, 0, strlen(tag_begin)); + memset(tag_start, 0, strlen(tag_start)); state = prev_state; break; } else { tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char)); tags[ta]->attrs[at]->name[atn] = 0; atn = 0; - cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_begin); + cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_start); return NULL; } } + if (buf == '\n') { + cho_log(LOG_ERR, "Newline character inside an tag attribute name is invalid."); + return NULL; + } tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char)); tags[ta]->attrs[at]->name[atn] = buf; atn++; break; case STATE_MARKUP_ATTR_VALUE: + if (buf == '\n') { + cho_log(LOG_ERR, "Newline character inside an attribute value is invalid."); + return NULL; + } if (avs == AVS_NO) { if (is_whitespace(buf)) { cho_log(LOG_ERR, "Whitespace character after equals sign is invalid."); return NULL; } if (buf == '>') { - cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_begin); + cho_log(LOG_ERR, "Attribute with name '%s' of tag '%s' has no value.", tags[ta]->attrs[at]->name, tag_start); return NULL; } if (buf == '\'') { @@ -3520,10 +3543,6 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) } break; } - if (buf == '\n') { - cho_log(LOG_ERR, "Newline character inside an attribute value is invalid."); - return NULL; - } if (avs == AVS_UNQUOTED && buf == '>') { tags[ta]->attrs[at]->value = realloc(tags[ta]->attrs[at]->value, (atv+1) * sizeof(char)); tags[ta]->attrs[at]->value[atv] = 0; @@ -3531,7 +3550,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) at++; tags[ta]->attrs = realloc(tags[ta]->attrs, (at+1) * sizeof(struct Attr *)); tags[ta]->attrs[at] = NULL; - tag_style = cho_style_parse(tag_begin, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1)); + tag_style = cho_style_parse(tag_start, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1)); if (!tag_style) { LOG_DEBUG("cho_style_parse failed."); return NULL; @@ -3556,7 +3575,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config) } at = 0; avs = AVS_NO; - memset(tag_begin, 0, strlen(tag_begin)); + memset(tag_start, 0, strlen(tag_start)); state = prev_state; break; }