Fixed a buffer overflow if there is given a not null terminated string with a precision parameter.

Added handling of the precision parameter for counted strings.
Reduced some overhead for strings.

svn path=/trunk/; revision=3491
This commit is contained in:
Hartmut Birr 2002-09-13 18:45:10 +00:00
parent 1950866768
commit 3f316cde99
2 changed files with 209 additions and 242 deletions

View file

@ -1,4 +1,4 @@
/* $Id: sprintf.c,v 1.9 2002/09/12 17:50:42 guido Exp $
/* $Id: sprintf.c,v 1.10 2002/09/13 18:45:10 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -151,6 +151,95 @@ number(char * buf, char * end, long long num, int base, int size, int precision,
return buf;
}
static char*
string(char* buf, char* end, const char* s, int len, int field_width, int precision, int flags)
{
int i;
if (s == NULL)
{
s = "<NULL>";
len = 6;
}
else
{
if (len == -1)
{
len = 0;
while (s[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (buf <= end)
*buf = ' ';
++buf;
}
for (i = 0; i < len; ++i)
{
if (buf <= end)
*buf = *s++;
++buf;
}
while (len < field_width--)
{
if (buf <= end)
*buf = ' ';
++buf;
}
return buf;
}
static char*
stringw(char* buf, char* end, const wchar_t* sw, int len, int field_width, int precision, int flags)
{
int i;
if (sw == NULL)
{
sw = L"<NULL>";
len = 6;
}
else
{
if (len == -1)
{
len = 0;
while (sw[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (buf <= end)
*buf = ' ';
++buf;
}
for (i = 0; i < len; ++i)
{
if (buf <= end)
*buf = (unsigned char)(*sw++);
++buf;
}
while (len < field_width--)
{
if (buf <= end)
*buf = ' ';
++buf;
}
return buf;
}
int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
{
@ -288,57 +377,11 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
if (qualifier == 'l' || qualifier == 'w') {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = (unsigned char)(*sw);
++str;
++sw;
}
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
str = stringw(str, end, sw, -1, field_width, precision, flags);
} else {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = *s;
++str;
++s;
}
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
str = string(str, end, s, -1, field_width, precision, flags);
}
continue;
@ -346,57 +389,11 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
if (qualifier == 'h') {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = *s;
++str;
++s;
}
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
str = string(str, end, s, -1, field_width, precision, flags);
} else {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = (unsigned char)(*sw);
++str;
++sw;
}
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
str = stringw(str, end, sw, -1, field_width, precision, flags);
}
continue;
@ -405,38 +402,24 @@ int _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
/* print counted unicode string */
PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
if ((pus == NULL) || (pus->Buffer == NULL)) {
s = "<NULL>";
while ((*s) != 0) {
if (str <= end)
*str = *s;
++str;
++s;
}
sw = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length / sizeof(WCHAR); i++) {
if (str <= end)
*str = (unsigned char)(pus->Buffer[i]);
++str;
}
sw = pus->Buffer;
len = pus->Length / sizeof(WCHAR);
}
str = stringw(str, end, sw, len, field_width, precision, flags);
} else {
/* print counted ascii string */
PANSI_STRING pus = va_arg(args, PANSI_STRING);
if ((pus == NULL) || (pus->Buffer == NULL)) {
s = "<NULL>";
while ((*s) != 0) {
if (str <= end)
*str = *s;
++str;
++s;
}
s = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length; i++) {
if (str <= end)
*str = pus->Buffer[i];
++str;
}
s = pus->Buffer;
len = pus->Length;
}
str = string(str, end, s, len, field_width, precision, flags);
}
continue;

View file

@ -1,4 +1,4 @@
/* $Id: swprintf.c,v 1.11 2002/09/12 17:50:42 guido Exp $
/* $Id: swprintf.c,v 1.12 2002/09/13 18:45:10 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -153,6 +153,96 @@ number(wchar_t * buf, wchar_t * end, long long num, int base, int size, int prec
return buf;
}
static wchar_t*
string(wchar_t* buf, wchar_t* end, const char* s, int len, int field_width, int precision, int flags)
{
int i;
if (s == NULL)
{
s = "<NULL>";
len = 6;
}
else
{
if (len == -1)
{
len = 0;
while (s[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (buf <= end)
*buf = L' ';
++buf;
}
for (i = 0; i < len; ++i)
{
if (buf <= end)
*buf = *s++;
++buf;
}
while (len < field_width--)
{
if (buf <= end)
*buf = L' ';
++buf;
}
return buf;
}
static wchar_t*
stringw(wchar_t* buf, wchar_t* end, const wchar_t* sw, int len, int field_width, int precision, int flags)
{
int i;
if (sw == NULL)
{
sw = L"<NULL>";
len = 6;
}
else
{
if (len == -1)
{
len = 0;
while (sw[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (buf <= end)
*buf = L' ';
buf++;
}
for (i = 0; i < len; ++i)
{
if (buf <= end)
*buf = *sw++;
buf++;
}
while (len < field_width--)
{
if (buf <= end)
*buf = L' ';
buf++;
}
return buf;
}
int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args)
{
@ -290,57 +380,11 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args)
if (qualifier == 'h') {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = (wchar_t)(*s);
++str;
++s;
}
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
str = string(str, end, s, -1, field_width, precision, flags);
} else {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = *sw;
++str;
++sw;
}
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
str = stringw(str, end, sw, -1, field_width, precision, flags);
}
continue;
@ -348,57 +392,11 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args)
if (qualifier == 'l' || qualifier == 'w') {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = *sw;
++str;
++sw;
}
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
str = stringw(str, end, sw, -1, field_width, precision, flags);
} else {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = (wchar_t)(*s);
++str;
++s;
}
while (len < field_width--) {
if (str <= end)
*str = L' ';
++str;
}
str = string(str, end, s, -1, field_width, precision, flags);
}
continue;
@ -407,38 +405,24 @@ int _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list args)
/* print counted ascii string */
PANSI_STRING pus = va_arg(args, PANSI_STRING);
if ((pus == NULL) || (pus->Buffer == NULL)) {
sw = L"<NULL>";
while ((*sw) != 0) {
if (str <= end)
*str = *sw;
++str;
++sw;
}
s = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length; i++) {
if (str <= end)
*str = (wchar_t)(pus->Buffer[i]);
++str;
}
s = pus->Buffer;
len = pus->Length;
}
str = string(str, end, s, len, field_width, precision, flags);
} else {
/* print counted unicode string */
PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
if ((pus == NULL) || (pus->Buffer == NULL)) {
sw = L"<NULL>";
while ((*sw) != 0) {
if (str <= end)
*str = *sw;
++str;
++sw;
}
sw = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length / sizeof(WCHAR); i++) {
if (str <= end)
*str = pus->Buffer[i];
++str;
}
sw = pus->Buffer;
len = pus->Length / sizeof(WCHAR);
}
str = stringw(str, end, sw, len, field_width, precision, flags);
}
continue;