summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/b_print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bio/b_print.c')
-rw-r--r--src/lib/libcrypto/bio/b_print.c346
1 files changed, 158 insertions, 188 deletions
diff --git a/src/lib/libcrypto/bio/b_print.c b/src/lib/libcrypto/bio/b_print.c
index b11b501512..a62f551635 100644
--- a/src/lib/libcrypto/bio/b_print.c
+++ b/src/lib/libcrypto/bio/b_print.c
@@ -61,7 +61,6 @@
61 */ 61 */
62 62
63#include <stdio.h> 63#include <stdio.h>
64#include <stdarg.h>
65#include <string.h> 64#include <string.h>
66#include <ctype.h> 65#include <ctype.h>
67#include <assert.h> 66#include <assert.h>
@@ -78,48 +77,7 @@
78# endif 77# endif
79#endif 78#endif
80 79
81static void dopr (char *buffer, size_t maxlen, size_t *retlen, 80/***************************************************************************/
82 const char *format, va_list args);
83#ifdef USE_ALLOCATING_PRINT
84static void doapr (char **buffer, size_t *retlen,
85 const char *format, va_list args);
86#endif
87
88int BIO_printf (BIO *bio, ...)
89 {
90 va_list args;
91 char *format;
92 int ret;
93 size_t retlen;
94#ifdef USE_ALLOCATING_PRINT
95 char *hugebuf;
96#else
97 MS_STATIC char hugebuf[1024*2]; /* 10k in one chunk is the limit */
98#endif
99
100 va_start(args, bio);
101 format=va_arg(args, char *);
102
103#ifndef USE_ALLOCATING_PRINT
104 hugebuf[0]='\0';
105 dopr(hugebuf, sizeof(hugebuf), &retlen, format, args);
106#else
107 hugebuf = NULL;
108 CRYPTO_push_info("doapr()");
109 doapr(&hugebuf, &retlen, format, args);
110 if (hugebuf)
111 {
112#endif
113 ret=BIO_write(bio, hugebuf, (int)retlen);
114
115#ifdef USE_ALLOCATING_PRINT
116 Free(hugebuf);
117 }
118 CRYPTO_pop_info();
119#endif
120 va_end(args);
121 return(ret);
122 }
123 81
124/* 82/*
125 * Copyright Patrick Powell 1995 83 * Copyright Patrick Powell 1995
@@ -140,6 +98,7 @@ int BIO_printf (BIO *bio, ...)
140 * o Andrew Tridgell <tridge@samba.org> (1998, for Samba) 98 * o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
141 * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP) 99 * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
142 * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth) 100 * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
101 * o ... (for OpenSSL)
143 */ 102 */
144 103
145#if HAVE_LONG_DOUBLE 104#if HAVE_LONG_DOUBLE
@@ -154,25 +113,15 @@ int BIO_printf (BIO *bio, ...)
154#define LLONG long 113#define LLONG long
155#endif 114#endif
156 115
157static void fmtstr (void (*)(char **, size_t *, size_t *, int), 116static void fmtstr (char **, char **, size_t *, size_t *,
158 char **, size_t *, size_t *, const char *, int, int, 117 const char *, int, int, int);
159 int); 118static void fmtint (char **, char **, size_t *, size_t *,
160static void fmtint (void (*)(char **, size_t *, size_t *, int), 119 LLONG, int, int, int, int);
161 char **, size_t *, size_t *, LLONG, int, int, int, int); 120static void fmtfp (char **, char **, size_t *, size_t *,
162static void fmtfp (void (*)(char **, size_t *, size_t *, int), 121 LDOUBLE, int, int, int);
163 char **, size_t *, size_t *, LDOUBLE, int, int, int); 122static void doapr_outch (char **, char **, size_t *, size_t *, int);
164#ifndef USE_ALLOCATING_PRINT 123static void _dopr(char **sbuffer, char **buffer,
165static int dopr_isbig (size_t, size_t); 124 size_t *maxlen, size_t *retlen, int *truncated,
166static int dopr_copy (size_t);
167static void dopr_outch (char **, size_t *, size_t *, int);
168#else
169static int doapr_isbig (size_t, size_t);
170static int doapr_copy (size_t);
171static void doapr_outch (char **, size_t *, size_t *, int);
172#endif
173static void _dopr(void (*)(char **, size_t *, size_t *, int),
174 int (*)(size_t, size_t), int (*)(size_t),
175 char **buffer, size_t *maxlen, size_t *retlen,
176 const char *format, va_list args); 125 const char *format, va_list args);
177 126
178/* format read states */ 127/* format read states */
@@ -204,41 +153,13 @@ static void _dopr(void (*)(char **, size_t *, size_t *, int),
204#define char_to_int(p) (p - '0') 153#define char_to_int(p) (p - '0')
205#define MAX(p,q) ((p >= q) ? p : q) 154#define MAX(p,q) ((p >= q) ? p : q)
206 155
207#ifndef USE_ALLOCATING_PRINT
208static void
209dopr(
210 char *buffer,
211 size_t maxlen,
212 size_t *retlen,
213 const char *format,
214 va_list args)
215{
216 _dopr(dopr_outch, dopr_isbig, dopr_copy,
217 &buffer, &maxlen, retlen, format, args);
218}
219
220#else
221static void
222doapr(
223 char **buffer,
224 size_t *retlen,
225 const char *format,
226 va_list args)
227{
228 size_t dummy_maxlen = 0;
229 _dopr(doapr_outch, doapr_isbig, doapr_copy,
230 buffer, &dummy_maxlen, retlen, format, args);
231}
232#endif
233
234static void 156static void
235_dopr( 157_dopr(
236 void (*outch_fn)(char **, size_t *, size_t *, int), 158 char **sbuffer,
237 int (*isbig_fn)(size_t, size_t),
238 int (*copy_fn)(size_t),
239 char **buffer, 159 char **buffer,
240 size_t *maxlen, 160 size_t *maxlen,
241 size_t *retlen, 161 size_t *retlen,
162 int *truncated,
242 const char *format, 163 const char *format,
243 va_list args) 164 va_list args)
244{ 165{
@@ -259,7 +180,7 @@ _dopr(
259 ch = *format++; 180 ch = *format++;
260 181
261 while (state != DP_S_DONE) { 182 while (state != DP_S_DONE) {
262 if ((ch == '\0') || (*isbig_fn)(currlen, *maxlen)) 183 if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
263 state = DP_S_DONE; 184 state = DP_S_DONE;
264 185
265 switch (state) { 186 switch (state) {
@@ -267,7 +188,7 @@ _dopr(
267 if (ch == '%') 188 if (ch == '%')
268 state = DP_S_FLAGS; 189 state = DP_S_FLAGS;
269 else 190 else
270 (*outch_fn)(buffer, &currlen, maxlen, ch); 191 doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
271 ch = *format++; 192 ch = *format++;
272 break; 193 break;
273 case DP_S_FLAGS: 194 case DP_S_FLAGS:
@@ -373,8 +294,8 @@ _dopr(
373 value = va_arg(args, int); 294 value = va_arg(args, int);
374 break; 295 break;
375 } 296 }
376 fmtint(outch_fn, buffer, &currlen, maxlen, 297 fmtint(sbuffer, buffer, &currlen, maxlen,
377 value, 10, min, max, flags); 298 value, 10, min, max, flags);
378 break; 299 break;
379 case 'X': 300 case 'X':
380 flags |= DP_F_UP; 301 flags |= DP_F_UP;
@@ -399,7 +320,7 @@ _dopr(
399 unsigned int); 320 unsigned int);
400 break; 321 break;
401 } 322 }
402 fmtint(outch_fn, buffer, &currlen, maxlen, value, 323 fmtint(sbuffer, buffer, &currlen, maxlen, value,
403 ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), 324 ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
404 min, max, flags); 325 min, max, flags);
405 break; 326 break;
@@ -408,8 +329,8 @@ _dopr(
408 fvalue = va_arg(args, LDOUBLE); 329 fvalue = va_arg(args, LDOUBLE);
409 else 330 else
410 fvalue = va_arg(args, double); 331 fvalue = va_arg(args, double);
411 fmtfp(outch_fn, buffer, &currlen, maxlen, 332 fmtfp(sbuffer, buffer, &currlen, maxlen,
412 fvalue, min, max, flags); 333 fvalue, min, max, flags);
413 break; 334 break;
414 case 'E': 335 case 'E':
415 flags |= DP_F_UP; 336 flags |= DP_F_UP;
@@ -428,19 +349,23 @@ _dopr(
428 fvalue = va_arg(args, double); 349 fvalue = va_arg(args, double);
429 break; 350 break;
430 case 'c': 351 case 'c':
431 (*outch_fn)(buffer, &currlen, maxlen, 352 doapr_outch(sbuffer, buffer, &currlen, maxlen,
432 va_arg(args, int)); 353 va_arg(args, int));
433 break; 354 break;
434 case 's': 355 case 's':
435 strvalue = va_arg(args, char *); 356 strvalue = va_arg(args, char *);
436 if (max < 0) 357 if (max < 0) {
437 max = (*copy_fn)(*maxlen); 358 if (buffer)
438 fmtstr(outch_fn, buffer, &currlen, maxlen, strvalue, 359 max = INT_MAX;
439 flags, min, max); 360 else
361 max = *maxlen;
362 }
363 fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
364 flags, min, max);
440 break; 365 break;
441 case 'p': 366 case 'p':
442 value = (long)va_arg(args, void *); 367 value = (long)va_arg(args, void *);
443 fmtint(outch_fn, buffer, &currlen, maxlen, 368 fmtint(sbuffer, buffer, &currlen, maxlen,
444 value, 16, min, max, flags); 369 value, 16, min, max, flags);
445 break; 370 break;
446 case 'n': /* XXX */ 371 case 'n': /* XXX */
@@ -463,7 +388,7 @@ _dopr(
463 } 388 }
464 break; 389 break;
465 case '%': 390 case '%':
466 (*outch_fn)(buffer, &currlen, maxlen, ch); 391 doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
467 break; 392 break;
468 case 'w': 393 case 'w':
469 /* not supported yet, treat as next char */ 394 /* not supported yet, treat as next char */
@@ -484,16 +409,17 @@ _dopr(
484 break; 409 break;
485 } 410 }
486 } 411 }
487 if (currlen >= *maxlen - 1) 412 *truncated = (currlen > *maxlen - 1);
413 if (*truncated)
488 currlen = *maxlen - 1; 414 currlen = *maxlen - 1;
489 (*buffer)[currlen] = '\0'; 415 doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
490 *retlen = currlen; 416 *retlen = currlen - 1;
491 return; 417 return;
492} 418}
493 419
494static void 420static void
495fmtstr( 421fmtstr(
496 void (*outch_fn)(char **, size_t *, size_t *, int), 422 char **sbuffer,
497 char **buffer, 423 char **buffer,
498 size_t *currlen, 424 size_t *currlen,
499 size_t *maxlen, 425 size_t *maxlen,
@@ -516,16 +442,16 @@ fmtstr(
516 padlen = -padlen; 442 padlen = -padlen;
517 443
518 while ((padlen > 0) && (cnt < max)) { 444 while ((padlen > 0) && (cnt < max)) {
519 (*outch_fn)(buffer, currlen, maxlen, ' '); 445 doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
520 --padlen; 446 --padlen;
521 ++cnt; 447 ++cnt;
522 } 448 }
523 while (*value && (cnt < max)) { 449 while (*value && (cnt < max)) {
524 (*outch_fn)(buffer, currlen, maxlen, *value++); 450 doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
525 ++cnt; 451 ++cnt;
526 } 452 }
527 while ((padlen < 0) && (cnt < max)) { 453 while ((padlen < 0) && (cnt < max)) {
528 (*outch_fn)(buffer, currlen, maxlen, ' '); 454 doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
529 ++padlen; 455 ++padlen;
530 ++cnt; 456 ++cnt;
531 } 457 }
@@ -533,7 +459,7 @@ fmtstr(
533 459
534static void 460static void
535fmtint( 461fmtint(
536 void (*outch_fn)(char **, size_t *, size_t *, int), 462 char **sbuffer,
537 char **buffer, 463 char **buffer,
538 size_t *currlen, 464 size_t *currlen,
539 size_t *maxlen, 465 size_t *maxlen,
@@ -590,28 +516,28 @@ fmtint(
590 516
591 /* spaces */ 517 /* spaces */
592 while (spadlen > 0) { 518 while (spadlen > 0) {
593 (*outch_fn)(buffer, currlen, maxlen, ' '); 519 doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
594 --spadlen; 520 --spadlen;
595 } 521 }
596 522
597 /* sign */ 523 /* sign */
598 if (signvalue) 524 if (signvalue)
599 (*outch_fn)(buffer, currlen, maxlen, signvalue); 525 doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
600 526
601 /* zeros */ 527 /* zeros */
602 if (zpadlen > 0) { 528 if (zpadlen > 0) {
603 while (zpadlen > 0) { 529 while (zpadlen > 0) {
604 (*outch_fn)(buffer, currlen, maxlen, '0'); 530 doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
605 --zpadlen; 531 --zpadlen;
606 } 532 }
607 } 533 }
608 /* digits */ 534 /* digits */
609 while (place > 0) 535 while (place > 0)
610 (*outch_fn)(buffer, currlen, maxlen, convert[--place]); 536 doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
611 537
612 /* left justified spaces */ 538 /* left justified spaces */
613 while (spadlen < 0) { 539 while (spadlen < 0) {
614 (*outch_fn)(buffer, currlen, maxlen, ' '); 540 doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
615 ++spadlen; 541 ++spadlen;
616 } 542 }
617 return; 543 return;
@@ -650,7 +576,7 @@ round(LDOUBLE value)
650 576
651static void 577static void
652fmtfp( 578fmtfp(
653 void (*outch_fn)(char **, size_t *, size_t *, int), 579 char **sbuffer,
654 char **buffer, 580 char **buffer,
655 size_t *currlen, 581 size_t *currlen,
656 size_t *maxlen, 582 size_t *maxlen,
@@ -731,114 +657,158 @@ fmtfp(
731 657
732 if ((flags & DP_F_ZERO) && (padlen > 0)) { 658 if ((flags & DP_F_ZERO) && (padlen > 0)) {
733 if (signvalue) { 659 if (signvalue) {
734 (*outch_fn)(buffer, currlen, maxlen, signvalue); 660 doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
735 --padlen; 661 --padlen;
736 signvalue = 0; 662 signvalue = 0;
737 } 663 }
738 while (padlen > 0) { 664 while (padlen > 0) {
739 (*outch_fn)(buffer, currlen, maxlen, '0'); 665 doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
740 --padlen; 666 --padlen;
741 } 667 }
742 } 668 }
743 while (padlen > 0) { 669 while (padlen > 0) {
744 (*outch_fn)(buffer, currlen, maxlen, ' '); 670 doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
745 --padlen; 671 --padlen;
746 } 672 }
747 if (signvalue) 673 if (signvalue)
748 (*outch_fn)(buffer, currlen, maxlen, signvalue); 674 doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
749 675
750 while (iplace > 0) 676 while (iplace > 0)
751 (*outch_fn)(buffer, currlen, maxlen, iconvert[--iplace]); 677 doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
752 678
753 /* 679 /*
754 * Decimal point. This should probably use locale to find the correct 680 * Decimal point. This should probably use locale to find the correct
755 * char to print out. 681 * char to print out.
756 */ 682 */
757 if (max > 0) { 683 if (max > 0) {
758 (*outch_fn)(buffer, currlen, maxlen, '.'); 684 doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
759 685
760 while (fplace > 0) 686 while (fplace > 0)
761 (*outch_fn)(buffer, currlen, maxlen, fconvert[--fplace]); 687 doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
762 } 688 }
763 while (zpadlen > 0) { 689 while (zpadlen > 0) {
764 (*outch_fn)(buffer, currlen, maxlen, '0'); 690 doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
765 --zpadlen; 691 --zpadlen;
766 } 692 }
767 693
768 while (padlen < 0) { 694 while (padlen < 0) {
769 (*outch_fn)(buffer, currlen, maxlen, ' '); 695 doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
770 ++padlen; 696 ++padlen;
771 } 697 }
772} 698}
773 699
774static int
775dopr_copy(
776 size_t len)
777{
778 return len;
779}
780
781#ifdef USE_ALLOCATING_PRINT
782static int
783doapr_copy(
784 size_t len)
785{
786 /* Return as high an integer as possible */
787 return INT_MAX;
788}
789#endif
790
791static int
792dopr_isbig(
793 size_t currlen,
794 size_t maxlen)
795{
796 return currlen > maxlen;
797}
798
799#ifdef USE_ALLOCATING_PRINT
800static int
801doapr_isbig(
802 size_t currlen,
803 size_t maxlen)
804{
805 return 0;
806}
807#endif
808
809static void
810dopr_outch(
811 char **buffer,
812 size_t *currlen,
813 size_t *maxlen,
814 int c)
815{
816 if (*currlen < *maxlen)
817 (*buffer)[(*currlen)++] = (char)c;
818 return;
819}
820
821#ifdef USE_ALLOCATING_PRINT
822static void 700static void
823doapr_outch( 701doapr_outch(
702 char **sbuffer,
824 char **buffer, 703 char **buffer,
825 size_t *currlen, 704 size_t *currlen,
826 size_t *maxlen, 705 size_t *maxlen,
827 int c) 706 int c)
828{ 707{
829 if (*buffer == NULL) { 708 /* If we haven't at least one buffer, someone has doe a big booboo */
830 if (*maxlen == 0) 709 assert(*sbuffer != NULL || buffer != NULL);
831 *maxlen = 1024; 710
832 *buffer = Malloc(*maxlen); 711 if (buffer) {
712 while (*currlen >= *maxlen) {
713 if (*buffer == NULL) {
714 assert(*sbuffer != NULL);
715 if (*maxlen == 0)
716 *maxlen = 1024;
717 *buffer = OPENSSL_malloc(*maxlen);
718 if (*currlen > 0)
719 memcpy(*buffer, *sbuffer, *currlen);
720 *sbuffer = NULL;
721 } else {
722 *maxlen += 1024;
723 *buffer = OPENSSL_realloc(*buffer, *maxlen);
724 }
725 }
726 /* What to do if *buffer is NULL? */
727 assert(*sbuffer != NULL || *buffer != NULL);
833 } 728 }
834 while (*currlen >= *maxlen) { 729
835 *maxlen += 1024; 730 if (*currlen < *maxlen) {
836 *buffer = Realloc(*buffer, *maxlen); 731 if (*sbuffer)
732 (*sbuffer)[(*currlen)++] = (char)c;
733 else
734 (*buffer)[(*currlen)++] = (char)c;
837 } 735 }
838 /* What to do if *buffer is NULL? */
839 assert(*buffer != NULL);
840 736
841 (*buffer)[(*currlen)++] = (char)c;
842 return; 737 return;
843} 738}
844#endif 739
740/***************************************************************************/
741
742int BIO_printf (BIO *bio, const char *format, ...)
743 {
744 va_list args;
745 int ret;
746
747 va_start(args, format);
748
749 ret = BIO_vprintf(bio, format, args);
750
751 va_end(args);
752 return(ret);
753 }
754
755int BIO_vprintf (BIO *bio, const char *format, va_list args)
756 {
757 int ret;
758 size_t retlen;
759 MS_STATIC char hugebuf[1024*10];
760 char *hugebufp = hugebuf;
761 size_t hugebufsize = sizeof(hugebuf);
762 char *dynbuf = NULL;
763 int ignored;
764
765 dynbuf = NULL;
766 CRYPTO_push_info("doapr()");
767 _dopr(&hugebufp, &dynbuf, &hugebufsize,
768 &retlen, &ignored, format, args);
769 if (dynbuf)
770 {
771 ret=BIO_write(bio, dynbuf, (int)retlen);
772 OPENSSL_free(dynbuf);
773 }
774 else
775 {
776 ret=BIO_write(bio, hugebuf, (int)retlen);
777 }
778 CRYPTO_pop_info();
779 return(ret);
780 }
781
782/* As snprintf is not available everywhere, we provide our own implementation.
783 * This function has nothing to do with BIOs, but it's closely related
784 * to BIO_printf, and we need *some* name prefix ...
785 * (XXX the function should be renamed, but to what?) */
786int BIO_snprintf(char *buf, size_t n, const char *format, ...)
787 {
788 va_list args;
789 int ret;
790
791 va_start(args, format);
792
793 ret = BIO_vsnprintf(buf, n, format, args);
794
795 va_end(args);
796 return(ret);
797 }
798
799int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
800 {
801 size_t retlen;
802 int truncated;
803
804 _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
805
806 if (truncated)
807 /* In case of truncation, return -1 like traditional snprintf.
808 * (Current drafts for ISO/IEC 9899 say snprintf should return
809 * the number of characters that would have been written,
810 * had the buffer been large enough.) */
811 return -1;
812 else
813 return (retlen <= INT_MAX) ? retlen : -1;
814 }