1 /* mpfr_vasnprintf_aux -- helper function for the formatted output functions
2    (printf functions family).
3 
4 Copyright 2007-2020 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6 
7 This file is part of the GNU MPFR Library.
8 
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17 License for more details.
18 
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23 
24 /* If the number of output characters is larger than INT_MAX, the
25    ISO C99 / C11 standards are silent, but POSIX[*] requires the
26    function to return a negative value and set errno to EOVERFLOW.
27    [*] The Open Group Base Specifications Issue 7, 2018 edition
28        IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008)
29    http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
30    This follows a defect report submitted in 2007 to austin-review-l.
31    Even in case of such a failure (just because of the limitation on int),
32    we try to support %n, %ln, %jn when possible. That's why the sizes (or
33    lengths) are expressed using mpfr_intmax_t in the code below. */
34 
35 /* Notes about limitations on some platforms:
36 
37    Due to limitations from the C standard and GMP, if size_t < unsigned int
38    (which is allowed by the C standard but unlikely to occur on any
39    platform), the behavior is undefined for output that would reach
40    SIZE_MAX = (size_t) -1 (if the result cannot be delivered, there should
41    be an assertion failure, but this could not be tested).
42 
43    The stdarg(3) Linux man page says:
44       On some systems, va_end contains a closing '}' matching a '{' in
45       va_start, so that both macros must occur in the same function,
46       and in a way that allows this.
47    However, the only requirement from ISO C is that both macros must be
48    invoked in the same function (MPFR uses va_copy instead of va_start,
49    but the requirement is the same). Here, MPFR just follows ISO C.
50 */
51 
52 /* Needed due to the tests on HAVE_STDARG and MPFR_USE_MINI_GMP */
53 #ifdef HAVE_CONFIG_H
54 # include "config.h"
55 #endif
56 
57 /* The mpfr_printf-like functions are defined only if <stdarg.h> exists.
58    Since they use mpf_t, they cannot be defined with mini-gmp. */
59 #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
60 
61 #include <stdarg.h>
62 
63 #ifndef HAVE_VA_COPY
64 # ifdef HAVE___VA_COPY
65 #  define va_copy(dst,src) __va_copy(dst, src)
66 # else
67 /* autoconf manual advocates this fallback.
68    This is also the solution chosen by gmp */
69 #  define va_copy(dst,src) \
70   do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0)
71 # endif /* HAVE___VA_COPY */
72 #endif /* HAVE_VA_COPY */
73 
74 #ifdef HAVE_WCHAR_H
75 #include <wchar.h>
76 #endif
77 
78 #if defined (__cplusplus)
79 #include <cstddef>
80 #else
81 #include <stddef.h>             /* for ptrdiff_t */
82 #endif
83 
84 #include <errno.h>
85 
86 #define MPFR_NEED_LONGLONG_H
87 #define MPFR_NEED_INTMAX_H
88 #include "mpfr-impl.h"
89 
90 /* Define a length modifier corresponding to mpfr_prec_t.
91    We use literal string instead of literal character so as to permit future
92    extension to long long int ("ll"). */
93 #if   _MPFR_PREC_FORMAT == 1
94 #define MPFR_PREC_FORMAT_TYPE "h"
95 #define MPFR_PREC_FORMAT_SIZE 1
96 #elif _MPFR_PREC_FORMAT == 2
97 #define MPFR_PREC_FORMAT_TYPE ""
98 #define MPFR_PREC_FORMAT_SIZE 0
99 #elif _MPFR_PREC_FORMAT == 3
100 #define MPFR_PREC_FORMAT_TYPE "l"
101 #define MPFR_PREC_FORMAT_SIZE 1
102 #else
103 #error "mpfr_prec_t size not supported"
104 #endif
105 
106 /* Output for special values defined in the C99 standard */
107 #define MPFR_NAN_STRING_LC "nan"
108 #define MPFR_NAN_STRING_UC "NAN"
109 #define MPFR_NAN_STRING_LENGTH 3
110 #define MPFR_INF_STRING_LC "inf"
111 #define MPFR_INF_STRING_UC "INF"
112 #define MPFR_INF_STRING_LENGTH 3
113 
114 #define DEFAULT_DECIMAL_PREC 6
115 
116 /* The implicit \0 is useless, but we do not write num_to_text[16]
117    otherwise g++ complains. */
118 static const char num_to_text[] = "0123456789abcdef";
119 
120 /* some macro and functions for parsing format string */
121 
122 /* Read an integer var of type mpfr_intmax_t. In case of overflow, set
123    overflow to 1.
124    Note: Since mpfr_intmax_t = int is theoretically possible, all values
125    of var are potentially valid values (via '*'). Hence the need of an
126    overflow flag instead of a special value that would indicate overflow.
127    Saturating would not be OK either as the maximum value could be
128    meaningful with %jn and/or in the case mpfr_intmax_t = int, for
129    MPFR_PREC_ARG.
130 */
131 #define READ_INT(ap, format, var)                                       \
132   do {                                                                  \
133     MPFR_ASSERTD ((var) == 0);                                          \
134     if (*(format) == '*')                                               \
135       {                                                                 \
136         (var) = va_arg ((ap), int);                                     \
137         ++(format);                                                     \
138       }                                                                 \
139     else                                                                \
140       for ( ; *(format) >= '0' && *(format) <= '9' ; ++(format))        \
141         if (!(overflow))                                                \
142           {                                                             \
143             if ((var) > MPFR_INTMAX_MAX / 10)                           \
144               (overflow) = 1;                                           \
145             else                                                        \
146               {                                                         \
147                 int _i;                                                 \
148                 (var) *= 10;                                            \
149                 _i = *(format) - '0';                                   \
150                 MPFR_ASSERTN (_i >= 0 && _i <= 9);                      \
151                 if ((var) > MPFR_INTMAX_MAX - _i)                       \
152                   (overflow) = 1;                                       \
153                 else                                                    \
154                   (var) += _i;                                          \
155               }                                                         \
156           }                                                             \
157   } while (0)
158 
159 /* arg_t contains all the types described by the 'type' field of the
160    format string */
161 enum arg_t
162   {
163     NONE,
164     CHAR_ARG,
165     SHORT_ARG,
166     LONG_ARG,
167     LONG_LONG_ARG,
168     INTMAX_ARG,
169     SIZE_ARG,
170     PTRDIFF_ARG,
171     LONG_DOUBLE_ARG,
172     MPF_ARG,
173     MPQ_ARG,
174     MP_LIMB_ARG,
175     MP_LIMB_ARRAY_ARG,
176     MPZ_ARG,
177     MPFR_PREC_ARG,
178     MPFR_ARG,
179     UNSUPPORTED
180   };
181 
182 /* Each conversion specification of the format string will be translated in a
183    printf_spec structure by the parser.
184    This structure is adapted from the GNU libc one. */
185 struct printf_spec
186 {
187   unsigned int alt:1;           /* # flag */
188   unsigned int space:1;         /* Space flag */
189   unsigned int left:1;          /* - flag */
190   unsigned int showsign:1;      /* + flag */
191   unsigned int group:1;         /* ' flag */
192 
193   mpfr_intmax_t width;          /* Width */
194   mpfr_intmax_t prec;           /* Precision, or negative if omitted */
195   size_t size;                  /* Wanted size (0 iff snprintf with size=0) */
196 
197   enum arg_t arg_type;          /* Type of argument */
198   mpfr_rnd_t rnd_mode;          /* Rounding mode */
199   char spec;                    /* Conversion specifier */
200 
201   char pad;                     /* Padding character */
202 };
203 
204 static void
specinfo_init(struct printf_spec * specinfo)205 specinfo_init (struct printf_spec *specinfo)
206 {
207   specinfo->alt = 0;
208   specinfo->space = 0;
209   specinfo->left = 0;
210   specinfo->showsign = 0;
211   specinfo->group = 0;
212   specinfo->width = 0;
213   specinfo->prec = 0;
214   specinfo->size = 1;
215   specinfo->arg_type = NONE;
216   specinfo->rnd_mode = MPFR_RNDN;
217   specinfo->spec = '\0';
218   specinfo->pad = ' ';
219 }
220 
221 #define FLOATING_POINT_ARG_TYPE(at) \
222   ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG)
223 
224 #define INTEGER_LIKE_ARG_TYPE(at)                                       \
225   ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG       \
226    || (at) == INTMAX_ARG  || (at) == MPFR_PREC_ARG || (at) == MPZ_ARG   \
227    || (at) == MPQ_ARG || (at) == MP_LIMB_ARG || (at) == MP_LIMB_ARRAY_ARG \
228    || (at) == CHAR_ARG || (at) == SIZE_ARG || (at) == PTRDIFF_ARG)
229 
230 static int
specinfo_is_valid(struct printf_spec spec)231 specinfo_is_valid (struct printf_spec spec)
232 {
233   switch (spec.spec)
234     {
235     case 'n':
236       return -1;
237 
238     case 'a':    case 'A':
239     case 'e':    case 'E':
240     case 'f':    case 'F':
241     case 'g':    case 'G':
242       return (spec.arg_type == NONE
243               || FLOATING_POINT_ARG_TYPE (spec.arg_type));
244 
245     case 'b':
246       return spec.arg_type == MPFR_ARG;
247 
248     case 'd':    case 'i':
249     case 'u':    case 'o':
250     case 'x':    case 'X':
251       return (spec.arg_type == NONE
252               || INTEGER_LIKE_ARG_TYPE (spec.arg_type));
253 
254     case 'c':
255     case 's':
256       return (spec.arg_type == NONE || spec.arg_type == LONG_ARG);
257 
258     case 'p':
259       return spec.arg_type == NONE;
260 
261     default:
262       return 0;
263     }
264 }
265 
266 /* Note: additional flags should be added to the MPFR_PREC_ARG code
267    for gmp_asprintf (when supported). */
268 MPFR_RETURNS_NONNULL static const char *
parse_flags(const char * format,struct printf_spec * specinfo)269 parse_flags (const char *format, struct printf_spec *specinfo)
270 {
271   while (*format)
272     {
273       switch (*format)
274         {
275         case '0':
276           specinfo->pad = '0';
277           ++format;
278           break;
279         case '#':
280           specinfo->alt = 1;
281           ++format;
282           break;
283         case '+':
284           specinfo->showsign = 1;
285           ++format;
286           break;
287         case ' ':
288           specinfo->space = 1;
289           ++format;
290           break;
291         case '-':
292           specinfo->left = 1;
293           ++format;
294           break;
295         case '\'':
296           /* Single UNIX Specification for thousand separator */
297           specinfo->group = 1;
298           ++format;
299           break;
300         default:
301           return format;
302         }
303     }
304   return format;
305 }
306 
307 MPFR_RETURNS_NONNULL static const char *
parse_arg_type(const char * format,struct printf_spec * specinfo)308 parse_arg_type (const char *format, struct printf_spec *specinfo)
309 {
310   switch (*format)
311     {
312     case '\0':
313       break;
314     case 'h':
315       if (*++format == 'h')
316         {
317           ++format;
318           specinfo->arg_type = CHAR_ARG;
319         }
320       else
321         specinfo->arg_type = SHORT_ARG;
322       break;
323     case 'l':
324       if (*++format == 'l')
325         {
326           ++format;
327 #if defined (HAVE_LONG_LONG)
328           specinfo->arg_type = LONG_LONG_ARG;
329 #else
330           specinfo->arg_type = UNSUPPORTED;
331 #endif
332           break;
333         }
334       else
335         {
336           specinfo->arg_type = LONG_ARG;
337           break;
338         }
339     case 'j':
340       ++format;
341 #if defined(_MPFR_H_HAVE_INTMAX_T)
342       specinfo->arg_type = INTMAX_ARG;
343 #else
344       specinfo->arg_type = UNSUPPORTED;
345 #endif
346       break;
347     case 'z':
348       ++format;
349       specinfo->arg_type = SIZE_ARG;
350       break;
351     case 't':
352       ++format;
353       specinfo->arg_type = PTRDIFF_ARG;
354       break;
355     case 'L':
356       ++format;
357       specinfo->arg_type = LONG_DOUBLE_ARG;
358       break;
359     case 'F':
360       ++format;
361       specinfo->arg_type = MPF_ARG;
362       break;
363     case 'Q':
364       ++format;
365       specinfo->arg_type = MPQ_ARG;
366       break;
367     case 'M':
368       ++format;
369       /* The 'M' specifier was added in gmp 4.2.0 */
370       specinfo->arg_type = MP_LIMB_ARG;
371       break;
372     case 'N':
373       ++format;
374       specinfo->arg_type = MP_LIMB_ARRAY_ARG;
375       break;
376     case 'Z':
377       ++format;
378       specinfo->arg_type = MPZ_ARG;
379       break;
380 
381       /* mpfr specific specifiers */
382     case 'P':
383       ++format;
384       specinfo->arg_type = MPFR_PREC_ARG;
385       break;
386     case 'R':
387       ++format;
388       specinfo->arg_type = MPFR_ARG;
389     }
390   return format;
391 }
392 
393 
394 /* some macros and functions filling the buffer */
395 
396 /* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */
397 
398 /* With a C++ compiler wchar_t and enumeration in va_list are converted to
399    integer type : int, unsigned int, long or unsigned long (unfortunately,
400    this is implementation dependent).
401    We follow gmp which assumes in print/doprnt.c that wchar_t is converted
402    to int (because wchar_t <= int).
403    For wint_t, we assume that the case WINT_MAX < INT_MAX yields an
404    integer promotion. */
405 #ifdef HAVE_WCHAR_H
406 #if defined(WINT_MAX) && WINT_MAX < INT_MAX
407 typedef int    mpfr_va_wint;  /* integer promotion */
408 #else
409 typedef wint_t mpfr_va_wint;
410 #endif
411 #define CASE_LONG_ARG(specinfo, ap)                                     \
412   case LONG_ARG:                                                        \
413   if ((specinfo).spec == 'd' || (specinfo).spec == 'i'                  \
414       || (specinfo).spec == 'o' || (specinfo).spec == 'u'               \
415       || (specinfo).spec == 'x' || (specinfo).spec == 'X')              \
416     (void) va_arg ((ap), long);                                         \
417   else if ((specinfo).spec == 'c')                                      \
418     (void) va_arg ((ap), mpfr_va_wint);                                 \
419   else if ((specinfo).spec == 's')                                      \
420     (void) va_arg ((ap), int); /* we assume integer promotion */        \
421   break;
422 #else
423 #define CASE_LONG_ARG(specinfo, ap)             \
424   case LONG_ARG:                                \
425   (void) va_arg ((ap), long);                   \
426   break;
427 #endif
428 
429 #if defined(_MPFR_H_HAVE_INTMAX_T)
430 #define CASE_INTMAX_ARG(specinfo, ap)           \
431   case INTMAX_ARG:                              \
432   (void) va_arg ((ap), intmax_t);               \
433   break;
434 #else
435 #define CASE_INTMAX_ARG(specinfo, ap)
436 #endif
437 
438 #ifdef HAVE_LONG_LONG
439 #define CASE_LONG_LONG_ARG(specinfo, ap)        \
440   case LONG_LONG_ARG:                           \
441   (void) va_arg ((ap), long long);              \
442   break;
443 #else
444 #define CASE_LONG_LONG_ARG(specinfo, ap)
445 #endif
446 
447 /* Note: (specinfo).width may be incorrect in case of overflow,
448    but it is not used by CONSUME_VA_ARG. */
449 #define CONSUME_VA_ARG(specinfo, ap)            \
450   do {                                          \
451     switch ((specinfo).arg_type)                \
452       {                                         \
453       case CHAR_ARG:                            \
454       case SHORT_ARG:                           \
455         (void) va_arg ((ap), int);              \
456         break;                                  \
457       CASE_LONG_ARG (specinfo, ap)              \
458       CASE_LONG_LONG_ARG (specinfo, ap)         \
459       CASE_INTMAX_ARG (specinfo, ap)            \
460       case SIZE_ARG:                            \
461         (void) va_arg ((ap), size_t);           \
462         break;                                  \
463       case PTRDIFF_ARG:                         \
464         (void) va_arg ((ap), ptrdiff_t);        \
465         break;                                  \
466       case LONG_DOUBLE_ARG:                     \
467         (void) va_arg ((ap), long double);      \
468         break;                                  \
469       case MPF_ARG:                             \
470         (void) va_arg ((ap), mpf_srcptr);       \
471         break;                                  \
472       case MPQ_ARG:                             \
473         (void) va_arg ((ap), mpq_srcptr);       \
474         break;                                  \
475       case MP_LIMB_ARG:                         \
476         (void) va_arg ((ap), mp_limb_t);        \
477         break;                                  \
478       case MP_LIMB_ARRAY_ARG:                   \
479         (void) va_arg ((ap), mpfr_limb_ptr);    \
480         (void) va_arg ((ap), mp_size_t);        \
481         break;                                  \
482       case MPZ_ARG:                             \
483         (void) va_arg ((ap), mpz_srcptr);       \
484         break;                                  \
485       default:                                  \
486         switch ((specinfo).spec)                \
487           {                                     \
488           case 'd':                             \
489           case 'i':                             \
490           case 'o':                             \
491           case 'u':                             \
492           case 'x':                             \
493           case 'X':                             \
494           case 'c':                             \
495             (void) va_arg ((ap), int);          \
496             break;                              \
497           case 'f':                             \
498           case 'F':                             \
499           case 'e':                             \
500           case 'E':                             \
501           case 'g':                             \
502           case 'G':                             \
503           case 'a':                             \
504           case 'A':                             \
505             (void) va_arg ((ap), double);       \
506             break;                              \
507           case 's':                             \
508             (void) va_arg ((ap), char *);       \
509             break;                              \
510           case 'p':                             \
511             (void) va_arg ((ap), void *);       \
512           }                                     \
513       }                                         \
514   } while (0)
515 
516 /* Process the format part which does not deal with mpfr types,
517    Jump to external label 'error' if gmp_asprintf return -1.
518    Note: start and end are pointers to the format string, so that
519    size_t is the best type to express the difference.
520    FIXME: If buf.size = 0 or size != 0, gmp_vsnprintf should be called
521    instead of gmp_vasprintf, outputting data directly to the buffer
522    when applicable.
523 */
524 #define FLUSH(flag, start, end, ap, buf_ptr)                            \
525   do {                                                                  \
526     const size_t n = (end) - (start);                                   \
527     if ((flag))                                                         \
528       /* previous specifiers are understood by gmp_printf */            \
529       {                                                                 \
530         MPFR_TMP_DECL (marker);                                         \
531         char *fmt_copy, *s;                                             \
532         int length;                                                     \
533                                                                         \
534         MPFR_TMP_MARK (marker);                                         \
535         fmt_copy = (char *) MPFR_TMP_ALLOC (n + 1);                     \
536         strncpy (fmt_copy, (start), n);                                 \
537         fmt_copy[n] = '\0';                                             \
538         length = gmp_vasprintf (&s, fmt_copy, (ap));                    \
539         if (length < 0)                                                 \
540           {                                                             \
541             MPFR_TMP_FREE (marker);                                     \
542             goto error;                                                 \
543           }                                                             \
544         buffer_cat ((buf_ptr), s, length);                              \
545         mpfr_free_str (s);                                              \
546         (flag) = 0;                                                     \
547         MPFR_TMP_FREE (marker);                                         \
548       }                                                                 \
549     else if ((start) != (end))                                          \
550       /* no conversion specification, just simple characters */         \
551       buffer_cat ((buf_ptr), (start), n);                               \
552   } while (0)
553 
554 /* Note: in case some form of %n is used in the format string,
555    we may need the maximum signed integer type for len. */
556 struct string_buffer
557 {
558   char *start;                  /* beginning of the buffer */
559   char *curr;                   /* null terminating character */
560   size_t size;                  /* buffer capacity */
561   mpfr_intmax_t len;            /* string length or -1 if overflow */
562 };
563 
564 static void
buffer_init(struct string_buffer * b,size_t s)565 buffer_init (struct string_buffer *b, size_t s)
566 {
567   if (s != 0)
568     {
569       b->start = (char *) mpfr_allocate_func (s);
570       b->start[0] = '\0';
571       b->curr = b->start;
572     }
573   b->size = s;
574   b->len = 0;
575 }
576 
577 /* Increase the len field of the buffer. Return non-zero iff overflow. */
578 static int
buffer_incr_len(struct string_buffer * b,mpfr_intmax_t len)579 buffer_incr_len (struct string_buffer *b, mpfr_intmax_t len)
580 {
581   if (b->len == -1)
582     return 1;
583   else
584     {
585       /* We need to take mpfr_uintmax_t as the type must be as large
586          as both size_t (which is unsigned) and mpfr_intmax_t (which
587          is used for the 'n' format specifier). */
588       mpfr_uintmax_t newlen = (mpfr_uintmax_t) b->len + len;
589 
590       /* mpfr_uintmax_t is unsigned, thus the above is valid, but one
591          has newlen < len in case of overflow. */
592 
593       if (MPFR_UNLIKELY (newlen < len || newlen > MPFR_INTMAX_MAX))
594         {
595           MPFR_LOG_MSG (("Overflow\n", 0));
596           b->len = -1;
597           return 1;
598         }
599       else
600         {
601           b->len = newlen;
602           return 0;
603         }
604     }
605 }
606 
607 /* Increase buffer size by a number of character being the least multiple of
608    4096 greater than len+1. */
609 static void
buffer_widen(struct string_buffer * b,size_t len)610 buffer_widen (struct string_buffer *b, size_t len)
611 {
612   const size_t pos = b->curr - b->start;
613   const size_t n = 0x1000 + (len & ~((size_t) 0xfff));
614 
615   /* There are currently limitations here. We would need to switch to
616      the null-size behavior once there is an overflow in the buffer. */
617 
618   MPFR_ASSERTN (n >= 0x1000 && n >= len);
619 
620   MPFR_ASSERTD (*b->curr == '\0');
621   MPFR_ASSERTD (pos < b->size);
622 
623   MPFR_ASSERTN (b->size < ((size_t) -1) - n);
624 
625   b->start = (char *) mpfr_reallocate_func (b->start, b->size, b->size + n);
626   b->size += n;
627   b->curr = b->start + pos;
628 
629   MPFR_ASSERTD (pos < b->size);
630   MPFR_ASSERTD (*b->curr == '\0');
631 }
632 
633 /* Concatenate the first len characters of the string s to the buffer b and
634    expand it if needed. Return non-zero if overflow. */
635 static int
buffer_cat(struct string_buffer * b,const char * s,size_t len)636 buffer_cat (struct string_buffer *b, const char *s, size_t len)
637 {
638   /* If len == 0, which is possible when outputting an integer 0
639      (either a native one or mpfr_prec_t) with precision field = 0,
640      do nothing. This test is not necessary since the code below is
641      valid for len == 0, but this is safer, just in case. */
642   if (len == 0)
643     return 0;
644 
645   MPFR_ASSERTD (len <= strlen (s));
646 
647   if (buffer_incr_len (b, len))
648     return 1;
649 
650   if (b->size != 0)
651     {
652       MPFR_ASSERTD (*b->curr == '\0');
653       MPFR_ASSERTN (b->size < ((size_t) -1) - len);
654       if (MPFR_UNLIKELY (b->curr + len >= b->start + b->size))
655         buffer_widen (b, len);
656 
657       /* strncat is similar to strncpy here, except that strncat ensures
658          that the buffer will be null-terminated. */
659       strncat (b->curr, s, len);
660       b->curr += len;
661 
662       MPFR_ASSERTD (b->curr < b->start + b->size);
663       MPFR_ASSERTD (*b->curr == '\0');
664     }
665 
666   return 0;
667 }
668 
669 /* Add n characters c to the end of buffer b. Return non-zero if overflow. */
670 static int
buffer_pad(struct string_buffer * b,const char c,const mpfr_intmax_t n)671 buffer_pad (struct string_buffer *b, const char c, const mpfr_intmax_t n)
672 {
673   MPFR_ASSERTD (n > 0);
674 
675   if (buffer_incr_len (b, n))
676     return 1;
677 
678   if (b->size != 0)
679     {
680       MPFR_ASSERTD (*b->curr == '\0');
681 
682       if (n > (size_t) -1 || b->size > ((size_t) -1) - n)
683         {
684           /* Reallocation will not be possible. Regard this as an overflow. */
685           b->len = -1;
686           return 1;
687         }
688 
689       if (MPFR_UNLIKELY (b->curr + n >= b->start + b->size))
690         buffer_widen (b, n);
691 
692       if (n == 1)
693         *b->curr = c;
694       else
695         memset (b->curr, c, n);
696       b->curr += n;
697       *b->curr = '\0';
698 
699       MPFR_ASSERTD (b->curr < b->start + b->size);
700     }
701 
702   return 0;
703 }
704 
705 /* Form a string by concatenating the first len characters of str to tz
706    zero(s), insert into one character c each 3 characters starting from end
707    to beginning and concatenate the result to the buffer b.
708    Assume c is not null (\0). Return non-zero if overflow. */
709 static int
buffer_sandwich(struct string_buffer * b,char * str,size_t len,const size_t tz,const char c)710 buffer_sandwich (struct string_buffer *b, char *str, size_t len,
711                  const size_t tz, const char c)
712 {
713   const size_t step = 3;
714   size_t size, q, r, fullsize, i;
715   char *oldcurr;
716 
717   MPFR_ASSERTD (b->size != 0);
718   MPFR_ASSERTD (tz == 0 || tz == 1);
719 
720   if (len <= ULONG_MAX)
721     MPFR_LOG_MSG (("len=%lu\n", (unsigned long) len));
722   if (tz <= ULONG_MAX)
723     MPFR_LOG_MSG (("tz=%lu\n", (unsigned long) tz));
724 
725   MPFR_ASSERTD (len <= strlen (str));
726   MPFR_ASSERTD (c != '\0');
727 
728   /* check that len + tz does not overflow */
729   if (len > (size_t) -1 - tz)
730     return 1;
731 
732   size = len + tz;              /* number of digits */
733   MPFR_ASSERTD (size > 0);
734 
735   q = (size - 1) / step;        /* number of separators C */
736   r = ((size - 1) % step) + 1;  /* number of digits in the leftmost block */
737   MPFR_ASSERTD (r >= 1 && r <= step);
738 
739   /* check that size + q does not overflow */
740   if (size > (size_t) -1 - q)
741     return 1;
742 
743   fullsize = size + q;          /* number of digits and separators */
744 
745   if (buffer_incr_len (b, fullsize))
746     return 1;
747 
748   MPFR_ASSERTD (*b->curr == '\0');
749   MPFR_ASSERTN (b->size < ((size_t) -1) - fullsize);
750   if (MPFR_UNLIKELY (b->curr + fullsize >= b->start + b->size))
751     buffer_widen (b, fullsize);
752 
753   MPFR_DBGRES (oldcurr = b->curr);
754 
755   /* first r significant digits (leftmost block) */
756   if (r <= len)
757     {
758       memcpy (b->curr, str, r);
759       str += r;
760       len -= r;
761     }
762   else
763     {
764       MPFR_ASSERTD (r > len);
765       MPFR_ASSERTD (len < step);    /* as a consequence */
766       MPFR_ASSERTD (size <= step);  /* as a consequence */
767       MPFR_ASSERTD (q == 0);        /* as a consequence */
768       MPFR_ASSERTD (r == size);     /* as a consequence */
769       MPFR_ASSERTD (tz == 1);       /* as a consequence */
770       memcpy (b->curr, str, len);
771       *(b->curr + len) = '0';  /* trailing zero */
772       /* We do not need to set len to 0 since it will not be read again
773          (q = 0, so that the loop below will have 0 iterations). */
774     }
775   b->curr += r;
776 
777   for (i = 0; i < q; ++i)
778     {
779       *b->curr++ = c;
780       if (MPFR_LIKELY (len >= step))
781         {
782           memcpy (b->curr, str, step);
783           len -= step;
784           str += step;
785         }
786       else
787         {
788           /* last digits */
789           MPFR_ASSERTD (i == q - 1 && step - len == 1);
790           memcpy (b->curr, str, len);
791           *(b->curr + len) = '0';  /* trailing zero */
792         }
793       b->curr += step;
794     }
795 
796   MPFR_ASSERTD (b->curr - oldcurr == fullsize);
797 
798   *b->curr = '\0';
799 
800   MPFR_ASSERTD (b->curr < b->start + b->size);
801 
802   return 0;
803 }
804 
805 /* Helper struct and functions for temporary strings management */
806 /* struct for easy string clearing */
807 struct string_list
808 {
809   char *string;
810   struct string_list *next; /* NULL in last node */
811 };
812 
813 /* initialization */
814 static void
init_string_list(struct string_list * sl)815 init_string_list (struct string_list *sl)
816 {
817   sl->string = NULL;
818   sl->next = NULL;
819 }
820 
821 /* clear all strings in the list */
822 static void
clear_string_list(struct string_list * sl)823 clear_string_list (struct string_list *sl)
824 {
825   struct string_list *n;
826 
827   while (sl)
828     {
829       if (sl->string)
830         mpfr_free_str (sl->string);
831       n = sl->next;
832       mpfr_free_func (sl, sizeof(struct string_list));
833       sl = n;
834     }
835 }
836 
837 /* add a string in the list */
838 static char *
register_string(struct string_list * sl,char * new_string)839 register_string (struct string_list *sl, char *new_string)
840 {
841   /* look for the last node */
842   while (sl->next)
843     sl = sl->next;
844 
845   sl->next = (struct string_list *)
846     mpfr_allocate_func (sizeof (struct string_list));
847 
848   sl = sl->next;
849   sl->next = NULL;
850   return sl->string = new_string;
851 }
852 
853 /* padding type: where are the padding characters */
854 enum pad_t
855   {
856     LEFT,          /* spaces in left hand side for right justification */
857     LEADING_ZEROS, /* padding with '0' characters in integral part */
858     RIGHT          /* spaces in right hand side for left justification */
859   };
860 
861 /* number_parts details how much characters are needed in each part of a float
862    print.  */
863 struct number_parts
864 {
865   enum pad_t pad_type;    /* Padding type */
866   mpfr_intmax_t pad_size; /* Number of padding characters */
867 
868   char sign;              /* Sign character */
869 
870   char *prefix_ptr;       /* Pointer to prefix part */
871   size_t prefix_size;     /* Number of characters in *prefix_ptr */
872 
873   char thousands_sep;     /* Thousands separator (only with style 'f') */
874 
875   char *ip_ptr;           /* Pointer to integral part characters*/
876   size_t ip_size;         /* Number of digits in *ip_ptr */
877   int ip_trailing_digits; /* Number of additional digits in integral part
878                              (if spec.size != 0, this can only be a zero) */
879 
880   char point;             /* Decimal point character */
881 
882   mpfr_intmax_t fp_leading_zeros;  /* Number of additional leading zeros in
883                                       fractional part */
884   char *fp_ptr;           /* Pointer to fractional part characters */
885   size_t fp_size;         /* Number of digits in *fp_ptr */
886   mpfr_intmax_t fp_trailing_zeros;  /* Number of additional trailing zeros in
887                                        fractional part */
888 
889   char *exp_ptr;          /* Pointer to exponent part */
890   size_t exp_size;        /* Number of characters in *exp_ptr */
891 
892   struct string_list *sl; /* List of string buffers in use: we need such a
893                              mechanism because fp_ptr may point into the same
894                              string as ip_ptr */
895 };
896 
897 /* For a real non zero number x, what is the base exponent f when rounding x
898    with rounding mode r to r(x) = m*b^f, where m is a digit and 1 <= m < b ?
899    Return non zero value if x is rounded up to b^f, return zero otherwise */
900 static int
next_base_power_p(mpfr_srcptr x,int base,mpfr_rnd_t rnd)901 next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd)
902 {
903   mpfr_prec_t nbits;
904   mp_limb_t pm;
905   mp_limb_t xm;
906 
907   MPFR_ASSERTD (MPFR_IS_PURE_FP (x));
908   MPFR_ASSERTD (base == 2 || base == 16);
909 
910   /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output
911      representation. */
912   nbits = base == 2 ? 1 : 4;
913 
914   if (rnd == MPFR_RNDZ
915       || (rnd == MPFR_RNDD && MPFR_IS_POS (x))
916       || (rnd == MPFR_RNDU && MPFR_IS_NEG (x))
917       || MPFR_PREC (x) <= nbits)
918     /* no rounding when printing x with 1 digit */
919     return 0;
920 
921   xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1];
922   pm = MPFR_LIMB_MASK (GMP_NUMB_BITS - nbits);
923   if ((xm & ~pm) ^ ~pm)
924     /* do no round up if some of the nbits first bits are 0s. */
925     return 0;
926 
927   if (rnd == MPFR_RNDN)
928     /* mask for rounding bit */
929     pm = (MPFR_LIMB_ONE << (GMP_NUMB_BITS - nbits - 1));
930 
931   /* round up if some remaining bits are 1 */
932   /* warning: the return value must be an int */
933   return xm & pm ? 1 : 0;
934 }
935 
936 /* Record information from mpfr_get_str() so as to avoid multiple
937    calls to this expensive function. */
938 struct decimal_info
939 {
940   mpfr_exp_t exp;
941   char *str;
942 };
943 
944 /* For a real non zero number x, what is the exponent f so that
945    10^f <= x < 10^(f+1). */
946 static mpfr_exp_t
floor_log10(mpfr_srcptr x)947 floor_log10 (mpfr_srcptr x)
948 {
949   mpfr_t y;
950   mpfr_exp_t exp;
951 
952   /* make sure first that y can represent a mpfr_exp_t exactly
953      and can compare with x */
954   mpfr_prec_t prec = sizeof (mpfr_exp_t) * CHAR_BIT;
955   mpfr_init2 (y, MAX (prec, MPFR_PREC (x)));
956 
957   exp = mpfr_ceil_mul (MPFR_GET_EXP (x), 10, 1) - 1;
958   mpfr_set_exp_t (y, exp, MPFR_RNDU);
959   /* The following call to mpfr_ui_pow should be fast: y is an integer
960      (not too large), so that mpfr_pow_z will be used internally. */
961   mpfr_ui_pow (y, 10, y, MPFR_RNDU);
962   if (mpfr_cmpabs (x, y) < 0)
963     exp--;
964 
965   mpfr_clear (y);
966   return exp;
967 }
968 
969 #define NDIGITS 8
970 
971 MPFR_RETURNS_NONNULL static char *
mpfr_get_str_wrapper(mpfr_exp_t * exp,int base,size_t n,mpfr_srcptr op,const struct printf_spec spec)972 mpfr_get_str_wrapper (mpfr_exp_t *exp, int base, size_t n, mpfr_srcptr op,
973                       const struct printf_spec spec)
974 {
975   size_t ndigits;
976   char *str, *s, nine;
977   int neg;
978 
979   /* Possibles bases for the *printf functions. */
980   MPFR_ASSERTD (base == 2 || base == 10 || base == 16);
981 
982   if (spec.size != 0)
983     return mpfr_get_str (NULL, exp, base, n, op, spec.rnd_mode);
984 
985   /* Special case size = 0, i.e., xxx_snprintf with size = 0: we only want
986      to compute the number of printed characters. Try to deduce it from
987      a small number of significant digits. */
988   nine = base == 2 ? '1' : base == 10 ? '9' : 'f';
989   for (ndigits = NDIGITS; ; ndigits *= 2)
990     {
991       mpfr_rnd_t rnd = MPFR_RNDZ;
992       /* when ndigits > n, we reduce it to the target size n, and then we use
993          the wanted rounding mode, to avoid errors for example when n=1 and
994          x = 9.5 with spec.rnd_mode = RNDU */
995       if (ndigits >= n)
996         {
997           ndigits = n;
998           rnd = spec.rnd_mode;
999         }
1000       str = mpfr_get_str (NULL, exp, base, ndigits, op, rnd);
1001       if (ndigits == n)
1002         break;
1003       neg = str[0] == '-';
1004       s = str + neg;
1005       while (*s == nine)
1006         s ++;
1007       if (s < str + neg + ndigits) /* we don't have ndigits 'nines' */
1008         break;
1009       mpfr_free_str (str);
1010       MPFR_ASSERTN (ndigits <= ((size_t) -1) / 2);
1011       /* to make sure that the product by 2 is representable. */
1012     }
1013   return str;
1014 }
1015 
1016 /* Determine the different parts of the string representation of the regular
1017    number P when spec.spec is 'a', 'A', or 'b'.
1018 
1019    Return -1 in case of overflow on the sizes. */
1020 static int
regular_ab(struct number_parts * np,mpfr_srcptr p,const struct printf_spec spec)1021 regular_ab (struct number_parts *np, mpfr_srcptr p,
1022             const struct printf_spec spec)
1023 {
1024   int uppercase;
1025   int base;
1026   char *str;
1027   mpfr_exp_t exp;
1028 
1029   uppercase = spec.spec == 'A';
1030 
1031   /* sign */
1032   if (MPFR_IS_NEG (p))
1033     np->sign = '-';
1034   else if (spec.showsign || spec.space)
1035     np->sign = spec.showsign ? '+' : ' ';
1036 
1037   if (spec.spec == 'a' || spec.spec == 'A')
1038     /* prefix part */
1039     {
1040       np->prefix_size = 2;
1041       str = (char *) mpfr_allocate_func (1 + np->prefix_size);
1042       str[0] = '0';
1043       str[1] = uppercase ? 'X' : 'x';
1044       str[2] = '\0';
1045       np->prefix_ptr = register_string (np->sl, str);
1046     }
1047 
1048   /* integral part */
1049   np->ip_size = 1;
1050   base = (spec.spec == 'b') ? 2 : 16;
1051 
1052   if (spec.prec != 0)
1053     {
1054       size_t nsd;
1055 
1056       /* Number of significant digits:
1057          - if no given precision, let mpfr_get_str determine it;
1058          - if a non-zero precision is specified, then one digit before decimal
1059          point plus SPEC.PREC after it (which will give nsd > 1 below). */
1060       MPFR_ASSERTD (np->ip_size == 1);  /* thus the + 1 below */
1061       if (spec.prec < 0)
1062         nsd = 0;
1063       else
1064         {
1065           if (MPFR_UNLIKELY (spec.prec > (size_t) -2))  /* overflow */
1066             return -1;
1067           nsd = (size_t) spec.prec + 1;
1068           MPFR_ASSERTD (nsd != 1);
1069         }
1070       str = mpfr_get_str_wrapper (&exp, base, nsd, p, spec);
1071       register_string (np->sl, str);
1072       np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str;  /* skip sign if any */
1073 
1074       if (base == 16)
1075         /* EXP is the exponent for radix sixteen with decimal point BEFORE the
1076            first digit, we want the exponent for radix two and the decimal
1077            point AFTER the first digit. */
1078         {
1079           /* An integer overflow is normally not possible since MPFR_EXP_MIN
1080              is twice as large as MPFR_EMIN_MIN. */
1081           MPFR_ASSERTN (exp > (MPFR_EXP_MIN + 3) / 4);
1082           exp = (exp - 1) * 4;
1083         }
1084       else
1085         /* EXP is the exponent for decimal point BEFORE the first digit, we
1086            want the exponent for decimal point AFTER the first digit. */
1087         {
1088           /* An integer overflow is normally not possible since MPFR_EXP_MIN
1089              is twice as large as MPFR_EMIN_MIN. */
1090           MPFR_ASSERTN (exp > MPFR_EXP_MIN);
1091           --exp;
1092         }
1093     }
1094   else if (next_base_power_p (p, base, spec.rnd_mode))
1095     {
1096       str = (char *) mpfr_allocate_func (2);
1097       str[0] = '1';
1098       str[1] = '\0';
1099       np->ip_ptr = register_string (np->sl, str);
1100 
1101       exp = MPFR_GET_EXP (p);
1102     }
1103   else if (base == 2)
1104     {
1105       str = (char *) mpfr_allocate_func (2);
1106       str[0] = '1';
1107       str[1] = '\0';
1108       np->ip_ptr = register_string (np->sl, str);
1109 
1110       exp = MPFR_GET_EXP (p) - 1;
1111     }
1112   else
1113     {
1114       int digit;
1115       mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1];
1116       int rnd_bit = GMP_NUMB_BITS - 5;
1117 
1118       /* pick up the 4 first bits */
1119       digit = msl >> (rnd_bit + 1);
1120       if (spec.rnd_mode == MPFR_RNDA
1121           || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1122           || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1123           || (spec.rnd_mode == MPFR_RNDN
1124               && (msl & (MPFR_LIMB_ONE << rnd_bit))))
1125         digit++;
1126       MPFR_ASSERTD (0 <= digit && digit <= 15);
1127 
1128       str = (char *) mpfr_allocate_func (1 + np->ip_size);
1129       str[0] = num_to_text [digit];
1130       str[1] = '\0';
1131       np->ip_ptr = register_string (np->sl, str);
1132 
1133       exp = MPFR_GET_EXP (p) - 4;
1134     }
1135 
1136   if (uppercase)
1137     /* All digits in upper case */
1138     {
1139       char *s1 = str;
1140       while (*s1)
1141         {
1142           switch (*s1)
1143             {
1144             case 'a':
1145               *s1 = 'A';
1146               break;
1147             case 'b':
1148               *s1 = 'B';
1149               break;
1150             case 'c':
1151               *s1 = 'C';
1152               break;
1153             case 'd':
1154               *s1 = 'D';
1155               break;
1156             case 'e':
1157               *s1 = 'E';
1158               break;
1159             case 'f':
1160               *s1 = 'F';
1161               break;
1162             }
1163           s1++;
1164         }
1165     }
1166 
1167   if (spec.spec == 'b' || spec.prec != 0)
1168     /* compute the number of digits in fractional part */
1169     {
1170       char *ptr;
1171       size_t str_len;
1172 
1173       /* the sign has been skipped, skip also the first digit */
1174       ++str;
1175       str_len = strlen (str);
1176       ptr = str + str_len - 1; /* points to the end of str */
1177 
1178       if (spec.prec < 0)
1179         /* remove trailing zeros, if any */
1180         {
1181           while (*ptr == '0' && str_len != 0)
1182             {
1183               --ptr;
1184               --str_len;
1185             }
1186         }
1187 
1188       if (str_len != 0)
1189         /* there are some non-zero digits in fractional part */
1190         {
1191           np->fp_ptr = str;
1192           np->fp_size = str_len;
1193           /* Warning! str_len has type size_t, which is unsigned. */
1194           if (spec.prec > 0 && str_len < spec.prec)
1195             {
1196               np->fp_trailing_zeros = spec.prec - str_len;
1197               MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1198             }
1199         }
1200     }
1201 
1202   /* decimal point */
1203   if (np->fp_size != 0 || spec.alt)
1204     np->point = MPFR_DECIMAL_POINT;
1205 
1206   /* the exponent part contains the character 'p', or 'P' plus the sign
1207      character plus at least one digit and only as many more digits as
1208      necessary to represent the exponent.
1209      We assume that |EXP| < 10^INT_MAX. */
1210   np->exp_size = 3;
1211   {
1212     mpfr_uexp_t x;
1213 
1214     x = SAFE_ABS (mpfr_uexp_t, exp);
1215     while (x > 9)
1216       {
1217         np->exp_size++;
1218         x /= 10;
1219       }
1220   }
1221   str = (char *) mpfr_allocate_func (1 + np->exp_size);
1222   np->exp_ptr = register_string (np->sl, str);
1223   {
1224     char exp_fmt[8];  /* contains at most 7 characters like in "p%+.1i",
1225                          or "P%+.2li" */
1226 
1227     exp_fmt[0] = uppercase ? 'P' : 'p';
1228     exp_fmt[1] = '\0';
1229     strcat (exp_fmt, "%+.1" MPFR_EXP_FSPEC "d");
1230 
1231     if (MPFR_UNLIKELY (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0))
1232       return -1;
1233   }
1234 
1235   return 0;
1236 }
1237 
1238 /* Determine the different parts of the string representation of the regular
1239    number P when spec.spec is 'e', 'E', 'g', or 'G'.
1240    dec_info contains the previously computed exponent and string or is
1241    a null pointer.
1242 
1243    Return -1 in case of overflow on the sizes. */
1244 static int
regular_eg(struct number_parts * np,mpfr_srcptr p,const struct printf_spec spec,struct decimal_info * dec_info,int keep_trailing_zeros)1245 regular_eg (struct number_parts *np, mpfr_srcptr p,
1246             const struct printf_spec spec, struct decimal_info *dec_info,
1247             int keep_trailing_zeros)
1248 {
1249   char *str;
1250   mpfr_exp_t exp;
1251 
1252   const int uppercase = spec.spec == 'E' || spec.spec == 'G';
1253 
1254   /* sign */
1255   if (MPFR_IS_NEG (p))
1256     np->sign = '-';
1257   else if (spec.showsign || spec.space)
1258     np->sign = spec.showsign ? '+' : ' ';
1259 
1260   /* integral part */
1261   np->ip_size = 1;
1262   if (dec_info == NULL)
1263     {
1264       size_t nsd;
1265 
1266       /* Number of significant digits:
1267          - if no given precision, then let mpfr_get_str determine it,
1268          - if a precision is specified, then one digit before decimal point
1269          plus SPEC.PREC after it.
1270          We use the fact here that mpfr_get_str allows us to ask for only one
1271          significant digit when the base is not a power of 2. */
1272       MPFR_ASSERTD (np->ip_size == 1);  /* thus the + 1 below */
1273       if (spec.prec < 0)
1274         nsd = 0;
1275       else
1276         {
1277           if (MPFR_UNLIKELY (spec.prec > (size_t) -2))  /* overflow */
1278             return -1;
1279           nsd = (size_t) spec.prec + 1;
1280         }
1281       str = mpfr_get_str_wrapper (&exp, 10, nsd, p, spec);
1282       register_string (np->sl, str);
1283     }
1284   else
1285     {
1286       exp = dec_info->exp;
1287       str = dec_info->str;
1288     }
1289   np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str;  /* skip sign if any */
1290 
1291   if (spec.prec != 0)
1292     /* compute the number of digits in fractional part */
1293     {
1294       char *ptr;
1295       size_t str_len;
1296 
1297       /* the sign has been skipped, skip also the first digit */
1298       ++str;
1299       str_len = strlen (str);
1300       ptr = str + str_len - 1; /* points to the end of str */
1301 
1302       if (!keep_trailing_zeros)
1303         /* remove trailing zeros, if any */
1304         {
1305           while (*ptr == '0' && str_len != 0)
1306             {
1307               --ptr;
1308               --str_len;
1309             }
1310         }
1311 
1312       if (str_len != 0)
1313         /* there are some non-zero digits in fractional part */
1314         {
1315           np->fp_ptr = str;
1316           np->fp_size = str_len;
1317           /* Warning! str_len has type size_t, which is unsigned. */
1318           if (keep_trailing_zeros && spec.prec > 0 && str_len < spec.prec)
1319             {
1320               /* add missing trailing zeros */
1321               np->fp_trailing_zeros = spec.prec - str_len;
1322               MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1323             }
1324         }
1325     }
1326 
1327   /* decimal point */
1328   if (np->fp_size != 0 || spec.alt)
1329     np->point = MPFR_DECIMAL_POINT;
1330 
1331   /* EXP is the exponent for decimal point BEFORE the first digit, we want
1332      the exponent for decimal point AFTER the first digit.
1333      Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
1334   exp--;
1335 
1336   /* the exponent part contains the character 'e', or 'E' plus the sign
1337      character plus at least two digits and only as many more digits as
1338      necessary to represent the exponent.
1339      We assume that |EXP| < 10^INT_MAX. */
1340   np->exp_size = 3;
1341   {
1342     mpfr_uexp_t x;
1343 
1344     x = SAFE_ABS (mpfr_uexp_t, exp);
1345     while (x > 9)
1346       {
1347         np->exp_size++;
1348         x /= 10;
1349       }
1350   }
1351   if (np->exp_size < 4)
1352     np->exp_size = 4;
1353 
1354   str = (char *) mpfr_allocate_func (1 + np->exp_size);
1355   np->exp_ptr = register_string (np->sl, str);
1356 
1357   {
1358     char exp_fmt[8];  /* e.g. "e%+.2i", or "E%+.2li" */
1359 
1360     exp_fmt[0] = uppercase ? 'E' : 'e';
1361     exp_fmt[1] = '\0';
1362     strcat (exp_fmt, "%+.2" MPFR_EXP_FSPEC "d");
1363 
1364     if (MPFR_UNLIKELY (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0))
1365       return -1;
1366   }
1367 
1368   return 0;
1369 }
1370 
1371 /* Determine the different parts of the string representation of the regular
1372    number P when spec.spec is 'f', 'F', 'g', or 'G'.
1373    dec_info contains the previously computed exponent and string or is
1374    a null pointer.
1375 
1376    Return -1 in case of overflow on the sizes. */
1377 static int
regular_fg(struct number_parts * np,mpfr_srcptr p,const struct printf_spec spec,struct decimal_info * dec_info,int keep_trailing_zeros)1378 regular_fg (struct number_parts *np, mpfr_srcptr p,
1379             const struct printf_spec spec, struct decimal_info *dec_info,
1380             int keep_trailing_zeros)
1381 {
1382   mpfr_exp_t exp;
1383   char * str;
1384 
1385   /* WARNING: an empty precision field is forbidden (it means precision = 6
1386      and it should have been changed to 6 before the function call) */
1387   MPFR_ASSERTD (spec.prec >= 0);
1388 
1389   /* sign */
1390   if (MPFR_IS_NEG (p))
1391     np->sign = '-';
1392   else if (spec.showsign || spec.space)
1393     np->sign = spec.showsign ? '+' : ' ';
1394 
1395   if (MPFR_GET_EXP (p) <= 0)
1396     /* 0 < |p| < 1 */
1397     {
1398       /* Most of the time, integral part is 0 */
1399       np->ip_size = 1;
1400       str = (char *) mpfr_allocate_func (1 + np->ip_size);
1401       str[0] = '0';
1402       str[1] = '\0';
1403       np->ip_ptr = register_string (np->sl, str);
1404 
1405       if (spec.prec == 0)
1406         /* only two possibilities: either 1 or 0. */
1407         {
1408           mpfr_t y;
1409           /* y = abs(p) */
1410           MPFR_ALIAS (y, p, 1, MPFR_EXP (p));
1411 
1412           if (spec.rnd_mode == MPFR_RNDA
1413               || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1414               || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1415               || (spec.rnd_mode == MPFR_RNDN && mpfr_cmp_d (y, 0.5) > 0))
1416             /* rounded up to 1: one digit '1' in integral part.
1417                note that 0.5 is rounded to 0 with RNDN (round ties to even) */
1418             np->ip_ptr[0] = '1';
1419         }
1420       else
1421         {
1422           /* exp =  position of the most significant decimal digit. */
1423           exp = floor_log10 (p);
1424           MPFR_ASSERTD (exp < 0);
1425 
1426           if (exp < -spec.prec)
1427             /* only the last digit may be non zero */
1428             {
1429               int round_away;
1430 
1431               /* Due to mpfr_set_si below... */
1432               if (MPFR_UNLIKELY (spec.prec > LONG_MAX))  /* overflow */
1433                 return -1;
1434 
1435               switch (spec.rnd_mode)
1436                 {
1437                 case MPFR_RNDA:
1438                 case MPFR_RNDF:  /* round_away = 1 needed for %Rg */
1439                   round_away = 1;
1440                   break;
1441                 case MPFR_RNDZ:
1442                   round_away = 0;
1443                   break;
1444                 case MPFR_RNDD:
1445                   round_away = MPFR_IS_NEG (p);
1446                   break;
1447                 case MPFR_RNDU:
1448                   round_away = MPFR_IS_POS (p);
1449                   break;
1450                 default:
1451                   {
1452                     /* compare |p| to y = 0.5*10^(-spec.prec) */
1453                     mpfr_t y;
1454                     mpfr_exp_t e = MAX (MPFR_PREC (p), 56);
1455                     int cmp;
1456 
1457                     MPFR_ASSERTN (spec.rnd_mode == MPFR_RNDN);
1458                     mpfr_init2 (y, e + 8);
1459 
1460                     do
1461                       {
1462                         /* find a lower approximation of
1463                            0.5*10^(-spec.prec) different from |p| */
1464                         e += 8;
1465                         mpfr_set_prec (y, e);
1466                         mpfr_set_si (y, -spec.prec, MPFR_RNDN);
1467                         mpfr_exp10 (y, y, MPFR_RNDD);
1468                         mpfr_div_2ui (y, y, 1, MPFR_RNDN);
1469                         cmp = mpfr_cmpabs (y, p);
1470                       }
1471                     while (cmp == 0);
1472 
1473                     round_away = cmp < 0;
1474                     mpfr_clear (y);
1475                   }
1476                   break;
1477                 }
1478 
1479               if (round_away)
1480                 /* round away from zero: the last output digit is '1' */
1481                 {
1482                   np->fp_leading_zeros = spec.prec - 1;
1483 
1484                   np->fp_size = 1;
1485                   str = (char *) mpfr_allocate_func (1 + np->fp_size);
1486                   str[0] = '1';
1487                   str[1] = '\0';
1488                   np->fp_ptr = register_string (np->sl, str);
1489                 }
1490               else
1491                 /* only zeros in fractional part */
1492                 {
1493                   MPFR_ASSERTD (spec.spec == 'f' || spec.spec == 'F');
1494                   np->fp_leading_zeros = spec.prec;
1495                 }
1496             }
1497           else  /* exp >= -spec.prec */
1498             /* the most significant digits are the last
1499                spec.prec + exp + 1 digits in fractional part */
1500             {
1501               char *ptr;
1502               size_t str_len;
1503 
1504               MPFR_ASSERTD (exp >= -spec.prec);
1505               if (dec_info == NULL)
1506                 {
1507                   size_t nsd;
1508 
1509                   MPFR_ASSERTD (exp <= -1);
1510                   MPFR_ASSERTD (spec.prec + (exp + 1) >= 0);
1511                   if (MPFR_UNLIKELY (spec.prec + (exp + 1) > (size_t) -1))
1512                     return -1;
1513                   nsd = spec.prec + (exp + 1);
1514                   /* WARNING: nsd may equal 1, but here we use the
1515                      fact that mpfr_get_str can return one digit with
1516                      base ten (undocumented feature, see comments in
1517                      get_str.c) */
1518 
1519                   str = mpfr_get_str_wrapper (&exp, 10, nsd, p, spec);
1520                   register_string (np->sl, str);
1521                 }
1522               else
1523                 {
1524                   exp = dec_info->exp;
1525                   str = dec_info->str;
1526                 }
1527               if (MPFR_IS_NEG (p))
1528                 /* skip sign */
1529                 ++str;
1530               if (exp == 1)
1531                 /* round up to 1 */
1532                 {
1533                   MPFR_ASSERTD (str[0] == '1');
1534                   np->ip_ptr[0] = '1';
1535                   if (keep_trailing_zeros)
1536                     np->fp_leading_zeros = spec.prec;
1537                 }
1538               else
1539                 {
1540                   np->fp_ptr = str;
1541                   np->fp_leading_zeros = -exp;
1542                   MPFR_ASSERTD (exp <= 0);
1543 
1544                   str_len = strlen (str); /* the sign has been skipped */
1545                   ptr = str + str_len - 1; /* points to the end of str */
1546 
1547                   if (!keep_trailing_zeros)
1548                     /* remove trailing zeros, if any */
1549                     {
1550                       while (*ptr == '0' && str_len != 0)
1551                         {
1552                           --ptr;
1553                           --str_len;
1554                         }
1555                     }
1556 
1557                   MPFR_ASSERTD (str_len > 0);
1558                   np->fp_size = str_len;
1559 
1560                   /* The np->fp_size <= MPFR_INTMAX_MAX test and the
1561                      cast to mpfr_uintmax_t below allow one to avoid
1562                      integer overflow. */
1563                   if (keep_trailing_zeros
1564                       && spec.prec > 0
1565                       && np->fp_size <= MPFR_INTMAX_MAX
1566                       && ((mpfr_uintmax_t)
1567                           np->fp_leading_zeros + np->fp_size) < spec.prec)
1568                     {
1569                       /* add missing trailing zeros */
1570                       np->fp_trailing_zeros = spec.prec
1571                         - np->fp_leading_zeros - np->fp_size;
1572                       MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1573                     }
1574                 }
1575             }
1576         }
1577 
1578       if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0
1579           || np->fp_trailing_zeros != 0)
1580         np->point = MPFR_DECIMAL_POINT;
1581     }
1582   else
1583     /* 1 <= |p| */
1584     {
1585       size_t str_len;
1586 
1587       /* Determine the position of the most significant decimal digit. */
1588       exp = floor_log10 (p);
1589       MPFR_ASSERTD (exp >= 0);
1590 
1591       if (dec_info == NULL)
1592         {
1593           /* %f case */
1594           mpfr_uintmax_t n;
1595 
1596           n = (mpfr_uintmax_t) spec.prec + (exp + 1);
1597           if (MPFR_UNLIKELY (n > (size_t) -1))
1598             return -1;
1599           str = mpfr_get_str_wrapper (&exp, 10, n, p, spec);
1600           register_string (np->sl, str);
1601         }
1602       else
1603         {
1604           /* %g case */
1605           exp = dec_info->exp;
1606           str = dec_info->str;
1607         }
1608       np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
1609       str_len = strlen (str);
1610 
1611       /* integral part */
1612       if (exp > str_len)
1613         {
1614           /* When spec.size == 0, mpfr_get_str may be called in a reduced
1615              precision, so that some trailing digits may have been ignored.
1616              When spec.size != 0, this case is also possible in the case
1617              where p is rounded up to the next power of 10: a zero must be
1618              added since the exponent has been increased by 1. */
1619           np->ip_trailing_digits = exp - str_len;
1620           np->ip_size = str_len;
1621         }
1622       else
1623         np->ip_size = exp;
1624 
1625       if (spec.group)
1626         /* thousands separator in integral part */
1627         np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
1628 
1629       /* fractional part */
1630       str += np->ip_size;
1631       str_len -= np->ip_size;
1632       if (!keep_trailing_zeros)
1633         /* remove trailing zeros, if any */
1634         {
1635           char *ptr = str + str_len - 1; /* pointer to the last digit of
1636                                             str */
1637           while (*ptr == '0' && str_len != 0)
1638             {
1639               --ptr;
1640               --str_len;
1641             }
1642         }
1643 
1644       if (str_len > 0)
1645         /* some nonzero digits in fractional part */
1646         {
1647           np->point = MPFR_DECIMAL_POINT;
1648           np->fp_ptr = str;
1649           np->fp_size = str_len;
1650         }
1651 
1652       /* Warning! str_len has type size_t, which is unsigned. */
1653       MPFR_ASSERTD (spec.prec >= 0);  /* let's recall this */
1654       if (keep_trailing_zeros && str_len < spec.prec)
1655         /* add missing trailing zeros */
1656         {
1657           np->point = MPFR_DECIMAL_POINT;
1658           np->fp_trailing_zeros = spec.prec - np->fp_size;
1659           MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1660         }
1661 
1662       if (spec.alt)
1663         /* add decimal point even if no digits follow it */
1664         np->point = MPFR_DECIMAL_POINT;
1665     }
1666 
1667   return 0;
1668 }
1669 
1670 /* partition_number determines the different parts of the string
1671    representation of the number p according to the given specification.
1672    partition_number initializes the given structure np, so all previous
1673    information in that variable is lost.
1674    Return the total number of characters to be written.
1675    Return -1 if an error occurred, in that case np's fields are in an
1676    undefined state but all string buffers have been freed. */
1677 static mpfr_intmax_t
partition_number(struct number_parts * np,mpfr_srcptr p,struct printf_spec spec)1678 partition_number (struct number_parts *np, mpfr_srcptr p,
1679                   struct printf_spec spec)
1680 {
1681   char *str;
1682   mpfr_uintmax_t total;  /* can hold the sum of two non-negative
1683                             signed integers + 1 */
1684   int uppercase;
1685 
1686   /* WARNING: left justification means right space padding */
1687   np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
1688   np->pad_size = 0;
1689   np->sign = '\0';
1690   np->prefix_ptr =NULL;
1691   np->prefix_size = 0;
1692   np->thousands_sep = '\0';
1693   np->ip_ptr = NULL;
1694   np->ip_size = 0;
1695   np->ip_trailing_digits = 0;
1696   np->point = '\0';
1697   np->fp_leading_zeros = 0;
1698   np->fp_ptr = NULL;
1699   np->fp_size = 0;
1700   np->fp_trailing_zeros = 0;
1701   np->exp_ptr = NULL;
1702   np->exp_size = 0;
1703   np->sl = (struct string_list *)
1704     mpfr_allocate_func (sizeof (struct string_list));
1705   init_string_list (np->sl);
1706 
1707   uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
1708     || spec.spec == 'G';
1709 
1710   if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
1711     {
1712       if (MPFR_IS_NAN (p))
1713         {
1714           if (np->pad_type == LEADING_ZEROS)
1715             /* don't want "0000nan", change to right justification padding
1716                with left spaces instead */
1717             np->pad_type = LEFT;
1718 
1719           np->ip_size = MPFR_NAN_STRING_LENGTH;
1720           str = (char *) mpfr_allocate_func (1 + np->ip_size);
1721           strcpy (str, uppercase ? MPFR_NAN_STRING_UC : MPFR_NAN_STRING_LC);
1722           np->ip_ptr = register_string (np->sl, str);
1723         }
1724       else if (MPFR_IS_INF (p))
1725         {
1726           if (np->pad_type == LEADING_ZEROS)
1727             /* don't want "0000inf", change to right justification padding
1728                with left spaces instead */
1729             np->pad_type = LEFT;
1730 
1731           if (MPFR_IS_NEG (p))
1732             np->sign = '-';
1733 
1734           np->ip_size = MPFR_INF_STRING_LENGTH;
1735           str = (char *) mpfr_allocate_func (1 + np->ip_size);
1736           strcpy (str, uppercase ? MPFR_INF_STRING_UC : MPFR_INF_STRING_LC);
1737           np->ip_ptr = register_string (np->sl, str);
1738         }
1739       else
1740         {
1741           MPFR_ASSERTD (MPFR_IS_ZERO (p));
1742           /* note: for 'g' spec, zero is always displayed with 'f'-style with
1743              precision spec.prec - 1 and the trailing zeros are removed unless
1744              the flag '#' is used. */
1745           if (MPFR_IS_NEG (p))
1746             /* signed zero */
1747             np->sign = '-';
1748           else if (spec.showsign || spec.space)
1749             np->sign = spec.showsign ? '+' : ' ';
1750 
1751           if (spec.spec == 'a' || spec.spec == 'A')
1752             /* prefix part */
1753             {
1754               np->prefix_size = 2;
1755               str = (char *) mpfr_allocate_func (1 + np->prefix_size);
1756               str[0] = '0';
1757               str[1] = uppercase ? 'X' : 'x';
1758               str[2] = '\0';
1759               np->prefix_ptr = register_string (np->sl, str);
1760             }
1761 
1762           /* integral part */
1763           np->ip_size = 1;
1764           str = (char *) mpfr_allocate_func (1 + np->ip_size);
1765           str[0] = '0';
1766           str[1] = '\0';
1767           np->ip_ptr = register_string (np->sl, str);
1768 
1769           if (spec.prec < 0)  /* empty precision field */
1770             {
1771               if (spec.spec == 'e' || spec.spec == 'E')
1772                 spec.prec = mpfr_get_str_ndigits (10, MPFR_GET_PREC (p)) - 1;
1773               else if (spec.spec == 'f' || spec.spec == 'F' ||
1774                        spec.spec == 'g' || spec.spec == 'G')
1775                 spec.prec = DEFAULT_DECIMAL_PREC;
1776             }
1777 
1778           if (spec.prec > 0
1779               && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
1780             /* fractional part */
1781             {
1782               np->point = MPFR_DECIMAL_POINT;
1783               np->fp_trailing_zeros = (spec.spec == 'g' || spec.spec == 'G') ?
1784                 spec.prec - 1 : spec.prec;
1785               MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1786             }
1787           else if (spec.alt)
1788             np->point = MPFR_DECIMAL_POINT;
1789 
1790           if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
1791               || spec.spec == 'e' || spec.spec == 'E')
1792             /* exponent part */
1793             {
1794               np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
1795               str = (char *) mpfr_allocate_func (1 + np->exp_size);
1796               if (spec.spec == 'e' || spec.spec == 'E')
1797                 strcpy (str, uppercase ? "E+00" : "e+00");
1798               else
1799                 strcpy (str, uppercase ? "P+0" : "p+0");
1800               np->exp_ptr = register_string (np->sl, str);
1801             }
1802         }
1803     }
1804   else if (MPFR_UNLIKELY (MPFR_IS_UBF (p)))
1805     {
1806       /* mpfr_get_str does not support UBF, so that UBF numbers are regarded
1807          as special cases here. This is not much a problem since UBF numbers
1808          are internal to MPFR and here, they only for logging. */
1809       if (np->pad_type == LEADING_ZEROS)
1810         /* change to right justification padding with left spaces */
1811         np->pad_type = LEFT;
1812 
1813       if (MPFR_IS_NEG (p))
1814         np->sign = '-';
1815 
1816       np->ip_size = 3;
1817       str = (char *) mpfr_allocate_func (1 + np->ip_size);
1818       strcpy (str, uppercase ? "UBF" : "ubf");
1819       np->ip_ptr = register_string (np->sl, str);
1820       /* TODO: output more information (e.g. the exponent) if need be. */
1821     }
1822   else
1823     {
1824       MPFR_ASSERTD (MPFR_IS_PURE_FP (p));
1825       if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
1826         {
1827           if (regular_ab (np, p, spec) == -1)
1828             goto error;
1829         }
1830       else if (spec.spec == 'f' || spec.spec == 'F')
1831         {
1832           if (spec.prec < 0)
1833             spec.prec = DEFAULT_DECIMAL_PREC;
1834           if (regular_fg (np, p, spec, NULL, 1) == -1)
1835             goto error;
1836         }
1837       else if (spec.spec == 'e' || spec.spec == 'E')
1838         {
1839           if (regular_eg (np, p, spec, NULL, 1) == -1)
1840             goto error;
1841         }
1842       else
1843         /* %g case */
1844         {
1845           /* Use the C99 rules:
1846              if T > X >= -4 then the conversion is with style 'f'/'F' and
1847              precision T-(X+1).
1848              otherwise, the conversion is with style 'e'/'E' and
1849              precision T-1.
1850              where T is the threshold computed below and X is the exponent
1851              that would be displayed with style 'e' and precision T-1. */
1852           int threshold;
1853           mpfr_exp_t x, e, k;
1854           struct decimal_info dec_info;
1855 
1856           threshold = spec.prec < 0 ? DEFAULT_DECIMAL_PREC :
1857             spec.prec == 0 ? 1 : spec.prec;
1858           MPFR_ASSERTD (threshold >= 1);
1859 
1860           /* Here we cannot call mpfr_get_str_wrapper since we need the full
1861              significand in dec_info.str.
1862              Moreover, threshold may be huge while one can know that the
1863              number of digits that are not trailing zeros remains limited;
1864              such a limit occurs in practical cases, e.g. with numbers
1865              representable in the IEEE 754-2008 basic formats. Since the
1866              trailing zeros are not necessarily output, we do not want to
1867              waste time and memory by making mpfr_get_str generate them.
1868              So, let us try to find a smaller threshold for mpfr_get_str.
1869              |p| < 2^EXP(p) = 10^(EXP(p)*log10(2)). So, the integer part
1870              takes at most ceil(EXP(p)*log10(2)) digits (unless p rounds
1871              to the next power of 10, but in this case any threshold will
1872              be OK). So, for the integer part, we will take:
1873              max(0,floor((EXP(p)+2)/3)).
1874              Let k = PREC(p) - EXP(p), so that the last bit of p has
1875              weight 2^(-k). If k <= 0, then p is an integer, otherwise
1876              the fractional part in base 10 may have up to k digits
1877              (this bound is reached if the last bit is 1).
1878              Note: The bound could be improved, but this is not critical. */
1879           e = MPFR_GET_EXP (p);
1880           k = MPFR_PREC (p) - e;
1881           e = e <= 0 ? k : (e + 2) / 3 + (k <= 0 ? 0 : k);
1882           MPFR_ASSERTD (e >= 1);
1883 
1884           dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10,
1885                                        e < threshold ? e : threshold,
1886                                        p, spec.rnd_mode);
1887           register_string (np->sl, dec_info.str);
1888           /* mpfr_get_str corresponds to a significand between 0.1 and 1,
1889              whereas here we want a significand between 1 and 10. */
1890           x = dec_info.exp - 1;
1891 
1892           if (threshold > x && x >= -4)
1893             {
1894               /* the conversion is with style 'f' */
1895               spec.prec = threshold - x - 1;
1896 
1897               if (regular_fg (np, p, spec, &dec_info, spec.alt) == -1)
1898                 goto error;
1899             }
1900           else
1901             {
1902               spec.prec = threshold - 1;
1903 
1904               if (regular_eg (np, p, spec, &dec_info, spec.alt) == -1)
1905                 goto error;
1906             }
1907         }
1908     }
1909 
1910   /* compute the number of characters to be written verifying it is not too
1911      much */
1912 
1913 #define INCR_TOTAL(v)                                   \
1914   do {                                                  \
1915     MPFR_ASSERTD ((v) >= 0);                            \
1916     if (MPFR_UNLIKELY ((v) > MPFR_INTMAX_MAX))          \
1917       goto error;                                       \
1918     total += (v);                                       \
1919     if (MPFR_UNLIKELY (total > MPFR_INTMAX_MAX))        \
1920       goto error;                                       \
1921   } while (0)
1922 
1923   total = np->sign ? 1 : 0;
1924   INCR_TOTAL (np->prefix_size);
1925   INCR_TOTAL (np->ip_size);
1926   INCR_TOTAL (np->ip_trailing_digits);
1927   MPFR_ASSERTD (np->ip_size + np->ip_trailing_digits >= 1);
1928   if (np->thousands_sep)
1929     /* ' flag, style f and the thousands separator in current locale is not
1930        reduced to the null character */
1931     INCR_TOTAL ((np->ip_size + np->ip_trailing_digits - 1) / 3);
1932   if (np->point)
1933     ++total;
1934   INCR_TOTAL (np->fp_leading_zeros);
1935   INCR_TOTAL (np->fp_size);
1936   INCR_TOTAL (np->fp_trailing_zeros);
1937   INCR_TOTAL (np->exp_size);
1938 
1939   if (spec.width > total)
1940     /* pad with spaces or zeros depending on np->pad_type */
1941     {
1942       np->pad_size = spec.width - total;
1943       total = spec.width;
1944     }
1945 
1946   MPFR_ASSERTD (total > 0 && total <= MPFR_INTMAX_MAX);
1947   return total;
1948 
1949  error:
1950   clear_string_list (np->sl);
1951   np->prefix_ptr = NULL;
1952   np->ip_ptr = NULL;
1953   np->fp_ptr = NULL;
1954   np->exp_ptr = NULL;
1955   return -1;
1956 }
1957 
1958 /* sprnt_fp prints a mpfr_t according to spec.spec specification.
1959 
1960    Return the size of the string (not counting the terminating '\0').
1961    Return -1 if the built string is too long (i.e. has more than
1962    INT_MAX or MPFR_INTMAX_MAX characters).
1963 
1964    If spec.size is 0, we only want the size of the string.
1965 */
1966 static int
sprnt_fp(struct string_buffer * buf,mpfr_srcptr p,const struct printf_spec spec)1967 sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
1968           const struct printf_spec spec)
1969 {
1970   mpfr_intmax_t length, start;
1971   struct number_parts np;
1972 
1973   length = partition_number (&np, p, spec);
1974   if (MPFR_UNLIKELY (length < 0))
1975     {
1976       buf->len = -1;
1977       return -1;
1978     }
1979 
1980   if (spec.size == 0)
1981     {
1982       /* This is equivalent to the following code (no need to fill the buffer
1983          and length is known). */
1984       buffer_incr_len (buf, length);
1985       goto clear_and_exit;
1986     }
1987 
1988   MPFR_DBGRES (start = buf->len);
1989 
1990   /* right justification padding with left spaces */
1991   if (np.pad_type == LEFT && np.pad_size != 0)
1992     buffer_pad (buf, ' ', np.pad_size);
1993 
1994   /* sign character (may be '-', '+', or ' ') */
1995   if (np.sign)
1996     buffer_pad (buf, np.sign, 1);
1997 
1998   /* prefix part */
1999   if (np.prefix_ptr)
2000     buffer_cat (buf, np.prefix_ptr, np.prefix_size);
2001 
2002   /* right justification  padding with leading zeros */
2003   if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
2004     buffer_pad (buf, '0', np.pad_size);
2005 
2006   /* integral part (may also be "nan" or "inf") */
2007   MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
2008   if (MPFR_UNLIKELY (np.thousands_sep))
2009     {
2010       if (buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_digits,
2011                            np.thousands_sep))
2012         {
2013           buf->len = -1;
2014           goto clear_and_exit;
2015         }
2016     }
2017   else
2018     {
2019       buffer_cat (buf, np.ip_ptr, np.ip_size);
2020 
2021       /* possible trailing zero in integral part (spec.size != 0) */
2022       MPFR_ASSERTD (np.ip_trailing_digits <= 1);
2023       if (np.ip_trailing_digits != 0)
2024         buffer_pad (buf, '0', 1);
2025     }
2026 
2027   /* decimal point */
2028   if (np.point)
2029     buffer_pad (buf, np.point, 1);
2030 
2031   /* leading zeros in fractional part */
2032   if (np.fp_leading_zeros != 0)
2033     buffer_pad (buf, '0', np.fp_leading_zeros);
2034 
2035   /* significant digits in fractional part */
2036   if (np.fp_ptr)
2037     buffer_cat (buf, np.fp_ptr, np.fp_size);
2038 
2039   /* trailing zeros in fractional part */
2040   if (np.fp_trailing_zeros != 0)
2041     buffer_pad (buf, '0', np.fp_trailing_zeros);
2042 
2043   /* exponent part */
2044   if (np.exp_ptr)
2045     buffer_cat (buf, np.exp_ptr, np.exp_size);
2046 
2047   /* left justification padding with right spaces */
2048   if (np.pad_type == RIGHT && np.pad_size != 0)
2049     buffer_pad (buf, ' ', np.pad_size);
2050 
2051   MPFR_ASSERTD (buf->len == -1 || buf->len - start == length);
2052 
2053  clear_and_exit:
2054   clear_string_list (np.sl);
2055   return buf->len == -1 ? -1 : length;
2056 }
2057 
2058 /* The following internal function implements both mpfr_vasprintf and
2059    mpfr_vsnprintf:
2060    (a) either ptr <> NULL, and then Buf and size are not used, and it
2061        implements mpfr_vasprintf (ptr, fmt, ap)
2062    (b) or ptr = NULL, and it implements mpfr_vsnprintf (Buf, size, fmt, ap)
2063    It returns the number of characters that would have been written had 'size'
2064    been sufficiently large, not counting the terminating null character, or -1
2065    if this number is too large for the return type 'int' (overflow).
2066 */
2067 int
mpfr_vasnprintf_aux(char ** ptr,char * Buf,size_t size,const char * fmt,va_list ap)2068 mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt,
2069                      va_list ap)
2070 {
2071   struct string_buffer buf;
2072   int nbchar;
2073 
2074   /* information on the conversion specification filled by the parser */
2075   struct printf_spec spec;
2076   /* flag raised when previous part of fmt need to be processed by
2077      gmp_vsnprintf */
2078   int xgmp_fmt_flag;
2079   /* beginning and end of the previous unprocessed part of fmt */
2080   const char *start, *end;
2081   /* pointer to arguments for gmp_vasprintf */
2082   va_list ap2;
2083 
2084   MPFR_SAVE_EXPO_DECL (expo);
2085   MPFR_SAVE_EXPO_MARK (expo);
2086 
2087   /* FIXME: Once buf.len >= size, switch to size = 0 for efficiency and
2088      avoid potential DoS? i.e. we no longer need to generate the strings
2089      (potentially huge), just compute the lengths. */
2090 
2091   buffer_init (&buf, ptr != NULL || size != 0 ? 4096 : 0);
2092   xgmp_fmt_flag = 0;
2093   va_copy (ap2, ap);
2094   start = fmt;
2095   while (*fmt != '\0')
2096     {
2097       int overflow = 0;
2098 
2099       /* Look for the next format specification */
2100       while (*fmt != '\0' && *fmt != '%')
2101         ++fmt;
2102 
2103       if (*fmt == '\0')
2104         break;
2105 
2106       if (*++fmt == '%')
2107         /* %%: go one step further otherwise the second '%' would be
2108            considered as a new conversion specification introducing
2109            character */
2110         {
2111           ++fmt;
2112           xgmp_fmt_flag = 1;
2113           continue;
2114         }
2115 
2116       end = fmt - 1;
2117 
2118       /* format string analysis */
2119       specinfo_init (&spec);
2120       fmt = parse_flags (fmt, &spec);
2121 
2122       READ_INT (ap, fmt, spec.width);
2123       if (spec.width < 0)  /* integer read via '*', no overflow */
2124         {
2125           spec.left = 1;
2126           /* Since the type of the integer is int, spec.width >= INT_MIN,
2127              so that an overflow is possible here only if mpfr_intmax_t
2128              has the same size of int. The INT_MIN < - MPFR_INTMAX_MAX
2129              test allows the compiler to optimize when it is false. */
2130           if (MPFR_UNLIKELY (INT_MIN < - MPFR_INTMAX_MAX &&
2131                              spec.width < - MPFR_INTMAX_MAX))
2132             overflow = 1;
2133           else
2134             spec.width = - spec.width;
2135         }
2136       /* Note: We will make sure that spec.width is not used in case of
2137          overflow. */
2138       MPFR_ASSERTD (overflow || spec.width >= 0);
2139 
2140       if (*fmt == '.')
2141         {
2142           const char *f = ++fmt;
2143           READ_INT (ap, fmt, spec.prec);
2144           if (f == fmt || spec.prec < 0)
2145             spec.prec = -1;
2146         }
2147       else
2148         spec.prec = -1;
2149       MPFR_ASSERTD (spec.prec >= -1);
2150 
2151       fmt = parse_arg_type (fmt, &spec);
2152       if (spec.arg_type == UNSUPPORTED)
2153         /* the current architecture doesn't support the type corresponding to
2154            the format specifier; according to the ISO C99 standard, the
2155            behavior is undefined. We choose to print the format specifier as a
2156            literal string, what may be printed after this string is
2157            undefined. */
2158         continue;
2159       else if (spec.arg_type == MPFR_ARG)
2160         {
2161           switch (*fmt)
2162             {
2163             case '\0':
2164               break;
2165             case '*':
2166               ++fmt;
2167               spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
2168               break;
2169             case 'D':
2170               ++fmt;
2171               spec.rnd_mode = MPFR_RNDD;
2172               break;
2173             case 'U':
2174               ++fmt;
2175               spec.rnd_mode = MPFR_RNDU;
2176               break;
2177             case 'Y':
2178               ++fmt;
2179               spec.rnd_mode = MPFR_RNDA;
2180               break;
2181             case 'Z':
2182               ++fmt;
2183               spec.rnd_mode = MPFR_RNDZ;
2184               break;
2185             case 'N':
2186               ++fmt;
2187               MPFR_FALLTHROUGH;
2188             default:
2189               spec.rnd_mode = MPFR_RNDN;
2190             }
2191         }
2192 
2193       spec.spec = *fmt;
2194       if (!specinfo_is_valid (spec))
2195         /* the format specifier is invalid; according to the ISO C99 standard,
2196            the behavior is undefined. We choose to print the invalid format
2197            specifier as a literal string, what may be printed after this
2198            string is undefined. */
2199         continue;
2200 
2201       if (*fmt != '\0')
2202         fmt++;
2203 
2204       /* Format processing */
2205       if (spec.spec == '\0')
2206         /* end of the format string */
2207         break;
2208       else if (spec.spec == 'n')
2209         /* put the number of characters written so far in the location pointed
2210            by the next va_list argument; the types of pointer accepted are the
2211            same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
2212            so as to be able to accept the same format strings. */
2213         {
2214           void *p;
2215 
2216           p = va_arg (ap, void *);
2217           FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2218           va_end (ap2);
2219           start = fmt;
2220 
2221           switch (spec.arg_type)
2222             {
2223             case CHAR_ARG:
2224               *(char *) p = (char) buf.len;
2225               break;
2226             case SHORT_ARG:
2227               *(short *) p = (short) buf.len;
2228               break;
2229             case LONG_ARG:
2230               *(long *) p = (long) buf.len;
2231               break;
2232 #ifdef HAVE_LONG_LONG
2233             case LONG_LONG_ARG:
2234               *(long long *) p = (long long) buf.len;
2235               break;
2236 #endif
2237 #ifdef _MPFR_H_HAVE_INTMAX_T
2238             case INTMAX_ARG:
2239               *(intmax_t *) p = (intmax_t) buf.len;
2240               break;
2241 #endif
2242             case SIZE_ARG:
2243               *(size_t *) p = buf.len;
2244               break;
2245             case PTRDIFF_ARG:
2246               *(ptrdiff_t *) p = (ptrdiff_t) buf.len;
2247               break;
2248             case MPF_ARG:
2249               mpf_set_ui ((mpf_ptr) p, (unsigned long) buf.len);
2250               break;
2251             case MPQ_ARG:
2252               mpq_set_ui ((mpq_ptr) p, (unsigned long) buf.len, 1L);
2253               break;
2254             case MP_LIMB_ARG:
2255               *(mp_limb_t *) p = (mp_limb_t) buf.len;
2256               break;
2257             case MP_LIMB_ARRAY_ARG:
2258               {
2259                 mp_limb_t *q = (mp_limb_t *) p;
2260                 mp_size_t n;
2261                 n = va_arg (ap, mp_size_t);
2262                 if (n < 0)
2263                   n = -n;
2264                 else if (n == 0)
2265                   break;
2266 
2267                 /* we assume here that mp_limb_t is wider than int */
2268                 *q = (mp_limb_t) buf.len;
2269                 while (--n != 0)
2270                   {
2271                     q++;
2272                     *q = MPFR_LIMB_ZERO;
2273                   }
2274               }
2275               break;
2276             case MPZ_ARG:
2277               mpz_set_ui ((mpz_ptr) p, (unsigned long) buf.len);
2278               break;
2279 
2280             case MPFR_ARG:
2281               mpfr_set_ui ((mpfr_ptr) p, (unsigned long) buf.len,
2282                            spec.rnd_mode);
2283               break;
2284 
2285             default:
2286               *(int *) p = (int) buf.len;
2287             }
2288           va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
2289                                 case */
2290         }
2291       else if (spec.arg_type == MPFR_PREC_ARG)
2292         /* output mpfr_prec_t variable */
2293         {
2294           char *s;
2295           char format[MPFR_PREC_FORMAT_SIZE + 12]; /* e.g. "%0#+ -'*.*ld\0" */
2296           size_t length;
2297           mpfr_prec_t prec;
2298 
2299           /* FIXME: With buf.size = 0 and a huge width or precision, this
2300              can uselessly take much memory. And even with buf.size != 0,
2301              this would take more memory than necessary and need a large
2302              buffer_cat. A solution: compute a bound on the maximum
2303              number of significant digits, and handle the additional
2304              characters separately. Moreover, if buf.size = 0 or size != 0,
2305              gmp_snprintf should be called instead of gmp_asprintf,
2306              outputting data directly to the buffer when applicable.
2307              See also: https://sourceware.org/bugzilla/show_bug.cgi?id=23432
2308              Add testcases. */
2309 
2310           prec = va_arg (ap, mpfr_prec_t);
2311 
2312           FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2313           va_end (ap2);
2314           va_copy (ap2, ap);
2315           start = fmt;
2316 
2317           /* The restriction to INT_MAX is a limitation due to the fact
2318              that *.* is used below. If the width or precision field is
2319              larger than INT_MAX, then there is a real overflow on the
2320              return value due to the padding characters, thus the error
2321              is correct. The only minor drawback is that some variables
2322              corresponding to the 'n' conversion specifier with a type
2323              larger than int may not be set. This is not a bug, as there
2324              are no strong guarantees for such variables in case of error.
2325              FIXME: If size = 0 and max(spec.width,spec.prec) is large
2326              enough, there is no need to call gmp_asprintf since we are
2327              just interested in the length, which should be this maximum;
2328              in particular, this should avoid the overflow issue. */
2329           if (overflow || spec.width > INT_MAX || spec.prec > INT_MAX)
2330             {
2331               buf.len = -1;
2332               goto error;
2333             }
2334 
2335           /* Recalled from above. */
2336           MPFR_ASSERTD (spec.width >= 0);
2337           MPFR_ASSERTD (spec.prec >= -1);
2338 
2339           /* construct format string, like "%*.*hd" "%*.*d" or "%*.*ld" */
2340           sprintf (format, "%%%s%s%s%s%s%s*.*" MPFR_PREC_FORMAT_TYPE "%c",
2341                    spec.pad == '0' ? "0" : "",
2342                    spec.alt ? "#" : "",
2343                    spec.showsign ? "+" : "",
2344                    spec.space ? " " : "",
2345                    spec.left ? "-" : "",
2346                    spec.group ? "'" : "",
2347                    spec.spec);
2348           MPFR_LOG_MSG (("MPFR_PREC_ARG: format for gmp_asprintf: \"%s\"\n",
2349                          format));
2350           MPFR_LOG_MSG (("MPFR_PREC_ARG: width = %d, prec = %d, value = %"
2351                          MPFR_PREC_FORMAT_TYPE "d\n",
2352                          (int) spec.width, (int) spec.prec, prec));
2353           length = gmp_asprintf (&s, format,
2354                                  (int) spec.width, (int) spec.prec, prec);
2355           MPFR_ASSERTN (length >= 0);  /* guaranteed by GMP 6 */
2356           buffer_cat (&buf, s, length);
2357           mpfr_free_str (s);
2358         }
2359       else if (spec.arg_type == MPFR_ARG)
2360         /* output a mpfr_t variable */
2361         {
2362           mpfr_srcptr p;
2363 
2364           if (spec.spec != 'a' && spec.spec != 'A'
2365               && spec.spec != 'b'
2366               && spec.spec != 'e' && spec.spec != 'E'
2367               && spec.spec != 'f' && spec.spec != 'F'
2368               && spec.spec != 'g' && spec.spec != 'G')
2369             /* The format specifier is invalid; skip the invalid format
2370                specifier so as to print it as a literal string. What may
2371                be printed after this string is undefined. */
2372             continue;
2373 
2374           p = va_arg (ap, mpfr_srcptr);
2375 
2376           FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2377           va_end (ap2);
2378           va_copy (ap2, ap);
2379           start = fmt;
2380 
2381           if (overflow)
2382             {
2383               buf.len = -1;
2384               goto error;
2385             }
2386 
2387           if (ptr == NULL)
2388             spec.size = size;
2389           sprnt_fp (&buf, p, spec);
2390         }
2391       else
2392         /* gmp_printf specification, step forward in the va_list */
2393         {
2394           CONSUME_VA_ARG (spec, ap);
2395           xgmp_fmt_flag = 1;
2396         }
2397     }
2398 
2399   if (start != fmt)
2400     FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
2401 
2402   va_end (ap2);
2403 
2404   if (buf.len == -1 || buf.len > INT_MAX)  /* overflow */
2405     goto overflow;
2406 
2407   nbchar = buf.len;
2408   MPFR_ASSERTD (nbchar >= 0);
2409 
2410   if (ptr != NULL)  /* implement mpfr_vasprintf */
2411     {
2412       MPFR_ASSERTD (nbchar == strlen (buf.start));
2413       *ptr = (char *) mpfr_reallocate_func (buf.start, buf.size, nbchar + 1);
2414     }
2415   else if (size != 0)  /* implement mpfr_vsnprintf */
2416     {
2417       if (nbchar < size)
2418         {
2419           strncpy (Buf, buf.start, nbchar);
2420           Buf[nbchar] = '\0';
2421         }
2422       else
2423         {
2424           strncpy (Buf, buf.start, size - 1);
2425           Buf[size-1] = '\0';
2426         }
2427       mpfr_free_func (buf.start, buf.size);
2428     }
2429 
2430   MPFR_SAVE_EXPO_FREE (expo);
2431   return nbchar; /* return the number of characters that would have
2432                     been written had 'size' been sufficiently large,
2433                     not counting the terminating null character */
2434 
2435  error:
2436   va_end (ap2);
2437   if (buf.len == -1)  /* overflow */
2438     {
2439     overflow:
2440       MPFR_LOG_MSG (("Overflow\n", 0));
2441       MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_ERANGE);
2442 #ifdef EOVERFLOW
2443       MPFR_LOG_MSG (("Setting errno to EOVERFLOW\n", 0));
2444       errno = EOVERFLOW;
2445 #endif
2446     }
2447 
2448   MPFR_SAVE_EXPO_FREE (expo);
2449   if (ptr != NULL)  /* implement mpfr_vasprintf */
2450     *ptr = NULL;
2451   if (ptr != NULL || size != 0)
2452     mpfr_free_func (buf.start, buf.size);
2453 
2454   return -1;
2455 }
2456 
2457 #else /* HAVE_STDARG */
2458 
2459 /* Avoid an empty translation unit (see ISO C99, 6.9) */
2460 typedef int foo;
2461 
2462 #endif /* HAVE_STDARG */
2463