summaryrefslogtreecommitdiff
path: root/crypto/encode_decode
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-06-11 12:43:00 +0100
committerMatt Caswell <matt@openssl.org>2021-06-14 10:05:50 +0100
commitf77208693ec3bda99618e6f76c0f8d279c0077bb (patch)
treee6ab05aa94fdd14106774c4443c19ce5c8d05f8a /crypto/encode_decode
parent8c7c1c84cbaa38a4053404883d666ea8dff81b3a (diff)
downloadopenssl-new-f77208693ec3bda99618e6f76c0f8d279c0077bb.tar.gz
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 <levitte@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15716)
Diffstat (limited to 'crypto/encode_decode')
-rw-r--r--crypto/encode_decode/decoder_lib.c29
1 files 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;
}