bug in gmp_fprintf?
Torbjörn Granlund
tg at gmplib.org
Sun Nov 29 19:57:17 UTC 2015
Our printf/scanf code is sloppily typed, and fixing that is more than a
few hours of work. Changing sizes to size_t will not work in many cases
since the code relies on signedness. I supppose ptrdiff_t might be
useful, but for now I change things to simply use 'long'.
The code needs a deeper cleanup. At a minimum, the variable should be
more clearly named, and then used for its intended purpose. And they
need to be carefully typed.
Plain stadio printf defines "precision" as an int; this might inadequate
for GMP. Not sure how it works now or how we should actually handle it.
Please try the following patch. I have only fixed things that caused
problems triggered by your test case, and things dependent on the
variables thus type changed.
If you could check the behaviour of rationals (huge numerator, huge
denominator, huge both) and huge-precision floats, that would be
helpful.
diff -Nrc2 gmp-main.bb072477386f/gmp-impl.h gmp-main/gmp-impl.h
*** gmp-main.bb072477386f/gmp-impl.h Sun Nov 29 20:37:24 2015
--- gmp-main/gmp-impl.h Sun Nov 29 20:37:25 2015
***************
*** 4408,4417 ****
char fill; /* character */
int justify; /* choices above */
! int prec; /* prec field, or -1 for all digits */
int showbase; /* choices above */
int showpoint; /* if radix point always shown */
int showtrailing; /* if trailing zeros wanted */
char sign; /* '+', ' ', or '\0' */
! int width; /* width field */
};
--- 4408,4417 ----
char fill; /* character */
int justify; /* choices above */
! long prec; /* prec field, or -1 for all digits */
int showbase; /* choices above */
int showpoint; /* if radix point always shown */
int showtrailing; /* if trailing zeros wanted */
char sign; /* '+', ' ', or '\0' */
! long width; /* width field */
};
diff -Nrc2 gmp-main.bb072477386f/printf/doprnt.c gmp-main/printf/doprnt.c
*** gmp-main.bb072477386f/printf/doprnt.c Sun Nov 29 20:37:24 2015
--- gmp-main/printf/doprnt.c Sun Nov 29 20:37:25 2015
***************
*** 164,168 ****
char *fmt, *alloc_fmt, *last_fmt, *this_fmt, *gmp_str;
int retval = 0;
! int type, fchar, *value, seen_precision;
struct doprnt_params_t param;
--- 164,169 ----
char *fmt, *alloc_fmt, *last_fmt, *this_fmt, *gmp_str;
int retval = 0;
! int type, fchar, seen_precision;
! long *value;
struct doprnt_params_t param;
***************
*** 588,592 ****
/* process all digits to form a value */
{
! int n = 0;
do {
n = n * 10 + (fchar-'0');
--- 589,593 ----
/* process all digits to form a value */
{
! long n = 0;
do {
n = n * 10 + (fchar-'0');
diff -Nrc2 gmp-main.bb072477386f/printf/doprnti.c gmp-main/printf/doprnti.c
*** gmp-main.bb072477386f/printf/doprnti.c Sun Nov 29 20:37:24 2015
--- gmp-main/printf/doprnti.c Sun Nov 29 20:37:25 2015
***************
*** 5,9 ****
FUTURE GNU MP RELEASES.
! Copyright 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
--- 5,9 ----
FUTURE GNU MP RELEASES.
! Copyright 2001, 2015 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
***************
*** 49,53 ****
{
int retval = 0;
! int slen, justlen, showbaselen, sign, signlen, slashlen, zeros;
int justify, den_showbaselen;
const char *slash, *showbase;
--- 49,54 ----
{
int retval = 0;
! long slen, justlen, zeros, slashlen;
! int showbaselen, sign, signlen;
int justify, den_showbaselen;
const char *slash, *showbase;
diff -Nrc2 gmp-main.bb072477386f/scanf/doscan.c gmp-main/scanf/doscan.c
*** gmp-main.bb072477386f/scanf/doscan.c Sun Nov 29 20:37:24 2015
--- gmp-main/scanf/doscan.c Sun Nov 29 20:37:25 2015
***************
*** 191,195 ****
int ignore;
char type;
! int width;
};
--- 191,195 ----
int ignore;
char type;
! long width;
};
***************
*** 223,228 ****
const struct gmp_doscan_params_t *p, void *dst)
{
! int chars, c, base, first, width, seen_point, seen_digit, hexfloat;
! size_t s_upto, s_alloc, hexexp;
char *s;
int invalid = 0;
--- 223,228 ----
const struct gmp_doscan_params_t *p, void *dst)
{
! int c, base, first, seen_point, seen_digit, hexfloat;
! size_t chars, s_upto, width, s_alloc, hexexp;
char *s;
int invalid = 0;
***************
*** 239,243 ****
first = 1;
seen_point = 0;
! width = (p->width == 0 ? INT_MAX-1 : p->width);
base = p->base;
s_alloc = S_ALLOC_STEP;
--- 239,243 ----
first = 1;
seen_point = 0;
! width = (p->width == 0 ? LONG_MAX-1 : p->width);
base = p->base;
s_alloc = S_ALLOC_STEP;
***************
*** 475,482 ****
const char *fmt, *this_fmt, *end_fmt;
size_t orig_fmt_len, alloc_fmt_size, len;
- int new_fields, new_chars;
char fchar;
! int fields = 0;
! int chars = 0;
TRACE (printf ("__gmp_doscan \"%s\"\n", orig_fmt);
--- 475,481 ----
const char *fmt, *this_fmt, *end_fmt;
size_t orig_fmt_len, alloc_fmt_size, len;
char fchar;
! int new_fields, fields = 0;
! long new_chars, chars = 0;
TRACE (printf ("__gmp_doscan \"%s\"\n", orig_fmt);
--
Torbjörn
Please encrypt, key id 0xC8601622
More information about the gmp-bugs
mailing list