From 74d9519a68ee484db584aebc6ab6b2cb4bf98b2a Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Wed, 29 Mar 2017 23:10:08 +0200 Subject: [PATCH] bio/b_print.c: recognize even 'j' format modifier. 'j' is specified as modifier for "greatest-width integer type", which in practice means 64 bits on both 32- and 64-bit platforms. Since we rely on __attribute__((__format__(__printf__,...))) to sanitize BIO_print format, we can use it to denote [u]int64_t-s in platform-neutral manner. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/3083) --- CHANGES | 6 +++--- crypto/bio/b_print.c | 1 + test/bioprinttest.c | 34 ++++++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index d6a09b00e2..0cce21a3bf 100644 --- a/CHANGES +++ b/CHANGES @@ -4,9 +4,9 @@ Changes between 1.1.0e and 1.1.1 [xx XXX xxxx] - *) Add the z modifier parsing to BIO_printf() et al formatting string, - to be used for size_t and ssize_t (ossl_ssize_t). - [Richard Levitte] + *) Add the 'z' and 'j' modifiers to BIO_printf() et al formatting string, + 'z' is to be used for [s]size_t, and 'j' - with [u]int64_t. + [Richard Levitte, Andy Polyakov] *) Add EC_KEY_get0_engine(), which does for EC_KEY what RSA_get0_engine() does for RSA, etc. diff --git a/crypto/bio/b_print.c b/crypto/bio/b_print.c index 883af19388..79ae4a9c41 100644 --- a/crypto/bio/b_print.c +++ b/crypto/bio/b_print.c @@ -208,6 +208,7 @@ _dopr(char **sbuffer, ch = *format++; break; case 'q': + case 'j': cflags = DP_C_LLONG; ch = *format++; break; diff --git a/test/bioprinttest.c b/test/bioprinttest.c index c3ab6a179f..4eeb4c67a9 100644 --- a/test/bioprinttest.c +++ b/test/bioprinttest.c @@ -173,6 +173,34 @@ static void dozutest(int test, const struct z_data_st *data, int *fail) } } +struct j_data_st { + uint64_t value; + const char *format; + const char *expected; +}; +static struct j_data_st j_data[] = { + { 0xffffffffffffffffU, "%ju", "18446744073709551615" }, + { 0xffffffffffffffffU, "%jx", "ffffffffffffffff" }, + { 0x8000000000000000U, "%ju", "9223372036854775808" }, + /* + * These tests imply two's-complement, but it's the only binary + * representation we support, see test/sanitytest.c... + */ + { 0x8000000000000000U, "%ji", "-9223372036854775808" }, +}; + +static void dojtest(int test, const struct j_data_st *data, int *fail) +{ + char bio_buf[80]; + + BIO_snprintf(bio_buf, sizeof(bio_buf) - 1, data->format, data->value); + if (strcmp(bio_buf, data->expected) != 0) { + printf("Test %d failed. Expected \"%s\". Got \"%s\". " + "Format \"%s\"\n", test, data->expected, bio_buf, data->format); + *fail = 1; + } +} + int main(int argc, char **argv) { int test = 0; @@ -246,11 +274,9 @@ int main(int argc, char **argv) dozutest(test++, &zu_data[i], &fail); } -#if 0 - for (i = 0; i < nelem(zi_data); i++) { - dozitest(test++, &zu_data[i], &fail); + for (i = 0; i < nelem(j_data); i++) { + dojtest(test++, &j_data[i], &fail); } -#endif #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) -- GitLab