prepare to upload
[debian/sudo] / compat / snprintf.c
1 /*
2  * Copyright (c) 1999-2005, 2008, 2010-2011
3  *      Todd C. Miller <Todd.Miller@courtesan.com>
4  * Copyright (c) 1990, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Chris Torek.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * From: @(#)vfprintf.c 8.1 (Berkeley) 6/4/93
35  */
36
37 /*
38  * v?snprintf/v?asprintf based on 4.4BSD stdio.
39  * NOTE: does not support floating point.
40  */
41
42 #include <config.h>
43
44 #include <sys/types.h>
45 #include <sys/param.h>
46
47 #include <stdio.h>
48 #ifdef STDC_HEADERS
49 # include <stdlib.h>
50 # include <stddef.h>
51 #else
52 # ifdef HAVE_STDLIB_H
53 #  include <stdlib.h>
54 # endif
55 #endif /* STDC_HEADERS */
56 #ifdef HAVE_STDINT_H
57 # include <stdint.h>
58 #endif
59 #ifdef HAVE_STRING_H
60 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
61 #  include <memory.h>
62 # endif
63 # include <string.h>
64 #endif /* HAVE_STRING_H */
65 #ifdef HAVE_STRINGS_H
66 # include <strings.h>
67 #endif /* HAVE_STRINGS_H */
68 #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
69 # include <malloc.h>
70 #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
71 #include <limits.h>
72 #include <stdarg.h>
73
74 #include "missing.h"
75
76 static int xxxprintf(char **, size_t, int, const char *, va_list);
77
78 /*
79  * Some systems may not have these defined in <limits.h>
80  */
81 #ifndef ULONG_MAX
82 # define ULONG_MAX      ((unsigned long)-1)
83 #endif
84 #ifndef LONG_MAX
85 # define LONG_MAX       (ULONG_MAX / 2)
86 #endif
87 #ifdef HAVE_LONG_LONG_INT
88 # ifndef ULLONG_MAX
89 #  ifdef UQUAD_MAX
90 #   define ULLONG_MAX   UQUAD_MAX
91 #  else
92 #   define ULLONG_MAX   ((unsigned long long)-1)
93 #  endif
94 # endif
95 # ifndef LLONG_MAX
96 #  ifdef QUAD_MAX
97 #   define LLONG_MAX    QUAD_MAX
98 #  else
99 #   define LLONG_MAX    (ULLONG_MAX / 2)
100 #  endif
101 # endif
102 #endif /* HAVE_LONG_LONG_INT */
103
104 /*
105  * Macros for converting digits to letters and vice versa
106  */
107 #define to_digit(c)     ((c) - '0')
108 #define is_digit(c)     ((unsigned int)to_digit(c) <= 9)
109 #define to_char(n)      ((n) + '0')
110
111 /*
112  * Flags used during conversion.
113  */
114 #define ALT             0x001           /* alternate form */
115 #define HEXPREFIX       0x002           /* add 0x or 0X prefix */
116 #define LADJUST         0x004           /* left adjustment */
117 #define LONGDBL         0x008           /* long double; unimplemented */
118 #define LONGINT         0x010           /* long integer */
119 #define QUADINT         0x020           /* quad integer */
120 #define SHORTINT        0x040           /* short integer */
121 #define ZEROPAD         0x080           /* zero (as opposed to blank) pad */
122
123 #define BUF             68
124
125 /*
126  * Convert an unsigned long to ASCII for printf purposes, returning
127  * a pointer to the first character of the string representation.
128  * Octal numbers can be forced to have a leading zero; hex numbers
129  * use the given digits.
130  */
131 static char *
132 __ultoa(unsigned long val, char *endp, int base, int octzero, char *xdigs)
133 {
134         char *cp = endp;
135         long sval;
136
137         /*
138          * Handle the three cases separately, in the hope of getting
139          * better/faster code.
140          */
141         switch (base) {
142         case 10:
143                 if (val < 10) { /* many numbers are 1 digit */
144                         *--cp = to_char(val);
145                         return cp;
146                 }
147                 /*
148                  * On many machines, unsigned arithmetic is harder than
149                  * signed arithmetic, so we do at most one unsigned mod and
150                  * divide; this is sufficient to reduce the range of
151                  * the incoming value to where signed arithmetic works.
152                  */
153                 if (val > LONG_MAX) {
154                         *--cp = to_char(val % 10);
155                         sval = val / 10;
156                 } else
157                         sval = val;
158                 do {
159                         *--cp = to_char(sval % 10);
160                         sval /= 10;
161                 } while (sval != 0);
162                 break;
163
164         case 8:
165                 do {
166                         *--cp = to_char(val & 7);
167                         val >>= 3;
168                 } while (val);
169                 if (octzero && *cp != '0')
170                         *--cp = '0';
171                 break;
172
173         case 16:
174                 do {
175                         *--cp = xdigs[val & 15];
176                         val >>= 4;
177                 } while (val);
178                 break;
179
180         default:                        /* oops */
181                 abort();
182         }
183         return cp;
184 }
185
186 /* Identical to __ultoa, but for quads. */
187 #ifdef HAVE_LONG_LONG_INT
188 # if SIZEOF_LONG_INT == 8
189 #  define __uqtoa(v, e, b, o, x) __ultoa((unsigned long)(v), (e), (b), (o), (x))
190 # else
191 static char *
192 __uqtoa(unsigned long long val, char *endp, int base, int octzero, char *xdigs)
193 {
194         char *cp = endp;
195         long long sval;
196
197         /* quick test for small values; __ultoa is typically much faster */
198         /* (perhaps instead we should run until small, then call __ultoa?) */
199         if (val <= (unsigned long long)ULONG_MAX)
200                 return __ultoa((unsigned long)val, endp, base, octzero, xdigs);
201         switch (base) {
202         case 10:
203                 if (val < 10) {
204                         *--cp = to_char(val % 10);
205                         return cp;
206                 }
207                 if (val > LLONG_MAX) {
208                         *--cp = to_char(val % 10);
209                         sval = val / 10;
210                 } else
211                         sval = val;
212                 do {
213                         *--cp = to_char(sval % 10);
214                         sval /= 10;
215                 } while (sval != 0);
216                 break;
217
218         case 8:
219                 do {
220                         *--cp = to_char(val & 7);
221                         val >>= 3;
222                 } while (val);
223                 if (octzero && *cp != '0')
224                         *--cp = '0';
225                 break;
226
227         case 16:
228                 do {
229                         *--cp = xdigs[val & 15];
230                         val >>= 4;
231                 } while (val);
232                 break;
233
234         default:                        /* oops */
235                 abort();
236         }
237         return cp;
238 }
239 # endif /* !SIZEOF_LONG_INT */
240 #endif /* HAVE_LONG_LONG_INT */
241
242 /*
243  * Actual printf innards.
244  */
245 static int
246 xxxprintf(char **strp, size_t strsize, int alloc, const char *fmt0, va_list ap)
247 {
248         char *fmt;              /* format string */
249         int ch;                 /* character from fmt */
250         int n;                  /* handy integer (short term usage) */
251         char *cp;               /* handy char pointer (short term usage) */
252         int flags;              /* flags as above */
253         int ret;                /* return value accumulator */
254         int width;              /* width from format (%8d), or 0 */
255         int prec;               /* precision from format (%.3d), or -1 */
256         char sign;              /* sign prefix (' ', '+', '-', or \0) */
257         unsigned long ulval = 0; /* integer arguments %[diouxX] */
258 #ifdef HAVE_LONG_LONG_INT
259         unsigned long long uqval = 0; /* %q (quad) integers */
260 #endif
261         int base;               /* base for [diouxX] conversion */
262         int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
263         int fieldsz;            /* field size expanded by sign, etc */
264         int realsz;             /* field size expanded by dprec */
265         int size;               /* size of converted field or string */
266         char *xdigs = "";       /* digits for [xX] conversion */
267         char buf[BUF];          /* space for %c, %[diouxX], %[eEfgG] */
268         char ox[2];             /* space for 0x hex-prefix */
269         char *str;              /* pointer to string to fill */
270         char *estr;             /* pointer to last char in str */
271
272         /*
273          * Choose PADSIZE to trade efficiency vs. size.  If larger printf
274          * fields occur frequently, increase PADSIZE and make the initialisers
275          * below longer.
276          */
277 #define PADSIZE 16              /* pad chunk size */
278         static char blanks[PADSIZE] =
279          {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
280         static char zeroes[PADSIZE] =
281          {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
282
283         /* Print chars to "str", (allocate as needed if alloc is set). */
284 #define PRINT(ptr, len) do { \
285         const char *p = ptr; \
286         const char *endp = ptr + len; \
287         while (p < endp && (str < estr || alloc)) { \
288                 if (alloc && str >= estr) { \
289                         char *t; \
290                         strsize = (strsize << 1) + 1; \
291                         if (!(t = (char *)realloc(*strp, strsize))) { \
292                                 free(str); \
293                                 *strp = NULL; \
294                                 ret = -1; \
295                                 goto done; \
296                         } \
297                         str = t + (str - *strp); \
298                         estr = t + strsize - 1; \
299                         *strp = t; \
300                 } \
301                 *str++ = *p++; \
302         } \
303 } while (0)
304
305         /* BEWARE, PAD uses `n'. */
306 #define PAD(plen, pstr) do { \
307         if ((n = (plen)) > 0) { \
308                 while (n > PADSIZE) { \
309                         PRINT(pstr, PADSIZE); \
310                         n -= PADSIZE; \
311                 } \
312                 PRINT(pstr, n); \
313         } \
314 } while (0)
315
316         /*
317          * To extend shorts properly, we need both signed and unsigned
318          * argument extraction methods.
319          */
320 #define SARG() \
321         (flags&LONGINT ? va_arg(ap, long) : \
322             flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
323             (long)va_arg(ap, int))
324 #define UARG() \
325         (flags&LONGINT ? va_arg(ap, unsigned long) : \
326             flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
327             (unsigned long)va_arg(ap, unsigned int))
328
329         fmt = (char *)fmt0;
330         ret = 0;
331
332         if (alloc) {
333                 strsize = 128;
334                 *strp = str = (char *)malloc(strsize);
335                 if (str == NULL) {
336                         ret = -1;
337                         goto done;
338                 }
339                 estr = str + 127;
340         } else {
341                 str = *strp;
342                 if (strsize)
343                         estr = str + strsize - 1;
344                 else
345                         estr = NULL;
346         }
347
348         /*
349          * Scan the format for conversions (`%' character).
350          */
351         for (;;) {
352                 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
353                         /* void */;
354                 if ((n = fmt - cp) != 0) {
355                         PRINT(cp, n);
356                         ret += n;
357                 }
358                 if (ch == '\0')
359                         goto done;
360                 fmt++;          /* skip over '%' */
361
362                 flags = 0;
363                 dprec = 0;
364                 width = 0;
365                 prec = -1;
366                 sign = '\0';
367
368 rflag:          ch = *fmt++;
369 reswitch:       switch (ch) {
370                 case ' ':
371                         /*
372                          * ``If the space and + flags both appear, the space
373                          * flag will be ignored.''
374                          *      -- ANSI X3J11
375                          */
376                         if (!sign)
377                                 sign = ' ';
378                         goto rflag;
379                 case '#':
380                         flags |= ALT;
381                         goto rflag;
382                 case '*':
383                         /*
384                          * ``A negative field width argument is taken as a
385                          * - flag followed by a positive field width.''
386                          *      -- ANSI X3J11
387                          * They don't exclude field widths read from args.
388                          */
389                         if ((width = va_arg(ap, int)) >= 0)
390                                 goto rflag;
391                         width = -width;
392                         /* FALLTHROUGH */
393                 case '-':
394                         flags |= LADJUST;
395                         goto rflag;
396                 case '+':
397                         sign = '+';
398                         goto rflag;
399                 case '.':
400                         if ((ch = *fmt++) == '*') {
401                                 n = va_arg(ap, int);
402                                 prec = n < 0 ? -1 : n;
403                                 goto rflag;
404                         }
405                         n = 0;
406                         while (is_digit(ch)) {
407                                 n = 10 * n + to_digit(ch);
408                                 ch = *fmt++;
409                         }
410                         prec = n < 0 ? -1 : n;
411                         goto reswitch;
412                 case '0':
413                         /*
414                          * ``Note that 0 is taken as a flag, not as the
415                          * beginning of a field width.''
416                          *      -- ANSI X3J11
417                          */
418                         flags |= ZEROPAD;
419                         goto rflag;
420                 case '1': case '2': case '3': case '4':
421                 case '5': case '6': case '7': case '8': case '9':
422                         n = 0;
423                         do {
424                                 n = 10 * n + to_digit(ch);
425                                 ch = *fmt++;
426                         } while (is_digit(ch));
427                         width = n;
428                         goto reswitch;
429                 case 'h':
430                         flags |= SHORTINT;
431                         goto rflag;
432                 case 'l':
433                         flags |= LONGINT;
434                         goto rflag;
435 #ifdef HAVE_LONG_LONG_INT
436                 case 'q':
437                         flags |= QUADINT;
438                         goto rflag;
439 #endif /* HAVE_LONG_LONG_INT */
440                 case 'c':
441                         *(cp = buf) = va_arg(ap, int);
442                         size = 1;
443                         sign = '\0';
444                         break;
445                 case 'D':
446                         flags |= LONGINT;
447                         /*FALLTHROUGH*/
448                 case 'd':
449                 case 'i':
450 #ifdef HAVE_LONG_LONG_INT
451                         if (flags & QUADINT) {
452                                 uqval = va_arg(ap, long long);
453                                 if ((long long)uqval < 0) {
454                                         uqval = -uqval;
455                                         sign = '-';
456                                 }
457                         }
458                         else
459 #endif /* HAVE_LONG_LONG_INT */
460                         {
461                                 ulval = SARG();
462                                 if ((long)ulval < 0) {
463                                         ulval = -ulval;
464                                         sign = '-';
465                                 }
466                         }
467                         base = 10;
468                         goto number;
469                 case 'n':
470 #ifdef HAVE_LONG_LONG_INT
471                         if (flags & QUADINT)
472                                 *va_arg(ap, long long *) = ret;
473                         else
474 #endif /* HAVE_LONG_LONG_INT */
475                         if (flags & LONGINT)
476                                 *va_arg(ap, long *) = ret;
477                         else if (flags & SHORTINT)
478                                 *va_arg(ap, short *) = ret;
479                         else
480                                 *va_arg(ap, int *) = ret;
481                         continue;       /* no output */
482                 case 'O':
483                         flags |= LONGINT;
484                         /*FALLTHROUGH*/
485                 case 'o':
486 #ifdef HAVE_LONG_LONG_INT
487                         if (flags & QUADINT)
488                                 uqval = va_arg(ap, unsigned long long);
489                         else
490 #endif /* HAVE_LONG_LONG_INT */
491                                 ulval = UARG();
492                         base = 8;
493                         goto nosign;
494                 case 'p':
495                         /*
496                          * ``The argument shall be a pointer to void.  The
497                          * value of the pointer is converted to a sequence
498                          * of printable characters, in an implementation-
499                          * defined manner.''
500                          *      -- ANSI X3J11
501                          */
502                         ulval = (unsigned long)va_arg(ap, void *);
503                         base = 16;
504                         xdigs = "0123456789abcdef";
505                         flags = (flags & ~QUADINT) | HEXPREFIX;
506                         ch = 'x';
507                         goto nosign;
508                 case 's':
509                         if ((cp = va_arg(ap, char *)) == NULL)
510                                 cp = "(null)";
511                         if (prec >= 0) {
512                                 /*
513                                  * can't use strlen; can only look for the
514                                  * NUL in the first `prec' characters, and
515                                  * strlen() will go further.
516                                  */
517                                 char *p = memchr(cp, 0, prec);
518
519                                 if (p != NULL) {
520                                         size = p - cp;
521                                         if (size > prec)
522                                                 size = prec;
523                                 } else
524                                         size = prec;
525                         } else
526                                 size = strlen(cp);
527                         sign = '\0';
528                         break;
529                 case 'U':
530                         flags |= LONGINT;
531                         /*FALLTHROUGH*/
532                 case 'u':
533 #ifdef HAVE_LONG_LONG_INT
534                         if (flags & QUADINT)
535                                 uqval = va_arg(ap, unsigned long long);
536                         else
537 #endif /* HAVE_LONG_LONG_INT */
538                                 ulval = UARG();
539                         base = 10;
540                         goto nosign;
541                 case 'X':
542                         xdigs = "0123456789ABCDEF";
543                         goto hex;
544                 case 'x':
545                         xdigs = "0123456789abcdef";
546 hex:
547 #ifdef HAVE_LONG_LONG_INT
548                         if (flags & QUADINT)
549                                 uqval = va_arg(ap, unsigned long long);
550                         else
551 #endif /* HAVE_LONG_LONG_INT */
552                                 ulval = UARG();
553                         base = 16;
554                         /* leading 0x/X only if non-zero */
555                         if (flags & ALT &&
556 #ifdef HAVE_LONG_LONG_INT
557                             (flags & QUADINT ? uqval != 0 : ulval != 0))
558 #else
559                             ulval != 0)
560 #endif /* HAVE_LONG_LONG_INT */
561                                 flags |= HEXPREFIX;
562
563                         /* unsigned conversions */
564 nosign:                 sign = '\0';
565                         /*
566                          * ``... diouXx conversions ... if a precision is
567                          * specified, the 0 flag will be ignored.''
568                          *      -- ANSI X3J11
569                          */
570 number:                 if ((dprec = prec) >= 0)
571                                 flags &= ~ZEROPAD;
572
573                         /*
574                          * ``The result of converting a zero value with an
575                          * explicit precision of zero is no characters.''
576                          *      -- ANSI X3J11
577                          */
578                         cp = buf + BUF;
579 #ifdef HAVE_LONG_LONG_INT
580                         if (flags & QUADINT) {
581                                 if (uqval != 0 || prec != 0)
582                                         cp = __uqtoa(uqval, cp, base,
583                                             flags & ALT, xdigs);
584                         }
585                         else
586 #endif /* HAVE_LONG_LONG_INT */
587                         {
588                                 if (ulval != 0 || prec != 0)
589                                         cp = __ultoa(ulval, cp, base,
590                                             flags & ALT, xdigs);
591                         }
592                         size = buf + BUF - cp;
593                         break;
594                 default:        /* "%?" prints ?, unless ? is NUL */
595                         if (ch == '\0')
596                                 goto done;
597                         /* pretend it was %c with argument ch */
598                         cp = buf;
599                         *cp = ch;
600                         size = 1;
601                         sign = '\0';
602                         break;
603                 }
604
605                 /*
606                  * All reasonable formats wind up here.  At this point, `cp'
607                  * points to a string which (if not flags&LADJUST) should be
608                  * padded out to `width' places.  If flags&ZEROPAD, it should
609                  * first be prefixed by any sign or other prefix; otherwise,
610                  * it should be blank padded before the prefix is emitted.
611                  * After any left-hand padding and prefixing, emit zeroes
612                  * required by a decimal [diouxX] precision, then print the
613                  * string proper, then emit zeroes required by any leftover
614                  * floating precision; finally, if LADJUST, pad with blanks.
615                  *
616                  * Compute actual size, so we know how much to pad.
617                  * fieldsz excludes decimal prec; realsz includes it.
618                  */
619                 fieldsz = size;
620                 if (sign)
621                         fieldsz++;
622                 else if (flags & HEXPREFIX)
623                         fieldsz += 2;
624                 realsz = dprec > fieldsz ? dprec : fieldsz;
625
626                 /* right-adjusting blank padding */
627                 if ((flags & (LADJUST|ZEROPAD)) == 0)
628                         PAD(width - realsz, blanks);
629
630                 /* prefix */
631                 if (sign) {
632                         PRINT(&sign, 1);
633                 } else if (flags & HEXPREFIX) {
634                         ox[0] = '0';
635                         ox[1] = ch;
636                         PRINT(ox, 2);
637                 }
638
639                 /* right-adjusting zero padding */
640                 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
641                         PAD(width - realsz, zeroes);
642
643                 /* leading zeroes from decimal precision */
644                 PAD(dprec - fieldsz, zeroes);
645
646                 /* the string or number proper */
647                 PRINT(cp, size);
648
649                 /* left-adjusting padding (always blank) */
650                 if (flags & LADJUST)
651                         PAD(width - realsz, blanks);
652
653                 /* finally, adjust ret */
654                 ret += width > realsz ? width : realsz;
655         }
656 done:
657         if (strsize)
658                 *str = '\0';
659         return ret;
660         /* NOTREACHED */
661 }
662
663 #ifndef HAVE_VSNPRINTF
664 int
665 vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
666 {
667
668         return xxxprintf(&str, n, 0, fmt, ap);
669 }
670 #endif /* HAVE_VSNPRINTF */
671
672 #ifndef HAVE_SNPRINTF
673 int
674 snprintf(char *str, size_t n, char const *fmt, ...)
675 {
676         int ret;
677         va_list ap;
678
679         va_start(ap, fmt);
680         ret = xxxprintf(&str, n, 0, fmt, ap);
681         va_end(ap);
682         return ret;
683 }
684 #endif /* HAVE_SNPRINTF */
685
686 #ifndef HAVE_VASPRINTF
687 int
688 vasprintf(char **str, const char *fmt, va_list ap)
689 {
690
691         return xxxprintf(str, 0, 1, fmt, ap);
692 }
693 #endif /* HAVE_VASPRINTF */
694
695 #ifndef HAVE_ASPRINTF
696 int
697 asprintf(char **str, char const *fmt, ...)
698 {
699         int ret;
700         va_list ap;
701
702         va_start(ap, fmt);
703         ret = xxxprintf(str, 0, 1, fmt, ap);
704         va_end(ap);
705         return ret;
706 }
707 #endif /* HAVE_ASPRINTF */