From nobody Tue May 21 01:29:04 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+96503+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96503+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1668875295; cv=none; d=zohomail.com; s=zohoarc; b=NE44whFxKYtZ/AYvGGTnv7vHs3G/Zj/nj99P1j848D4lVFwrN+MwkkbNhr7tw+hrJkJu8bt7v7YuOYOFYGc07i0DEgHx0dZfflOXYsu5Z17ymcoDlwicMSvKzLmv/FOCd3+dUeN21H9L9e4lZ44UmHA2b0Sgb/6jYQJyupvxICs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668875295; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=XxwjRfnMZFocpMPOtR74L3bEvYuvzaAD7Yd/HWPImno=; b=Ra7XSzt88gqG3Df6gNgbSKFzgSTK2VNRRr3TQOxwiCcaLKSgSBN4QSZnqX93PBZeRO/JK1x8TMwIRlp5IlO3bbYiS4Z0UYBxiDAo6tVL7E101r4A0lqQ7nKjDWBxKNN7+aJc9BLNC4r2tgwa9uAPynu5GjFaInrjk1ukJgX0sfU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+96503+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1668875295536454.65377365578775; Sat, 19 Nov 2022 08:28:15 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 81kCYY1788612x74DX4CTEaM; Sat, 19 Nov 2022 08:28:15 -0800 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web10.24273.1668875293777895887 for ; Sat, 19 Nov 2022 08:28:14 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10536"; a="314479336" X-IronPort-AV: E=Sophos;i="5.96,176,1665471600"; d="scan'208";a="314479336" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2022 08:28:13 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10536"; a="815248639" X-IronPort-AV: E=Sophos;i="5.96,176,1665471600"; d="scan'208";a="815248639" X-Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2022 08:28:11 -0800 From: "Li, Yi" To: devel@edk2.groups.io Cc: Yi Li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Subject: [edk2-devel] [PATCH] CryptoPkg: Add b_print.c which removed floating-point to OpensslLib Date: Sun, 20 Nov 2022 00:27:54 +0800 Message-Id: <20221119162754.1034-1-yi1.li@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yi1.li@intel.com X-Gm-Message-State: fxMoWJRhz1rWEZInvtQ4YzMKx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1668875295; bh=nwVPU9Op2qoLkYISuGV5MuuYv+wfE3K+q1XW4v6pMZQ=; h=Cc:Date:From:Reply-To:Subject:To; b=SZCsEv98JCTMiNGKxKUTibHiGsBLy5IndzyzNndOskTdW8xBWCpE1NNqLwjo+7oedDI 5aT9bFpXZS7IYFq4QvqXZY7jOsp0ovUu6NIy5A4IncGshSjeAR0lIPUUtnCHOe+BvXfBy qIbaBcsffUY/56r899hhf6cs5kFJfe+PUFM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1668875297598100002 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4110 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 Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li --- 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/CryptoPk= g/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; } =20 -// -// -- 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 retu= rns -1 as error. - // Otherwise, the consumer may think that the buf is valid and parse the= buffer. - return -1; -} - #ifdef __GNUC__ =20 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; } =20 -// -// -- 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/Librar= y/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 =20 [Packages] MdePkg/MdePkg.dec diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/L= ibrary/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 =20 [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 =20 [Packages] MdePkg/MdePkg.dec diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf b/CryptoPkg/Li= brary/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 =20 [Packages] MdePkg/MdePkg.dec diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoP= kg/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 =20 [Sources.IA32] # Autogenerated IA32 files list starts here diff --git a/CryptoPkg/Library/OpensslLib/b_print.c b/CryptoPkg/Library/Ope= nsslLib/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 long= er supported. + * + */ + +#include +#include +#include "internal/cryptlib.h" +#include "crypto/ctype.h" +#include "internal/numbers.h" +#include + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * 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 >=3D 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 =3D DP_S_DEFAULT; + flags =3D currlen =3D cflags =3D min =3D 0; + max =3D -1; + ch =3D *format++; + + while (state !=3D DP_S_DONE) { + if (ch =3D=3D '\0' || (buffer =3D=3D NULL && currlen >=3D *maxlen)) + state =3D DP_S_DONE; + + switch (state) { + case DP_S_DEFAULT: + if (ch =3D=3D '%') + state =3D DP_S_FLAGS; + else + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) + return 0; + ch =3D *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |=3D DP_F_MINUS; + ch =3D *format++; + break; + case '+': + flags |=3D DP_F_PLUS; + ch =3D *format++; + break; + case ' ': + flags |=3D DP_F_SPACE; + ch =3D *format++; + break; + case '#': + flags |=3D DP_F_NUM; + ch =3D *format++; + break; + case '0': + flags |=3D DP_F_ZERO; + ch =3D *format++; + break; + default: + state =3D DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (ossl_isdigit(ch)) { + min =3D 10 * min + char_to_int(ch); + ch =3D *format++; + } else if (ch =3D=3D '*') { + min =3D va_arg(args, int); + ch =3D *format++; + state =3D DP_S_DOT; + } else + state =3D DP_S_DOT; + break; + case DP_S_DOT: + if (ch =3D=3D '.') { + state =3D DP_S_MAX; + ch =3D *format++; + } else + state =3D DP_S_MOD; + break; + case DP_S_MAX: + if (ossl_isdigit(ch)) { + if (max < 0) + max =3D 0; + max =3D 10 * max + char_to_int(ch); + ch =3D *format++; + } else if (ch =3D=3D '*') { + max =3D va_arg(args, int); + ch =3D *format++; + state =3D DP_S_MOD; + } else + state =3D DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags =3D DP_C_SHORT; + ch =3D *format++; + break; + case 'l': + if (*format =3D=3D 'l') { + cflags =3D DP_C_LLONG; + format++; + } else + cflags =3D DP_C_LONG; + ch =3D *format++; + break; + case 'q': + case 'j': + cflags =3D DP_C_LLONG; + ch =3D *format++; + break; + case 'L': + //Unsupported fmt in UEFI + return -1; + case 'z': + cflags =3D DP_C_SIZE; + ch =3D *format++; + break; + default: + break; + } + state =3D DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + switch (cflags) { + case DP_C_SHORT: + value =3D (short int)va_arg(args, int); + break; + case DP_C_LONG: + value =3D va_arg(args, long int); + break; + case DP_C_LLONG: + value =3D va_arg(args, int64_t); + break; + case DP_C_SIZE: + value =3D va_arg(args, ossl_ssize_t); + break; + default: + value =3D va_arg(args, int); + break; + } + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, = min, + max, flags)) + return 0; + break; + case 'X': + flags |=3D DP_F_UP; + /* FALLTHROUGH */ + case 'x': + case 'o': + case 'u': + flags |=3D DP_F_UNSIGNED; + switch (cflags) { + case DP_C_SHORT: + value =3D (unsigned short int)va_arg(args, unsigned in= t); + break; + case DP_C_LONG: + value =3D va_arg(args, unsigned long int); + break; + case DP_C_LLONG: + value =3D va_arg(args, uint64_t); + break; + case DP_C_SIZE: + value =3D va_arg(args, size_t); + break; + default: + value =3D va_arg(args, unsigned int); + break; + } + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, + ch =3D=3D 'o' ? 8 : (ch =3D=3D '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 =3D va_arg(args, char *); + if (max < 0) { + if (buffer) + max =3D INT_MAX; + else + max =3D *maxlen; + } + if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, + flags, min, max)) + return 0; + break; + case 'p': + value =3D (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 =3D va_arg(args, int *); + *num =3D currlen; + } + break; + case '%': + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) + return 0; + break; + case 'w': + /* not supported yet, treat as next char */ + ch =3D *format++; + break; + default: + /* unknown, skip */ + break; + } + ch =3D *format++; + state =3D DP_S_DEFAULT; + flags =3D cflags =3D min =3D 0; + max =3D -1; + break; + case DP_S_DONE: + break; + default: + break; + } + } + /* + * We have to truncate if there is no dynamic buffer and we have fille= d the + * static buffer. + */ + if (buffer =3D=3D NULL) { + *truncated =3D (currlen > *maxlen - 1); + if (*truncated) + currlen =3D *maxlen - 1; + } + if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) + return 0; + *retlen =3D 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 =3D 0; + + if (value =3D=3D 0) + value =3D ""; + + strln =3D OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max); + + padlen =3D min - strln; + if (min < 0 || padlen < 0) + padlen =3D 0; + if (max >=3D 0) { + /* + * Calculate the maximum output including padding. + * Make sure max doesn't overflow into negativity + */ + if (max < INT_MAX - padlen) + max +=3D padlen; + else + max =3D INT_MAX; + } + if (flags & DP_F_MINUS) + padlen =3D -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 flag= s) +{ + int signvalue =3D 0; + const char *prefix =3D ""; + uint64_t uvalue; + char convert[DECIMAL_SIZE(value) + 3]; + int place =3D 0; + int spadlen =3D 0; + int zpadlen =3D 0; + int caps =3D 0; + uint32_t uremainder =3D 0; + + if (max < 0) + max =3D 0; + uvalue =3D value; + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue =3D '-'; + uvalue =3D 0 - (uint64_t)value; + } else if (flags & DP_F_PLUS) + signvalue =3D '+'; + else if (flags & DP_F_SPACE) + signvalue =3D ' '; + } + if (flags & DP_F_NUM) { + if (base =3D=3D 8) + prefix =3D "0"; + if (base =3D=3D 16) + prefix =3D "0x"; + } + if (flags & DP_F_UP) + caps =3D 1; + do { + uvalue =3D DivU64x32Remainder(uvalue, (unsigned)base, &uremainder); + convert[place++] =3D (caps ? "0123456789ABCDEF" : "0123456789abcde= f") + [uremainder]; + } while (uvalue && (place < (int)sizeof(convert))); + if (place =3D=3D sizeof(convert)) + place--; + convert[place] =3D 0; + + zpadlen =3D max - place; + spadlen =3D + min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix); + if (zpadlen < 0) + zpadlen =3D 0; + if (spadlen < 0) + spadlen =3D 0; + if (flags & DP_F_ZERO) { + zpadlen =3D OSSL_MAX(zpadlen, spadlen); + spadlen =3D 0; + } + if (flags & DP_F_MINUS) + spadlen =3D -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 !=3D NULL || buffer !=3D NULL)) + return 0; + + /* |currlen| must always be <=3D |*maxlen| */ + if (!ossl_assert(*currlen <=3D *maxlen)) + return 0; + + if (buffer && *currlen =3D=3D *maxlen) { + if (*maxlen > INT_MAX - BUFFER_INC) + return 0; + + *maxlen +=3D BUFFER_INC; + if (*buffer =3D=3D NULL) { + if ((*buffer =3D OPENSSL_malloc(*maxlen)) =3D=3D NULL) { + BIOerr(BIO_F_DOAPR_OUTCH, ERR_R_MALLOC_FAILURE); + return 0; + } + if (*currlen > 0) { + if (!ossl_assert(*sbuffer !=3D NULL)) + return 0; + memcpy(*buffer, *sbuffer, *currlen); + } + *sbuffer =3D NULL; + } else { + char *tmpbuf; + tmpbuf =3D OPENSSL_realloc(*buffer, *maxlen); + if (tmpbuf =3D=3D NULL) + return 0; + *buffer =3D tmpbuf; + } + } + + if (*currlen < *maxlen) { + if (*sbuffer) + (*sbuffer)[(*currlen)++] =3D (char)c; + else + (*buffer)[(*currlen)++] =3D (char)c; + } + + return 1; +} + +/*************************************************************************= **/ + +int BIO_printf(BIO *bio, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret =3D 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 unreasonab= le + * in small-stack environments, like threa= ds + * or DOS programs. */ + char *hugebufp =3D hugebuf; + size_t hugebufsize =3D sizeof(hugebuf); + char *dynbuf =3D NULL; + int ignored; + + dynbuf =3D NULL; + if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, + args)) { + OPENSSL_free(dynbuf); + return -1; + } + if (dynbuf) { + ret =3D BIO_write(bio, dynbuf, (int)retlen); + OPENSSL_free(dynbuf); + } else { + ret =3D 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 =3D 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 buff= er + * been large enough.) + */ + return -1; + else + return (retlen <=3D INT_MAX) ? (int)retlen : -1; +} --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96503): https://edk2.groups.io/g/devel/message/96503 Mute This Topic: https://groups.io/mt/95135786/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-