Fix another integer overflow issue discovered by Maksymilian Arciemowicz.

On top of this, limit the range of getnumber to 0x00ffffff to make sure
that adding two of them does not cause an integer overflow.
This commit is contained in:
christos 2008-03-27 21:50:30 +00:00
parent 930dfcfc6c
commit 23b2e3cd80

View File

@ -1,4 +1,4 @@
/* $NetBSD: strfmon.c,v 1.5 2008/03/18 18:16:08 christos Exp $ */
/* $NetBSD: strfmon.c,v 1.6 2008/03/27 21:50:30 christos Exp $ */
/*-
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
@ -32,7 +32,7 @@
#if 0
__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $");
#else
__RCSID("$NetBSD: strfmon.c,v 1.5 2008/03/18 18:16:08 christos Exp $");
__RCSID("$NetBSD: strfmon.c,v 1.6 2008/03/27 21:50:30 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -50,6 +50,7 @@ __RCSID("$NetBSD: strfmon.c,v 1.5 2008/03/18 18:16:08 christos Exp $");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
/* internal flags */
#define NEED_GROUPING 0x01 /* print digits grouped (default) */
@ -75,15 +76,12 @@ __RCSID("$NetBSD: strfmon.c,v 1.5 2008/03/18 18:16:08 christos Exp $");
} while (/* CONSTCOND */ 0)
#define GET_NUMBER(VAR) do { \
int ovar; \
ovar = VAR = 0; \
VAR = 0; \
while (isdigit((unsigned char)*fmt)) { \
VAR *= 10; \
VAR += *fmt - '0'; \
if (ovar > VAR) \
if (VAR > 0x00ffffff) \
goto e2big_error; \
else \
ovar = VAR; \
fmt++; \
} \
} while (/* CONSTCOND */ 0)
@ -200,11 +198,13 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
/* field Width */
if (isdigit((unsigned char)*fmt)) {
ptrdiff_t d = dst - s;
GET_NUMBER(width);
/* Do we have enough space to put number with
* required width ?
*/
if (dst + width >= s + maxsize)
if (d + width >= maxsize)
goto e2big_error;
}