changeset 30797:1213e3988168 v9.0.0733

patch 9.0.0733: use of strftime() is not safe Commit: https://github.com/vim/vim/commit/84d14ccdb50dc9f362066a2c83bfaf331314e5ea Author: Dominique Pelle <dominique.pelle@gmail.com> Date: Wed Oct 12 13:30:25 2022 +0100 patch 9.0.0733: use of strftime() is not safe 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)
author Bram Moolenaar <Bram@vim.org>
date Wed, 12 Oct 2022 14:45:03 +0200
parents 454cefb34cfa
children a87c6faa01e3
files src/time.c src/version.c
diffstat 2 files changed, 22 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/time.c
+++ b/src/time.c
@@ -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_newlin
     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_newlin
 	    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 *
 	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, tim
 #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
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    733,
+/**/
     732,
 /**/
     731,