diff options
Diffstat (limited to 'main/spprintf.c')
| -rw-r--r-- | main/spprintf.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/main/spprintf.c b/main/spprintf.c index f248e8eeb5..104a2a58f6 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -285,6 +285,10 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) * Modifier check */ switch (*fmt) { + case 'L': + fmt++; + modifier = LM_LONG_DOUBLE; + break; case 'l': fmt++; #if SIZEOF_LONG_LONG @@ -296,9 +300,11 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) modifier = LM_LONG; break; case 'z': + fmt++; modifier = LM_SIZE_T; break; case 'j': + fmt++; #if SIZEOF_INTMAX_T modifier = LM_INTMAX_T; #else @@ -306,6 +312,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) #endif break; case 't': + fmt++; #if SIZEOF_PTRDIFF_T modifier = LM_PTRDIFF_T; #else @@ -340,6 +347,8 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) default: i_num = (wide_int) va_arg(ap, unsigned int); break; + case LM_LONG_DOUBLE: + goto fmt_error; case LM_LONG: i_num = (wide_int) va_arg(ap, unsigned long int); break; @@ -376,6 +385,8 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) default: i_num = (wide_int) va_arg(ap, int); break; + case LM_LONG_DOUBLE: + goto fmt_error; case LM_LONG: i_num = (wide_int) va_arg(ap, long int); break; @@ -423,6 +434,8 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) default: ui_num = (u_wide_int) va_arg(ap, unsigned int); break; + case LM_LONG_DOUBLE: + goto fmt_error; case LM_LONG: ui_num = (u_wide_int) va_arg(ap, unsigned long int); break; @@ -461,6 +474,8 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) default: ui_num = (u_wide_int) va_arg(ap, unsigned int); break; + case LM_LONG_DOUBLE: + goto fmt_error; case LM_LONG: ui_num = (u_wide_int) va_arg(ap, unsigned long int); break; @@ -511,7 +526,16 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) case 'f': case 'e': case 'E': - fp_num = va_arg(ap, double); + switch(modifier) { + case LM_LONG_DOUBLE: + fp_num = (double) va_arg(ap, long double); + break; + case LM_STD: + fp_num = va_arg(ap, double); + break; + default: + goto fmt_error; + } if (zend_isnan(fp_num)) { s = "nan"; @@ -535,6 +559,16 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) case 'g': case 'G': + switch(modifier) { + case LM_LONG_DOUBLE: + fp_num = (double) va_arg(ap, long double); + break; + case LM_STD: + fp_num = va_arg(ap, double); + break; + default: + goto fmt_error; + } if (adjust_precision == NO) precision = FLOAT_DIGITS; else if (precision == 0) @@ -542,7 +576,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* * * We use &num_buf[ 1 ], so that we have room for the sign */ - s = ap_php_gcvt(va_arg(ap, double), precision, &num_buf[1], + s = ap_php_gcvt(fp_num, precision, &num_buf[1], alternate_form); if (*s == '-') prefix_char = *s++; @@ -614,6 +648,8 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) continue; +fmt_error: + php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt); /* * The default case is for unrecognized %'s. * We print %<char> to help the user identify what |
