source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_print.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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