]> git.sur5r.net Git - c128-kasse/commitdiff
fix print_log() format string
authorMaik Fischer <maikf@qu.cx>
Wed, 1 Nov 2017 07:55:49 +0000 (08:55 +0100)
committerMaik Fischer <maikf@qu.cx>
Wed, 1 Nov 2017 14:20:13 +0000 (15:20 +0100)
The previous code interpolated "sizeof(…)" as string, not as number
which overflowed the print_buffer, leading to program crashes.

include/general.h
src/credit_manager.c
src/itemz.c
src/kasse.c

index df02244841ac1a03c13c3c0ab11296295c2403df..4b7c99ba502db45d8be450fb2c22f3d42ec0d861 100644 (file)
@@ -66,8 +66,9 @@ extern BYTE _oserror;
 
 #define VIDEOMODE (((*(BYTE *)0xD7) == 0x80) ? 80 : 40)
 
+/* "999,99€" */
 #define EUR_FORMAT "%3d,%02d" EURSYM
-#define EUR_FORMAT_MINLEN (sizeof("999,99" EURSYM) + 1)
+#define EUR_FORMAT_MINLEN 7
 
 /* because there is no macro expansion when stringifying, we need to use two
  * levels of macros to stringify the value of a macro (for example
index 7aa4724536c1216d884352ff825f0e4b69fccf23..7f32d754bba47bb57878352cd559287e54be8891 100644 (file)
@@ -24,7 +24,7 @@ static BYTE current_credits_page = 0;
 
 static void credit_print_screen(void) {
   BYTE i, pages;
-  char buffer[EUR_FORMAT_MINLEN];
+  char buffer[EUR_FORMAT_MINLEN + 1];
 
   clrscr();
   cprintf("credit_manager (phil_fry, sECuRE, sur5r) v:" GV "\r\n\r\n");
index 7cf8ea6d6acba579876ea9c9c0c6adf6abfbb050..19e4233e24cd8a8f2dc337f4cca5d6efc179bef2 100644 (file)
@@ -21,7 +21,7 @@
 
 static void itemz_print_screen(void) {
   BYTE i;
-  char buffer[EUR_FORMAT_MINLEN];
+  char buffer[EUR_FORMAT_MINLEN + 1];
 
   clrscr();
   cprintf("itemz (phil_fry, sECuRE, sur5r, mxf) v:" GV "\r\n\r\n");
index d20ad93d0ee2039ccc1d8b1f7bd51df93c3092e0..e50999810d1fb63262553d1e4e33301b564129a0 100644 (file)
@@ -25,7 +25,7 @@
 // graphic 4,0,10
 
 void print_item(BYTE i) {
-  char profit[EUR_FORMAT_MINLEN];
+  char profit[EUR_FORMAT_MINLEN + 1];
   if (format_euro(profit, sizeof(profit), status.status[i].price) == NULL) {
     cprintf("Preis %ld konnte nicht umgerechnet werden\r\n",
             status.status[i].price);
@@ -42,7 +42,7 @@ void print_item(BYTE i) {
 static void print_screen(void) {
   BYTE i = 0;
   char *time = get_time();
-  char profit[EUR_FORMAT_MINLEN];
+  char profit[EUR_FORMAT_MINLEN + 1];
   clrscr();
   if (format_euro(profit, sizeof(profit), money) == NULL) {
     cprintf("Einnahme %ld konnte nicht umgerechnet werden\r\n", money);
@@ -112,7 +112,8 @@ static void print_screen(void) {
 static void print_log(char *name, int item_price, int einheiten, char *nickname,
                       char *rest) {
   char *time = get_time();
-  char price[EUR_FORMAT_MINLEN];
+  uint8_t n;
+  char price[EUR_FORMAT_MINLEN + 1];
   if (format_euro(price, sizeof(price), item_price) == NULL) {
     cprintf("Preis %d konnte nicht umgerechnet werden\r\n", item_price);
     exit(1);
@@ -124,27 +125,34 @@ static void print_log(char *name, int item_price, int einheiten, char *nickname,
   rest[EUR_FORMAT_MINLEN - 1] = 'E';
 
   /* clang-format off */
-  sprintf(print_buffer,
-          /* enable lower case letters */
-          "%c"
-          /*  Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!)
-              -- 5-stellig */
-          "[%3u] "
-          /* Uhrzeit -- 8-stellig */
-          "%8s - "
-          /*  Eintragname (= Getränk) -- 9-stellig */
-          "%-" xstr(MAX_ITEM_NAME_LENGTH) "s - "
-          /*  Preis (in Cents) -- 7-stellig */
-          "%" xstr(sizeof(price) - 1) "s - "
-          /*  restguthaben (7-stellig) */
-          "%" xstr(sizeof(rest) - 1) "s - "
-          /*  Anzahl -- 2-stellig */
-          "%2d - "
-          /*  Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig */
-          "an %" xstr(NICKNAME_MAX_LEN)"s\r",
-          17, status.transaction_id, time, name, price, rest, einheiten,
-          (*nickname != '\0' ? nickname : "Unbekannt"));
+  n = snprintf(print_buffer, sizeof(print_buffer),
+        /* enable lower case letters -- 1 */
+        "%c"
+        /*  Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!)
+            -- 6-stellig */
+        "[%3u] "
+        /* Uhrzeit -- 8-stellig + 3 */
+        "%8s - "
+        /*  Eintragname (= Getränk) -- 9-stellig + 3 */
+        "%-" xstr(MAX_ITEM_NAME_LENGTH) "s - "
+        /*  Preis (in Cents) -- 7-stellig  + 3 */
+        "%" xstr(EUR_FORMAT_MINLEN) "s - "
+        /*  restguthaben (7-stellig) + 3 */
+        "%" xstr(EUR_FORMAT_MINLEN) "s - "
+        /*  Anzahl -- 2-stellig + 3 */
+        "%2d - "
+        /*  Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig + 4 */
+        "an %" xstr(NICKNAME_MAX_LEN)"s\r",
+        17, status.transaction_id, time, name, price, rest, einheiten,
+        (*nickname != '\0' ? nickname : "Unbekannt"));
   /* clang-format on */
+  if (n > sizeof(print_buffer)) {
+    cprintf("\r\nprint_log(): print_buffer overflowed!\r\n"
+            "Wanted to write %d bytes\r\n%s\r\n",
+            n, print_buffer);
+    exit(1);
+  }
+
   status.transaction_id++;
   print_the_buffer();
 }
@@ -155,7 +163,7 @@ static signed int buy(char *name, unsigned int price) {
   BYTE c, nickname_len;
   int einheiten;
   char nickname[NICKNAME_MAX_LEN + 1];
-  char rest[EUR_FORMAT_MINLEN];
+  char rest[EUR_FORMAT_MINLEN + 1];
   struct credits_t *credit;
 
   clrscr();