Module: wine Branch: master Commit: 8b8b43d5f3ebff602bbd15d939de7766ef252114 URL: https://source.winehq.org/git/wine.git/?a=commit;h=8b8b43d5f3ebff602bbd15d93...
Author: Rémi Bernon rbernon@codeweavers.com Date: Fri Jul 2 12:18:22 2021 +0200
crypt32: Grow item size buffer by more than 1 at a time.
When Steam starts and connects, it sometimes does some crypt32 processing and ends up spending a huge amount of time in ntdll memcpy, reallocating buffers, effectively getting stuck while connecting to the user account.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/crypt32/decode.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 5d195d42f7b..a0e78d62b4d 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -628,7 +628,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) { - DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded; + DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, capacity = 0, decoded; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); /* There can be arbitrarily many items, but there is often only one. */ @@ -687,17 +687,18 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, continue; }
- cItems++; - if (itemSizes != &itemSize) - itemSizes = CryptMemRealloc(itemSizes, - cItems * sizeof(struct AsnArrayItemSize)); - else if (cItems > 1) + if (++cItems <= 1) + itemSizes = &itemSize; + else if (itemSizes == &itemSize) { - itemSizes = - CryptMemAlloc( - cItems * sizeof(struct AsnArrayItemSize)); - if (itemSizes) - *itemSizes = itemSize; + capacity = 1024; + itemSizes = CryptMemAlloc(capacity * sizeof(struct AsnArrayItemSize)); + if (itemSizes) *itemSizes = itemSize; + } + else if (cItems > capacity) + { + capacity = capacity * 3 / 2; + itemSizes = CryptMemRealloc(itemSizes, capacity * sizeof(struct AsnArrayItemSize)); } if (itemSizes) {