Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions common/snprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,26 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );

/* Conversion Flags */
#define DP_C_SHORT 1
/* Note: Originally DP_C_SHORT converted to "short int" types, but modernish
* (C99+ or even earlier) standards require that the minimal type passed
* through variadic args '...' is an int, and smaller types are padded up
* to it - so value shifts in memory and erroneous access crashes can occur
* if smaller data is accessed blindly. Code below has been fixed to not pass
* "short int" anymore - it just casts the int to desired smaller type (and
* so drops the padding bits). */
#define DP_C_LONG 2
#define DP_C_LDOUBLE 3
#define DP_C_LLONG 4

#ifdef C89PLUS
#undef C89PLUS
#endif

#if defined(__STDC__) || defined(__STDC_VERSION__)
/* C89+ and C90+ code respectively */
#define C89PLUS 1
#endif

#define char_to_int(p) ((p)- '0')
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))

Expand Down Expand Up @@ -275,7 +291,11 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
case 'd':
case 'i':
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (short int)va_arg (args, int);
#else
value = va_arg (args, short int);
#endif
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
else if (cflags == DP_C_LLONG)
Expand All @@ -287,7 +307,11 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
case 'o':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (unsigned short int)va_arg (args, unsigned int);
#else
value = va_arg (args, unsigned short int);
#endif
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
Expand All @@ -299,7 +323,11 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
case 'u':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (unsigned short int)va_arg (args, unsigned int);
#else
value = va_arg (args, unsigned short int);
#endif
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
Expand All @@ -313,7 +341,11 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
case 'x':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (unsigned short int)va_arg (args, unsigned int);
#else
value = va_arg (args, unsigned short int);
#endif
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
Expand Down Expand Up @@ -365,7 +397,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
short int *num;
num = va_arg (args, short int *);
*num = currlen;
}
}
else if (cflags == DP_C_LONG)
{
long int *num;
Expand Down Expand Up @@ -543,6 +575,7 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
}
}

#ifndef HAVE_ABS_VAL
static LDOUBLE abs_val (LDOUBLE value)
{
LDOUBLE result = value;
Expand All @@ -552,7 +585,13 @@ static LDOUBLE abs_val (LDOUBLE value)

return result;
}
#endif

#ifndef HAVE_FCVT
/* The two routines that may get defined below are only used if we also don't
* have a fcvt() in the system. Defining and not using the routines may be a
* warning (fatal with -Werror), so we hide them here. */
# ifndef HAVE_POW10
static LDOUBLE pow10 (int exp)
{
LDOUBLE result = 1;
Expand All @@ -565,7 +604,9 @@ static LDOUBLE pow10 (int exp)

return result;
}
# endif

# ifndef HAVE_ROUND
static long round (LDOUBLE value)
{
long intpart;
Expand All @@ -577,6 +618,8 @@ static long round (LDOUBLE value)

return intpart;
}
# endif
#endif /* HAVE_FCVT */

static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags)
Expand All @@ -602,10 +645,12 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
int fplace = 0;
int padlen = 0; /* amount to pad */
int zpadlen = 0;
#ifndef HAVE_FCVT
int caps = 0;
long intpart;
long fracpart;

#endif

/*
* AIX manpage says the default is 0, but Solaris says the default
* is 6, and sprintf on AIX defaults to 6
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ AC_C_BIGENDIAN
AC_C_INLINE
AC_C_FLEXIBLE_ARRAY_MEMBER
AC_C_VARARRAYS
AC_CHECK_FUNCS(flock lockf fcvt fcvtl)
AC_CHECK_FUNCS(flock lockf fcvt fcvtl pow10 round abs_val)
AC_CHECK_FUNCS(cfsetispeed tcsendbreak)
AC_CHECK_FUNCS(seteuid setsid getpassphrase)
AC_CHECK_FUNCS(on_exit strptime setlogmask)
Expand Down