main/mpfr4: upgrade to 4.2.1
Changelog:
Changes from version 4.2.0 to version 4.2.1:
- Bug fixes (see <https://www.mpfr.org/mpfr-4.2.0/#fixed> and/or the
ChangeLog file).
- Improved MPFR manual.
- Configure tests: replaced the test of the link with GMP, in order to
avoid the use of a function without a prototype (Autoconf issue), as
this is obsolescent in ISO C. The new test should be more robust.
Fixed bugs, with patches:
A test of the thousands separator in tsprintf.c is based on the output from the GNU C Library up to 2.36, which is incorrect. The output has changed in 2.37 (partly fixed), so that tsprintf fails with glibc 2.37. The tsprintf-thousands patch modifies the test to conform to POSIX and also avoid the buggy case in 2.36 and below. However, this new test, which was expected to succeed, triggers a serious bug in 2.37 (bug 30068 / CVE-2023-25139). We did not modify the test again since this bug affects MPFR's mpfr_sprintf function, with a possible buffer overflow in particular cases. This bug has been fixed in the 2.37 branch. In short, this patch is useful (and needed) for a fixed glibc 2.37 and some other libraries, depending on the current locales.
Corresponding changesets in the 4.2 branch: 4f03d40b5, 78ff7526d, e66bb7121.
The mpfr_ui_pow_ui function has infinite loop in case of overflow. This can affect mpfr_log10, which uses this function (this is how this bug was found). This bug is fixed by the ui_pow_ui-overflow patch (with testcases).
Corresponding changeset in the 4.2 branch: 0216f40ed.
The tfprintf and tprintf tests may fail in locales where decimal_point has several bytes, such as ps_AF. This is fixed by the multibyte-decimal_point patch, which makes the tests aware of the length of decimal_point.
Corresponding changeset in the 4.2 branch: 0383bea85.
In particular cases that are very hard to round, mpfr_rec_sqrt may yield a stack overflow due to many small allocations in the stack, based on alloca(). This is due to the fact that the working precision is increased each step (Ziv loop) by 32 or 64 bits only, until the approximate result can be rounded (thus we have an arithmetic progression here, while a geometric progression is used for the other functions), and that at each iteration, the previous allocations in the stack cannot be freed. Individual allocations in the stack are limited to 16384 bytes, so that the issue can occur only when there are many iterations in working precisions that are not too large, which is possible with an arithmetic progression. This bug is fixed by the rec_sqrt-zivloop patch, which changes the Ziv loop to use the standard MPFR_ZIV_* macros; the patch also provides a testcase obtained by a function that constructs a hard-to-round case involving large enough precisions (this function is commonly used in the MPFR testsuite, but not with so large precisions). This bug was originally reported by Fredrik Johansson.
Corresponding changeset in the 4.2 branch: 934dd8842.
The mpfr_reldiff function, which computes |b−c|/b, is buggy on special values, e.g. on the following (b,c) values: (+Inf,+Inf) gives ±0 instead of NaN (like NaN/Inf); (+0,+0) gives 1 instead of NaN (like 0/0); (+0,1) gives 1 instead of Inf (like 1/0). Moreover, the sign of 0 for (+Inf,+Inf) or (−Inf,−Inf) is not set, i.e. it is just the sign of the destination before the call; as a consequence, results are not even consistent. These bugs are fixed by the reldiff patch.
Corresponding changeset in the 4.2 branch: 81e4d4427.
The reuse tests are incomplete: the sign of a result zero is not checked, so that it can miss bugs (one of the mpfr_reldiff bugs mentioned above, in particular). The tests-reuse patch adds a check of the sign of zero and contains other minor improvements.
Corresponding changeset in the 4.2 branch: e6d47b8f5.
The general code for the power function (mpfr_pow_general internal function) has two bugs in particular cases: the first one is an incorrect computation of the error bound when there has been an intermediate underflow or overflow (in such a case, the computation is performed again with a rescaling, thus with an additional error term, but there is a bug in the computation of this term), so that the result may be rounded incorrectly (in particular, a spurious overflow is possible); the second one occurs in a corner case (destination precision 1, rounding to nearest, and where the rounded result assuming an unbounded exponent range would be 2emin−2 and the exact result is larger than this value), with the only consequence being a missing underflow exception (the underflow flag is not set). These two bugs are fixed by the pow_general patch, which also provides testcases.
Note: The second bug was introduced by commit 936df8ef6 in MPFR 4.1.0 (the code simplification was incorrect, and there were no associated tests in the testsuite).
Corresponding changesets in the 4.2 branch: 85bc7331c, 5fa407a6c, 9a16c173e.
The mpfr_compound_si function can take a huge amount of memory and time in some cases (when the argument x is a large even integer and xn is represented exactly in the target precision) and does not correctly detect overflows and underflows. This is fixed by the compound patch, which also provides various tests.
Corresponding changesets in the 4.2 branch: 7635c4a35, 74d86a61f, 952fb0f5c, a4894f68d, 7bb748775, f5cb40571, d87459969.
MPFR can crash when a formatted output function is called with %.2147483648Rg in the format string. For instance: mpfr_snprintf (NULL, 0, "%.2147483648Rg\n", x);. This is fixed by the printf_large_prec_for_g patch, which also provides testcases.
Corresponding changesets in the 4.2 branch: 686f82776, 769ad91a6.
GCC 12 emits a spurious "may be used uninitialized" warning on tests/tfpif.c with -O1, and GCC 13 has the same issue also with -O2 (GCC bug 106155). This can make some test scripts fail for the developers. The gcc-pr106155-workaround patch provides a workaround for this bug in GCC.
Corresponding changeset in the 4.2 branch: c0031f1af.
The mpfr_inp_str function does not handle the '\0' character correctly when it is not a whitespace character (which is almost always the case in practice, or really always the case). For instance, if the word is the sequence { '1', '\0', '2' }, the string "1" is passed to mpfr_set_str because '\0' is regarded as a terminating null character, and one gets a valid number (1) while '\0' in a word is necessarily invalid. This is fixed by the inp_str-nullchar patch. The testcase in the repository cannot be provided in the patch because of the null character in one of the files.
Corresponding changeset in the 4.2 branch: 6a68387b2.
When '\0' is a whitespace character, i.e. when isspace(0) is true in the current locale (as allowed by ISO C for non-"C" locales), the mpfr_strtofr function regards a '\0' in the leading whitespace sequence as a whitespace. This is incorrect, since from the definition of a string, the first '\0' is the terminating null character (before the notion of whitespace is involved). In such locales, this is a vulnerability, because characters after the terminating null character are read to determine the result; however, such locales are rare or nonexistent (Mutt's lib.h suggests that some systems have such locales, but this was in 1998). This is fixed by the strtofr-nullchar patch.
Corresponding changeset in the 4.2 branch: 964fbaa31