Make sure that we can't scan past the end of the format string.
[rsync/rsync.git] / log.c
diff --git a/log.c b/log.c
index f91f7a5..87cd1d7 100644 (file)
--- a/log.c
+++ b/log.c
@@ -371,6 +371,8 @@ static void log_formatted(enum logcode code, char *format, char *op,
                        *n++ = *p++;
                while (isdigit(*(uchar*)p) && n - fmt < (int)(sizeof fmt) - 8)
                        *n++ = *p++;
+               if (!*p)
+                       break;
                *n = '\0';
                n = NULL;
 
@@ -397,7 +399,10 @@ static void log_formatted(enum logcode code, char *format, char *op,
                                         file->dir.root, n);
                                /* The buffer from safe_fname() has more
                                 * room than MAXPATHLEN, so this is safe. */
-                               strcpy(n, buf2);
+                               if (fmt[1])
+                                       strcpy(n, buf2);
+                               else
+                                       n = buf2;
                        }
                        clean_fname(n, 0);
                        if (*n == '/')
@@ -494,9 +499,6 @@ static void log_formatted(enum logcode code, char *format, char *op,
                        break;
                }
 
-               /* Subtract the length of the escape from the string's size. */
-               total -= p - s;
-
                /* "n" is the string to be inserted in place of this % code. */
                if (!n)
                        continue;
@@ -507,6 +509,9 @@ static void log_formatted(enum logcode code, char *format, char *op,
                }
                len = strlen(n);
 
+               /* Subtract the length of the escape from the string's size. */
+               total -= p - s;
+
                if (len + total >= sizeof buf) {
                        rprintf(FERROR,
                                "buffer overflow expanding %%%c -- exiting\n",