HI Yi I have question for 1 - The original file uses code related to floating-point and ulldrvm.
a) Openssl supports OPENSSL_SYS_UEFI macro (https://github.com/tianocore/edk2/blob/master/CryptoPkg/Library/Include/openssl/opensslconf.h#L28), why not use OPENSSL_SYS_UEFI macro to eliminate float point action? b) For ulldrvm, why not implement it in https://github.com/tianocore/edk2/tree/master/CryptoPkg/Library/IntrinsicLib, as we already did. Thank you Yao, Jiewen > -----Original Message----- > From: Li, Yi1 <yi1...@intel.com> > Sent: Sunday, November 20, 2022 12:33 AM > To: devel@edk2.groups.io > Cc: Yao, Jiewen <jiewen....@intel.com>; Wang, Jian J > <jian.j.w...@intel.com>; Lu, Xiaoyu1 <xiaoyu1...@intel.com>; Jiang, > Guomin <guomin.ji...@intel.com> > Subject: RE: [PATCH] CryptoPkg: Add b_print.c which removed floating- > point to OpensslLib > > Hi all, > > This patch is the pre-work for enabling the X509 certificate time check. > I know it looks weird to add a new b_print.c, so I wanted to explain the > background of this patch. > > 1. Why not directly use the b_print.c file in openssl? > The original file uses code related to floating-point and ulldrvm, which will > cause compilation errors like: > unresolved external symbol __aulldvrm > error: SSE register return with SSE disabled > ref: https://github.com/tianocore/edk2/pull/3508 > > So I removed all float code and replaced ulldrvm with > DivU64x32Remainder(): > 1). > case 'f': > case 'E': > case 'e': > case 'G': > case 'g': > return -1; > 2). > + uvalue = DivU64x32Remainder(uvalue, (unsigned)base, &uremainder); > convert[place++] = (caps ? "0123456789ABCDEF" : > "0123456789abcdef") > - [uvalue % (unsigned)base]; > - uvalue = (uvalue / (unsigned)base); > + [uremainder]; > > > 2. Why not use the similar print function AsciiVSPrint in EDK2? > EDK2 functions are all ms_abi but openssl functions not, so they use > different va_list definitions, the relevant codes are as follows: > GCC:*_*_X64_CC_FLAGS = ...... -DNO_MSABI_VA_FUNCS > https://github.com/tianocore/edk2/blob/fff6d81270b57ee786ea18ad74f4 > 3149b9f03494/CryptoPkg/Library/OpensslLib/OpensslLib.inf#LL636C2- > L636C3 > > Therefore, segmentation fault will occur when calling the edk2 VA > parameter function in the openssl function. > > 3. Why not remove NO_MSABI_VA_FUNCS? > Similarly, ms va_list cannot be used in the sysv function in openssl, which > will also cause segmentation fault. > > I am not expert of compilation, let me know if there is other better idea. > > Thanks, > Yi > > -----Original Message----- > From: Li, Yi1 <yi1...@intel.com> > Sent: Sunday, November 20, 2022 12:28 AM > To: devel@edk2.groups.io > Cc: Li, Yi1 <yi1...@intel.com>; Yao, Jiewen <jiewen....@intel.com>; Wang, > Jian J <jian.j.w...@intel.com>; Lu, Xiaoyu1 <xiaoyu1...@intel.com>; Jiang, > Guomin <guomin.ji...@intel.com> > Subject: [PATCH] CryptoPkg: Add b_print.c which removed floating-point to > OpensslLib > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4110 > > Openssl will use BIO_snprintf() to print time string when converting time_t > to ASN1_time. > Currently edk2 code just give it a NULL implement in CrtWrapper.c, so > getting current time in X509 time check will be fail. > > This patch add a copy of OpensslLib\openssl\crypto\bio\b_print.c to > OpensslLib, with below changes: > > 1. All floating point related code removed. > 2. Replace ull divide and remainder with DivU64x32Remainder(). > > Cc: Jiewen Yao <jiewen....@intel.com> > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Xiaoyu Lu <xiaoyu1...@intel.com> > Cc: Guomin Jiang <guomin.ji...@intel.com> > Signed-off-by: Yi Li <yi1...@intel.com> > --- > CryptoPkg/CryptoPkg.ci.yaml | 4 +- > .../Library/BaseCryptLib/SysCall/CrtWrapper.c | 27 - > .../SysCall/UnitTestHostCrtWrapper.c | 25 - > CryptoPkg/Library/OpensslLib/OpensslLib.inf | 1 + > .../Library/OpensslLib/OpensslLibAccel.inf | 1 + > .../Library/OpensslLib/OpensslLibCrypto.inf | 1 + > .../Library/OpensslLib/OpensslLibFull.inf | 1 + > .../OpensslLib/OpensslLibFullAccel.inf | 1 + > CryptoPkg/Library/OpensslLib/b_print.c | 613 ++++++++++++++++++ > 9 files changed, 621 insertions(+), 53 deletions(-) create mode 100644 > CryptoPkg/Library/OpensslLib/b_print.c > > diff --git a/CryptoPkg/CryptoPkg.ci.yaml b/CryptoPkg/CryptoPkg.ci.yaml > index 47f2975967..8c25f581fb 100644 > --- a/CryptoPkg/CryptoPkg.ci.yaml > +++ b/CryptoPkg/CryptoPkg.ci.yaml > @@ -13,7 +13,9 @@ > "Library/OpensslLib/IA32Gcc", > "Library/OpensslLib/X64", > "Library/OpensslLib/X64Gcc", > - "Library/Include/openssl" > + "Library/Include/openssl", > + # b_print.c is a copy from OpenSSl. > + "Library/OpensslLib/b_print.c" > ] > }, > "EccCheck": { > diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c > b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c > index b65d29485b..6d7ac3efdc 100644 > --- a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c > +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c > @@ -472,33 +472,6 @@ fwrite ( > return 0; > } > > -// > -// -- Dummy OpenSSL Support Routines -- -// > - > -int > -BIO_printf ( > - void *bio, > - const char *format, > - ... > - ) > -{ > - return 0; > -} > - > -int > -BIO_snprintf ( > - char *buf, > - size_t n, > - const char *format, > - ... > - ) > -{ > - // Because the function does not actually print anything to buf, it returns > -1 as error. > - // Otherwise, the consumer may think that the buf is valid and parse the > buffer. > - return -1; > -} > - > #ifdef __GNUC__ > > typedef > diff --git > a/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c > b/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c > index 066d53e4fa..244e57437e 100644 > --- a/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c > +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c > @@ -72,31 +72,6 @@ sscanf ( > return 0; > } > > -// > -// -- Dummy OpenSSL Support Routines -- -// > - > -int > -BIO_printf ( > - void *bio, > - const char *format, > - ... > - ) > -{ > - return 0; > -} > - > -int > -BIO_snprintf ( > - char *buf, > - size_t n, > - const char *format, > - ... > - ) > -{ > - return 0; > -} > - > uid_t > getuid ( > void > diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf > b/CryptoPkg/Library/OpensslLib/OpensslLib.inf > index 60c6c24b0a..f8ddfadc51 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf > @@ -580,6 +580,7 @@ > rand_pool.c > # SslNull.c > EcSm2Null.c > + b_print.c > > [Packages] > MdePkg/MdePkg.dec > diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf > b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf > index 103ef7bda2..6ee7bfd329 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf > @@ -580,6 +580,7 @@ > rand_pool.c > # SslNull.c > EcSm2Null.c > + b_print.c > > [Sources.IA32] > # Autogenerated IA32 files list starts here diff --git > a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > index c4eaea888c..3e43cf146b 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > @@ -530,6 +530,7 @@ > rand_pool.c > SslNull.c > EcSm2Null.c > + b_print.c > > [Packages] > MdePkg/MdePkg.dec > diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf > b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf > index 309e43055c..440d3e7e1d 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf > @@ -635,6 +635,7 @@ > rand_pool.c > # SslNull.c > # EcSm2Null.c > + b_print.c > > [Packages] > MdePkg/MdePkg.dec > diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf > b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf > index 4eeeeb79bd..413f70f733 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf > @@ -635,6 +635,7 @@ > rand_pool.c > # SslNull.c > # EcSm2Null.c > + b_print.c > > [Sources.IA32] > # Autogenerated IA32 files list starts here diff --git > a/CryptoPkg/Library/OpensslLib/b_print.c > b/CryptoPkg/Library/OpensslLib/b_print.c > new file mode 100644 > index 0000000000..885c3b9264 > --- /dev/null > +++ b/CryptoPkg/Library/OpensslLib/b_print.c > @@ -0,0 +1,613 @@ > +/* > + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. > + * > + * Licensed under the OpenSSL license (the "License"). You may not use > + * this file except in compliance with the License. You can obtain a > +copy > + * in the file LICENSE in the source distribution or at > + * https://www.openssl.org/source/license.html > + * > + * Please notes: > + * This file is a copy of OpensslLib\openssl\crypto\bio\b_print.c > + * with all floating point related code removed (Not supported in UEFI). > + * This means that '%f' '%g' '%e' and related combined formats are no > longer supported. > + * > + */ > + > +#include <stdio.h> > +#include <string.h> > +#include "internal/cryptlib.h" > +#include "crypto/ctype.h" > +#include "internal/numbers.h" > +#include <openssl/bio.h> > + > +/* > + * Copyright Patrick Powell 1995 > + * This code is based on code written by Patrick Powell > +<papow...@astart.com> > + * It may be used for any purpose as long as this notice remains intact > + * on all source code distributions. > + */ > + > +static int fmtstr(char **, char **, size_t *, size_t *, > + const char *, int, int, int); static int fmtint(char > +**, char **, size_t *, size_t *, > + int64_t, int, int, int, int); static int > +doapr_outch(char **, char **, size_t *, size_t *, int); static int > +_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 */ > +/* left-aligned padding */ > +#define DP_F_MINUS (1 << 0) > +/* print an explicit '+' for a value with positive sign */ > +#define DP_F_PLUS (1 << 1) > +/* print an explicit ' ' for a value with positive sign */ > +#define DP_F_SPACE (1 << 2) > +/* print 0/0x prefix for octal/hex and decimal point for floating point */ > +#define DP_F_NUM (1 << 3) > +/* print leading zeroes */ > +#define DP_F_ZERO (1 << 4) > +/* print HEX in UPPPERcase */ > +#define DP_F_UP (1 << 5) > +/* treat value as unsigned */ > +#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 > +#define DP_C_SIZE 5 > + > +/* Floating point formats */ > +// #define F_FORMAT 0 > +// #define E_FORMAT 1 > +// #define G_FORMAT 2 > + > +/* some handy macros */ > +#define char_to_int(p) (p - '0') > +#define OSSL_MAX(p,q) ((p >= q) ? p : q) > + > +static int > +_dopr(char **sbuffer, > + char **buffer, > + size_t *maxlen, > + size_t *retlen, int *truncated, const char *format, va_list args) > +{ > + char ch; > + int64_t value; > + 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 > + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) > + return 0; > + 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 (ossl_isdigit(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 (ossl_isdigit(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': > + case 'j': > + cflags = DP_C_LLONG; > + ch = *format++; > + break; > + case 'L': > + //Unsupported fmt in UEFI > + return -1; > + case 'z': > + cflags = DP_C_SIZE; > + 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, int64_t); > + break; > + case DP_C_SIZE: > + value = va_arg(args, ossl_ssize_t); > + break; > + default: > + value = va_arg(args, int); > + break; > + } > + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, > min, > + max, flags)) > + return 0; > + 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 = va_arg(args, unsigned long int); > + break; > + case DP_C_LLONG: > + value = va_arg(args, uint64_t); > + break; > + case DP_C_SIZE: > + value = va_arg(args, size_t); > + break; > + default: > + value = va_arg(args, unsigned int); > + break; > + } > + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, > + ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), > + min, max, flags)) > + return 0; > + break; > + case 'f': > + case 'E': > + case 'e': > + case 'G': > + case 'g': > + return -1; > + case 'c': > + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, > + va_arg(args, int))) > + return 0; > + break; > + case 's': > + strvalue = va_arg(args, char *); > + if (max < 0) { > + if (buffer) > + max = INT_MAX; > + else > + max = *maxlen; > + } > + if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, > + flags, min, max)) > + return 0; > + break; > + case 'p': > + value = (size_t)va_arg(args, void *); > + if (!fmtint(sbuffer, buffer, &currlen, maxlen, > + value, 16, min, max, flags | DP_F_NUM)) > + return 0; > + break; > + case 'n': > + { > + int *num; > + num = va_arg(args, int *); > + *num = currlen; > + } > + break; > + case '%': > + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) > + return 0; > + 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; > + } > + } > + /* > + * We have to truncate if there is no dynamic buffer and we have filled > the > + * static buffer. > + */ > + if (buffer == NULL) { > + *truncated = (currlen > *maxlen - 1); > + if (*truncated) > + currlen = *maxlen - 1; > + } > + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) > + return 0; > + *retlen = currlen - 1; > + return 1; > +} > + > +static int > +fmtstr(char **sbuffer, > + char **buffer, > + size_t *currlen, > + size_t *maxlen, const char *value, int flags, int min, int max) > +{ > + int padlen; > + size_t strln; > + int cnt = 0; > + > + if (value == 0) > + value = "<NULL>"; > + > + strln = OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max); > + > + padlen = min - strln; > + if (min < 0 || padlen < 0) > + padlen = 0; > + if (max >= 0) { > + /* > + * Calculate the maximum output including padding. > + * Make sure max doesn't overflow into negativity > + */ > + if (max < INT_MAX - padlen) > + max += padlen; > + else > + max = INT_MAX; > + } > + if (flags & DP_F_MINUS) > + padlen = -padlen; > + > + while ((padlen > 0) && (max < 0 || cnt < max)) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) > + return 0; > + --padlen; > + ++cnt; > + } > + while (strln > 0 && (max < 0 || cnt < max)) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++)) > + return 0; > + --strln; > + ++cnt; > + } > + while ((padlen < 0) && (max < 0 || cnt < max)) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) > + return 0; > + ++padlen; > + ++cnt; > + } > + return 1; > +} > + > +static int > +fmtint(char **sbuffer, > + char **buffer, > + size_t *currlen, > + size_t *maxlen, int64_t value, int base, int min, int max, int > +flags) { > + int signvalue = 0; > + const char *prefix = ""; > + uint64_t uvalue; > + char convert[DECIMAL_SIZE(value) + 3]; > + int place = 0; > + int spadlen = 0; > + int zpadlen = 0; > + int caps = 0; > + uint32_t uremainder = 0; > + > + if (max < 0) > + max = 0; > + uvalue = value; > + if (!(flags & DP_F_UNSIGNED)) { > + if (value < 0) { > + signvalue = '-'; > + uvalue = 0 - (uint64_t)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 { > + uvalue = DivU64x32Remainder(uvalue, (unsigned)base, &uremainder); > + convert[place++] = (caps ? "0123456789ABCDEF" : > "0123456789abcdef") > + [uremainder]; > + } 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) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) > + return 0; > + --spadlen; > + } > + > + /* sign */ > + if (signvalue) > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) > + return 0; > + > + /* prefix */ > + while (*prefix) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix)) > + return 0; > + prefix++; > + } > + > + /* zeros */ > + if (zpadlen > 0) { > + while (zpadlen > 0) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) > + return 0; > + --zpadlen; > + } > + } > + /* digits */ > + while (place > 0) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place])) > + return 0; > + } > + > + /* left justified spaces */ > + while (spadlen < 0) { > + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) > + return 0; > + ++spadlen; > + } > + return 1; > +} > + > +#define BUFFER_INC 1024 > + > +static int > +doapr_outch(char **sbuffer, > + char **buffer, size_t *currlen, size_t *maxlen, int c) { > + /* If we haven't at least one buffer, someone has done a big booboo */ > + if (!ossl_assert(*sbuffer != NULL || buffer != NULL)) > + return 0; > + > + /* |currlen| must always be <= |*maxlen| */ > + if (!ossl_assert(*currlen <= *maxlen)) > + return 0; > + > + if (buffer && *currlen == *maxlen) { > + if (*maxlen > INT_MAX - BUFFER_INC) > + return 0; > + > + *maxlen += BUFFER_INC; > + if (*buffer == NULL) { > + if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) { > + BIOerr(BIO_F_DOAPR_OUTCH, ERR_R_MALLOC_FAILURE); > + return 0; > + } > + if (*currlen > 0) { > + if (!ossl_assert(*sbuffer != NULL)) > + return 0; > + memcpy(*buffer, *sbuffer, *currlen); > + } > + *sbuffer = NULL; > + } else { > + char *tmpbuf; > + tmpbuf = OPENSSL_realloc(*buffer, *maxlen); > + if (tmpbuf == NULL) > + return 0; > + *buffer = tmpbuf; > + } > + } > + > + if (*currlen < *maxlen) { > + if (*sbuffer) > + (*sbuffer)[(*currlen)++] = (char)c; > + else > + (*buffer)[(*currlen)++] = (char)c; > + } > + > + return 1; > +} > + > +/********************************************************* > ************* > +*****/ > + > +int BIO_printf(BIO *bio, const char *format, ...) { > + va_list args; > + int ret; > + > + va_start(args, format); > + > + ret = BIO_vprintf(bio, format, args); > + > + va_end(args); > + return ret; > +} > + > +int BIO_vprintf(BIO *bio, const char *format, va_list args) { > + 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; > + if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, > format, > + args)) { > + OPENSSL_free(dynbuf); > + return -1; > + } > + if (dynbuf) { > + ret = BIO_write(bio, dynbuf, (int)retlen); > + OPENSSL_free(dynbuf); > + } else { > + ret = BIO_write(bio, hugebuf, (int)retlen); > + } > + return ret; > +} > + > +/* > + * As snprintf is not available everywhere, we provide our own > + * implementation. This function has nothing to do with BIOs, but it's > + * closely related to BIO_printf, and we need *some* name prefix ... > +(XXX the > + * function should be renamed, but to what?) */ int BIO_snprintf(char > +*buf, size_t n, const char *format, ...) { > + va_list args; > + int ret; > + > + va_start(args, format); > + > + ret = BIO_vsnprintf(buf, n, format, args); > + > + va_end(args); > + return ret; > +} > + > +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list > +args) { > + size_t retlen; > + int truncated; > + > + if (!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args)) > + return -1; > + > + 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; } > -- > 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96505): https://edk2.groups.io/g/devel/message/96505 Mute This Topic: https://groups.io/mt/95135786/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-