tapas

[discontinued] A small program used for compiling refer output into the APA reference format.
git clone https://noxz.tech/git/tapas.git
Log | Files | 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
Mconfig.def.h9--
Mtapas.c116++++++++++++++------
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) {