forked from pool/openssl
7f772876ff
- update to 1.0.2d * fixes CVE-2015-1793 (bsc#936746) Alternate chains certificate forgery During certificate verfification, OpenSSL will attempt to find an alternative certificate chain if the first attempt to build such a chain fails. An error in the implementation of this logic can mean that an attacker could cause certain checks on untrusted certificates to be bypassed, such as the CA flag, enabling them to use a valid leaf certificate to act as a CA and "issue" an invalid certificate. - drop openssl-fix_invalid_manpage_name.patch (upstream) (forwarded request 315682 from vitezslav_cizek) OBS-URL: https://build.opensuse.org/request/show/315685 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openssl?expand=0&rev=128
794 lines
22 KiB
Diff
794 lines
22 KiB
Diff
From fd708c2242408187cff392e8b0850275ac99376f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= <crrodriguez@opensuse.org>
|
|
Date: Sun, 4 May 2014 23:36:54 -0400
|
|
Subject: [PATCH] Axe builtin printf implementation, use glibc instead
|
|
|
|
|
|
Index: openssl-1.0.2b/crypto/bio/b_print.c
|
|
===================================================================
|
|
--- openssl-1.0.2b.orig/crypto/bio/b_print.c 2015-06-11 15:01:06.000000000 +0200
|
|
+++ openssl-1.0.2b/crypto/bio/b_print.c 2015-06-11 17:50:00.893823977 +0200
|
|
@@ -56,17 +56,10 @@
|
|
* [including the GNU Public Licence.]
|
|
*/
|
|
|
|
-/* disable assert() unless BIO_DEBUG has been defined */
|
|
-#ifndef BIO_DEBUG
|
|
-# ifndef NDEBUG
|
|
-# define NDEBUG
|
|
-# endif
|
|
+#ifndef _GNU_SOURCE
|
|
+#define _GNU_SOURCE
|
|
#endif
|
|
|
|
-/*
|
|
- * Stolen from tjh's ssl/ssl_trc.c stuff.
|
|
- */
|
|
-
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
@@ -79,668 +72,6 @@
|
|
#include <openssl/bn.h> /* To get BN_LLONG properly defined */
|
|
#include <openssl/bio.h>
|
|
|
|
-#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
|
|
-# ifndef HAVE_LONG_LONG
|
|
-# define HAVE_LONG_LONG 1
|
|
-# endif
|
|
-#endif
|
|
-
|
|
-/***************************************************************************/
|
|
-
|
|
-/*
|
|
- * Copyright Patrick Powell 1995
|
|
- * This code is based on code written by Patrick Powell <papowell@astart.com>
|
|
- * It may be used for any purpose as long as this notice remains intact
|
|
- * on all source code distributions.
|
|
- */
|
|
-
|
|
-/*-
|
|
- * This code contains numerious changes and enhancements which were
|
|
- * made by lots of contributors over the last years to Patrick Powell's
|
|
- * original code:
|
|
- *
|
|
- * o Patrick Powell <papowell@astart.com> (1995)
|
|
- * o Brandon Long <blong@fiction.net> (1996, for Mutt)
|
|
- * o Thomas Roessler <roessler@guug.de> (1998, for Mutt)
|
|
- * o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt)
|
|
- * o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
|
|
- * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
|
|
- * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
|
|
- * o ... (for OpenSSL)
|
|
- */
|
|
-
|
|
-#ifdef HAVE_LONG_DOUBLE
|
|
-# define LDOUBLE long double
|
|
-#else
|
|
-# define LDOUBLE double
|
|
-#endif
|
|
-
|
|
-#ifdef HAVE_LONG_LONG
|
|
-# if defined(_WIN32) && !defined(__GNUC__)
|
|
-# define LLONG __int64
|
|
-# else
|
|
-# define LLONG long long
|
|
-# endif
|
|
-#else
|
|
-# define LLONG long
|
|
-#endif
|
|
-
|
|
-static void fmtstr(char **, char **, size_t *, size_t *,
|
|
- const char *, int, int, int);
|
|
-static void fmtint(char **, char **, size_t *, size_t *,
|
|
- LLONG, int, int, int, int);
|
|
-static void fmtfp(char **, char **, size_t *, size_t *,
|
|
- LDOUBLE, int, int, int);
|
|
-static void doapr_outch(char **, char **, size_t *, size_t *, int);
|
|
-static void _dopr(char **sbuffer, char **buffer,
|
|
- size_t *maxlen, size_t *retlen, int *truncated,
|
|
- const char *format, va_list args);
|
|
-
|
|
-/* format read states */
|
|
-#define DP_S_DEFAULT 0
|
|
-#define DP_S_FLAGS 1
|
|
-#define DP_S_MIN 2
|
|
-#define DP_S_DOT 3
|
|
-#define DP_S_MAX 4
|
|
-#define DP_S_MOD 5
|
|
-#define DP_S_CONV 6
|
|
-#define DP_S_DONE 7
|
|
-
|
|
-/* format flags - Bits */
|
|
-#define DP_F_MINUS (1 << 0)
|
|
-#define DP_F_PLUS (1 << 1)
|
|
-#define DP_F_SPACE (1 << 2)
|
|
-#define DP_F_NUM (1 << 3)
|
|
-#define DP_F_ZERO (1 << 4)
|
|
-#define DP_F_UP (1 << 5)
|
|
-#define DP_F_UNSIGNED (1 << 6)
|
|
-
|
|
-/* conversion flags */
|
|
-#define DP_C_SHORT 1
|
|
-#define DP_C_LONG 2
|
|
-#define DP_C_LDOUBLE 3
|
|
-#define DP_C_LLONG 4
|
|
-
|
|
-/* some handy macros */
|
|
-#define char_to_int(p) (p - '0')
|
|
-#define OSSL_MAX(p,q) ((p >= q) ? p : q)
|
|
-
|
|
-static void
|
|
-_dopr(char **sbuffer,
|
|
- char **buffer,
|
|
- size_t *maxlen,
|
|
- size_t *retlen, int *truncated, const char *format, va_list args)
|
|
-{
|
|
- char ch;
|
|
- LLONG value;
|
|
- LDOUBLE fvalue;
|
|
- char *strvalue;
|
|
- int min;
|
|
- int max;
|
|
- int state;
|
|
- int flags;
|
|
- int cflags;
|
|
- size_t currlen;
|
|
-
|
|
- state = DP_S_DEFAULT;
|
|
- flags = currlen = cflags = min = 0;
|
|
- max = -1;
|
|
- ch = *format++;
|
|
-
|
|
- while (state != DP_S_DONE) {
|
|
- if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
|
|
- state = DP_S_DONE;
|
|
-
|
|
- switch (state) {
|
|
- case DP_S_DEFAULT:
|
|
- if (ch == '%')
|
|
- state = DP_S_FLAGS;
|
|
- else
|
|
- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
|
|
- ch = *format++;
|
|
- break;
|
|
- case DP_S_FLAGS:
|
|
- switch (ch) {
|
|
- case '-':
|
|
- flags |= DP_F_MINUS;
|
|
- ch = *format++;
|
|
- break;
|
|
- case '+':
|
|
- flags |= DP_F_PLUS;
|
|
- ch = *format++;
|
|
- break;
|
|
- case ' ':
|
|
- flags |= DP_F_SPACE;
|
|
- ch = *format++;
|
|
- break;
|
|
- case '#':
|
|
- flags |= DP_F_NUM;
|
|
- ch = *format++;
|
|
- break;
|
|
- case '0':
|
|
- flags |= DP_F_ZERO;
|
|
- ch = *format++;
|
|
- break;
|
|
- default:
|
|
- state = DP_S_MIN;
|
|
- break;
|
|
- }
|
|
- break;
|
|
- case DP_S_MIN:
|
|
- if (isdigit((unsigned char)ch)) {
|
|
- min = 10 * min + char_to_int(ch);
|
|
- ch = *format++;
|
|
- } else if (ch == '*') {
|
|
- min = va_arg(args, int);
|
|
- ch = *format++;
|
|
- state = DP_S_DOT;
|
|
- } else
|
|
- state = DP_S_DOT;
|
|
- break;
|
|
- case DP_S_DOT:
|
|
- if (ch == '.') {
|
|
- state = DP_S_MAX;
|
|
- ch = *format++;
|
|
- } else
|
|
- state = DP_S_MOD;
|
|
- break;
|
|
- case DP_S_MAX:
|
|
- if (isdigit((unsigned char)ch)) {
|
|
- if (max < 0)
|
|
- max = 0;
|
|
- max = 10 * max + char_to_int(ch);
|
|
- ch = *format++;
|
|
- } else if (ch == '*') {
|
|
- max = va_arg(args, int);
|
|
- ch = *format++;
|
|
- state = DP_S_MOD;
|
|
- } else
|
|
- state = DP_S_MOD;
|
|
- break;
|
|
- case DP_S_MOD:
|
|
- switch (ch) {
|
|
- case 'h':
|
|
- cflags = DP_C_SHORT;
|
|
- ch = *format++;
|
|
- break;
|
|
- case 'l':
|
|
- if (*format == 'l') {
|
|
- cflags = DP_C_LLONG;
|
|
- format++;
|
|
- } else
|
|
- cflags = DP_C_LONG;
|
|
- ch = *format++;
|
|
- break;
|
|
- case 'q':
|
|
- cflags = DP_C_LLONG;
|
|
- ch = *format++;
|
|
- break;
|
|
- case 'L':
|
|
- cflags = DP_C_LDOUBLE;
|
|
- ch = *format++;
|
|
- break;
|
|
- default:
|
|
- break;
|
|
- }
|
|
- state = DP_S_CONV;
|
|
- break;
|
|
- case DP_S_CONV:
|
|
- switch (ch) {
|
|
- case 'd':
|
|
- case 'i':
|
|
- switch (cflags) {
|
|
- case DP_C_SHORT:
|
|
- value = (short int)va_arg(args, int);
|
|
- break;
|
|
- case DP_C_LONG:
|
|
- value = va_arg(args, long int);
|
|
- break;
|
|
- case DP_C_LLONG:
|
|
- value = va_arg(args, LLONG);
|
|
- break;
|
|
- default:
|
|
- value = va_arg(args, int);
|
|
- break;
|
|
- }
|
|
- fmtint(sbuffer, buffer, &currlen, maxlen,
|
|
- value, 10, min, max, flags);
|
|
- break;
|
|
- case 'X':
|
|
- flags |= DP_F_UP;
|
|
- /* FALLTHROUGH */
|
|
- case 'x':
|
|
- case 'o':
|
|
- case 'u':
|
|
- flags |= DP_F_UNSIGNED;
|
|
- switch (cflags) {
|
|
- case DP_C_SHORT:
|
|
- value = (unsigned short int)va_arg(args, unsigned int);
|
|
- break;
|
|
- case DP_C_LONG:
|
|
- value = (LLONG) va_arg(args, unsigned long int);
|
|
- break;
|
|
- case DP_C_LLONG:
|
|
- value = va_arg(args, unsigned LLONG);
|
|
- break;
|
|
- default:
|
|
- value = (LLONG) va_arg(args, unsigned int);
|
|
- break;
|
|
- }
|
|
- fmtint(sbuffer, buffer, &currlen, maxlen, value,
|
|
- ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
|
|
- min, max, flags);
|
|
- break;
|
|
- case 'f':
|
|
- if (cflags == DP_C_LDOUBLE)
|
|
- fvalue = va_arg(args, LDOUBLE);
|
|
- else
|
|
- fvalue = va_arg(args, double);
|
|
- fmtfp(sbuffer, buffer, &currlen, maxlen,
|
|
- fvalue, min, max, flags);
|
|
- break;
|
|
- case 'E':
|
|
- flags |= DP_F_UP;
|
|
- case 'e':
|
|
- if (cflags == DP_C_LDOUBLE)
|
|
- fvalue = va_arg(args, LDOUBLE);
|
|
- else
|
|
- fvalue = va_arg(args, double);
|
|
- break;
|
|
- case 'G':
|
|
- flags |= DP_F_UP;
|
|
- case 'g':
|
|
- if (cflags == DP_C_LDOUBLE)
|
|
- fvalue = va_arg(args, LDOUBLE);
|
|
- else
|
|
- fvalue = va_arg(args, double);
|
|
- break;
|
|
- case 'c':
|
|
- doapr_outch(sbuffer, buffer, &currlen, maxlen,
|
|
- va_arg(args, int));
|
|
- break;
|
|
- case 's':
|
|
- strvalue = va_arg(args, char *);
|
|
- if (max < 0) {
|
|
- if (buffer)
|
|
- max = INT_MAX;
|
|
- else
|
|
- max = *maxlen;
|
|
- }
|
|
- fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
|
|
- flags, min, max);
|
|
- break;
|
|
- case 'p':
|
|
- value = (long)va_arg(args, void *);
|
|
- fmtint(sbuffer, buffer, &currlen, maxlen,
|
|
- value, 16, min, max, flags | DP_F_NUM);
|
|
- break;
|
|
- case 'n': /* XXX */
|
|
- if (cflags == DP_C_SHORT) {
|
|
- short int *num;
|
|
- num = va_arg(args, short int *);
|
|
- *num = currlen;
|
|
- } else if (cflags == DP_C_LONG) { /* XXX */
|
|
- long int *num;
|
|
- num = va_arg(args, long int *);
|
|
- *num = (long int)currlen;
|
|
- } else if (cflags == DP_C_LLONG) { /* XXX */
|
|
- LLONG *num;
|
|
- num = va_arg(args, LLONG *);
|
|
- *num = (LLONG) currlen;
|
|
- } else {
|
|
- int *num;
|
|
- num = va_arg(args, int *);
|
|
- *num = currlen;
|
|
- }
|
|
- break;
|
|
- case '%':
|
|
- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
|
|
- break;
|
|
- case 'w':
|
|
- /* not supported yet, treat as next char */
|
|
- ch = *format++;
|
|
- break;
|
|
- default:
|
|
- /* unknown, skip */
|
|
- break;
|
|
- }
|
|
- ch = *format++;
|
|
- state = DP_S_DEFAULT;
|
|
- flags = cflags = min = 0;
|
|
- max = -1;
|
|
- break;
|
|
- case DP_S_DONE:
|
|
- break;
|
|
- default:
|
|
- break;
|
|
- }
|
|
- }
|
|
- *truncated = (currlen > *maxlen - 1);
|
|
- if (*truncated)
|
|
- currlen = *maxlen - 1;
|
|
- doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
|
|
- *retlen = currlen - 1;
|
|
- return;
|
|
-}
|
|
-
|
|
-static void
|
|
-fmtstr(char **sbuffer,
|
|
- char **buffer,
|
|
- size_t *currlen,
|
|
- size_t *maxlen, const char *value, int flags, int min, int max)
|
|
-{
|
|
- int padlen, strln;
|
|
- int cnt = 0;
|
|
-
|
|
- if (value == 0)
|
|
- value = "<NULL>";
|
|
- for (strln = 0; value[strln]; ++strln) ;
|
|
- padlen = min - strln;
|
|
- if (padlen < 0)
|
|
- padlen = 0;
|
|
- if (flags & DP_F_MINUS)
|
|
- padlen = -padlen;
|
|
-
|
|
- while ((padlen > 0) && (cnt < max)) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
- --padlen;
|
|
- ++cnt;
|
|
- }
|
|
- while (*value && (cnt < max)) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
|
|
- ++cnt;
|
|
- }
|
|
- while ((padlen < 0) && (cnt < max)) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
- ++padlen;
|
|
- ++cnt;
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-fmtint(char **sbuffer,
|
|
- char **buffer,
|
|
- size_t *currlen,
|
|
- size_t *maxlen, LLONG value, int base, int min, int max, int flags)
|
|
-{
|
|
- int signvalue = 0;
|
|
- const char *prefix = "";
|
|
- unsigned LLONG uvalue;
|
|
- char convert[DECIMAL_SIZE(value) + 3];
|
|
- int place = 0;
|
|
- int spadlen = 0;
|
|
- int zpadlen = 0;
|
|
- int caps = 0;
|
|
-
|
|
- if (max < 0)
|
|
- max = 0;
|
|
- uvalue = value;
|
|
- if (!(flags & DP_F_UNSIGNED)) {
|
|
- if (value < 0) {
|
|
- signvalue = '-';
|
|
- uvalue = -value;
|
|
- } else if (flags & DP_F_PLUS)
|
|
- signvalue = '+';
|
|
- else if (flags & DP_F_SPACE)
|
|
- signvalue = ' ';
|
|
- }
|
|
- if (flags & DP_F_NUM) {
|
|
- if (base == 8)
|
|
- prefix = "0";
|
|
- if (base == 16)
|
|
- prefix = "0x";
|
|
- }
|
|
- if (flags & DP_F_UP)
|
|
- caps = 1;
|
|
- do {
|
|
- convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
|
- [uvalue % (unsigned)base];
|
|
- uvalue = (uvalue / (unsigned)base);
|
|
- } while (uvalue && (place < (int)sizeof(convert)));
|
|
- if (place == sizeof(convert))
|
|
- place--;
|
|
- convert[place] = 0;
|
|
-
|
|
- zpadlen = max - place;
|
|
- spadlen =
|
|
- min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
|
|
- if (zpadlen < 0)
|
|
- zpadlen = 0;
|
|
- if (spadlen < 0)
|
|
- spadlen = 0;
|
|
- if (flags & DP_F_ZERO) {
|
|
- zpadlen = OSSL_MAX(zpadlen, spadlen);
|
|
- spadlen = 0;
|
|
- }
|
|
- if (flags & DP_F_MINUS)
|
|
- spadlen = -spadlen;
|
|
-
|
|
- /* spaces */
|
|
- while (spadlen > 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
- --spadlen;
|
|
- }
|
|
-
|
|
- /* sign */
|
|
- if (signvalue)
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
|
-
|
|
- /* prefix */
|
|
- while (*prefix) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
|
|
- prefix++;
|
|
- }
|
|
-
|
|
- /* zeros */
|
|
- if (zpadlen > 0) {
|
|
- while (zpadlen > 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
|
- --zpadlen;
|
|
- }
|
|
- }
|
|
- /* digits */
|
|
- while (place > 0)
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
|
|
-
|
|
- /* left justified spaces */
|
|
- while (spadlen < 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
- ++spadlen;
|
|
- }
|
|
- return;
|
|
-}
|
|
-
|
|
-static LDOUBLE abs_val(LDOUBLE value)
|
|
-{
|
|
- LDOUBLE result = value;
|
|
- if (value < 0)
|
|
- result = -value;
|
|
- return result;
|
|
-}
|
|
-
|
|
-static LDOUBLE pow_10(int in_exp)
|
|
-{
|
|
- LDOUBLE result = 1;
|
|
- while (in_exp) {
|
|
- result *= 10;
|
|
- in_exp--;
|
|
- }
|
|
- return result;
|
|
-}
|
|
-
|
|
-static long roundv(LDOUBLE value)
|
|
-{
|
|
- long intpart;
|
|
- intpart = (long)value;
|
|
- value = value - intpart;
|
|
- if (value >= 0.5)
|
|
- intpart++;
|
|
- return intpart;
|
|
-}
|
|
-
|
|
-static void
|
|
-fmtfp(char **sbuffer,
|
|
- char **buffer,
|
|
- size_t *currlen,
|
|
- size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags)
|
|
-{
|
|
- int signvalue = 0;
|
|
- LDOUBLE ufvalue;
|
|
- char iconvert[20];
|
|
- char fconvert[20];
|
|
- int iplace = 0;
|
|
- int fplace = 0;
|
|
- int padlen = 0;
|
|
- int zpadlen = 0;
|
|
- long intpart;
|
|
- long fracpart;
|
|
- long max10;
|
|
-
|
|
- if (max < 0)
|
|
- max = 6;
|
|
- ufvalue = abs_val(fvalue);
|
|
- if (fvalue < 0)
|
|
- signvalue = '-';
|
|
- else if (flags & DP_F_PLUS)
|
|
- signvalue = '+';
|
|
- else if (flags & DP_F_SPACE)
|
|
- signvalue = ' ';
|
|
-
|
|
- intpart = (long)ufvalue;
|
|
-
|
|
- /*
|
|
- * sorry, we only support 9 digits past the decimal because of our
|
|
- * conversion method
|
|
- */
|
|
- if (max > 9)
|
|
- max = 9;
|
|
-
|
|
- /*
|
|
- * we "cheat" by converting the fractional part to integer by multiplying
|
|
- * by a factor of 10
|
|
- */
|
|
- max10 = roundv(pow_10(max));
|
|
- fracpart = roundv(pow_10(max) * (ufvalue - intpart));
|
|
-
|
|
- if (fracpart >= max10) {
|
|
- intpart++;
|
|
- fracpart -= max10;
|
|
- }
|
|
-
|
|
- /* convert integer part */
|
|
- do {
|
|
- iconvert[iplace++] = "0123456789"[intpart % 10];
|
|
- intpart = (intpart / 10);
|
|
- } while (intpart && (iplace < (int)sizeof(iconvert)));
|
|
- if (iplace == sizeof iconvert)
|
|
- iplace--;
|
|
- iconvert[iplace] = 0;
|
|
-
|
|
- /* convert fractional part */
|
|
- do {
|
|
- fconvert[fplace++] = "0123456789"[fracpart % 10];
|
|
- fracpart = (fracpart / 10);
|
|
- } while (fplace < max);
|
|
- if (fplace == sizeof fconvert)
|
|
- fplace--;
|
|
- fconvert[fplace] = 0;
|
|
-
|
|
- /* -1 for decimal point, another -1 if we are printing a sign */
|
|
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
|
|
- zpadlen = max - fplace;
|
|
- if (zpadlen < 0)
|
|
- zpadlen = 0;
|
|
- if (padlen < 0)
|
|
- padlen = 0;
|
|
- if (flags & DP_F_MINUS)
|
|
- padlen = -padlen;
|
|
-
|
|
- if ((flags & DP_F_ZERO) && (padlen > 0)) {
|
|
- if (signvalue) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
|
- --padlen;
|
|
- signvalue = 0;
|
|
- }
|
|
- while (padlen > 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
|
- --padlen;
|
|
- }
|
|
- }
|
|
- while (padlen > 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
- --padlen;
|
|
- }
|
|
- if (signvalue)
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
|
-
|
|
- while (iplace > 0)
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
|
|
-
|
|
- /*
|
|
- * Decimal point. This should probably use locale to find the correct
|
|
- * char to print out.
|
|
- */
|
|
- if (max > 0 || (flags & DP_F_NUM)) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
|
|
-
|
|
- while (fplace > 0)
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
|
|
- }
|
|
- while (zpadlen > 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
|
- --zpadlen;
|
|
- }
|
|
-
|
|
- while (padlen < 0) {
|
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
- ++padlen;
|
|
- }
|
|
-}
|
|
-
|
|
-static void
|
|
-doapr_outch(char **sbuffer,
|
|
- char **buffer, size_t *currlen, size_t *maxlen, int c)
|
|
-{
|
|
- /* If we haven't at least one buffer, someone has doe a big booboo */
|
|
- assert(*sbuffer != NULL || buffer != NULL);
|
|
-
|
|
- /* |currlen| must always be <= |*maxlen| */
|
|
- assert(*currlen <= *maxlen);
|
|
-
|
|
- if (buffer && *currlen == *maxlen) {
|
|
- *maxlen += 1024;
|
|
- if (*buffer == NULL) {
|
|
- *buffer = OPENSSL_malloc(*maxlen);
|
|
- if (!*buffer) {
|
|
- /* Panic! Can't really do anything sensible. Just return */
|
|
- return;
|
|
- }
|
|
- if (*currlen > 0) {
|
|
- assert(*sbuffer != NULL);
|
|
- memcpy(*buffer, *sbuffer, *currlen);
|
|
- }
|
|
- *sbuffer = NULL;
|
|
- } else {
|
|
- *buffer = OPENSSL_realloc(*buffer, *maxlen);
|
|
- if (!*buffer) {
|
|
- /* Panic! Can't really do anything sensible. Just return */
|
|
- return;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- if (*currlen < *maxlen) {
|
|
- if (*sbuffer)
|
|
- (*sbuffer)[(*currlen)++] = (char)c;
|
|
- else
|
|
- (*buffer)[(*currlen)++] = (char)c;
|
|
- }
|
|
-
|
|
- return;
|
|
-}
|
|
-
|
|
-/***************************************************************************/
|
|
-
|
|
int BIO_printf(BIO *bio, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
@@ -754,28 +85,36 @@ int BIO_printf(BIO *bio, const char *for
|
|
return (ret);
|
|
}
|
|
|
|
+static ssize_t cookie_BIO_write(void *cookie, const char *buf, size_t size)
|
|
+{
|
|
+ int ret;
|
|
+ ret = BIO_write(cookie, buf, size);
|
|
+ /* BIO_write may return negative value on error,
|
|
+ * but we must return 0 on that case
|
|
+ */
|
|
+ return (ret < 0) ? 0 : ret;
|
|
+}
|
|
+
|
|
int BIO_vprintf(BIO *bio, const char *format, va_list args)
|
|
{
|
|
+ FILE *fp;
|
|
int ret;
|
|
- size_t retlen;
|
|
- char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable
|
|
- * in small-stack environments, like threads
|
|
- * or DOS programs. */
|
|
- char *hugebufp = hugebuf;
|
|
- size_t hugebufsize = sizeof(hugebuf);
|
|
- char *dynbuf = NULL;
|
|
- int ignored;
|
|
-
|
|
- dynbuf = NULL;
|
|
- CRYPTO_push_info("doapr()");
|
|
- _dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, args);
|
|
- if (dynbuf) {
|
|
- ret = BIO_write(bio, dynbuf, (int)retlen);
|
|
- OPENSSL_free(dynbuf);
|
|
- } else {
|
|
- ret = BIO_write(bio, hugebuf, (int)retlen);
|
|
- }
|
|
- CRYPTO_pop_info();
|
|
+
|
|
+ cookie_io_functions_t bio_funcs = {
|
|
+ .read = NULL,
|
|
+ .write = cookie_BIO_write,
|
|
+ .seek = NULL,
|
|
+ .close = NULL,
|
|
+ };
|
|
+
|
|
+ fp = fopencookie(bio, "w", bio_funcs);
|
|
+
|
|
+ if (fp == NULL)
|
|
+ return -1;
|
|
+
|
|
+ ret = vfprintf(fp, format, args);
|
|
+
|
|
+ fclose(fp);
|
|
return (ret);
|
|
}
|
|
|
|
@@ -791,28 +130,22 @@ int BIO_snprintf(char *buf, size_t n, co
|
|
int ret;
|
|
|
|
va_start(args, format);
|
|
+ ret = vsnprintf(buf, n, format, args);
|
|
+ va_end(args);
|
|
|
|
- ret = BIO_vsnprintf(buf, n, format, args);
|
|
+ if (ret >= n || ret == -1) return (-1);
|
|
|
|
- va_end(args);
|
|
return (ret);
|
|
}
|
|
|
|
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
|
|
{
|
|
- size_t retlen;
|
|
- int truncated;
|
|
+ int ret;
|
|
|
|
- _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
|
|
+ ret = vsnprintf(buf, n, format, args);
|
|
|
|
- if (truncated)
|
|
- /*
|
|
- * In case of truncation, return -1 like traditional snprintf.
|
|
- * (Current drafts for ISO/IEC 9899 say snprintf should return the
|
|
- * number of characters that would have been written, had the buffer
|
|
- * been large enough.)
|
|
- */
|
|
- return -1;
|
|
- else
|
|
- return (retlen <= INT_MAX) ? (int)retlen : -1;
|
|
+ if (ret >= n || ret == -1)
|
|
+ return (-1);
|
|
+
|
|
+ return (ret);
|
|
}
|