← Commit list

bdda3a268f

Daniel Stenberg
Daniel Stenberg
2026-08-27
SUCCESS Duration: 398s

Subject

mprintf: fix long double output

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/mprintf.c+11 -8
@@ -395,22 +395,22 @@ static bool parse_conversion(const char f, unsigned int *flagp,
flags |= FLAGS_CHAR;
break;
case 'f':
- type = MTYPE_DOUBLE;
+ type = flags & FLAGS_LONGDOUBLE ? MTYPE_LONGDOUBLE : MTYPE_DOUBLE;
break;
case 'e':
- type = MTYPE_DOUBLE;
+ type = flags & FLAGS_LONGDOUBLE ? MTYPE_LONGDOUBLE : MTYPE_DOUBLE;
flags |= FLAGS_FLOATE;
break;
case 'E':
- type = MTYPE_DOUBLE;
+ type = flags & FLAGS_LONGDOUBLE ? MTYPE_LONGDOUBLE : MTYPE_DOUBLE;
flags |= FLAGS_FLOATE | FLAGS_UPPER;
break;
case 'g':
- type = MTYPE_DOUBLE;
+ type = flags & FLAGS_LONGDOUBLE ? MTYPE_LONGDOUBLE : MTYPE_DOUBLE;
flags |= FLAGS_FLOATG;
break;
case 'G':
- type = MTYPE_DOUBLE;
+ type = flags & FLAGS_LONGDOUBLE ? MTYPE_LONGDOUBLE : MTYPE_DOUBLE;
flags |= FLAGS_FLOATG | FLAGS_UPPER;
break;
default:
@@ -618,6 +618,10 @@ static int parsefmt(const char *format,
iptr->val.dnum = va_arg(arglist, double);
break;
+ case MTYPE_LONGDOUBLE:
+ iptr->val.dnum = (double)va_arg(arglist, long double);
+ break;
+
default:
DEBUGASSERT(NULL); /* unexpected */
break;
@@ -712,9 +716,7 @@ static bool out_double(void *userp,
#ifdef _WIN32
curlx_win32_snprintf(work, BUFFSIZE, fmt, dnum);
#else
- /* !checksrc! disable BANNEDFUNC 1 */
- /* !checksrc! disable LONGLINE */
- /* NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) */
+ /* !checksrc! disable BANNEDFUNC 2 */
snprintf(work, BUFFSIZE, fmt, dnum);
#endif
#ifdef CURL_HAVE_DIAG
@@ -1065,6 +1067,7 @@ static int formatf(void *userp, /* untouched by format(), sent to the
break;
case MTYPE_DOUBLE:
+ case MTYPE_LONGDOUBLE:
if(out_double(userp, stream, &p, iptr->val.dnum, work, &done))
return done;
break;
tests/libtest/lib557.c+61 -14
@@ -46,6 +46,15 @@
#endif
#endif
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#endif
+#ifdef CURL_HAVE_DIAG
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
+
#define BUFSZ 256
struct unsshort_st {
@@ -1047,6 +1056,53 @@ static int test_weird_arguments(void)
return errors;
}
+static int double_check(void)
+{
+ const long double val = 1.234567890123456789L;
+ int mismatches = 0;
+ unsigned int i;
+ struct dbcheck {
+ const char *fmt;
+ const char *prefix; /* starts with this */
+ const char *suffix; /* ends with this */
+ };
+ /* because floats are annoying beasts, different libc's produce different
+ outputs so we cannot compare exact output, only prefix + suffix */
+ struct dbcheck c[] = {
+ { "%.17Lf", /* "1.23456789012345669" */
+ "1.23456789012345", "", },
+ { "%.17Le", /* "1.23456789012345669e+00" */
+ "1.234567890123456", "e+00" },
+ { "%.17LE", /* "1.23456789012345669E+00" */
+ "1.234567890123456", "E+00" },
+ { "%.17Lg", /* "1.2345678901234567" */
+ "1.234567890123456", "" },
+ { "%.17LG", /* "1.2345678901234567" */
+ "1.234567890123456", ""}
+ };
+ for(i = 0; i < CURL_ARRAYSIZE(c); i++) {
+ char curl_out[128];
+ size_t len =
+ curl_msnprintf(curl_out, sizeof(curl_out), c[i].fmt, val);
+ if(strncmp(curl_out, c[i].prefix, strlen(c[i].prefix))) {
+ curl_mfprintf(stderr,
+ "MISMATCH (prefix): %s curl=%s libc=%s\n",
+ c[i].fmt, curl_out, c[i].prefix);
+ mismatches++;
+ }
+ if((len < strlen(c[i].suffix) ||
+ strncmp(curl_out + len - strlen(c[i].suffix),
+ c[i].suffix, strlen(c[i].suffix)))) {
+ curl_mfprintf(stderr,
+ "MISMATCH (suffix): %s curl=%s libc=%s\n",
+ c[i].fmt, curl_out, c[i].suffix);
+ mismatches++;
+ }
+ }
+ curl_mfprintf(stderr, "mismatches=%d/5\n", mismatches);
+ return mismatches;
+}
+
/* DBL_MAX value from Linux */
#define MAXIMIZE (-1.7976931348623157081452E+308)
@@ -1165,6 +1221,8 @@ static int test_float_formatting(void)
curl_msnprintf(buf, 6, "%f", MAXIMIZE);
errors += strlen_check(buf, 5);
+ errors += double_check();
+
if(!errors)
curl_mprintf("All float strings tests OK!\n");
else
@@ -1246,14 +1304,6 @@ static int test_return_codes(void)
- curl_mvsprintf
- curl_mvaprintf
*/
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
-#endif
-#ifdef CURL_HAVE_DIAG
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
-#endif
static int var557(int expected_len, const char *format, ...)
{
va_list arg;
@@ -1319,12 +1369,6 @@ error:
curl_mprintf("The v-functions test failed!\n");
return errors;
}
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-#ifdef CURL_HAVE_DIAG
-#pragma GCC diagnostic pop
-#endif
static int test_vversions(void)
{
@@ -1370,3 +1414,6 @@ static CURLcode test_lib557(const char *URL)
#ifdef CURL_HAVE_DIAG
#pragma GCC diagnostic pop
#endif
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif