]> granicus.if.org Git - vim/commitdiff
patch 9.0.0733: use of strftime() is not safe v9.0.0733
authorDominique Pelle <dominique.pelle@gmail.com>
Wed, 12 Oct 2022 12:30:25 +0000 (13:30 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 12 Oct 2022 12:30:25 +0000 (13:30 +0100)
Problem:    Use of strftime() is not safe.
Solution:   Check the return value of strftime().  Use a larger buffer and
            correctly pass the available space. (Dominique PellĂ©, closes
            #11348)

src/time.c
src/version.c

index f8e8c5afe29961fb0c0dcb6c9a038ac9d4134993..a5be297d392b54e487d2ebf9c726f2a103f59528 100644 (file)
@@ -82,7 +82,7 @@ vim_time(void)
     char *
 get_ctime(time_t thetime, int add_newline)
 {
-    static char buf[50];
+    static char buf[100];  // hopefully enough for every language
 #ifdef HAVE_STRFTIME
     struct tm  tmval;
     struct tm  *curtime;
@@ -90,12 +90,20 @@ get_ctime(time_t thetime, int add_newline)
     curtime = vim_localtime(&thetime, &tmval);
     // MSVC returns NULL for an invalid value of seconds.
     if (curtime == NULL)
-       vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1);
+       vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 2);
     else
     {
        // xgettext:no-c-format
-       (void)strftime(buf, sizeof(buf) - 1, _("%a %b %d %H:%M:%S %Y"),
-                                                                   curtime);
+       if (strftime(buf, sizeof(buf) - 2, _("%a %b %d %H:%M:%S %Y"), curtime)
+                                                                         == 0)
+       {
+           // Quoting "man strftime":
+           // > If the length of the result string (including the terminating
+           // > null byte) would exceed max bytes, then strftime() returns 0,
+           // > and the contents of the array are undefined.
+           vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"),
+                                                             sizeof(buf) - 2);
+       }
 # ifdef MSWIN
        if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
        {
@@ -105,7 +113,7 @@ get_ctime(time_t thetime, int add_newline)
            acp_to_enc((char_u *)buf, (int)strlen(buf), &to_free, &len);
            if (to_free != NULL)
            {
-               STRCPY(buf, to_free);
+               STRNCPY(buf, to_free, sizeof(buf) - 2);
                vim_free(to_free);
            }
        }
@@ -318,10 +326,8 @@ f_strftime(typval_T *argvars, typval_T *rettv)
        convert_setup(&conv, p_enc, enc);
        if (conv.vc_type != CONV_NONE)
            p = string_convert(&conv, p, NULL);
-       if (p != NULL)
-           (void)strftime((char *)result_buf, sizeof(result_buf),
-                                                         (char *)p, curtime);
-       else
+       if (p == NULL || strftime((char *)result_buf, sizeof(result_buf),
+                                                 (char *)p, curtime) == 0)
            result_buf[0] = NUL;
 
        if (conv.vc_type != CONV_NONE)
@@ -1117,16 +1123,19 @@ add_time(char_u *buf, size_t buflen, time_t tt)
 #ifdef HAVE_STRFTIME
     struct tm  tmval;
     struct tm  *curtime;
+    int                n;
 
     if (vim_time() - tt >= 100)
     {
        curtime = vim_localtime(&tt, &tmval);
        if (vim_time() - tt < (60L * 60L * 12L))
            // within 12 hours
-           (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
+           n = strftime((char *)buf, buflen, "%H:%M:%S", curtime);
        else
            // longer ago
-           (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
+           n = strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
+       if (n == 0)
+           buf[0] = NUL;
     }
     else
 #endif
index 37d64fbfb7f1a0b03c814a73476d3bbc58b960b5..eeb1579ef23825b78aa1de8a855cb1daaecde29d 100644 (file)
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    733,
 /**/
     732,
 /**/