From eec75375c44960a991a26ad92f765b0cd8b708ff Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Fri, 13 Sep 2002 18:48:42 +0000 Subject: [PATCH] Fixed a buffer overflow if there is given a not null terminated string with a precision parameter. Reduced some overhead for outputing strings. Added handling of the precision parameter for counted strings. Return the outputed character count (or an error) in __vf(w)printf. svn path=/trunk/; revision=3492 --- reactos/lib/msvcrt/stdio/vfprintf.c | 471 ++++++++++++++++++++-------- reactos/lib/msvcrt/stdio/vfwprint.c | 442 ++++++++++++++++++-------- 2 files changed, 661 insertions(+), 252 deletions(-) diff --git a/reactos/lib/msvcrt/stdio/vfprintf.c b/reactos/lib/msvcrt/stdio/vfprintf.c index fd5bc9c5891..c24ccebdce9 100644 --- a/reactos/lib/msvcrt/stdio/vfprintf.c +++ b/reactos/lib/msvcrt/stdio/vfprintf.c @@ -20,6 +20,9 @@ vfprintf(FILE *f, const char *fmt, va_list ap) int len; char localbuf[BUFSIZ]; +#if 0 + __fileno_lock(fileno(f)); +#endif if (f->_flag & _IONBF) { f->_flag &= ~_IONBF; @@ -34,6 +37,9 @@ vfprintf(FILE *f, const char *fmt, va_list ap) } else len = __vfprintf(f,fmt, ap); +#if 0 + __fileno_unlock(fileno(f)); +#endif return (ferror(f) ? EOF : len); } @@ -91,18 +97,18 @@ static int do_div(long long *n,int base) } -static void number(FILE * f, long long num, int base, int size, int precision ,int type) +static int number(FILE * f, long long num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; - int i; + int i, done = 0; if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) - return; + return done; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { @@ -134,32 +140,62 @@ static void number(FILE * f, long long num, int base, int size, int precision ,i size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putc(' ',f); + { + if (putc(' ',f) == EOF) + return -1; + done++; + } if (sign) - putc(sign,f); + { + if (putc(sign,f) == EOF) + return -1; + done++; + } if (type & SPECIAL) { if (base==8) { - putc('0',f); + if (putc('0',f) == EOF) + return -1; + done++; } else if (base==16) { - putc('0', f); - putc(digits[33],f); + if (putc('0', f) == EOF) + return -1; + done++; + if (putc(digits[33],f) == EOF) + return -1; + done++; } } if (!(type & LEFT)) while (size-- > 0) - putc(c,f); + { + if (putc(c,f) == EOF) + return -1; + done++; + } while (i < precision--) - putc('0', f); + { + if (putc('0', f) == EOF) + return -1; + done++; + } while (i-- > 0) - putc(tmp[i],f); + { + if (putc(tmp[i],f) == EOF) + return -1; + done++; + } while (size-- > 0) - putc(' ', f); - return; + { + if (putc(' ', f) == EOF) + return -1; + done++; + } + return done; } -static void numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type) +static int numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type) { double exponent = 0.0; double e; @@ -176,6 +212,7 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio char sign; char c; char ro = 0; + int result, done = 0; double_t *n = (double_t *)&__n; @@ -197,16 +234,24 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio else if ( frac < -0.5 ) e--; - numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type); - putc( exp_sign,f); + result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type); + if (result < 0) + return -1; + done += result; + if (putc( exp_sign,f) == EOF) + return -1; + done++; size--; ie = (long)e; type = LEFT | PLUS; if ( ie < 0 ) type |= SIGN; - number(f,ie, 10,2, 2,type ); - return; + result = number(f,ie, 10,2, 2,type ); + if (result < 0) + return -1; + done += result; + return done; } if ( exp_sign == 'f' ) { @@ -293,19 +338,35 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putc(' ',f); + { + if (putc(' ',f) == EOF) + return -1; + done++; + } if (sign) - putc( sign,f); + { + if (putc( sign,f) == EOF) + return -1; + done++; + } if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putc(' ',f); + { + if (putc(' ',f) == EOF) + return -1; + done++; + } if (type & SPECIAL) { } if (!(type & LEFT)) while (size-- > 0) - putc(c,f); + { + if (putc(c,f) == EOF) + return -1; + done++; + } tmp = buf; if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) { @@ -319,14 +380,23 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio // while (i < precision--) // putc('0', f); while (i-- > 0) - putc(tmp[i],f); + { + if (putc(tmp[i],f) == EOF) + return -1; + done++; + } while (size-- > 0) - putc(' ', f); + { + if (putc(' ', f) == EOF) + return -1; + done++; + } } + return done; } -static void numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type) +static int numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type) { long double exponent = 0.0; long double e; @@ -344,6 +414,8 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr char c; char ro = 0; + int result, done = 0; + long_double_t *n = (long_double_t *)&__n; if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) { @@ -364,16 +436,24 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr else if ( frac < -0.5 ) e--; - numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type); - putc( exp_sign,f); + result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type); + if (result < 0) + return -1; + done += result; + if (putc( exp_sign,f) == EOF) + return -1; + done++; size--; ie = (long)e; type = LEFT | PLUS; if ( ie < 0 ) type |= SIGN; - number(f,ie, 10,2, 2,type ); - return; + result = number(f,ie, 10,2, 2,type ); + if (result < 0) + return -1; + done += result; + return done; } if ( exp_sign == 'f' ) { @@ -461,20 +541,35 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putc(' ',f); + { + if (putc(' ',f) == EOF) + return -1; + done++; + } if (sign) - putc(sign,f); + { + if (putc(sign,f) == EOF) + return -1; + done++; + } if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putc(' ',f); + { + if (putc(' ',f) == EOF) + return -1; + done++; + } if (type & SPECIAL) { } if (!(type & LEFT)) while (size-- > 0) - putc(c,f); - + { + if (putc(c,f) == EOF) + return -1; + done++; + } tmp = buf; if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) { j = 0; @@ -487,12 +582,108 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr // while (i < precision--) // putc( '0', f); while (i-- > 0) - putc(tmp[i],f); + { + if ( putc(tmp[i],f) == EOF) + return -1; + done++; + } while (size-- > 0) - putc(' ', f); + { + if (putc(' ', f) == EOF) + return -1; + done++; + } } + return done; } +static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags) +{ + int i, done = 0; + if (s == NULL) + { + s = ""; + 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 (putc(' ', f) == EOF) + return -1; + done++; + } + for (i = 0; i < len; ++i) + { + if (putc(*s++, f) == EOF) + return -1; + done++; + } + while (len < field_width--) + { + if (putc(' ', f) == EOF) + return -1; + done++; + } + return done; +} + +static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags) +{ + int i, done = 0; + if (sw == NULL) + { + sw = L""; + 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 (putc(' ', f) == EOF) + return -1; + done++; + } + for (i = 0; i < len; ++i) + { + if (putc((unsigned char)(*sw++), f) == EOF) + return -1; + done++; + } + while (len < field_width--) + { + if (putc(' ', f) == EOF) + return -1; + done++; + } + return done; +} int __vfprintf(FILE *f, const char *fmt, va_list args) { @@ -503,6 +694,7 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) double _double; const char *s; const short int* sw; + int result, done = 0; int flags; /* flags to number() */ @@ -513,7 +705,9 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) for (; *fmt ; ++fmt) { if (*fmt != '%') { - putc(*fmt,f); + if (putc(*fmt,f) == EOF) + return -1; + done++; continue; } @@ -597,101 +791,87 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) case 'c': if (!(flags & LEFT)) while (--field_width > 0) - putc(' ', f); + { + if (putc(' ', f) == EOF) + return -1; + done++; + } if (qualifier == 'l' || qualifier == 'w') - putc((unsigned char)(wchar_t) va_arg(args, int), f); + { + if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF) + return -1; + done++; + } else - putc((unsigned char) va_arg(args, int), f); + { + if (putc((unsigned char) va_arg(args, int), f) == EOF) + return -1; + done++; + } while (--field_width > 0) - putc(' ', f); + { + if (putc(' ', f) == EOF) + return -1; + done++; + } continue; case 'C': if (!(flags & LEFT)) while (--field_width > 0) - putc(' ', f); + { + if (putc(' ', f) == EOF) + return -1; + done++; + } if (qualifier == 'h') - putc((unsigned char) va_arg(args, int), f); + { + if (putc((unsigned char) va_arg(args, int), f) == EOF) + return -1; + done++; + } else - putc((unsigned char)(wchar_t) va_arg(args, int), f); + { + if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF) + return -1; + done++; + } while (--field_width > 0) - putc(' ', f); + { + if (putc(' ', f) == EOF) + return -1; + done++; + } continue; case 's': if (qualifier == 'l' || qualifier == 'w') { /* print unicode string */ sw = va_arg(args, wchar_t *); - if (sw == NULL) - sw = L""; - - len = wcslen (sw); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putc(' ', f); - for (i = 0; i < len; ++i) - putc((unsigned char)(*sw++), f); - while (len < field_width--) - putc(' ', f); + result = stringw(f, sw, -1, field_width, precision, flags); } else { /* print ascii string */ s = va_arg(args, char *); - if (s == NULL) - s = ""; - - len = strlen (s); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putc(' ', f); - for (i = 0; i < len; ++i) - putc(*s++, f); - while (len < field_width--) - putc(' ', f); + result = string(f, s, -1, field_width, precision, flags); } + if (result < 0) + return -1; + done += result; continue; case 'S': if (qualifier == 'h') { /* print ascii string */ s = va_arg(args, char *); - if (s == NULL) - s = ""; - - len = strlen (s); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putc(' ', f); - for (i = 0; i < len; ++i) - putc(*s++, f); - while (len < field_width--) - putc(' ', f); + result = string(f, s, -1, field_width, precision, flags); } else { /* print unicode string */ sw = va_arg(args, wchar_t *); - if (sw == NULL) - sw = L""; - - len = wcslen (sw); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putc(' ', f); - for (i = 0; i < len; ++i) - putc((unsigned char)(*sw++), f); - while (len < field_width--) - putc(' ', f); + result = stringw(f, sw, -1, field_width, precision, flags); } + if (result < 0) + return -1; + done += result; continue; case 'Z': @@ -699,25 +879,28 @@ int __vfprintf(FILE *f, 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 = ""; - while ((*s) != 0) - putc(*s++, f); + sw = NULL; + len = -1; } else { - for (i = 0; pus->Buffer[i] && i < pus->Length / sizeof(WCHAR); i++) - putc((unsigned char)(pus->Buffer[i]), f); + sw = pus->Buffer; + len = pus->Length / sizeof(WCHAR); } + result = stringw(f, 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 = ""; - while ((*s) != 0) - putc(*s++, f); + PANSI_STRING pas = va_arg(args, PANSI_STRING); + if ((pas == NULL) || (pas->Buffer == NULL)) { + s = NULL; + len = -1; } else { - for (i = 0; pus->Buffer[i] && i < pus->Length; i++) - putc(pus->Buffer[i], f); + s = pas->Buffer; + len = pas->Length; } + result = string(f, s, -1, field_width, precision, flags); } + if (result < 0) + return -1; + done += result; continue; case 'e': @@ -732,7 +915,9 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) s = "Nan"; len = 3; while ( len > 0 ) { - putc(*s++,f); + if (putc(*s++,f) == EOF) + return -1; + done++; len --; } } @@ -740,7 +925,9 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) s = "-Inf"; len = 4; while ( len > 0 ) { - putc(*s++,f); + if (putc(*s++,f) == EOF) + return -1; + done++; len --; } } @@ -748,13 +935,18 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) s = "+Inf"; len = 4; while ( len > 0 ) { - putc(*s++,f); + if (putc(*s++,f) == EOF) + return -1; + done++; len --; } } else { if ( precision == -1 ) precision = 6; - numberfl(f,_ldouble,*fmt,field_width,precision,flags); + result = numberfl(f,_ldouble,*fmt,field_width,precision,flags); + if (result < 0) + return -1; + done += result; } } else { _double = (double)va_arg(args, double); @@ -763,27 +955,36 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) s = "Nan"; len = 3; while ( len > 0 ) { - putc(*s++,f); + if (putc(*s++,f) == EOF) + return -1; + done++; len --; } } else if ( _isinf(_double) < 0 ) { s = "-Inf"; len = 4; while ( len > 0 ) { - putc(*s++,f); + if (putc(*s++,f) == EOF) + return -1; + done++; len --; } } else if ( _isinf(_double) > 0 ) { s = "+Inf"; len = 4; while ( len > 0 ) { - putc(*s++,f); + if (putc(*s++,f) == EOF) + return -1; + done++; len --; } } else { if ( precision == -1 ) precision = 6; - numberf(f,_double,*fmt,field_width,precision,flags); + result = numberf(f,_double,*fmt,field_width,precision,flags); + if (result < 0) + return -1; + done += result; } } continue; @@ -793,9 +994,12 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) field_width = 2*sizeof(void *); flags |= ZEROPAD; } - number(f, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); + result = number(f, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + if (result < 0) + return -1; + done += result; continue; case 'n': @@ -831,9 +1035,17 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) default: if (*fmt != '%') - putc('%', f); + { + if (putc('%', f) == EOF) + return -1; + done++; + } if (*fmt) - putc(*fmt, f); + { + if (putc(*fmt, f) == EOF) + return -1; + done++; + } else --fmt; continue; @@ -853,10 +1065,13 @@ int __vfprintf(FILE *f, const char *fmt, va_list args) num = va_arg(args, int); else num = va_arg(args, unsigned int); - number(f, num, base, field_width, precision, flags); + result = number(f, num, base, field_width, precision, flags); + if (result < 0) + return -1; + done += result; } //putc('\0',f); - return 0; + return done; } /* EOF */ diff --git a/reactos/lib/msvcrt/stdio/vfwprint.c b/reactos/lib/msvcrt/stdio/vfwprint.c index 91082d7971c..4266f5d45b5 100644 --- a/reactos/lib/msvcrt/stdio/vfwprint.c +++ b/reactos/lib/msvcrt/stdio/vfwprint.c @@ -20,6 +20,9 @@ vfwprintf(FILE *f, const wchar_t *fmt, va_list ap) int len; wchar_t localbuf[BUFSIZ]; +#if 0 + __fileno_lock(fileno(f)); +#endif if (f->_flag & _IONBF) { f->_flag &= ~_IONBF; f->_ptr = f->_base = (char *)localbuf; @@ -32,7 +35,9 @@ vfwprintf(FILE *f, const wchar_t *fmt, va_list ap) f->_cnt = 0; } else len = __vfwprintf(f,fmt,ap); - +#if 0 + __fileno_unlock(fileno(f)); +#endif return (ferror(f) ? EOF : len); } @@ -91,18 +96,18 @@ static int do_div(long long *n,int base) } -static void number(FILE * f, long long num, int base, int size, int precision ,int type) +static int number(FILE * f, long long num, int base, int size, int precision ,int type) { wchar_t c,sign,tmp[66]; const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz"; - int i; + int i, done = 0; if (type & LARGE) digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) - return; + return done; c = (type & ZEROPAD) ? L'0' : L' '; sign = 0; if (type & SIGN) { @@ -134,32 +139,63 @@ static void number(FILE * f, long long num, int base, int size, int precision ,i size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putwc(L' ',f); + { + if (putwc(L' ',f) == WEOF) + return -1; + done++; + } + if (sign) - putwc(sign,f); + { + if (putwc(sign,f) == WEOF) + return -1; + done++; + } if (type & SPECIAL) { if (base==8) { - putwc(L'0',f); + if (putwc(L'0',f) == WEOF) + return -1; + done++; } else if (base==16) { - putwc(L'0', f); - putwc(digits[33],f); + if (putwc(L'0', f) == WEOF) + return -1; + done++; + if (putwc(digits[33],f) == WEOF) + return -1; + done++; } } if (!(type & LEFT)) while (size-- > 0) - putwc(c,f); + { + if (putwc(c,f) == WEOF) + return -1; + done++; + } while (i < precision--) - putwc(L'0', f); + { + if (putwc(L'0', f) == WEOF) + return -1; + done++; + } while (i-- > 0) - putwc(tmp[i],f); + { + if (putwc(tmp[i],f) == WEOF) + return -1; + done++; + } while (size-- > 0) - putwc(L' ', f); - return; + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } + return done; } -static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type) +static int numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type) { double exponent = 0.0; double e; @@ -176,6 +212,7 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci wchar_t sign; wchar_t c; char ro = 0; + int result, done = 0; double_t *n = (double_t *)&__n; @@ -197,16 +234,24 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci else if ( frac < -0.5 ) e--; - numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type); - putwc( exp_sign,f); + result = numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type); + if (result < 0) + return -1; + done += result; + if (putwc( exp_sign,f) == WEOF) + return -1; + done++; size--; ie = (long)e; type = LEFT | PLUS; if ( ie < 0 ) type |= SIGN; - number(f,ie, 10,2, 2,type ); - return; + result = number(f,ie, 10,2, 2,type ); + if (result < 0) + return -1; + done += result; + return done; } if ( exp_sign == 'f' ) { @@ -293,19 +338,35 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putwc(L' ',f); + { + if (putwc(L' ',f) == WEOF) + return -1; + done++; + } if (sign) - putwc( sign,f); + { + if (putwc( sign,f) == WEOF) + return -1; + done++; + } if (!(type&(ZEROPAD+LEFT))) while(size-->0) - putwc(L' ',f); + { + if (putwc(L' ',f) == WEOF) + return -1; + done++; + } if (type & SPECIAL) { } if (!(type & LEFT)) while (size-- > 0) - putwc(c,f); + { + if (putwc(c,f) == WEOF) + return -1; + done++; + } tmp = buf; if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) { @@ -319,14 +380,23 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci // while (i < precision--) // putwc(L'0', f); while (i-- > 0) - putwc(tmp[i],f); + { + if (putwc(tmp[i],f) == WEOF) + return -1; + done++; + } while (size-- > 0) - putwc(L' ', f); + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } } + return done; } -static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type) +static int numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type) { long double exponent = 0.0; long double e; @@ -344,6 +414,8 @@ static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int wchar_t c; char ro = 0; + int result, done = 0; + long_double_t *n = (long_double_t *)&__n; if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) { @@ -364,16 +436,24 @@ static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int else if ( frac < -0.5 ) e--; - numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type); - putwc( exp_sign,f); + result = numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type); + if (result < 0) + return -1; + done += result; + if (putwc( exp_sign,f) == WEOF) + return -1; + done++; size--; ie = (long)e; type = LEFT | PLUS; if ( ie < 0 ) type |= SIGN; - number(f,ie, 10,2, 2,type ); - return; + result = number(f,ie, 10,2, 2,type ); + if (result < 0) + return -1; + done += result; + return done; } if ( exp_sign == L'f' ) { @@ -486,12 +566,108 @@ static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int // while (i < precision--) // putc( '0', f); while (i-- > 0) - putwc(tmp[i],f); + { + if (putwc(tmp[i],f) == WEOF) + return -1; + done++; + } while (size-- > 0) - putwc(L' ', f); + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } } + return done; } +static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags) +{ + int i, done = 0; + if (s == NULL) + { + s = ""; + 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 (putwc(L' ', f) == WEOF) + return -1; + done++; + } + for (i = 0; i < len; ++i) + { + if (putwc(*s++, f) == WEOF) + return -1; + done++; + } + while (len < field_width--) + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } + return done; +} + +static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags) +{ + int i, done = 0; + if (sw == NULL) + { + sw = L""; + 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 (putwc(L' ', f) == WEOF) + return -1; + done++; + } + for (i = 0; i < len; ++i) + { + if (putwc(*sw++, f) == WEOF) + return -1; + done++; + } + while (len < field_width--) + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } + return done; +} int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) { @@ -502,6 +678,7 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) double _double; const char *s; const wchar_t* sw; + int result, done = 0; int flags; /* flags to number() */ @@ -512,7 +689,9 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) for (; *fmt ; ++fmt) { if (*fmt != L'%') { - putwc(*fmt,f); + if (putwc(*fmt,f) == WEOF) + return -1; + done++; continue; } @@ -596,130 +775,113 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) case L'c': /* finished */ if (!(flags & LEFT)) while (--field_width > 0) - putwc(L' ', f); + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } if (qualifier == L'h') - putwc((wchar_t) va_arg(args, int), f); + { + if (putwc((wchar_t) va_arg(args, int), f) == WEOF) + return -1; + } else - putwc((wchar_t) va_arg(args, int), f); + { + if (putwc((wchar_t) va_arg(args, int), f) == WEOF) + return -1; + } + done++; while (--field_width > 0) - putwc(L' ', f); + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } continue; case L'C': /* finished */ if (!(flags & LEFT)) while (--field_width > 0) - putwc(L' ', f); + { + if (putwc(L' ', f) == WEOF) + return -1; + done; + } if (qualifier == L'l' || qualifier == L'w') - putwc((unsigned char) va_arg(args, int), f); + { + if (putwc((unsigned char) va_arg(args, int), f) == WEOF) + return -1; + } else - putwc((unsigned char) va_arg(args, int), f); + { + if (putwc((unsigned char) va_arg(args, int), f) == WEOF) + return -1; + } + done++; while (--field_width > 0) - putwc(L' ', f); + { + if (putwc(L' ', f) == WEOF) + return -1; + done++; + } continue; case L's': /* finished */ if (qualifier == L'h') { /* print ascii string */ s = va_arg(args, char *); - if (s == NULL) - s = ""; - - len = strlen (s); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putwc(L' ', f); - for (i = 0; i < len; ++i) - putwc((wchar_t)(*s++), f); - while (len < field_width--) - putwc(L' ', f); + result = string(f, s, -1, field_width, precision, flags); } else { /* print unicode string */ sw = va_arg(args, wchar_t *); - if (sw == NULL) - sw = L""; - - len = wcslen (sw); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putwc(L' ', f); - for (i = 0; i < len; ++i) - putwc(*sw++, f); - while (len < field_width--) - putwc(L' ', f); + result = stringw(f, sw, -1, field_width, precision, flags); } + if (result < 0) + return -1; + done += result; continue; case L'S': if (qualifier == L'l' || qualifier == L'w') { /* print unicode string */ sw = va_arg(args, wchar_t *); - if (sw == NULL) - sw = L""; - - len = wcslen (sw); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putwc(L' ', f); - for (i = 0; i < len; ++i) - putwc(*sw++, f); - while (len < field_width--) - putwc(L' ', f); + result = stringw(f, sw, -1, field_width, precision, flags); } else { /* print ascii string */ s = va_arg(args, char *); - if (s == NULL) - s = ""; - - len = strlen (s); - if ((unsigned int)len > (unsigned int)precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - putwc(L' ', f); - for (i = 0; i < len; ++i) - putwc((wchar_t)(*s++), f); - while (len < field_width--) - putwc(L' ', f); } + if (result < 0) + return -1; + done += result; continue; -#if 0 case L'Z': /* finished */ if (qualifier == L'w') { /* print counted unicode string */ PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING); if ((pus == NULL) || (pus->Buffer)) { - sw = L""; - while ((*sw) != 0) - putwc(*sw++, f); + sw = NULL; + len = -1; } else { - for (i = 0; pus->Buffer[i] && i < pus->Length; i++) - putwc(pus->Buffer[i], f); + sw = pus->Buffer; } + result = stringw(f, sw, len, field_width, precision, flags); } else { /* print counted ascii string */ PANSI_STRING pus = va_arg(args, PANSI_STRING); if ((pus == NULL) || (pus->Buffer)) { - sw = L""; - while ((*sw) != 0) - putwc(*sw++, f); + s = NULL; + len = -1; } else { - for (i = 0; pus->Buffer[i] && i < pus->Length; i++) - putwc((wchar_t)pus->Buffer[i], f); + s = pus->Buffer; + len = pus->Length; } + result = string(f, s, len, field_width, precision, flags); } + if (result < 0) + return -1; + done += result; continue; -#endif case L'e': /* finished */ case L'E': @@ -733,7 +895,9 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) sw = L"Nan"; len = 3; while ( len > 0 ) { - putwc(*sw++,f); + if (putwc(*sw++,f) == WEOF) + return -1; + done++; len --; } } @@ -741,7 +905,9 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) sw = L"-Inf"; len = 4; while ( len > 0 ) { - putwc(*sw++,f); + if (putwc(*sw++,f) == WEOF) + return -1; + done++; len --; } } @@ -749,13 +915,18 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) sw = L"+Inf"; len = 4; while ( len > 0 ) { - putwc(*sw++,f); + if (putwc(*sw++,f) == WEOF) + return -1; + done++; len --; } } else { if ( precision == -1 ) precision = 6; - numberfl(f,_ldouble,*fmt,field_width,precision,flags); + result = numberfl(f,_ldouble,*fmt,field_width,precision,flags); + if (result < 0) + return -1; + done += result; } } else { _double = (double)va_arg(args, double); @@ -764,27 +935,36 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) sw = L"Nan"; len = 3; while ( len > 0 ) { - putwc(*sw++,f); + if (putwc(*sw++,f) == WEOF) + return -1; + done++; len --; } } else if ( _isinf(_double) < 0 ) { sw = L"-Inf"; len = 4; while ( len > 0 ) { - putwc(*sw++,f); + if (putwc(*sw++,f) == WEOF) + return -1; + done++; len --; } } else if ( _isinf(_double) > 0 ) { sw = L"+Inf"; len = 4; while ( len > 0 ) { - putwc(*sw++,f); + if (putwc(*sw++,f) == WEOF) + return -1; + done++; len --; } } else { if ( precision == -1 ) precision = 6; - numberf(f,_double,*fmt,field_width,precision,flags); + result = numberf(f,_double,*fmt,field_width,precision,flags); + if (result < 0) + return -1; + done += result; } } continue; @@ -794,9 +974,12 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) field_width = 2*sizeof(void *); flags |= ZEROPAD; } - number(f, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); + result = number(f, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + if (result < 0) + return -1; + done += result; continue; case L'n': @@ -832,9 +1015,17 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) default: if (*fmt != L'%') - putwc(L'%', f); + { + if (putwc(L'%', f) == WEOF) + return -1; + done++; + } if (*fmt) - putwc(*fmt, f); + { + if (putwc(*fmt, f) == WEOF) + return -1; + done++; + } else --fmt; continue; @@ -854,10 +1045,13 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args) num = va_arg(args, int); else num = va_arg(args, unsigned int); - number(f, num, base, field_width, precision, flags); + result = number(f, num, base, field_width, precision, flags); + if (result < 0) + return -1; + done += result; } //putwc(L'\0',f); - return 0; + return done; } /* EOF */