diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2021-05-17 13:35:50 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2021-05-17 13:35:50 +0000 |
commit | 97e007684122b8696397176bccf4e76fc8033a8b (patch) | |
tree | dacd3c5be83d7d1ab9bda0082a38d2879d38c454 | |
parent | b8bcf0f4123f555a0bbd09c39a9b9edda12d546f (diff) | |
download | mpfr-97e007684122b8696397176bccf4e76fc8033a8b.tar.gz |
Formatted output functions (mpfr_*printf): bug fix; added tests.
* src/vasprintf.c: in buffer_cat, replaced incorrect assertion len > 0
by a test.
Note that len == 0 is possible when outputting an integer 0
(either a native one or mpfr_prec_t) with precision field = 0.
The consequence of this bug:
- In debug mode (MPFR_ASSERTD assertion checking), one would get
an assertion failure.
- Otherwise, there should be no side effects since the code was
valid for len == 0, possibly except with LTO (very unlikely,
though).
This incorrect assertion was added on 2009-03-13 in r6099.
* tests/tsprintf.c: added tests of native integer 0 and mpfr_prec_t
(specifier 'P') with precision field 0, both yielding a call to
buffer_cat with len = 0.
(merged changesets r14514,14520-14521 from the trunk)
git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/branches/4.1@14524 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/vasprintf.c | 8 | ||||
-rw-r--r-- | tests/tsprintf.c | 17 |
2 files changed, 21 insertions, 4 deletions
diff --git a/src/vasprintf.c b/src/vasprintf.c index fca6804d4..d33f478ef 100644 --- a/src/vasprintf.c +++ b/src/vasprintf.c @@ -635,7 +635,13 @@ buffer_widen (struct string_buffer *b, size_t len) static int buffer_cat (struct string_buffer *b, const char *s, size_t len) { - MPFR_ASSERTD (len > 0); + /* If len == 0, which is possible when outputting an integer 0 + (either a native one or mpfr_prec_t) with precision field = 0, + do nothing. This test is not necessary since the code below is + valid for len == 0, but this is safer, just in case. */ + if (len == 0) + return 0; + MPFR_ASSERTD (len <= strlen (s)); if (buffer_incr_len (b, len)) diff --git a/tests/tsprintf.c b/tests/tsprintf.c index 20e83ad0b..9cd25e1ef 100644 --- a/tests/tsprintf.c +++ b/tests/tsprintf.c @@ -193,6 +193,10 @@ native_types (void) sprintf (buf, "%d", i); check_vsprintf (buf, "%d", i); + check_vsprintf ("0", "%d", 0); + check_vsprintf ("", "%.d", 0); + check_vsprintf ("", "%.0d", 0); + sprintf (buf, "%e", d); check_vsprintf (buf, "%e", d); @@ -227,9 +231,6 @@ decimal (void) mpfr_prec_t p = 128; mpfr_t x, y, z; - mpfr_init (z); - mpfr_init2 (x, p); - /* specifier 'P' for precision */ check_vsprintf ("128", "%Pu", p); check_vsprintf ("00128", "%.5Pu", p); @@ -247,9 +248,19 @@ decimal (void) check_vsprintf ("0200:", "%0#+ -Po:", p); check_vsprintf ("+0000128 :", "%0+ *.*Pd:", -9, 7, p); check_vsprintf ("+12345 :", "%0+ -*.*Pd:", -9, -3, (mpfr_prec_t) 12345); + check_vsprintf ("0", "%Pu", (mpfr_prec_t) 0); /* Do not add a test like "%05.1Pd" as MS Windows is buggy: when a precision is given, the '0' flag must be ignored. */ + /* specifier 'P' with precision field 0 */ + check_vsprintf ("128", "%.Pu", p); + check_vsprintf ("128", "%.0Pd", p); + check_vsprintf ("", "%.Pu", (mpfr_prec_t) 0); + check_vsprintf ("", "%.0Pd", (mpfr_prec_t) 0); + + mpfr_init (z); + mpfr_init2 (x, 128); + /* special numbers */ mpfr_set_inf (x, 1); check_sprintf (pinf_str, "%Re", x); |