| Index: nss/lib/ckfw/builtins/bfind.c
|
| diff --git a/nss/lib/ckfw/builtins/bfind.c b/nss/lib/ckfw/builtins/bfind.c
|
| index e31c4ef099875e88d7614675bb56c21409c55089..df35ed8b689ff7e15dbab424391d8d86ade2d39f 100644
|
| --- a/nss/lib/ckfw/builtins/bfind.c
|
| +++ b/nss/lib/ckfw/builtins/bfind.c
|
| @@ -183,7 +183,16 @@ nss_builtins_FindObjectsInit
|
| NSSArena *arena;
|
| NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
|
| struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
|
| - builtinsInternalObject **temp = (builtinsInternalObject **)NULL;
|
| +
|
| + /*
|
| + * 99% of the time we get 0 or 1 matches. So we start with a small
|
| + * stack-allocated array to hold the matches and switch to a heap-allocated
|
| + * array later if the number of matches exceeds STACK_BUF_LENGTH.
|
| + */
|
| + #define STACK_BUF_LENGTH 1
|
| + builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
|
| + builtinsInternalObject **temp = stackTemp;
|
| + PRBool tempIsHeapAllocated = PR_FALSE;
|
| PRUint32 i;
|
|
|
| arena = NSSArena_Create();
|
| @@ -211,17 +220,24 @@ nss_builtins_FindObjectsInit
|
| rv->Next = builtins_mdFindObjects_Next;
|
| rv->null = (void *)NULL;
|
|
|
| - temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
|
| - nss_builtins_nObjects);
|
| - if( (builtinsInternalObject **)NULL == temp ) {
|
| - *pError = CKR_HOST_MEMORY;
|
| - goto loser;
|
| - }
|
| -
|
| for( i = 0; i < nss_builtins_nObjects; i++ ) {
|
| builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
|
|
|
| if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
|
| + if( fo->n == STACK_BUF_LENGTH ) {
|
| + /* Switch from the small stack array to a heap-allocated array large
|
| + * enough to handle matches in all remaining cases. */
|
| + temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
|
| + fo->n + nss_builtins_nObjects - i);
|
| + if( (builtinsInternalObject **)NULL == temp ) {
|
| + *pError = CKR_HOST_MEMORY;
|
| + goto loser;
|
| + }
|
| + tempIsHeapAllocated = PR_TRUE;
|
| + (void)nsslibc_memcpy(temp, stackTemp,
|
| + sizeof(builtinsInternalObject *) * fo->n);
|
| + }
|
| +
|
| temp[ fo->n ] = o;
|
| fo->n++;
|
| }
|
| @@ -234,13 +250,17 @@ nss_builtins_FindObjectsInit
|
| }
|
|
|
| (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
|
| - nss_ZFreeIf(temp);
|
| - temp = (builtinsInternalObject **)NULL;
|
| + if (tempIsHeapAllocated) {
|
| + nss_ZFreeIf(temp);
|
| + temp = (builtinsInternalObject **)NULL;
|
| + }
|
|
|
| return rv;
|
|
|
| loser:
|
| - nss_ZFreeIf(temp);
|
| + if (tempIsHeapAllocated) {
|
| + nss_ZFreeIf(temp);
|
| + }
|
| nss_ZFreeIf(fo);
|
| nss_ZFreeIf(rv);
|
| if ((NSSArena *)NULL != arena) {
|
|
|