]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - misc-utils/cal.c
lib/mbalign: fix unsigned integer overflow [AddressSanitizer]
[thirdparty/util-linux.git] / misc-utils / cal.c
index 81375fe19b7e00111cdcdca93256e9df21fa3bab..a11136a5ba2f1b2944b59657f718d793f85f9c0d 100644 (file)
@@ -137,7 +137,6 @@ static void my_putstring(char *s)
 
 #if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) || defined(HAVE_LIBTERMCAP)
 static const char      *term="";
-static int             Slen;           /* strlen of Senter+Sexit */
 #endif
 
 static const char      *Senter="", *Sexit="";/* enter and exit standout mode */
@@ -188,12 +187,7 @@ enum {
 
 #define TODAY_FLAG             0x400           /* flag day for highlighting */
 
-#define FMT_ST_LINES 9
 #define FMT_ST_CHARS 300       /* 90 suffices in most locales */
-struct fmt_st
-{
-       char s[FMT_ST_LINES][FMT_ST_CHARS];
-};
 
 static const int days_in_month[2][13] = {
        {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
@@ -304,7 +298,6 @@ int main(int argc, char **argv)
                if (ret > 0) {
                        Senter = my_tgetstr("so","smso");
                        Sexit = my_tgetstr("se","rmso");
-                       Slen = strlen(Senter) + strlen(Sexit);
                }
        }
 #endif
@@ -609,7 +602,7 @@ static void cal_output_header(struct cal_month *month, const struct cal_control
                        center(out, ctl->week_width - 1, i->next == NULL ? 0 : ctl->gutter_width);
                }
                if (!ctl->yflag) {
-                       fputs("\n", stdout);
+                       my_putstring("\n");
                        for (i = month; i; i = i->next) {
                                sprintf(out, _("%d"), i->year);
                                center(out, ctl->week_width - 1, i->next == NULL ? 0 : ctl->gutter_width);
@@ -621,23 +614,27 @@ static void cal_output_header(struct cal_month *month, const struct cal_control
                        center(out, ctl->week_width - 1, i->next == NULL ? 0 : ctl->gutter_width);
                }
        }
-       puts("");
+       my_putstring("\n");
        for (i = month; i; i = i->next) {
                if (ctl->weektype) {
                        if (ctl->julian)
-                               printf("%*s%s", (int)ctl->day_width - 1, "", day_headings);
+                               sprintf(out, "%*s%s", (int)ctl->day_width - 1, "", day_headings);
                        else
-                               printf("%*s%s", (int)ctl->day_width, "", day_headings);
+                               sprintf(out, "%*s%s", (int)ctl->day_width, "", day_headings);
+                       my_putstring(out);
                } else
-                       fputs(day_headings, stdout);
-               if (i->next != NULL)
-                       printf("%*s", ctl->gutter_width, "");
+                       my_putstring(day_headings);
+               if (i->next != NULL) {
+                       sprintf(out, "%*s", ctl->gutter_width, "");
+                       my_putstring(out);
+               }
        }
-       puts("");
+       my_putstring("\n");
 }
 
 static void cal_output_months(struct cal_month *month, const struct cal_control *ctl)
 {
+       char out[FMT_ST_CHARS];
        int reqday, week_line, d;
        int skip;
        struct cal_month *i;
@@ -659,12 +656,13 @@ static void cal_output_months(struct cal_month *month, const struct cal_control
                                if (0 < i->weeks[week_line]) {
                                        if ((ctl->weektype & WEEK_NUM_MASK) ==
                                            i->weeks[week_line])
-                                               printf("%s%2d%s", Senter, i->weeks[week_line],
+                                               sprintf(out, "%s%2d%s", Senter, i->weeks[week_line],
                                                       Sexit);
                                        else
-                                               printf("%2d", i->weeks[week_line]);
+                                               sprintf(out, "%2d", i->weeks[week_line]);
                                } else
-                                       printf("%2s", "");
+                                       sprintf(out, "%2s", "");
+                               my_putstring(out);
                                skip = ctl->day_width;
                        } else
                                /* First day of the week is one char narrower than the other days,
@@ -675,21 +673,26 @@ static void cal_output_months(struct cal_month *month, const struct cal_control
                             d < DAYS_IN_WEEK * week_line + DAYS_IN_WEEK; d++) {
                                if (0 < i->days[d]) {
                                        if (reqday == i->days[d])
-                                               printf("%*s%s%*d%s", skip - (ctl->julian ? 3 : 2),
+                                               sprintf(out, "%*s%s%*d%s", skip - (ctl->julian ? 3 : 2),
                                                       "", Senter, (ctl->julian ? 3 : 2),
                                                       i->days[d], Sexit);
                                        else
-                                               printf("%*d", skip, i->days[d]);
+                                               sprintf(out, "%*d", skip, i->days[d]);
                                } else
-                                       printf("%*s", skip, "");
+                                       sprintf(out, "%*s", skip, "");
+                               my_putstring(out);
                                if (skip < (int)ctl->day_width)
                                        skip++;
                        }
-                       if (i->next != NULL)
-                               printf("%*s", ctl->gutter_width, "");
+                       if (i->next != NULL) {
+                               sprintf(out, "%*s", ctl->gutter_width, "");
+                               my_putstring(out);
+                       }
+               }
+               if (i == NULL) {
+                       sprintf(out, "%*s\n", ctl->gutter_width - (ctl->yflag ? 0 : 1), "");
+                       my_putstring(out);
                }
-               if (i == NULL)
-                       printf("%*s\n", ctl->gutter_width - (ctl->yflag ? 0 : 1), "");
        }
 }
 
@@ -754,7 +757,7 @@ static void yearly(const struct cal_control *ctl)
                year_width--;
        sprintf(out, "%d", ctl->req.year);
        center(out, year_width, 0);
-       fputs("\n\n", stdout);
+       my_putstring("\n\n");
 
        for (month = 1; month < MONTHS_IN_YEAR; month += ctl->julian ? 2 : 3) {
                set_consecutive_months(&m1, month, ctl->req.year);
@@ -764,7 +767,7 @@ static void yearly(const struct cal_control *ctl)
                cal_output_months(&m1, ctl);
        }
        /* Is empty line at the end year output really needed? */
-       puts("");
+       my_putstring("\n");
 }
 
 /*