Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/bio/b_print.c
Line
Count
Source (jump to first uncovered line)
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
7.45k
# 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
7.45k
# define LLONG long
126
#endif
127
128
static int fmtstr(char **, char **, size_t *, size_t *,
129
                  const char *, int, int, int);
130
static int fmtint(char **, char **, size_t *, size_t *,
131
                  LLONG, int, int, int, int);
132
static int fmtfp(char **, char **, size_t *, size_t *,
133
                 LDOUBLE, int, int, int);
134
static int doapr_outch(char **, char **, size_t *, size_t *, int);
135
static int _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
29.8k
#define DP_S_DEFAULT    0
141
14.9k
#define DP_S_FLAGS      1
142
14.9k
#define DP_S_MIN        2
143
14.9k
#define DP_S_DOT        3
144
0
#define DP_S_MAX        4
145
14.9k
#define DP_S_MOD        5
146
14.9k
#define DP_S_CONV       6
147
82.0k
#define DP_S_DONE       7
148
149
/* format flags - Bits */
150
7.45k
#define DP_F_MINUS      (1 << 0)
151
0
#define DP_F_PLUS       (1 << 1)
152
0
#define DP_F_SPACE      (1 << 2)
153
7.45k
#define DP_F_NUM        (1 << 3)
154
7.45k
#define DP_F_ZERO       (1 << 4)
155
7.45k
#define DP_F_UP         (1 << 5)
156
14.9k
#define DP_F_UNSIGNED   (1 << 6)
157
158
/* conversion flags */
159
0
#define DP_C_SHORT      1
160
14.9k
#define DP_C_LONG       2
161
0
#define DP_C_LDOUBLE    3
162
0
#define DP_C_LLONG      4
163
164
/* some handy macros */
165
0
#define char_to_int(p) (p - '0')
166
7.45k
#define OSSL_MAX(p,q) ((p >= q) ? p : q)
167
168
static int
169
_dopr(char **sbuffer,
170
      char **buffer,
171
      size_t *maxlen,
172
      size_t *retlen, int *truncated, const char *format, va_list args)
173
7.45k
{
174
7.45k
    char ch;
175
7.45k
    LLONG value;
176
7.45k
    LDOUBLE fvalue;
177
7.45k
    char *strvalue;
178
7.45k
    int min;
179
7.45k
    int max;
180
7.45k
    int state;
181
7.45k
    int flags;
182
7.45k
    int cflags;
183
7.45k
    size_t currlen;
184
185
7.45k
    state = DP_S_DEFAULT;
186
7.45k
    flags = currlen = cflags = min = 0;
187
7.45k
    max = -1;
188
7.45k
    ch = *format++;
189
190
67.1k
    while (state != DP_S_DONE) {
191
59.6k
        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
192
7.45k
            state = DP_S_DONE;
193
194
59.6k
        switch (state) {
195
14.9k
        case DP_S_DEFAULT:
196
14.9k
            if (ch == '%')
197
7.45k
                state = DP_S_FLAGS;
198
7.45k
            else
199
7.45k
                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
200
0
                    return 0;
201
14.9k
            ch = *format++;
202
14.9k
            break;
203
7.45k
        case DP_S_FLAGS:
204
7.45k
            switch (ch) {
205
0
            case '-':
206
0
                flags |= DP_F_MINUS;
207
0
                ch = *format++;
208
0
                break;
209
0
            case '+':
210
0
                flags |= DP_F_PLUS;
211
0
                ch = *format++;
212
0
                break;
213
0
            case ' ':
214
0
                flags |= DP_F_SPACE;
215
0
                ch = *format++;
216
0
                break;
217
0
            case '#':
218
0
                flags |= DP_F_NUM;
219
0
                ch = *format++;
220
0
                break;
221
0
            case '0':
222
0
                flags |= DP_F_ZERO;
223
0
                ch = *format++;
224
0
                break;
225
7.45k
            default:
226
7.45k
                state = DP_S_MIN;
227
7.45k
                break;
228
7.45k
            }
229
7.45k
            break;
230
7.45k
        case DP_S_MIN:
231
7.45k
            if (isdigit((unsigned char)ch)) {
232
0
                min = 10 * min + char_to_int(ch);
233
0
                ch = *format++;
234
7.45k
            } else if (ch == '*') {
235
0
                min = va_arg(args, int);
236
0
                ch = *format++;
237
0
                state = DP_S_DOT;
238
0
            } else
239
7.45k
                state = DP_S_DOT;
240
7.45k
            break;
241
7.45k
        case DP_S_DOT:
242
7.45k
            if (ch == '.') {
243
0
                state = DP_S_MAX;
244
0
                ch = *format++;
245
0
            } else
246
7.45k
                state = DP_S_MOD;
247
7.45k
            break;
248
0
        case DP_S_MAX:
249
0
            if (isdigit((unsigned char)ch)) {
250
0
                if (max < 0)
251
0
                    max = 0;
252
0
                max = 10 * max + char_to_int(ch);
253
0
                ch = *format++;
254
0
            } else if (ch == '*') {
255
0
                max = va_arg(args, int);
256
0
                ch = *format++;
257
0
                state = DP_S_MOD;
258
0
            } else
259
0
                state = DP_S_MOD;
260
0
            break;
261
7.45k
        case DP_S_MOD:
262
7.45k
            switch (ch) {
263
0
            case 'h':
264
0
                cflags = DP_C_SHORT;
265
0
                ch = *format++;
266
0
                break;
267
7.45k
            case 'l':
268
7.45k
                if (*format == 'l') {
269
0
                    cflags = DP_C_LLONG;
270
0
                    format++;
271
0
                } else
272
7.45k
                    cflags = DP_C_LONG;
273
7.45k
                ch = *format++;
274
7.45k
                break;
275
0
            case 'q':
276
0
                cflags = DP_C_LLONG;
277
0
                ch = *format++;
278
0
                break;
279
0
            case 'L':
280
0
                cflags = DP_C_LDOUBLE;
281
0
                ch = *format++;
282
0
                break;
283
0
            default:
284
0
                break;
285
7.45k
            }
286
7.45k
            state = DP_S_CONV;
287
7.45k
            break;
288
7.45k
        case DP_S_CONV:
289
7.45k
            switch (ch) {
290
0
            case 'd':
291
0
            case 'i':
292
0
                switch (cflags) {
293
0
                case DP_C_SHORT:
294
0
                    value = (short int)va_arg(args, int);
295
0
                    break;
296
0
                case DP_C_LONG:
297
0
                    value = va_arg(args, long int);
298
0
                    break;
299
0
                case DP_C_LLONG:
300
0
                    value = va_arg(args, LLONG);
301
0
                    break;
302
0
                default:
303
0
                    value = va_arg(args, int);
304
0
                    break;
305
0
                }
306
0
                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
307
0
                            max, flags))
308
0
                    return 0;
309
0
                break;
310
0
            case 'X':
311
0
                flags |= DP_F_UP;
312
                /* FALLTHROUGH */
313
0
            case 'x':
314
0
            case 'o':
315
7.45k
            case 'u':
316
7.45k
                flags |= DP_F_UNSIGNED;
317
7.45k
                switch (cflags) {
318
0
                case DP_C_SHORT:
319
0
                    value = (unsigned short int)va_arg(args, unsigned int);
320
0
                    break;
321
7.45k
                case DP_C_LONG:
322
7.45k
                    value = (LLONG) va_arg(args, unsigned long int);
323
7.45k
                    break;
324
0
                case DP_C_LLONG:
325
0
                    value = va_arg(args, unsigned LLONG);
326
0
                    break;
327
0
                default:
328
0
                    value = (LLONG) va_arg(args, unsigned int);
329
0
                    break;
330
7.45k
                }
331
7.45k
                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
332
7.45k
                            ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
333
7.45k
                            min, max, flags))
334
0
                    return 0;
335
7.45k
                break;
336
7.45k
            case 'f':
337
0
                if (cflags == DP_C_LDOUBLE)
338
0
                    fvalue = va_arg(args, LDOUBLE);
339
0
                else
340
0
                    fvalue = va_arg(args, double);
341
0
                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
342
0
                           flags))
343
0
                    return 0;
344
0
                break;
345
0
            case 'E':
346
0
                flags |= DP_F_UP;
347
0
            case 'e':
348
0
                if (cflags == DP_C_LDOUBLE)
349
0
                    fvalue = va_arg(args, LDOUBLE);
350
0
                else
351
0
                    fvalue = va_arg(args, double);
352
0
                break;
353
0
            case 'G':
354
0
                flags |= DP_F_UP;
355
0
            case 'g':
356
0
                if (cflags == DP_C_LDOUBLE)
357
0
                    fvalue = va_arg(args, LDOUBLE);
358
0
                else
359
0
                    fvalue = va_arg(args, double);
360
0
                break;
361
0
            case 'c':
362
0
                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
363
0
                            va_arg(args, int)))
364
0
                    return 0;
365
0
                break;
366
0
            case 's':
367
0
                strvalue = va_arg(args, char *);
368
0
                if (max < 0) {
369
0
                    if (buffer)
370
0
                        max = INT_MAX;
371
0
                    else
372
0
                        max = *maxlen;
373
0
                }
374
0
                if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
375
0
                            flags, min, max))
376
0
                    return 0;
377
0
                break;
378
0
            case 'p':
379
0
                value = (long)va_arg(args, void *);
380
0
                if (!fmtint(sbuffer, buffer, &currlen, maxlen,
381
0
                            value, 16, min, max, flags | DP_F_NUM))
382
0
                    return 0;
383
0
                break;
384
0
            case 'n':          /* XXX */
385
0
                if (cflags == DP_C_SHORT) {
386
0
                    short int *num;
387
0
                    num = va_arg(args, short int *);
388
0
                    *num = currlen;
389
0
                } else if (cflags == DP_C_LONG) { /* XXX */
390
0
                    long int *num;
391
0
                    num = va_arg(args, long int *);
392
0
                    *num = (long int)currlen;
393
0
                } else if (cflags == DP_C_LLONG) { /* XXX */
394
0
                    LLONG *num;
395
0
                    num = va_arg(args, LLONG *);
396
0
                    *num = (LLONG) currlen;
397
0
                } else {
398
0
                    int *num;
399
0
                    num = va_arg(args, int *);
400
0
                    *num = currlen;
401
0
                }
402
0
                break;
403
0
            case '%':
404
0
                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
405
0
                    return 0;
406
0
                break;
407
0
            case 'w':
408
                /* not supported yet, treat as next char */
409
0
                ch = *format++;
410
0
                break;
411
0
            default:
412
                /* unknown, skip */
413
0
                break;
414
7.45k
            }
415
7.45k
            ch = *format++;
416
7.45k
            state = DP_S_DEFAULT;
417
7.45k
            flags = cflags = min = 0;
418
7.45k
            max = -1;
419
7.45k
            break;
420
7.45k
        case DP_S_DONE:
421
7.45k
            break;
422
0
        default:
423
0
            break;
424
59.6k
        }
425
59.6k
    }
426
    /*
427
     * We have to truncate if there is no dynamic buffer and we have filled the
428
     * static buffer.
429
     */
430
7.45k
    if (buffer == NULL) {
431
7.45k
        *truncated = (currlen > *maxlen - 1);
432
7.45k
        if (*truncated)
433
0
            currlen = *maxlen - 1;
434
7.45k
    }
435
7.45k
    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
436
0
        return 0;
437
7.45k
    *retlen = currlen - 1;
438
7.45k
    return 1;
439
7.45k
}
440
441
static int
442
fmtstr(char **sbuffer,
443
       char **buffer,
444
       size_t *currlen,
445
       size_t *maxlen, const char *value, int flags, int min, int max)
446
0
{
447
0
    int padlen;
448
0
    size_t strln;
449
0
    int cnt = 0;
450
451
0
    if (value == 0)
452
0
        value = "<NULL>";
453
454
0
    strln = strlen(value);
455
0
    if (strln > INT_MAX)
456
0
        strln = INT_MAX;
457
458
0
    padlen = min - strln;
459
0
    if (min < 0 || padlen < 0)
460
0
        padlen = 0;
461
0
    if (flags & DP_F_MINUS)
462
0
        padlen = -padlen;
463
464
0
    while ((padlen > 0) && (cnt < max)) {
465
0
        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
466
0
            return 0;
467
0
        --padlen;
468
0
        ++cnt;
469
0
    }
470
0
    while (*value && (cnt < max)) {
471
0
        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
472
0
            return 0;
473
0
        ++cnt;
474
0
    }
475
0
    while ((padlen < 0) && (cnt < max)) {
476
0
        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
477
0
            return 0;
478
0
        ++padlen;
479
0
        ++cnt;
480
0
    }
481
0
    return 1;
482
0
}
483
484
static int
485
fmtint(char **sbuffer,
486
       char **buffer,
487
       size_t *currlen,
488
       size_t *maxlen, LLONG value, int base, int min, int max, int flags)
489
7.45k
{
490
7.45k
    int signvalue = 0;
491
7.45k
    const char *prefix = "";
492
7.45k
    unsigned LLONG uvalue;
493
7.45k
    char convert[DECIMAL_SIZE(value) + 3];
494
7.45k
    int place = 0;
495
7.45k
    int spadlen = 0;
496
7.45k
    int zpadlen = 0;
497
7.45k
    int caps = 0;
498
499
7.45k
    if (max < 0)
500
7.45k
        max = 0;
501
7.45k
    uvalue = value;
502
7.45k
    if (!(flags & DP_F_UNSIGNED)) {
503
0
        if (value < 0) {
504
0
            signvalue = '-';
505
0
            uvalue = -(unsigned LLONG)value;
506
0
        } else if (flags & DP_F_PLUS)
507
0
            signvalue = '+';
508
0
        else if (flags & DP_F_SPACE)
509
0
            signvalue = ' ';
510
0
    }
511
7.45k
    if (flags & DP_F_NUM) {
512
0
        if (base == 8)
513
0
            prefix = "0";
514
0
        if (base == 16)
515
0
            prefix = "0x";
516
0
    }
517
7.45k
    if (flags & DP_F_UP)
518
0
        caps = 1;
519
9.94k
    do {
520
9.94k
        convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
521
9.94k
            [uvalue % (unsigned)base];
522
9.94k
        uvalue = (uvalue / (unsigned)base);
523
9.94k
    } while (uvalue && (place < (int)sizeof(convert)));
524
7.45k
    if (place == sizeof(convert))
525
0
        place--;
526
7.45k
    convert[place] = 0;
527
528
7.45k
    zpadlen = max - place;
529
7.45k
    spadlen =
530
7.45k
        min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
531
7.45k
    if (zpadlen < 0)
532
7.45k
        zpadlen = 0;
533
7.45k
    if (spadlen < 0)
534
7.45k
        spadlen = 0;
535
7.45k
    if (flags & DP_F_ZERO) {
536
0
        zpadlen = OSSL_MAX(zpadlen, spadlen);
537
0
        spadlen = 0;
538
0
    }
539
7.45k
    if (flags & DP_F_MINUS)
540
0
        spadlen = -spadlen;
541
542
    /* spaces */
543
7.45k
    while (spadlen > 0) {
544
0
        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
545
0
            return 0;
546
0
        --spadlen;
547
0
    }
548
549
    /* sign */
550
7.45k
    if (signvalue)
551
0
        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
552
0
            return 0;
553
554
    /* prefix */
555
7.45k
    while (*prefix) {
556
0
        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
557
0
            return 0;
558
0
        prefix++;
559
0
    }
560
561
    /* zeros */
562
7.45k
    if (zpadlen > 0) {
563
0
        while (zpadlen > 0) {
564
0
            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
565
0
                return 0;
566
0
            --zpadlen;
567
0
        }
568
0
    }
569
    /* digits */
570
17.4k
    while (place > 0) {
571
9.94k
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
572
0
            return 0;
573
9.94k
    }
574
575
    /* left justified spaces */
576
7.45k
    while (spadlen < 0) {
577
0
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
578
0
            return 0;
579
0
        ++spadlen;
580
0
    }
581
7.45k
    return 1;
582
7.45k
}
583
584
static LDOUBLE abs_val(LDOUBLE value)
585
0
{
586
0
    LDOUBLE result = value;
587
0
    if (value < 0)
588
0
        result = -value;
589
0
    return result;
590
0
}
591
592
static LDOUBLE pow_10(int in_exp)
593
0
{
594
0
    LDOUBLE result = 1;
595
0
    while (in_exp) {
596
0
        result *= 10;
597
0
        in_exp--;
598
0
    }
599
0
    return result;
600
0
}
601
602
static long roundv(LDOUBLE value)
603
0
{
604
0
    long intpart;
605
0
    intpart = (long)value;
606
0
    value = value - intpart;
607
0
    if (value >= 0.5)
608
0
        intpart++;
609
0
    return intpart;
610
0
}
611
612
static int
613
fmtfp(char **sbuffer,
614
      char **buffer,
615
      size_t *currlen,
616
      size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags)
617
0
{
618
0
    int signvalue = 0;
619
0
    LDOUBLE ufvalue;
620
0
    char iconvert[20];
621
0
    char fconvert[20];
622
0
    int iplace = 0;
623
0
    int fplace = 0;
624
0
    int padlen = 0;
625
0
    int zpadlen = 0;
626
0
    long intpart;
627
0
    long fracpart;
628
0
    long max10;
629
630
0
    if (max < 0)
631
0
        max = 6;
632
0
    ufvalue = abs_val(fvalue);
633
0
    if (fvalue < 0)
634
0
        signvalue = '-';
635
0
    else if (flags & DP_F_PLUS)
636
0
        signvalue = '+';
637
0
    else if (flags & DP_F_SPACE)
638
0
        signvalue = ' ';
639
640
0
    intpart = (long)ufvalue;
641
642
    /*
643
     * sorry, we only support 9 digits past the decimal because of our
644
     * conversion method
645
     */
646
0
    if (max > 9)
647
0
        max = 9;
648
649
    /*
650
     * we "cheat" by converting the fractional part to integer by multiplying
651
     * by a factor of 10
652
     */
653
0
    max10 = roundv(pow_10(max));
654
0
    fracpart = roundv(pow_10(max) * (ufvalue - intpart));
655
656
0
    if (fracpart >= max10) {
657
0
        intpart++;
658
0
        fracpart -= max10;
659
0
    }
660
661
    /* convert integer part */
662
0
    do {
663
0
        iconvert[iplace++] = "0123456789"[intpart % 10];
664
0
        intpart = (intpart / 10);
665
0
    } while (intpart && (iplace < (int)sizeof(iconvert)));
666
0
    if (iplace == sizeof iconvert)
667
0
        iplace--;
668
0
    iconvert[iplace] = 0;
669
670
    /* convert fractional part */
671
0
    do {
672
0
        fconvert[fplace++] = "0123456789"[fracpart % 10];
673
0
        fracpart = (fracpart / 10);
674
0
    } while (fplace < max);
675
0
    if (fplace == sizeof fconvert)
676
0
        fplace--;
677
0
    fconvert[fplace] = 0;
678
679
    /* -1 for decimal point, another -1 if we are printing a sign */
680
0
    padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
681
0
    zpadlen = max - fplace;
682
0
    if (zpadlen < 0)
683
0
        zpadlen = 0;
684
0
    if (padlen < 0)
685
0
        padlen = 0;
686
0
    if (flags & DP_F_MINUS)
687
0
        padlen = -padlen;
688
689
0
    if ((flags & DP_F_ZERO) && (padlen > 0)) {
690
0
        if (signvalue) {
691
0
            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
692
0
                return 0;
693
0
            --padlen;
694
0
            signvalue = 0;
695
0
        }
696
0
        while (padlen > 0) {
697
0
            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
698
0
                return 0;
699
0
            --padlen;
700
0
        }
701
0
    }
702
0
    while (padlen > 0) {
703
0
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
704
0
            return 0;
705
0
        --padlen;
706
0
    }
707
0
    if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
708
0
        return 0;
709
710
0
    while (iplace > 0) {
711
0
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
712
0
            return 0;
713
0
    }
714
715
    /*
716
     * Decimal point. This should probably use locale to find the correct
717
     * char to print out.
718
     */
719
0
    if (max > 0 || (flags & DP_F_NUM)) {
720
0
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
721
0
            return 0;
722
723
0
        while (fplace > 0) {
724
0
            if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
725
0
                            fconvert[--fplace]))
726
0
                return 0;
727
0
        }
728
0
    }
729
0
    while (zpadlen > 0) {
730
0
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
731
0
            return 0;
732
0
        --zpadlen;
733
0
    }
734
735
0
    while (padlen < 0) {
736
0
        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
737
0
            return 0;
738
0
        ++padlen;
739
0
    }
740
0
    return 1;
741
0
}
742
743
0
#define BUFFER_INC  1024
744
745
static int
746
doapr_outch(char **sbuffer,
747
            char **buffer, size_t *currlen, size_t *maxlen, int c)
748
24.8k
{
749
    /* If we haven't at least one buffer, someone has doe a big booboo */
750
24.8k
    assert(*sbuffer != NULL || buffer != NULL);
751
752
    /* |currlen| must always be <= |*maxlen| */
753
24.8k
    assert(*currlen <= *maxlen);
754
755
24.8k
    if (buffer && *currlen == *maxlen) {
756
0
        if (*maxlen > INT_MAX - BUFFER_INC)
757
0
            return 0;
758
759
0
        *maxlen += BUFFER_INC;
760
0
        if (*buffer == NULL) {
761
0
            *buffer = OPENSSL_malloc(*maxlen);
762
0
            if (*buffer == NULL)
763
0
                return 0;
764
0
            if (*currlen > 0) {
765
0
                assert(*sbuffer != NULL);
766
0
                memcpy(*buffer, *sbuffer, *currlen);
767
0
            }
768
0
            *sbuffer = NULL;
769
0
        } else {
770
0
            char *tmpbuf;
771
0
            tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
772
0
            if (tmpbuf == NULL)
773
0
                return 0;
774
0
            *buffer = tmpbuf;
775
0
        }
776
0
    }
777
778
24.8k
    if (*currlen < *maxlen) {
779
24.8k
        if (*sbuffer)
780
24.8k
            (*sbuffer)[(*currlen)++] = (char)c;
781
0
        else
782
0
            (*buffer)[(*currlen)++] = (char)c;
783
24.8k
    }
784
785
24.8k
    return 1;
786
24.8k
}
787
788
/***************************************************************************/
789
790
int BIO_printf(BIO *bio, const char *format, ...)
791
0
{
792
0
    va_list args;
793
0
    int ret;
794
795
0
    va_start(args, format);
796
797
0
    ret = BIO_vprintf(bio, format, args);
798
799
0
    va_end(args);
800
0
    return (ret);
801
0
}
802
803
int BIO_vprintf(BIO *bio, const char *format, va_list args)
804
0
{
805
0
    int ret;
806
0
    size_t retlen;
807
0
    char hugebuf[1024 * 2];     /* Was previously 10k, which is unreasonable
808
                                 * in small-stack environments, like threads
809
                                 * or DOS programs. */
810
0
    char *hugebufp = hugebuf;
811
0
    size_t hugebufsize = sizeof(hugebuf);
812
0
    char *dynbuf = NULL;
813
0
    int ignored;
814
815
0
    dynbuf = NULL;
816
0
    CRYPTO_push_info("doapr()");
817
0
    if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
818
0
                args)) {
819
0
        OPENSSL_free(dynbuf);
820
0
        return -1;
821
0
    }
822
0
    if (dynbuf) {
823
0
        ret = BIO_write(bio, dynbuf, (int)retlen);
824
0
        OPENSSL_free(dynbuf);
825
0
    } else {
826
0
        ret = BIO_write(bio, hugebuf, (int)retlen);
827
0
    }
828
0
    CRYPTO_pop_info();
829
0
    return (ret);
830
0
}
831
832
/*
833
 * As snprintf is not available everywhere, we provide our own
834
 * implementation. This function has nothing to do with BIOs, but it's
835
 * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
836
 * function should be renamed, but to what?)
837
 */
838
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
839
7.45k
{
840
7.45k
    va_list args;
841
7.45k
    int ret;
842
843
7.45k
    va_start(args, format);
844
845
7.45k
    ret = BIO_vsnprintf(buf, n, format, args);
846
847
7.45k
    va_end(args);
848
7.45k
    return (ret);
849
7.45k
}
850
851
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
852
7.45k
{
853
7.45k
    size_t retlen;
854
7.45k
    int truncated;
855
856
7.45k
    if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
857
0
        return -1;
858
859
7.45k
    if (truncated)
860
        /*
861
         * In case of truncation, return -1 like traditional snprintf.
862
         * (Current drafts for ISO/IEC 9899 say snprintf should return the
863
         * number of characters that would have been written, had the buffer
864
         * been large enough.)
865
         */
866
0
        return -1;
867
7.45k
    else
868
7.45k
        return (retlen <= INT_MAX) ? (int)retlen : -1;
869
7.45k
}