string: Simplify fieldwidth, fix overflow
authorJack Miller <jack@codezen.org>
Wed, 3 Aug 2016 19:33:38 +0000 (14:33 -0500)
committerJack Miller <jack@codezen.org>
Thu, 4 Aug 2016 01:31:06 +0000 (20:31 -0500)
Fieldwidth is a minimum, not a maximum, and is now ignored for strings.
Also fixes an overflow in convert when digits > remaining buffer.

kernel/string.c

index 564fde7..7e404d2 100644 (file)
@@ -61,9 +61,6 @@ static int convert(char *buf, char fill, u32 rem, s32 fieldwidth,
     int digits = 0;
     int i = 0;
 
-    if (fieldwidth > -1 && fieldwidth < rem)
-        rem = fieldwidth;
-
     /* Write the digits into tmp, backwards because it's easiest to calculate
      * the smallest digits first */
 
@@ -76,8 +73,8 @@ static int convert(char *buf, char fill, u32 rem, s32 fieldwidth,
     /* Pad out tmp to fieldwidth */
 
     i = 0;
-    if (fieldwidth != -1) {
-        for (i = 0; i < (rem - digits); i++)
+    if ((fieldwidth > digits)&&(rem >= fieldwidth)) {
+        for (i = 0; i < (fieldwidth - digits); i++)
             buf[i] = fill;
     }
 
@@ -92,12 +89,6 @@ static int convert(char *buf, char fill, u32 rem, s32 fieldwidth,
     return i;
 }
 
-#define shrink_fieldwidth()\
-    if (fieldwidth == -1)\
-        fieldwidth = size;\
-    else\
-        fieldwidth = min(fieldwidth, size);
-
 void vsnprintf(char *buf, u32 size, char *format, va_list ap)
 {
     char *str = buf;
@@ -132,36 +123,27 @@ void vsnprintf(char *buf, u32 size, char *format, va_list ap)
             case 'c':
                 c = (char)va_arg(ap, int);
                 *str++ = c;
-                fieldwidth = -1;
                 escaped = 0;
                 break;
             case 's':
                 s = va_arg(ap, char *);
 
-                shrink_fieldwidth();
-
-                while ((fieldwidth--) && (*s)) {
+                while ((size--) && (*s))
                     *str++ = *s++;
-                    size--;
-                }
 
-                fieldwidth = -1;
                 escaped = 0;
                 size++;
                 break;
             case 'S':
                 vs = tv_str(va_arg(ap, vua_tv_t));
 
-                shrink_fieldwidth();
-
                 if (vs) {
-                    for (tmp = 0; tmp < min(vs->len, fieldwidth); tmp++) {
+                    for (tmp = 0; tmp < min(vs->len, size); tmp++) {
                         *str++ = vs->data[tmp];
                         size--;
                     }
                 }
 
-                fieldwidth = -1;
                 escaped = 0;
                 size++;
                 break;