The branch master has been updated via f77208693ec3bda99618e6f76c0f8d279c0077bb (commit) from 8c7c1c84cbaa38a4053404883d666ea8dff81b3a (commit)
- Log ----------------------------------------------------------------- commit f77208693ec3bda99618e6f76c0f8d279c0077bb Author: Matt Caswell <m...@openssl.org> Date: Fri Jun 11 12:43:00 2021 +0100 Avoid excessive OSSL_DECODER_do_all_provided calls OSSL_DECODER_CTX_add_extra was calling OSSL_DECODER_do_all_provided in a loop which was resulting in a large number of calls. Since OSSL_DECODER_do_all_provided is quite "heavy" this was causing performance issues. Reviewed-by: Richard Levitte <levi...@openssl.org> Reviewed-by: Tomas Mraz <to...@openssl.org> Reviewed-by: Paul Dale <pa...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15716) ----------------------------------------------------------------------- Summary of changes: crypto/encode_decode/decoder_lib.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index eb90a9eaf5..4053eac62e 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -343,6 +343,16 @@ struct collect_extra_decoder_data_st { size_t w_new_start, w_new_end; /* "new" decoders */ }; +DEFINE_STACK_OF(OSSL_DECODER) + +static void collect_all_decoders(OSSL_DECODER *decoder, void *arg) +{ + STACK_OF(OSSL_DECODER) *skdecoders = arg; + + if (OSSL_DECODER_up_ref(decoder)) + sk_OSSL_DECODER_push(skdecoders, decoder); +} + static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg) { struct collect_extra_decoder_data_st *data = arg; @@ -459,6 +469,8 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, struct collect_extra_decoder_data_st data; size_t depth = 0; /* Counts the number of iterations */ size_t count; /* Calculates how many were added in each iteration */ + size_t numdecoders; + STACK_OF(OSSL_DECODER) *skdecoders; if (!ossl_assert(ctx != NULL)) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); @@ -477,12 +489,21 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, (void *)ctx); } OSSL_TRACE_END(DECODER); + + skdecoders = sk_OSSL_DECODER_new_null(); + if (skdecoders == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders); + numdecoders = sk_OSSL_DECODER_num(skdecoders); + memset(&data, 0, sizeof(data)); data.ctx = ctx; data.w_prev_start = 0; data.w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); do { - size_t i; + size_t i, j; data.w_new_start = data.w_new_end = data.w_prev_end; @@ -504,8 +525,9 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, = OSSL_DECODER_INSTANCE_get_input_type(decoder_inst); - OSSL_DECODER_do_all_provided(libctx, - collect_extra_decoder, &data); + for (j = 0; j < numdecoders; j++) + collect_extra_decoder(sk_OSSL_DECODER_value(skdecoders, j), + &data); } } /* How many were added in this iteration */ @@ -518,6 +540,7 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, depth++; } while (count != 0 && depth <= 10); + sk_OSSL_DECODER_pop_free(skdecoders, OSSL_DECODER_free); return 1; }