summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/vfprintf.c
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>2001-01-06 20:48:00 +0000
committerarchie <archie@FreeBSD.org>2001-01-06 20:48:00 +0000
commite85856e946310e2c3abfbdd2526466a6c73643f3 (patch)
tree893e15f0de0efababd061a3ab3bcc1f916379bff /lib/libc/stdio/vfprintf.c
parent00a5e748440a34ada47ccdee2a6a5daf59597586 (diff)
downloadFreeBSD-src-e85856e946310e2c3abfbdd2526466a6c73643f3.zip
FreeBSD-src-e85856e946310e2c3abfbdd2526466a6c73643f3.tar.gz
Fix bugs in the handling of > 8 positional arguments:
- The stack was getting smashed by __grow_type_table() - reallocf() was being called with the wrong pointer - The maximum argument number was being incorrectly computed PR: misc/23521
Diffstat (limited to 'lib/libc/stdio/vfprintf.c')
-rw-r--r--lib/libc/stdio/vfprintf.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 44fd34b..f8eb9ca 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -899,7 +899,7 @@ error:
* Find all arguments when a positional parameter is encountered. Returns a
* table, indexed by argument number, of pointers to each arguments. The
* initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
- * It will be replaces with a malloc-ed on if it overflows.
+ * It will be replaces with a malloc-ed one if it overflows.
*/
static void
__find_arguments (fmt0, ap, argtable)
@@ -925,8 +925,8 @@ __find_arguments (fmt0, ap, argtable)
#define ADDTYPE(type) \
((nextarg >= tablesize) ? \
__grow_type_table(nextarg, &typetable, &tablesize) : 0, \
- typetable[nextarg++] = type, \
- (nextarg > tablemax) ? tablemax = nextarg : 0)
+ (nextarg > tablemax) ? tablemax = nextarg : 0, \
+ typetable[nextarg++] = type)
#define ADDSARG() \
((flags&LONGINT) ? ADDTYPE(T_LONG) : \
@@ -1179,20 +1179,24 @@ __grow_type_table (nextarg, typetable, tablesize)
unsigned char **typetable;
int *tablesize;
{
- unsigned char *oldtable = *typetable;
- int newsize = *tablesize * 2;
-
- if (*tablesize == STATIC_ARG_TBL_SIZE) {
- *typetable = (unsigned char *)
- malloc (sizeof (unsigned char) * newsize);
- bcopy (oldtable, *typetable, *tablesize);
+ unsigned char *const oldtable = *typetable;
+ const int oldsize = *tablesize;
+ unsigned char *newtable;
+ int newsize = oldsize * 2;
+
+ if (newsize < nextarg + 1)
+ newsize = nextarg + 1;
+ if (oldsize == STATIC_ARG_TBL_SIZE) {
+ if ((newtable = malloc(newsize)) == NULL)
+ abort(); /* XXX handle better */
+ bcopy(oldtable, newtable, oldsize);
} else {
- *typetable = (unsigned char *)
- reallocf (typetable, sizeof (unsigned char) * newsize);
-
+ if ((newtable = reallocf(oldtable, newsize)) == NULL)
+ abort(); /* XXX handle better */
}
- memset (&typetable [*tablesize], T_UNUSED, (newsize - *tablesize));
+ memset(&newtable[oldsize], T_UNUSED, newsize - oldsize);
+ *typetable = newtable;
*tablesize = newsize;
}
OpenPOWER on IntegriCloud