LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/bio - b_print.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 81 289 28.0 %
Date: 2015-10-10 Functions: 5 9 55.6 %

          Line data    Source code
       1             : /* crypto/bio/b_print.c */
       2             : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3             :  * All rights reserved.
       4             :  *
       5             :  * This package is an SSL implementation written
       6             :  * by Eric Young (eay@cryptsoft.com).
       7             :  * The implementation was written so as to conform with Netscapes SSL.
       8             :  *
       9             :  * This library is free for commercial and non-commercial use as long as
      10             :  * the following conditions are aheared to.  The following conditions
      11             :  * apply to all code found in this distribution, be it the RC4, RSA,
      12             :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13             :  * included with this distribution is covered by the same copyright terms
      14             :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15             :  *
      16             :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17             :  * the code are not to be removed.
      18             :  * If this package is used in a product, Eric Young should be given attribution
      19             :  * as the author of the parts of the library used.
      20             :  * This can be in the form of a textual message at program startup or
      21             :  * in documentation (online or textual) provided with the package.
      22             :  *
      23             :  * Redistribution and use in source and binary forms, with or without
      24             :  * modification, are permitted provided that the following conditions
      25             :  * are met:
      26             :  * 1. Redistributions of source code must retain the copyright
      27             :  *    notice, this list of conditions and the following disclaimer.
      28             :  * 2. Redistributions in binary form must reproduce the above copyright
      29             :  *    notice, this list of conditions and the following disclaimer in the
      30             :  *    documentation and/or other materials provided with the distribution.
      31             :  * 3. All advertising materials mentioning features or use of this software
      32             :  *    must display the following acknowledgement:
      33             :  *    "This product includes cryptographic software written by
      34             :  *     Eric Young (eay@cryptsoft.com)"
      35             :  *    The word 'cryptographic' can be left out if the rouines from the library
      36             :  *    being used are not cryptographic related :-).
      37             :  * 4. If you include any Windows specific code (or a derivative thereof) from
      38             :  *    the apps directory (application code) you must include an acknowledgement:
      39             :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40             :  *
      41             :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51             :  * SUCH DAMAGE.
      52             :  *
      53             :  * The licence and distribution terms for any publically available version or
      54             :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55             :  * copied and put under another distribution licence
      56             :  * [including the GNU Public Licence.]
      57             :  */
      58             : 
      59             : /* disable assert() unless BIO_DEBUG has been defined */
      60             : #ifndef BIO_DEBUG
      61             : # ifndef NDEBUG
      62             : #  define NDEBUG
      63             : # endif
      64             : #endif
      65             : 
      66             : /*
      67             :  * Stolen from tjh's ssl/ssl_trc.c stuff.
      68             :  */
      69             : 
      70             : #include <stdio.h>
      71             : #include <string.h>
      72             : #include <ctype.h>
      73             : #include <assert.h>
      74             : #include <limits.h>
      75             : #include "cryptlib.h"
      76             : #ifndef NO_SYS_TYPES_H
      77             : # include <sys/types.h>
      78             : #endif
      79             : #include <openssl/bn.h>         /* To get BN_LLONG properly defined */
      80             : #include <openssl/bio.h>
      81             : 
      82             : #if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
      83             : # ifndef HAVE_LONG_LONG
      84             : #  define HAVE_LONG_LONG 1
      85             : # endif
      86             : #endif
      87             : 
      88             : /***************************************************************************/
      89             : 
      90             : /*
      91             :  * Copyright Patrick Powell 1995
      92             :  * This code is based on code written by Patrick Powell <papowell@astart.com>
      93             :  * It may be used for any purpose as long as this notice remains intact
      94             :  * on all source code distributions.
      95             :  */
      96             : 
      97             : /*-
      98             :  * This code contains numerious changes and enhancements which were
      99             :  * made by lots of contributors over the last years to Patrick Powell's
     100             :  * original code:
     101             :  *
     102             :  * o Patrick Powell <papowell@astart.com>      (1995)
     103             :  * o Brandon Long <blong@fiction.net>          (1996, for Mutt)
     104             :  * o Thomas Roessler <roessler@guug.de>        (1998, for Mutt)
     105             :  * o Michael Elkins <me@cs.hmc.edu>            (1998, for Mutt)
     106             :  * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
     107             :  * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
     108             :  * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
     109             :  * o ...                                       (for OpenSSL)
     110             :  */
     111             : 
     112             : #ifdef HAVE_LONG_DOUBLE
     113             : # define LDOUBLE long double
     114             : #else
     115             : # define LDOUBLE double
     116             : #endif
     117             : 
     118             : #ifdef HAVE_LONG_LONG
     119             : # if defined(_WIN32) && !defined(__GNUC__)
     120             : #  define LLONG __int64
     121             : # else
     122             : #  define LLONG long long
     123             : # endif
     124             : #else
     125             : # define LLONG long
     126             : #endif
     127             : 
     128             : static void fmtstr(char **, char **, size_t *, size_t *,
     129             :                    const char *, int, int, int);
     130             : static void fmtint(char **, char **, size_t *, size_t *,
     131             :                    LLONG, int, int, int, int);
     132             : static void fmtfp(char **, char **, size_t *, size_t *,
     133             :                   LDOUBLE, int, int, int);
     134             : static void doapr_outch(char **, char **, size_t *, size_t *, int);
     135             : static void _dopr(char **sbuffer, char **buffer,
     136             :                   size_t *maxlen, size_t *retlen, int *truncated,
     137             :                   const char *format, va_list args);
     138             : 
     139             : /* format read states */
     140             : #define DP_S_DEFAULT    0
     141             : #define DP_S_FLAGS      1
     142             : #define DP_S_MIN        2
     143             : #define DP_S_DOT        3
     144             : #define DP_S_MAX        4
     145             : #define DP_S_MOD        5
     146             : #define DP_S_CONV       6
     147             : #define DP_S_DONE       7
     148             : 
     149             : /* format flags - Bits */
     150             : #define DP_F_MINUS      (1 << 0)
     151             : #define DP_F_PLUS       (1 << 1)
     152             : #define DP_F_SPACE      (1 << 2)
     153             : #define DP_F_NUM        (1 << 3)
     154             : #define DP_F_ZERO       (1 << 4)
     155             : #define DP_F_UP         (1 << 5)
     156             : #define DP_F_UNSIGNED   (1 << 6)
     157             : 
     158             : /* conversion flags */
     159             : #define DP_C_SHORT      1
     160             : #define DP_C_LONG       2
     161             : #define DP_C_LDOUBLE    3
     162             : #define DP_C_LLONG      4
     163             : 
     164             : /* some handy macros */
     165             : #define char_to_int(p) (p - '0')
     166             : #define OSSL_MAX(p,q) ((p >= q) ? p : q)
     167             : 
     168             : static void
     169        1480 : _dopr(char **sbuffer,
     170             :       char **buffer,
     171             :       size_t *maxlen,
     172             :       size_t *retlen, int *truncated, const char *format, va_list args)
     173             : {
     174             :     char ch;
     175             :     LLONG value;
     176             :     LDOUBLE fvalue;
     177             :     char *strvalue;
     178             :     int min;
     179             :     int max;
     180             :     int state;
     181             :     int flags;
     182             :     int cflags;
     183             :     size_t currlen;
     184             : 
     185             :     state = DP_S_DEFAULT;
     186        1480 :     flags = currlen = cflags = min = 0;
     187             :     max = -1;
     188        1480 :     ch = *format++;
     189             : 
     190       76960 :     while (state != DP_S_DONE) {
     191       74000 :         if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
     192             :             state = DP_S_DONE;
     193             : 
     194       74000 :         switch (state) {
     195             :         case DP_S_DEFAULT:
     196       10360 :             if (ch == '%')
     197             :                 state = DP_S_FLAGS;
     198             :             else
     199        1480 :                 doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
     200       10360 :             ch = *format++;
     201       10360 :             break;
     202             :         case DP_S_FLAGS:
     203       17760 :             switch (ch) {
     204             :             case '-':
     205           0 :                 flags |= DP_F_MINUS;
     206           0 :                 ch = *format++;
     207           0 :                 break;
     208             :             case '+':
     209           0 :                 flags |= DP_F_PLUS;
     210           0 :                 ch = *format++;
     211           0 :                 break;
     212             :             case ' ':
     213           0 :                 flags |= DP_F_SPACE;
     214           0 :                 ch = *format++;
     215           0 :                 break;
     216             :             case '#':
     217           0 :                 flags |= DP_F_NUM;
     218           0 :                 ch = *format++;
     219           0 :                 break;
     220             :             case '0':
     221        8880 :                 flags |= DP_F_ZERO;
     222        8880 :                 ch = *format++;
     223        8880 :                 break;
     224             :             default:
     225             :                 state = DP_S_MIN;
     226             :                 break;
     227             :             }
     228             :             break;
     229             :         case DP_S_MIN:
     230       17760 :             if (isdigit((unsigned char)ch)) {
     231        8880 :                 min = 10 * min + char_to_int(ch);
     232        8880 :                 ch = *format++;
     233        8880 :             } else if (ch == '*') {
     234           0 :                 min = va_arg(args, int);
     235           0 :                 ch = *format++;
     236             :                 state = DP_S_DOT;
     237             :             } else
     238             :                 state = DP_S_DOT;
     239             :             break;
     240             :         case DP_S_DOT:
     241        8880 :             if (ch == '.') {
     242             :                 state = DP_S_MAX;
     243           0 :                 ch = *format++;
     244             :             } else
     245             :                 state = DP_S_MOD;
     246             :             break;
     247             :         case DP_S_MAX:
     248           0 :             if (isdigit((unsigned char)ch)) {
     249           0 :                 if (max < 0)
     250             :                     max = 0;
     251           0 :                 max = 10 * max + char_to_int(ch);
     252           0 :                 ch = *format++;
     253           0 :             } else if (ch == '*') {
     254           0 :                 max = va_arg(args, int);
     255           0 :                 ch = *format++;
     256             :                 state = DP_S_MOD;
     257             :             } else
     258             :                 state = DP_S_MOD;
     259             :             break;
     260             :         case DP_S_MOD:
     261        8880 :             switch (ch) {
     262             :             case 'h':
     263             :                 cflags = DP_C_SHORT;
     264           0 :                 ch = *format++;
     265           0 :                 break;
     266             :             case 'l':
     267           0 :                 if (*format == 'l') {
     268             :                     cflags = DP_C_LLONG;
     269           0 :                     format++;
     270             :                 } else
     271             :                     cflags = DP_C_LONG;
     272           0 :                 ch = *format++;
     273           0 :                 break;
     274             :             case 'q':
     275             :                 cflags = DP_C_LLONG;
     276           0 :                 ch = *format++;
     277           0 :                 break;
     278             :             case 'L':
     279             :                 cflags = DP_C_LDOUBLE;
     280           0 :                 ch = *format++;
     281           0 :                 break;
     282             :             default:
     283             :                 break;
     284             :             }
     285             :             state = DP_S_CONV;
     286             :             break;
     287             :         case DP_S_CONV:
     288        8880 :             switch (ch) {
     289             :             case 'd':
     290             :             case 'i':
     291        8880 :                 switch (cflags) {
     292             :                 case DP_C_SHORT:
     293           0 :                     value = (short int)va_arg(args, int);
     294           0 :                     break;
     295             :                 case DP_C_LONG:
     296           0 :                     value = va_arg(args, long int);
     297           0 :                     break;
     298             :                 case DP_C_LLONG:
     299           0 :                     value = va_arg(args, LLONG);
     300           0 :                     break;
     301             :                 default:
     302        8880 :                     value = va_arg(args, int);
     303        8880 :                     break;
     304             :                 }
     305        8880 :                 fmtint(sbuffer, buffer, &currlen, maxlen,
     306             :                        value, 10, min, max, flags);
     307        8880 :                 break;
     308             :             case 'X':
     309           0 :                 flags |= DP_F_UP;
     310             :                 /* FALLTHROUGH */
     311             :             case 'x':
     312             :             case 'o':
     313             :             case 'u':
     314           0 :                 flags |= DP_F_UNSIGNED;
     315           0 :                 switch (cflags) {
     316             :                 case DP_C_SHORT:
     317           0 :                     value = (unsigned short int)va_arg(args, unsigned int);
     318           0 :                     break;
     319             :                 case DP_C_LONG:
     320           0 :                     value = (LLONG) va_arg(args, unsigned long int);
     321           0 :                     break;
     322             :                 case DP_C_LLONG:
     323           0 :                     value = va_arg(args, unsigned LLONG);
     324           0 :                     break;
     325             :                 default:
     326           0 :                     value = (LLONG) va_arg(args, unsigned int);
     327           0 :                     break;
     328             :                 }
     329           0 :                 fmtint(sbuffer, buffer, &currlen, maxlen, value,
     330           0 :                        ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
     331             :                        min, max, flags);
     332           0 :                 break;
     333             :             case 'f':
     334           0 :                 if (cflags == DP_C_LDOUBLE)
     335           0 :                     fvalue = va_arg(args, LDOUBLE);
     336             :                 else
     337           0 :                     fvalue = va_arg(args, double);
     338           0 :                 fmtfp(sbuffer, buffer, &currlen, maxlen,
     339             :                       fvalue, min, max, flags);
     340           0 :                 break;
     341             :             case 'E':
     342             :                 flags |= DP_F_UP;
     343             :             case 'e':
     344           0 :                 if (cflags == DP_C_LDOUBLE)
     345           0 :                     fvalue = va_arg(args, LDOUBLE);
     346             :                 else
     347           0 :                     fvalue = va_arg(args, double);
     348             :                 break;
     349             :             case 'G':
     350             :                 flags |= DP_F_UP;
     351             :             case 'g':
     352           0 :                 if (cflags == DP_C_LDOUBLE)
     353           0 :                     fvalue = va_arg(args, LDOUBLE);
     354             :                 else
     355           0 :                     fvalue = va_arg(args, double);
     356             :                 break;
     357             :             case 'c':
     358           0 :                 doapr_outch(sbuffer, buffer, &currlen, maxlen,
     359             :                             va_arg(args, int));
     360           0 :                 break;
     361             :             case 's':
     362           0 :                 strvalue = va_arg(args, char *);
     363           0 :                 if (max < 0) {
     364           0 :                     if (buffer)
     365             :                         max = INT_MAX;
     366             :                     else
     367           0 :                         max = *maxlen;
     368             :                 }
     369           0 :                 fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
     370             :                        flags, min, max);
     371           0 :                 break;
     372             :             case 'p':
     373           0 :                 value = (long)va_arg(args, void *);
     374           0 :                 fmtint(sbuffer, buffer, &currlen, maxlen,
     375             :                        value, 16, min, max, flags | DP_F_NUM);
     376           0 :                 break;
     377             :             case 'n':          /* XXX */
     378           0 :                 if (cflags == DP_C_SHORT) {
     379             :                     short int *num;
     380           0 :                     num = va_arg(args, short int *);
     381           0 :                     *num = currlen;
     382           0 :                 } else if (cflags == DP_C_LONG) { /* XXX */
     383             :                     long int *num;
     384           0 :                     num = va_arg(args, long int *);
     385           0 :                     *num = (long int)currlen;
     386           0 :                 } else if (cflags == DP_C_LLONG) { /* XXX */
     387             :                     LLONG *num;
     388           0 :                     num = va_arg(args, LLONG *);
     389           0 :                     *num = (LLONG) currlen;
     390             :                 } else {
     391             :                     int *num;
     392           0 :                     num = va_arg(args, int *);
     393           0 :                     *num = currlen;
     394             :                 }
     395             :                 break;
     396             :             case '%':
     397           0 :                 doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
     398           0 :                 break;
     399             :             case 'w':
     400             :                 /* not supported yet, treat as next char */
     401           0 :                 ch = *format++;
     402           0 :                 break;
     403             :             default:
     404             :                 /* unknown, skip */
     405             :                 break;
     406             :             }
     407        8880 :             ch = *format++;
     408             :             state = DP_S_DEFAULT;
     409             :             flags = cflags = min = 0;
     410             :             max = -1;
     411        8880 :             break;
     412             :         case DP_S_DONE:
     413             :             break;
     414             :         default:
     415             :             break;
     416             :         }
     417             :     }
     418        1480 :     *truncated = (currlen > *maxlen - 1);
     419        1480 :     if (*truncated)
     420           0 :         currlen = *maxlen - 1;
     421        1480 :     doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
     422        1480 :     *retlen = currlen - 1;
     423        1480 :     return;
     424             : }
     425             : 
     426             : static void
     427           0 : fmtstr(char **sbuffer,
     428             :        char **buffer,
     429             :        size_t *currlen,
     430             :        size_t *maxlen, const char *value, int flags, int min, int max)
     431             : {
     432             :     int padlen, strln;
     433             :     int cnt = 0;
     434             : 
     435           0 :     if (value == 0)
     436             :         value = "<NULL>";
     437           0 :     for (strln = 0; value[strln]; ++strln) ;
     438           0 :     padlen = min - strln;
     439           0 :     if (padlen < 0)
     440             :         padlen = 0;
     441           0 :     if (flags & DP_F_MINUS)
     442           0 :         padlen = -padlen;
     443             : 
     444           0 :     while ((padlen > 0) && (cnt < max)) {
     445           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
     446           0 :         --padlen;
     447           0 :         ++cnt;
     448             :     }
     449           0 :     while (*value && (cnt < max)) {
     450           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
     451           0 :         ++cnt;
     452             :     }
     453           0 :     while ((padlen < 0) && (cnt < max)) {
     454           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
     455           0 :         ++padlen;
     456           0 :         ++cnt;
     457             :     }
     458           0 : }
     459             : 
     460             : static void
     461        8880 : fmtint(char **sbuffer,
     462             :        char **buffer,
     463             :        size_t *currlen,
     464             :        size_t *maxlen, LLONG value, int base, int min, int max, int flags)
     465             : {
     466             :     int signvalue = 0;
     467             :     const char *prefix = "";
     468             :     unsigned LLONG uvalue;
     469             :     char convert[DECIMAL_SIZE(value) + 3];
     470             :     int place = 0;
     471             :     int spadlen = 0;
     472             :     int zpadlen = 0;
     473             :     int caps = 0;
     474             : 
     475        8880 :     if (max < 0)
     476             :         max = 0;
     477        8880 :     uvalue = value;
     478        8880 :     if (!(flags & DP_F_UNSIGNED)) {
     479        8880 :         if (value < 0) {
     480             :             signvalue = '-';
     481           0 :             uvalue = -value;
     482        8880 :         } else if (flags & DP_F_PLUS)
     483             :             signvalue = '+';
     484        8880 :         else if (flags & DP_F_SPACE)
     485             :             signvalue = ' ';
     486             :     }
     487        8880 :     if (flags & DP_F_NUM) {
     488           0 :         if (base == 8)
     489             :             prefix = "0";
     490           0 :         if (base == 16)
     491             :             prefix = "0x";
     492             :     }
     493        8880 :     if (flags & DP_F_UP)
     494             :         caps = 1;
     495             :     do {
     496       31920 :         convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
     497       15960 :             [uvalue % (unsigned)base];
     498       15960 :         uvalue = (uvalue / (unsigned)base);
     499       15960 :     } while (uvalue && (place < (int)sizeof(convert)));
     500        8880 :     if (place == sizeof(convert))
     501             :         place--;
     502        8880 :     convert[place] = 0;
     503             : 
     504        8880 :     zpadlen = max - place;
     505       17760 :     spadlen =
     506       17760 :         min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
     507        8880 :     if (zpadlen < 0)
     508             :         zpadlen = 0;
     509        8880 :     if (spadlen < 0)
     510             :         spadlen = 0;
     511        8880 :     if (flags & DP_F_ZERO) {
     512        8880 :         zpadlen = OSSL_MAX(zpadlen, spadlen);
     513             :         spadlen = 0;
     514             :     }
     515        8880 :     if (flags & DP_F_MINUS)
     516           0 :         spadlen = -spadlen;
     517             : 
     518             :     /* spaces */
     519        8880 :     while (spadlen > 0) {
     520           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
     521           0 :         --spadlen;
     522             :     }
     523             : 
     524             :     /* sign */
     525        8880 :     if (signvalue)
     526           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
     527             : 
     528             :     /* prefix */
     529        8880 :     while (*prefix) {
     530           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
     531           0 :         prefix++;
     532             :     }
     533             : 
     534             :     /* zeros */
     535        8880 :     if (zpadlen > 0) {
     536        3600 :         while (zpadlen > 0) {
     537        1800 :             doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
     538        1800 :             --zpadlen;
     539             :         }
     540             :     }
     541             :     /* digits */
     542       24840 :     while (place > 0)
     543       15960 :         doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
     544             : 
     545             :     /* left justified spaces */
     546        8880 :     while (spadlen < 0) {
     547           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
     548           0 :         ++spadlen;
     549             :     }
     550        8880 :     return;
     551             : }
     552             : 
     553             : static LDOUBLE abs_val(LDOUBLE value)
     554             : {
     555             :     LDOUBLE result = value;
     556           0 :     if (value < 0)
     557           0 :         result = -value;
     558             :     return result;
     559             : }
     560             : 
     561             : static LDOUBLE pow_10(int in_exp)
     562             : {
     563             :     LDOUBLE result = 1;
     564           0 :     while (in_exp) {
     565           0 :         result *= 10;
     566           0 :         in_exp--;
     567             :     }
     568             :     return result;
     569             : }
     570             : 
     571             : static long roundv(LDOUBLE value)
     572             : {
     573             :     long intpart;
     574           0 :     intpart = (long)value;
     575           0 :     value = value - intpart;
     576           0 :     if (value >= 0.5)
     577           0 :         intpart++;
     578             :     return intpart;
     579             : }
     580             : 
     581             : static void
     582           0 : fmtfp(char **sbuffer,
     583             :       char **buffer,
     584             :       size_t *currlen,
     585             :       size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags)
     586             : {
     587             :     int signvalue = 0;
     588             :     LDOUBLE ufvalue;
     589             :     char iconvert[20];
     590             :     char fconvert[20];
     591             :     int iplace = 0;
     592             :     int fplace = 0;
     593             :     int padlen = 0;
     594             :     int zpadlen = 0;
     595             :     long intpart;
     596             :     long fracpart;
     597             :     long max10;
     598             : 
     599           0 :     if (max < 0)
     600             :         max = 6;
     601             :     ufvalue = abs_val(fvalue);
     602           0 :     if (fvalue < 0)
     603             :         signvalue = '-';
     604           0 :     else if (flags & DP_F_PLUS)
     605             :         signvalue = '+';
     606           0 :     else if (flags & DP_F_SPACE)
     607             :         signvalue = ' ';
     608             : 
     609           0 :     intpart = (long)ufvalue;
     610             : 
     611             :     /*
     612             :      * sorry, we only support 9 digits past the decimal because of our
     613             :      * conversion method
     614             :      */
     615           0 :     if (max > 9)
     616             :         max = 9;
     617             : 
     618             :     /*
     619             :      * we "cheat" by converting the fractional part to integer by multiplying
     620             :      * by a factor of 10
     621             :      */
     622             :     max10 = roundv(pow_10(max));
     623           0 :     fracpart = roundv(pow_10(max) * (ufvalue - intpart));
     624             : 
     625           0 :     if (fracpart >= max10) {
     626           0 :         intpart++;
     627           0 :         fracpart -= max10;
     628             :     }
     629             : 
     630             :     /* convert integer part */
     631             :     do {
     632           0 :         iconvert[iplace++] = "0123456789"[intpart % 10];
     633           0 :         intpart = (intpart / 10);
     634           0 :     } while (intpart && (iplace < (int)sizeof(iconvert)));
     635           0 :     if (iplace == sizeof iconvert)
     636             :         iplace--;
     637           0 :     iconvert[iplace] = 0;
     638             : 
     639             :     /* convert fractional part */
     640             :     do {
     641           0 :         fconvert[fplace++] = "0123456789"[fracpart % 10];
     642           0 :         fracpart = (fracpart / 10);
     643           0 :     } while (fplace < max);
     644           0 :     if (fplace == sizeof fconvert)
     645             :         fplace--;
     646           0 :     fconvert[fplace] = 0;
     647             : 
     648             :     /* -1 for decimal point, another -1 if we are printing a sign */
     649           0 :     padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
     650           0 :     zpadlen = max - fplace;
     651           0 :     if (zpadlen < 0)
     652             :         zpadlen = 0;
     653           0 :     if (padlen < 0)
     654             :         padlen = 0;
     655           0 :     if (flags & DP_F_MINUS)
     656           0 :         padlen = -padlen;
     657             : 
     658           0 :     if ((flags & DP_F_ZERO) && (padlen > 0)) {
     659           0 :         if (signvalue) {
     660           0 :             doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
     661           0 :             --padlen;
     662             :             signvalue = 0;
     663             :         }
     664           0 :         while (padlen > 0) {
     665           0 :             doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
     666           0 :             --padlen;
     667             :         }
     668             :     }
     669           0 :     while (padlen > 0) {
     670           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
     671           0 :         --padlen;
     672             :     }
     673           0 :     if (signvalue)
     674           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
     675             : 
     676           0 :     while (iplace > 0)
     677           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
     678             : 
     679             :     /*
     680             :      * Decimal point. This should probably use locale to find the correct
     681             :      * char to print out.
     682             :      */
     683           0 :     if (max > 0 || (flags & DP_F_NUM)) {
     684           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
     685             : 
     686           0 :         while (fplace > 0)
     687           0 :             doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
     688             :     }
     689           0 :     while (zpadlen > 0) {
     690           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
     691           0 :         --zpadlen;
     692             :     }
     693             : 
     694           0 :     while (padlen < 0) {
     695           0 :         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
     696           0 :         ++padlen;
     697             :     }
     698           0 : }
     699             : 
     700             : static void
     701       20720 : doapr_outch(char **sbuffer,
     702             :             char **buffer, size_t *currlen, size_t *maxlen, int c)
     703             : {
     704             :     /* If we haven't at least one buffer, someone has doe a big booboo */
     705             :     assert(*sbuffer != NULL || buffer != NULL);
     706             : 
     707             :     /* |currlen| must always be <= |*maxlen| */
     708             :     assert(*currlen <= *maxlen);
     709             : 
     710       20720 :     if (buffer && *currlen == *maxlen) {
     711           0 :         *maxlen += 1024;
     712           0 :         if (*buffer == NULL) {
     713           0 :             *buffer = OPENSSL_malloc(*maxlen);
     714           0 :             if (!*buffer) {
     715             :                 /* Panic! Can't really do anything sensible. Just return */
     716             :                 return;
     717             :             }
     718           0 :             if (*currlen > 0) {
     719             :                 assert(*sbuffer != NULL);
     720           0 :                 memcpy(*buffer, *sbuffer, *currlen);
     721             :             }
     722           0 :             *sbuffer = NULL;
     723             :         } else {
     724           0 :             *buffer = OPENSSL_realloc(*buffer, *maxlen);
     725           0 :             if (!*buffer) {
     726             :                 /* Panic! Can't really do anything sensible. Just return */
     727             :                 return;
     728             :             }
     729             :         }
     730             :     }
     731             : 
     732       20720 :     if (*currlen < *maxlen) {
     733       20720 :         if (*sbuffer)
     734       20720 :             (*sbuffer)[(*currlen)++] = (char)c;
     735             :         else
     736           0 :             (*buffer)[(*currlen)++] = (char)c;
     737             :     }
     738             : 
     739             :     return;
     740             : }
     741             : 
     742             : /***************************************************************************/
     743             : 
     744           0 : int BIO_printf(BIO *bio, const char *format, ...)
     745             : {
     746             :     va_list args;
     747             :     int ret;
     748             : 
     749           0 :     va_start(args, format);
     750             : 
     751           0 :     ret = BIO_vprintf(bio, format, args);
     752             : 
     753           0 :     va_end(args);
     754           0 :     return (ret);
     755             : }
     756             : 
     757           0 : int BIO_vprintf(BIO *bio, const char *format, va_list args)
     758             : {
     759             :     int ret;
     760             :     size_t retlen;
     761             :     char hugebuf[1024 * 2];     /* Was previously 10k, which is unreasonable
     762             :                                  * in small-stack environments, like threads
     763             :                                  * or DOS programs. */
     764           0 :     char *hugebufp = hugebuf;
     765           0 :     size_t hugebufsize = sizeof(hugebuf);
     766           0 :     char *dynbuf = NULL;
     767             :     int ignored;
     768             : 
     769             :     dynbuf = NULL;
     770           0 :     CRYPTO_push_info("doapr()");
     771           0 :     _dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, args);
     772           0 :     if (dynbuf) {
     773           0 :         ret = BIO_write(bio, dynbuf, (int)retlen);
     774           0 :         OPENSSL_free(dynbuf);
     775             :     } else {
     776           0 :         ret = BIO_write(bio, hugebuf, (int)retlen);
     777             :     }
     778           0 :     CRYPTO_pop_info();
     779           0 :     return (ret);
     780             : }
     781             : 
     782             : /*
     783             :  * As snprintf is not available everywhere, we provide our own
     784             :  * implementation. This function has nothing to do with BIOs, but it's
     785             :  * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
     786             :  * function should be renamed, but to what?)
     787             :  */
     788        1480 : int BIO_snprintf(char *buf, size_t n, const char *format, ...)
     789             : {
     790             :     va_list args;
     791             :     int ret;
     792             : 
     793        1480 :     va_start(args, format);
     794             : 
     795        1480 :     ret = BIO_vsnprintf(buf, n, format, args);
     796             : 
     797        1480 :     va_end(args);
     798        1480 :     return (ret);
     799             : }
     800             : 
     801        1480 : int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
     802             : {
     803             :     size_t retlen;
     804             :     int truncated;
     805             : 
     806        1480 :     _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
     807             : 
     808        1480 :     if (truncated)
     809             :         /*
     810             :          * In case of truncation, return -1 like traditional snprintf.
     811             :          * (Current drafts for ISO/IEC 9899 say snprintf should return the
     812             :          * number of characters that would have been written, had the buffer
     813             :          * been large enough.)
     814             :          */
     815             :         return -1;
     816             :     else
     817        1480 :         return (retlen <= INT_MAX) ? (int)retlen : -1;
     818             : }

Generated by: LCOV version 1.10