VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.0g/crypto/bio/b_print.c@ 69881

Last change on this file since 69881 was 69881, checked in by vboxsync, 7 years ago

Update OpenSSL to 1.1.0g.
bugref:8070: src/libs maintenance

  • Property svn:eol-style set to native
File size: 25.7 KB
Line 
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <string.h>
12#include <ctype.h>
13#ifndef VBOX
14#include "internal/numbers.h"
15#include "internal/cryptlib.h"
16#else
17# include "internal/cryptlib.h"
18# include "internal/numbers.h"
19#endif
20#ifndef NO_SYS_TYPES_H
21# include <sys/types.h>
22#endif
23#include <openssl/bn.h> /* To get BN_LLONG properly defined */
24#include <openssl/bio.h>
25
26/*
27 * Copyright Patrick Powell 1995
28 * This code is based on code written by Patrick Powell <[email protected]>
29 * It may be used for any purpose as long as this notice remains intact
30 * on all source code distributions.
31 */
32
33#ifdef HAVE_LONG_DOUBLE
34# define LDOUBLE long double
35#else
36# define LDOUBLE double
37#endif
38
39static int fmtstr(char **, char **, size_t *, size_t *,
40 const char *, int, int, int);
41static int fmtint(char **, char **, size_t *, size_t *,
42 int64_t, int, int, int, int);
43static int fmtfp(char **, char **, size_t *, size_t *,
44 LDOUBLE, int, int, int, int);
45static int doapr_outch(char **, char **, size_t *, size_t *, int);
46static int _dopr(char **sbuffer, char **buffer,
47 size_t *maxlen, size_t *retlen, int *truncated,
48 const char *format, va_list args);
49
50/* format read states */
51#define DP_S_DEFAULT 0
52#define DP_S_FLAGS 1
53#define DP_S_MIN 2
54#define DP_S_DOT 3
55#define DP_S_MAX 4
56#define DP_S_MOD 5
57#define DP_S_CONV 6
58#define DP_S_DONE 7
59
60/* format flags - Bits */
61/* left-aligned padding */
62#define DP_F_MINUS (1 << 0)
63/* print an explicit '+' for a value with positive sign */
64#define DP_F_PLUS (1 << 1)
65/* print an explicit ' ' for a value with positive sign */
66#define DP_F_SPACE (1 << 2)
67/* print 0/0x prefix for octal/hex and decimal point for floating point */
68#define DP_F_NUM (1 << 3)
69/* print leading zeroes */
70#define DP_F_ZERO (1 << 4)
71/* print HEX in UPPPERcase */
72#define DP_F_UP (1 << 5)
73/* treat value as unsigned */
74#define DP_F_UNSIGNED (1 << 6)
75
76/* conversion flags */
77#define DP_C_SHORT 1
78#define DP_C_LONG 2
79#define DP_C_LDOUBLE 3
80#define DP_C_LLONG 4
81
82/* Floating point formats */
83#define F_FORMAT 0
84#define E_FORMAT 1
85#define G_FORMAT 2
86
87/* some handy macros */
88#define char_to_int(p) (p - '0')
89#define OSSL_MAX(p,q) ((p >= q) ? p : q)
90
91static int
92_dopr(char **sbuffer,
93 char **buffer,
94 size_t *maxlen,
95 size_t *retlen, int *truncated, const char *format, va_list args)
96{
97 char ch;
98 int64_t value;
99 LDOUBLE fvalue;
100 char *strvalue;
101 int min;
102 int max;
103 int state;
104 int flags;
105 int cflags;
106 size_t currlen;
107
108 state = DP_S_DEFAULT;
109 flags = currlen = cflags = min = 0;
110 max = -1;
111 ch = *format++;
112
113 while (state != DP_S_DONE) {
114 if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
115 state = DP_S_DONE;
116
117 switch (state) {
118 case DP_S_DEFAULT:
119 if (ch == '%')
120 state = DP_S_FLAGS;
121 else
122 if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
123 return 0;
124 ch = *format++;
125 break;
126 case DP_S_FLAGS:
127 switch (ch) {
128 case '-':
129 flags |= DP_F_MINUS;
130 ch = *format++;
131 break;
132 case '+':
133 flags |= DP_F_PLUS;
134 ch = *format++;
135 break;
136 case ' ':
137 flags |= DP_F_SPACE;
138 ch = *format++;
139 break;
140 case '#':
141 flags |= DP_F_NUM;
142 ch = *format++;
143 break;
144 case '0':
145 flags |= DP_F_ZERO;
146 ch = *format++;
147 break;
148 default:
149 state = DP_S_MIN;
150 break;
151 }
152 break;
153 case DP_S_MIN:
154 if (isdigit((unsigned char)ch)) {
155 min = 10 * min + char_to_int(ch);
156 ch = *format++;
157 } else if (ch == '*') {
158 min = va_arg(args, int);
159 ch = *format++;
160 state = DP_S_DOT;
161 } else
162 state = DP_S_DOT;
163 break;
164 case DP_S_DOT:
165 if (ch == '.') {
166 state = DP_S_MAX;
167 ch = *format++;
168 } else
169 state = DP_S_MOD;
170 break;
171 case DP_S_MAX:
172 if (isdigit((unsigned char)ch)) {
173 if (max < 0)
174 max = 0;
175 max = 10 * max + char_to_int(ch);
176 ch = *format++;
177 } else if (ch == '*') {
178 max = va_arg(args, int);
179 ch = *format++;
180 state = DP_S_MOD;
181 } else
182 state = DP_S_MOD;
183 break;
184 case DP_S_MOD:
185 switch (ch) {
186 case 'h':
187 cflags = DP_C_SHORT;
188 ch = *format++;
189 break;
190 case 'l':
191 if (*format == 'l') {
192 cflags = DP_C_LLONG;
193 format++;
194 } else
195 cflags = DP_C_LONG;
196 ch = *format++;
197 break;
198 case 'q':
199 cflags = DP_C_LLONG;
200 ch = *format++;
201 break;
202 case 'L':
203 cflags = DP_C_LDOUBLE;
204 ch = *format++;
205 break;
206 default:
207 break;
208 }
209 state = DP_S_CONV;
210 break;
211 case DP_S_CONV:
212 switch (ch) {
213 case 'd':
214 case 'i':
215 switch (cflags) {
216 case DP_C_SHORT:
217 value = (short int)va_arg(args, int);
218 break;
219 case DP_C_LONG:
220 value = va_arg(args, long int);
221 break;
222 case DP_C_LLONG:
223 value = va_arg(args, int64_t);
224 break;
225 default:
226 value = va_arg(args, int);
227 break;
228 }
229 if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
230 max, flags))
231 return 0;
232 break;
233 case 'X':
234 flags |= DP_F_UP;
235 /* FALLTHROUGH */
236 case 'x':
237 case 'o':
238 case 'u':
239 flags |= DP_F_UNSIGNED;
240 switch (cflags) {
241 case DP_C_SHORT:
242 value = (unsigned short int)va_arg(args, unsigned int);
243 break;
244 case DP_C_LONG:
245 value = va_arg(args, unsigned long int);
246 break;
247 case DP_C_LLONG:
248 value = va_arg(args, uint64_t);
249 break;
250 default:
251 value = va_arg(args, unsigned int);
252 break;
253 }
254 if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
255 ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
256 min, max, flags))
257 return 0;
258 break;
259 case 'f':
260 if (cflags == DP_C_LDOUBLE)
261 fvalue = va_arg(args, LDOUBLE);
262 else
263 fvalue = va_arg(args, double);
264 if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
265 flags, F_FORMAT))
266 return 0;
267 break;
268 case 'E':
269 flags |= DP_F_UP;
270 /* fall thru */
271 case 'e':
272 if (cflags == DP_C_LDOUBLE)
273 fvalue = va_arg(args, LDOUBLE);
274 else
275 fvalue = va_arg(args, double);
276 if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
277 flags, E_FORMAT))
278 return 0;
279 break;
280 case 'G':
281 flags |= DP_F_UP;
282 /* fall thru */
283 case 'g':
284 if (cflags == DP_C_LDOUBLE)
285 fvalue = va_arg(args, LDOUBLE);
286 else
287 fvalue = va_arg(args, double);
288 if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
289 flags, G_FORMAT))
290 return 0;
291 break;
292 case 'c':
293 if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
294 va_arg(args, int)))
295 return 0;
296 break;
297 case 's':
298 strvalue = va_arg(args, char *);
299 if (max < 0) {
300 if (buffer)
301 max = INT_MAX;
302 else
303 max = *maxlen;
304 }
305 if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
306 flags, min, max))
307 return 0;
308 break;
309 case 'p':
310 value = (size_t)va_arg(args, void *);
311 if (!fmtint(sbuffer, buffer, &currlen, maxlen,
312 value, 16, min, max, flags | DP_F_NUM))
313 return 0;
314 break;
315 case 'n': /* XXX */
316 if (cflags == DP_C_SHORT) {
317 short int *num;
318 num = va_arg(args, short int *);
319 *num = currlen;
320 } else if (cflags == DP_C_LONG) { /* XXX */
321 long int *num;
322 num = va_arg(args, long int *);
323 *num = (long int)currlen;
324 } else if (cflags == DP_C_LLONG) { /* XXX */
325 int64_t *num;
326 num = va_arg(args, int64_t *);
327 *num = (int64_t)currlen;
328 } else {
329 int *num;
330 num = va_arg(args, int *);
331 *num = currlen;
332 }
333 break;
334 case '%':
335 if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
336 return 0;
337 break;
338 case 'w':
339 /* not supported yet, treat as next char */
340 ch = *format++;
341 break;
342 default:
343 /* unknown, skip */
344 break;
345 }
346 ch = *format++;
347 state = DP_S_DEFAULT;
348 flags = cflags = min = 0;
349 max = -1;
350 break;
351 case DP_S_DONE:
352 break;
353 default:
354 break;
355 }
356 }
357 /*
358 * We have to truncate if there is no dynamic buffer and we have filled the
359 * static buffer.
360 */
361 if (buffer == NULL) {
362 *truncated = (currlen > *maxlen - 1);
363 if (*truncated)
364 currlen = *maxlen - 1;
365 }
366 if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
367 return 0;
368 *retlen = currlen - 1;
369 return 1;
370}
371
372static int
373fmtstr(char **sbuffer,
374 char **buffer,
375 size_t *currlen,
376 size_t *maxlen, const char *value, int flags, int min, int max)
377{
378 int padlen;
379 size_t strln;
380 int cnt = 0;
381
382 if (value == 0)
383 value = "<NULL>";
384
385 strln = OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max);
386
387 padlen = min - strln;
388 if (min < 0 || padlen < 0)
389 padlen = 0;
390 if (max >= 0) {
391 /*
392 * Calculate the maximum output including padding.
393 * Make sure max doesn't overflow into negativity
394 */
395 if (max < INT_MAX - padlen)
396 max += padlen;
397 else
398 max = INT_MAX;
399 }
400 if (flags & DP_F_MINUS)
401 padlen = -padlen;
402
403 while ((padlen > 0) && (max < 0 || cnt < max)) {
404 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
405 return 0;
406 --padlen;
407 ++cnt;
408 }
409 while (strln > 0 && (max < 0 || cnt < max)) {
410 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
411 return 0;
412 --strln;
413 ++cnt;
414 }
415 while ((padlen < 0) && (max < 0 || cnt < max)) {
416 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
417 return 0;
418 ++padlen;
419 ++cnt;
420 }
421 return 1;
422}
423
424static int
425fmtint(char **sbuffer,
426 char **buffer,
427 size_t *currlen,
428 size_t *maxlen, int64_t value, int base, int min, int max, int flags)
429{
430 int signvalue = 0;
431 const char *prefix = "";
432 uint64_t uvalue;
433 char convert[DECIMAL_SIZE(value) + 3];
434 int place = 0;
435 int spadlen = 0;
436 int zpadlen = 0;
437 int caps = 0;
438
439 if (max < 0)
440 max = 0;
441 uvalue = value;
442 if (!(flags & DP_F_UNSIGNED)) {
443 if (value < 0) {
444 signvalue = '-';
445 uvalue = 0 - (uint64_t)value;
446 } else if (flags & DP_F_PLUS)
447 signvalue = '+';
448 else if (flags & DP_F_SPACE)
449 signvalue = ' ';
450 }
451 if (flags & DP_F_NUM) {
452 if (base == 8)
453 prefix = "0";
454 if (base == 16)
455 prefix = "0x";
456 }
457 if (flags & DP_F_UP)
458 caps = 1;
459 do {
460 convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
461 [uvalue % (unsigned)base];
462 uvalue = (uvalue / (unsigned)base);
463 } while (uvalue && (place < (int)sizeof(convert)));
464 if (place == sizeof(convert))
465 place--;
466 convert[place] = 0;
467
468 zpadlen = max - place;
469 spadlen =
470 min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
471 if (zpadlen < 0)
472 zpadlen = 0;
473 if (spadlen < 0)
474 spadlen = 0;
475 if (flags & DP_F_ZERO) {
476 zpadlen = OSSL_MAX(zpadlen, spadlen);
477 spadlen = 0;
478 }
479 if (flags & DP_F_MINUS)
480 spadlen = -spadlen;
481
482 /* spaces */
483 while (spadlen > 0) {
484 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
485 return 0;
486 --spadlen;
487 }
488
489 /* sign */
490 if (signvalue)
491 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
492 return 0;
493
494 /* prefix */
495 while (*prefix) {
496 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
497 return 0;
498 prefix++;
499 }
500
501 /* zeros */
502 if (zpadlen > 0) {
503 while (zpadlen > 0) {
504 if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
505 return 0;
506 --zpadlen;
507 }
508 }
509 /* digits */
510 while (place > 0) {
511 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
512 return 0;
513 }
514
515 /* left justified spaces */
516 while (spadlen < 0) {
517 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
518 return 0;
519 ++spadlen;
520 }
521 return 1;
522}
523
524static LDOUBLE abs_val(LDOUBLE value)
525{
526 LDOUBLE result = value;
527 if (value < 0)
528 result = -value;
529 return result;
530}
531
532static LDOUBLE pow_10(int in_exp)
533{
534 LDOUBLE result = 1;
535 while (in_exp) {
536 result *= 10;
537 in_exp--;
538 }
539 return result;
540}
541
542static long roundv(LDOUBLE value)
543{
544 long intpart;
545 intpart = (long)value;
546 value = value - intpart;
547 if (value >= 0.5)
548 intpart++;
549 return intpart;
550}
551
552static int
553fmtfp(char **sbuffer,
554 char **buffer,
555 size_t *currlen,
556 size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags, int style)
557{
558 int signvalue = 0;
559 LDOUBLE ufvalue;
560 LDOUBLE tmpvalue;
561 char iconvert[20];
562 char fconvert[20];
563 char econvert[20];
564 int iplace = 0;
565 int fplace = 0;
566 int eplace = 0;
567 int padlen = 0;
568 int zpadlen = 0;
569 long exp = 0;
570 unsigned long intpart;
571 unsigned long fracpart;
572 unsigned long max10;
573 int realstyle;
574
575 if (max < 0)
576 max = 6;
577
578 if (fvalue < 0)
579 signvalue = '-';
580 else if (flags & DP_F_PLUS)
581 signvalue = '+';
582 else if (flags & DP_F_SPACE)
583 signvalue = ' ';
584
585 /*
586 * G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
587 * depending on the number to be printed. Work out which one it is and use
588 * that from here on.
589 */
590 if (style == G_FORMAT) {
591 if (fvalue == 0.0) {
592 realstyle = F_FORMAT;
593 } else if (fvalue < 0.0001) {
594 realstyle = E_FORMAT;
595 } else if ((max == 0 && fvalue >= 10)
596 || (max > 0 && fvalue >= pow_10(max))) {
597 realstyle = E_FORMAT;
598 } else {
599 realstyle = F_FORMAT;
600 }
601 } else {
602 realstyle = style;
603 }
604
605 if (style != F_FORMAT) {
606 tmpvalue = fvalue;
607 /* Calculate the exponent */
608 if (fvalue != 0.0) {
609 while (tmpvalue < 1) {
610 tmpvalue *= 10;
611 exp--;
612 }
613 while (tmpvalue > 10) {
614 tmpvalue /= 10;
615 exp++;
616 }
617 }
618 if (style == G_FORMAT) {
619 /*
620 * In G_FORMAT the "precision" represents significant digits. We
621 * always have at least 1 significant digit.
622 */
623 if (max == 0)
624 max = 1;
625 /* Now convert significant digits to decimal places */
626 if (realstyle == F_FORMAT) {
627 max -= (exp + 1);
628 if (max < 0) {
629 /*
630 * Should not happen. If we're in F_FORMAT then exp < max?
631 */
632 return 0;
633 }
634 } else {
635 /*
636 * In E_FORMAT there is always one significant digit in front
637 * of the decimal point, so:
638 * significant digits == 1 + decimal places
639 */
640 max--;
641 }
642 }
643 if (realstyle == E_FORMAT)
644 fvalue = tmpvalue;
645 }
646 ufvalue = abs_val(fvalue);
647 if (ufvalue > ULONG_MAX) {
648 /* Number too big */
649 return 0;
650 }
651 intpart = (unsigned long)ufvalue;
652
653 /*
654 * sorry, we only support 9 digits past the decimal because of our
655 * conversion method
656 */
657 if (max > 9)
658 max = 9;
659
660 /*
661 * we "cheat" by converting the fractional part to integer by multiplying
662 * by a factor of 10
663 */
664 max10 = roundv(pow_10(max));
665 fracpart = roundv(pow_10(max) * (ufvalue - intpart));
666
667 if (fracpart >= max10) {
668 intpart++;
669 fracpart -= max10;
670 }
671
672 /* convert integer part */
673 do {
674 iconvert[iplace++] = "0123456789"[intpart % 10];
675 intpart = (intpart / 10);
676 } while (intpart && (iplace < (int)sizeof(iconvert)));
677 if (iplace == sizeof iconvert)
678 iplace--;
679 iconvert[iplace] = 0;
680
681 /* convert fractional part */
682 while (fplace < max) {
683 if (style == G_FORMAT && fplace == 0 && (fracpart % 10) == 0) {
684 /* We strip trailing zeros in G_FORMAT */
685 max--;
686 fracpart = fracpart / 10;
687 if (fplace < max)
688 continue;
689 break;
690 }
691 fconvert[fplace++] = "0123456789"[fracpart % 10];
692 fracpart = (fracpart / 10);
693 }
694
695 if (fplace == sizeof fconvert)
696 fplace--;
697 fconvert[fplace] = 0;
698
699 /* convert exponent part */
700 if (realstyle == E_FORMAT) {
701 int tmpexp;
702 if (exp < 0)
703 tmpexp = -exp;
704 else
705 tmpexp = exp;
706
707 do {
708 econvert[eplace++] = "0123456789"[tmpexp % 10];
709 tmpexp = (tmpexp / 10);
710 } while (tmpexp > 0 && eplace < (int)sizeof(econvert));
711 /* Exponent is huge!! Too big to print */
712 if (tmpexp > 0)
713 return 0;
714 /* Add a leading 0 for single digit exponents */
715 if (eplace == 1)
716 econvert[eplace++] = '0';
717 }
718
719 /*
720 * -1 for decimal point (if we have one, i.e. max > 0),
721 * another -1 if we are printing a sign
722 */
723 padlen = min - iplace - max - (max > 0 ? 1 : 0) - ((signvalue) ? 1 : 0);
724 /* Take some off for exponent prefix "+e" and exponent */
725 if (realstyle == E_FORMAT)
726 padlen -= 2 + eplace;
727 zpadlen = max - fplace;
728 if (zpadlen < 0)
729 zpadlen = 0;
730 if (padlen < 0)
731 padlen = 0;
732 if (flags & DP_F_MINUS)
733 padlen = -padlen;
734
735 if ((flags & DP_F_ZERO) && (padlen > 0)) {
736 if (signvalue) {
737 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
738 return 0;
739 --padlen;
740 signvalue = 0;
741 }
742 while (padlen > 0) {
743 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
744 return 0;
745 --padlen;
746 }
747 }
748 while (padlen > 0) {
749 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
750 return 0;
751 --padlen;
752 }
753 if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
754 return 0;
755
756 while (iplace > 0) {
757 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
758 return 0;
759 }
760
761 /*
762 * Decimal point. This should probably use locale to find the correct
763 * char to print out.
764 */
765 if (max > 0 || (flags & DP_F_NUM)) {
766 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
767 return 0;
768
769 while (fplace > 0) {
770 if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
771 fconvert[--fplace]))
772 return 0;
773 }
774 }
775 while (zpadlen > 0) {
776 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
777 return 0;
778 --zpadlen;
779 }
780 if (realstyle == E_FORMAT) {
781 char ech;
782
783 if ((flags & DP_F_UP) == 0)
784 ech = 'e';
785 else
786 ech = 'E';
787 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ech))
788 return 0;
789 if (exp < 0) {
790 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '-'))
791 return 0;
792 } else {
793 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '+'))
794 return 0;
795 }
796 while (eplace > 0) {
797 if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
798 econvert[--eplace]))
799 return 0;
800 }
801 }
802
803 while (padlen < 0) {
804 if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
805 return 0;
806 ++padlen;
807 }
808 return 1;
809}
810
811#define BUFFER_INC 1024
812
813static int
814doapr_outch(char **sbuffer,
815 char **buffer, size_t *currlen, size_t *maxlen, int c)
816{
817 /* If we haven't at least one buffer, someone has doe a big booboo */
818 OPENSSL_assert(*sbuffer != NULL || buffer != NULL);
819
820 /* |currlen| must always be <= |*maxlen| */
821 OPENSSL_assert(*currlen <= *maxlen);
822
823 if (buffer && *currlen == *maxlen) {
824 if (*maxlen > INT_MAX - BUFFER_INC)
825 return 0;
826
827 *maxlen += BUFFER_INC;
828 if (*buffer == NULL) {
829 *buffer = OPENSSL_malloc(*maxlen);
830 if (*buffer == NULL)
831 return 0;
832 if (*currlen > 0) {
833 OPENSSL_assert(*sbuffer != NULL);
834 memcpy(*buffer, *sbuffer, *currlen);
835 }
836 *sbuffer = NULL;
837 } else {
838 char *tmpbuf;
839 tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
840 if (tmpbuf == NULL)
841 return 0;
842 *buffer = tmpbuf;
843 }
844 }
845
846 if (*currlen < *maxlen) {
847 if (*sbuffer)
848 (*sbuffer)[(*currlen)++] = (char)c;
849 else
850 (*buffer)[(*currlen)++] = (char)c;
851 }
852
853 return 1;
854}
855
856/***************************************************************************/
857
858int BIO_printf(BIO *bio, const char *format, ...)
859{
860 va_list args;
861 int ret;
862
863 va_start(args, format);
864
865 ret = BIO_vprintf(bio, format, args);
866
867 va_end(args);
868 return (ret);
869}
870
871int BIO_vprintf(BIO *bio, const char *format, va_list args)
872{
873 int ret;
874 size_t retlen;
875 char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable
876 * in small-stack environments, like threads
877 * or DOS programs. */
878 char *hugebufp = hugebuf;
879 size_t hugebufsize = sizeof(hugebuf);
880 char *dynbuf = NULL;
881 int ignored;
882
883 dynbuf = NULL;
884 if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
885 args)) {
886 OPENSSL_free(dynbuf);
887 return -1;
888 }
889 if (dynbuf) {
890 ret = BIO_write(bio, dynbuf, (int)retlen);
891 OPENSSL_free(dynbuf);
892 } else {
893 ret = BIO_write(bio, hugebuf, (int)retlen);
894 }
895 return (ret);
896}
897
898/*
899 * As snprintf is not available everywhere, we provide our own
900 * implementation. This function has nothing to do with BIOs, but it's
901 * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
902 * function should be renamed, but to what?)
903 */
904int BIO_snprintf(char *buf, size_t n, const char *format, ...)
905{
906 va_list args;
907 int ret;
908
909 va_start(args, format);
910
911 ret = BIO_vsnprintf(buf, n, format, args);
912
913 va_end(args);
914 return (ret);
915}
916
917int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
918{
919 size_t retlen;
920 int truncated;
921
922 if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
923 return -1;
924
925 if (truncated)
926 /*
927 * In case of truncation, return -1 like traditional snprintf.
928 * (Current drafts for ISO/IEC 9899 say snprintf should return the
929 * number of characters that would have been written, had the buffer
930 * been large enough.)
931 */
932 return -1;
933 else
934 return (retlen <= INT_MAX) ? (int)retlen : -1;
935}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette