tapas

A small program used for compiling refer output into the APA reference format.
git clone git://git.noxz.tech/tapas
Log | Files | Refs | README | LICENSE

commit 60db686da3513fb1079b327afb37082f40542abf
parent ea3d5264debd829e18beba3670306acc184fc6ab
Author: Chris Noxz <chris@noxz.tech>
Date:   Sun, 10 Nov 2019 16:00:31 +0100

Make sscanf calls more safe

Diffstat:
Mconfig.def.h | 9---------
Mtapas.c | 116++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
2 files changed, 82 insertions(+), 43 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -1,10 +1 @@ #define BUF_SIZE 128 -#define BIB_START ".]<\n" -#define BIB_END ".]>\n" -#define REF_START ".]-\n" -#define REF_END ".][ %d" -#define REF_ATTR ".ds [%c %127[^\n]" -#define STR_HE ".ds APA_HE %127[^\n]" -#define STR_AN ".ds APA_AN %127[^\n]" -#define STR_IN ".ds APA_IN %127[^\n]" -#define STR_MS ".ds APA_MS %127[^\n]" diff --git a/tapas.c b/tapas.c @@ -27,6 +27,16 @@ #include "config.h" +#define BIB_START ".]<\n" +#define BIB_END ".]>\n" +#define REF_START ".]-\n" +#define REF_END ".][ %d" +#define REF_ATTR ".ds [%c" +#define STR_HE ".ds APA_HE " +#define STR_AN ".ds APA_AN " +#define STR_IN ".ds APA_IN " +#define STR_MS ".ds APA_MS " + struct Settings { char heading[BUF_SIZE]; char and[BUF_SIZE]; @@ -93,6 +103,44 @@ trim(char *source) } } +int +readstr(const char *src, const char *pre, char *str, int length) +{ + int c = 0; + const char *p; + + memset(str, 0x0, length); + + if (strncmp(src, pre, strlen(pre)) != 0) + return 0; + + p = (src + strlen(pre)); + + while (*p != '\n' && c < length) + str[c++] = *p++; + + return 1; +} + +int +readattr(const char *src, const char *fmt, char *t, char *val, int length) +{ + int c = 0; + const char *p; + + memset(val, 0x0, length); + + if (sscanf(src, fmt, t) == 0) + return 0; + + p = (src + strlen(fmt)); + + while (*p != '\n' && c < length) + val[c++] = *p++; + + return 1; +} + void findreplace(char *source, const char *find, const char *replace) { @@ -208,13 +256,13 @@ format_article_in_book(Referece *ref, int macroset) int loadstr(char *line) { - if (sscanf(line, STR_HE, &settings.heading) == 1) + if (readstr(line, STR_HE, settings.heading, BUF_SIZE)) trim(settings.heading); - else if (sscanf(line, STR_AN, &settings.and) == 1) + else if (readstr(line, STR_AN, settings.and, BUF_SIZE)) trim(settings.and); - else if (sscanf(line, STR_IN, &settings.in) == 1) + else if (readstr(line, STR_IN, settings.in, BUF_SIZE)) trim(settings.in); - else if (sscanf(line, STR_MS, &settings.ms) == 1) + else if (readstr(line, STR_MS, settings.ms, BUF_SIZE)) trim(settings.ms); else return 0; @@ -227,8 +275,8 @@ main(int arc, char *argv[]) int inbib = 0; int macroset = ms_ms; int reftype; - char atype; - char aval[BUF_SIZE]; + char at; + char av[BUF_SIZE]; size_t size; char *line; Referece *ref = NULL; @@ -263,34 +311,34 @@ main(int arc, char *argv[]) if (inbib) { if (!ref && strcmp(line, REF_START) == 0) { ref = (Referece*)calloc(1, sizeof(Referece)); - } else if (ref && sscanf(line, REF_ATTR, &atype, &aval) == 2) { - switch (atype) { - case 'A': strcpy(ref->author, aval); break; - case 'T': strcpy(ref->title, aval); break; - case 'B': strcpy(ref->book_title, aval); break; - case 'R': strcpy(ref->report_number, aval); break; - case 'J': strcpy(ref->journal_name, aval); break; - case 'E': strcpy(ref->editor, aval); break; - case 'e': strcpy(ref->edition, aval); break; - case 'V': strcpy(ref->volume, aval); break; - case 'N': strcpy(ref->journal_number, aval); break; - case 'S': strcpy(ref->series, aval); break; - case 'C': strcpy(ref->city, aval); break; - case 'I': strcpy(ref->publisher, aval); break; - case 'D': strcpy(ref->publication_date, aval); break; - case 'P': strcpy(ref->page_number, aval); break; - case 'G': strcpy(ref->gov_number, aval); break; - case 'O': strcpy(ref->other, aval); break; - case 'K': strcpy(ref->keywords, aval); break; - case 'd': strcpy(ref->original_pub_date, aval); break; - case 'a': strcpy(ref->additions, aval); break; - case 't': strcpy(ref->reprint_title, aval); break; - case 'l': strcpy(ref->translator, aval); break; - case 'r': strcpy(ref->translator_editor, aval); break; - case 's': strcpy(ref->site_name, aval); break; - case 'c': strcpy(ref->site_content, aval); break; - case 'o': strcpy(ref->organization, aval); break; - case 'u': strcpy(ref->url, aval); break; + } else if (ref && readattr(line, REF_ATTR, &at, av, BUF_SIZE)) { + switch (at) { + case 'A': strcpy(ref->author, av); break; + case 'T': strcpy(ref->title, av); break; + case 'B': strcpy(ref->book_title, av); break; + case 'R': strcpy(ref->report_number, av); break; + case 'J': strcpy(ref->journal_name, av); break; + case 'E': strcpy(ref->editor, av); break; + case 'e': strcpy(ref->edition, av); break; + case 'V': strcpy(ref->volume, av); break; + case 'N': strcpy(ref->journal_number, av); break; + case 'S': strcpy(ref->series, av); break; + case 'C': strcpy(ref->city, av); break; + case 'I': strcpy(ref->publisher, av); break; + case 'D': strcpy(ref->publication_date, av); break; + case 'P': strcpy(ref->page_number, av); break; + case 'G': strcpy(ref->gov_number, av); break; + case 'O': strcpy(ref->other, av); break; + case 'K': strcpy(ref->keywords, av); break; + case 'd': strcpy(ref->original_pub_date, av); break; + case 'a': strcpy(ref->additions, av); break; + case 't': strcpy(ref->reprint_title, av); break; + case 'l': strcpy(ref->translator, av); break; + case 'r': strcpy(ref->translator_editor, av); break; + case 's': strcpy(ref->site_name, av); break; + case 'c': strcpy(ref->site_content, av); break; + case 'o': strcpy(ref->organization, av); break; + case 'u': strcpy(ref->url, av); break; default: continue; } } else if (ref && sscanf(line, REF_END, &reftype) == 1) {