Improved curl_m*printf() integral data type size and signedness handling

This commit is contained in:
Yang Tse 2008-08-22 11:11:33 +00:00
parent d5a71fd567
commit 9bb5da968c
3 changed files with 57 additions and 57 deletions

View File

@ -6,8 +6,9 @@
Changelog Changelog
Yang Tse (21 Aug 2008) Yang Tse (22 Aug 2008)
- Fixed a couple of bugs in libcurl's internal curl_m*printf() functions. - Improved libcurl's internal curl_m*printf() functions integral data type
size and signedness handling.
Daniel Fandrich (20 Aug 2008) Daniel Fandrich (20 Aug 2008)
- Added an edited version of Vincent Le Normand's documentation of SFTP quote - Added an edited version of Vincent Le Normand's documentation of SFTP quote

View File

@ -55,6 +55,7 @@ This release includes the following bugfixes:
o potential buffer overflows in the MS-DOS command-line port fixed o potential buffer overflows in the MS-DOS command-line port fixed
o --stderr is now honoured with the -v option o --stderr is now honoured with the -v option
o memory leak in libcurl on Windows built with OpenSSL o memory leak in libcurl on Windows built with OpenSSL
o improved curl_m*printf() integral data type size and signedness handling
This release includes the following known bugs: This release includes the following known bugs:

View File

@ -49,6 +49,10 @@
#include <curl/mprintf.h> #include <curl/mprintf.h>
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
#ifndef SIZEOF_LONG_DOUBLE #ifndef SIZEOF_LONG_DOUBLE
#define SIZEOF_LONG_DOUBLE 0 #define SIZEOF_LONG_DOUBLE 0
#endif #endif
@ -74,9 +78,17 @@
# endif # endif
#endif #endif
#include "memory.h" /*
/* The last #include file should be: */ * Max integer data types that mprintf.c is capable
#include "memdebug.h" */
#ifdef HAVE_LONG_LONG_TYPE
# define mp_intmax_t LONG_LONG_TYPE
# define mp_uintmax_t unsigned LONG_LONG_TYPE
#else
# define mp_intmax_t long
# define mp_uintmax_t unsigned long
#endif
#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */ #define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
#define MAX_PARAMETERS 128 /* lame static limit */ #define MAX_PARAMETERS 128 /* lame static limit */
@ -146,10 +158,10 @@ typedef struct {
union { union {
char *str; char *str;
void *ptr; void *ptr;
long num; union {
#ifdef HAVE_LONG_LONG_TYPE mp_intmax_t as_signed;
LONG_LONG_TYPE lnum; mp_uintmax_t as_unsigned;
#endif } num;
double dnum; double dnum;
} data; } data;
} va_stack_t; } va_stack_t;
@ -544,7 +556,7 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
/* Width/precision arguments must be read before the main argument /* Width/precision arguments must be read before the main argument
* they are attached to * they are attached to
*/ */
vto[i + 1].data.num = va_arg(arglist, int); vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
} }
switch (vto[i].type) switch (vto[i].type)
@ -561,15 +573,27 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
case FORMAT_INT: case FORMAT_INT:
#ifdef HAVE_LONG_LONG_TYPE #ifdef HAVE_LONG_LONG_TYPE
if(vto[i].flags & FLAGS_LONGLONG) if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
vto[i].data.lnum = va_arg(arglist, LONG_LONG_TYPE); vto[i].data.num.as_unsigned =
(mp_uintmax_t)va_arg(arglist, unsigned LONG_LONG_TYPE);
else if(vto[i].flags & FLAGS_LONGLONG)
vto[i].data.num.as_signed =
(mp_intmax_t)va_arg(arglist, LONG_LONG_TYPE);
else else
#endif #endif
{ {
if(vto[i].flags & FLAGS_LONG) if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
vto[i].data.num = va_arg(arglist, long); vto[i].data.num.as_unsigned =
(mp_uintmax_t)va_arg(arglist, unsigned long);
else if(vto[i].flags & FLAGS_LONG)
vto[i].data.num.as_signed =
(mp_intmax_t)va_arg(arglist, long);
else if(vto[i].flags & FLAGS_UNSIGNED)
vto[i].data.num.as_unsigned =
(mp_uintmax_t)va_arg(arglist, unsigned int);
else else
vto[i].data.num = va_arg(arglist, int); vto[i].data.num.as_signed =
(mp_intmax_t)va_arg(arglist, int);
} }
break; break;
@ -645,13 +669,10 @@ static int dprintf_formatf(
long base; long base;
/* Integral values to be written. */ /* Integral values to be written. */
#ifdef HAVE_LONG_LONG_TYPE mp_uintmax_t num;
unsigned LONG_LONG_TYPE num;
LONG_LONG_TYPE signed_num; /* Used to convert negative in positive. */
#else mp_intmax_t signed_num;
unsigned long num;
long signed_num;
#endif
if(*f != '%') { if(*f != '%') {
/* This isn't a format spec, so write everything out until the next one /* This isn't a format spec, so write everything out until the next one
@ -690,13 +711,13 @@ static int dprintf_formatf(
/* pick up the specified width */ /* pick up the specified width */
if(p->flags & FLAGS_WIDTHPARAM) if(p->flags & FLAGS_WIDTHPARAM)
width = vto[p->width].data.num; width = (long)vto[p->width].data.num.as_signed;
else else
width = p->width; width = p->width;
/* pick up the specified precision */ /* pick up the specified precision */
if(p->flags & FLAGS_PRECPARAM) { if(p->flags & FLAGS_PRECPARAM) {
prec = vto[p->precision].data.num; prec = (long)vto[p->precision].data.num.as_signed;
param_num++; /* since the precision is extraced from a parameter, we param_num++; /* since the precision is extraced from a parameter, we
must skip that to get to the next one properly */ must skip that to get to the next one properly */
} }
@ -709,12 +730,7 @@ static int dprintf_formatf(
switch (p->type) { switch (p->type) {
case FORMAT_INT: case FORMAT_INT:
#ifdef HAVE_LONG_LONG_TYPE num = p->data.num.as_unsigned;
if(p->flags & FLAGS_LONGLONG)
num = (unsigned LONG_LONG_TYPE)p->data.lnum;
else
#endif
num = (unsigned long)p->data.num;
if(p->flags & FLAGS_CHAR) { if(p->flags & FLAGS_CHAR) {
/* Character. */ /* Character. */
if(!(p->flags & FLAGS_LEFT)) if(!(p->flags & FLAGS_LEFT))
@ -747,32 +763,14 @@ static int dprintf_formatf(
/* Decimal integer. */ /* Decimal integer. */
base = 10; base = 10;
#ifdef HAVE_LONG_LONG_TYPE is_neg = p->data.num.as_signed < 0;
if(p->flags & FLAGS_LONGLONG) { if(is_neg) {
/* long long */ /* signed_num might fail to hold absolute negative minimum by 1 */
is_neg = (p->data.lnum < 0); signed_num = p->data.num.as_signed + (mp_intmax_t)1;
if(is_neg) { num = (mp_uintmax_t)-signed_num;
/* signed long long might fail to hold absolute LLONG_MIN by 1 */ num += (mp_uintmax_t)1;
signed_num = p->data.lnum + (LONG_LONG_TYPE)1;
num = (unsigned LONG_LONG_TYPE)-signed_num;
num += (unsigned LONG_LONG_TYPE)1;
}
else
num = p->data.lnum;
}
else
#endif
{
is_neg = (p->data.num < 0);
if(is_neg) {
/* signed long might fail to hold absolute LONG_MIN by 1 */
signed_num = p->data.num + (long)1;
num = (unsigned long)-signed_num;
num += (unsigned long)1;
}
else
num = p->data.num;
} }
goto number; goto number;
unsigned_number: unsigned_number:
@ -938,13 +936,13 @@ static int dprintf_formatf(
if(p->flags & FLAGS_WIDTH) if(p->flags & FLAGS_WIDTH)
width = p->width; width = p->width;
else if(p->flags & FLAGS_WIDTHPARAM) else if(p->flags & FLAGS_WIDTHPARAM)
width = vto[p->width].data.num; width = (long)vto[p->width].data.num.as_signed;
prec = -1; prec = -1;
if(p->flags & FLAGS_PREC) if(p->flags & FLAGS_PREC)
prec = p->precision; prec = p->precision;
else if(p->flags & FLAGS_PRECPARAM) else if(p->flags & FLAGS_PRECPARAM)
prec = vto[p->precision].data.num; prec = (long)vto[p->precision].data.num.as_signed;
if(p->flags & FLAGS_LEFT) if(p->flags & FLAGS_LEFT)
strcat(formatbuf, "-"); strcat(formatbuf, "-");