Improved curl_m*printf() integral data type size and signedness handling
This commit is contained in:
parent
d5a71fd567
commit
9bb5da968c
5
CHANGES
5
CHANGES
@ -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
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
108
lib/mprintf.c
108
lib/mprintf.c
@ -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, "-");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user