aboutsummaryrefslogtreecommitdiff
path: root/lib/mprintf.c
diff options
context:
space:
mode:
authorYang Tse <yangsita@gmail.com>2008-08-21 01:49:19 +0000
committerYang Tse <yangsita@gmail.com>2008-08-21 01:49:19 +0000
commitafe7bb4b3309d260e9537af47a02f1a7dc6eee6a (patch)
treeecebe06f9508ad8c40948c1811492cda61deed1b /lib/mprintf.c
parent0f5f91df0bf2502f45261a7e9dd322123231d75d (diff)
Fix a LONG_MIN and LLONG_MIN related bug in internal m*printf()
Diffstat (limited to 'lib/mprintf.c')
-rw-r--r--lib/mprintf.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/mprintf.c b/lib/mprintf.c
index 41cb6777f..a358cc10a 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -213,10 +213,10 @@ static BOOL dprintf_IsQualifierNoDollar(char c)
}
#ifdef DPRINTF_DEBUG2
-int dprintf_Pass1Report(va_stack_t *vto, int max)
+static void dprintf_Pass1Report(va_stack_t *vto, int max)
{
int i;
- char buffer[128];
+ char buffer[256];
int bit;
int flags;
@@ -235,6 +235,9 @@ int dprintf_Pass1Report(va_stack_t *vto, int max)
case FORMAT_INT:
type = "int";
break;
+ case FORMAT_INTPTR:
+ type = "intptr";
+ break;
case FORMAT_LONG:
type = "long";
break;
@@ -649,7 +652,7 @@ static int dprintf_formatf(
long prec;
/* Decimal integer is negative. */
- char is_neg;
+ int is_neg;
/* Base of a number to be written. */
long base;
@@ -657,10 +660,11 @@ static int dprintf_formatf(
/* Integral values to be written. */
#ifdef HAVE_LONG_LONG_TYPE
unsigned LONG_LONG_TYPE num;
+ LONG_LONG_TYPE signed_num;
#else
unsigned long num;
-#endif
long signed_num;
+#endif
if(*f != '%') {
/* This isn't a format spec, so write everything out until the next one
@@ -759,15 +763,28 @@ static int dprintf_formatf(
#ifdef HAVE_LONG_LONG_TYPE
if(p->flags & FLAGS_LONGLONG) {
/* long long */
- is_neg = (char)(p->data.lnum < 0);
- num = is_neg ? (- p->data.lnum) : p->data.lnum;
+ is_neg = (p->data.lnum < 0);
+ if(is_neg) {
+ /* signed long long might fail to hold absolute LLONG_MIN by 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
{
- signed_num = (long) num;
- is_neg = (char)(signed_num < 0);
- num = is_neg ? (- signed_num) : signed_num;
+ 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;