[PATCH] crypt32: Grow item size buffer by more than 1 at a time.

Rémi Bernon rbernon at codeweavers.com
Fri Jul 2 05:18:22 CDT 2021


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.

This is mainly caused by the growth of the item size array which is only
done one item at a time, and allocating a bigger buffer initially and
growing it by bigger steps solves the problem.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 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)
                             {
-- 
2.32.0




More information about the wine-devel mailing list