Archived Forum Post

Index of archived forum posts

Question:

EncryptBytes possible leak

Mar 28 '13 at 18:09

We are experiencing a memory leak in our code and have seemed to isolate it to an EncryptBytes function. We examined the code and were able to isolate it specifically to

Variant vOutData = crypt->EncryptBytes(vInData);

We have read and tried the ::cleanupMemory but in this case, it does not look like the internal structures are being re-used as the memory increases with each call. We isolated EncryptBytes to a for loop and ran it 2000 times and watched as our memory usage increased with each subsequent call, even when placing VarClear(vOutData); on the following line within the forloop. Are we using EncryptBytes correctly or is there a better way to implement this solution? Thanks for the assistance guys. I've included the function and its code in question.

void __fastcall CEncryption::EncryptBinary(TMemoryStream* retValue, TMemoryStream* inData, EncryptionType iType)
{
    TChilkatCrypt2* crypt = new TChilkatCrypt2(Owner);
    const WideString unlockCodeBstr(L"removed");
        crypt->UnlockComponent(unlockCodeBstr.c_bstr());

    switch (iType)
    {
        case BLOWFISH:
        crypt->CryptAlgorithm = L"blowfish2";
            crypt->CipherMode = L"cbc";
        break;
        case AES:
        crypt->CryptAlgorithm = L"aes";
            break;
    }

        crypt->CipherMode = L"cbc";
    crypt->KeyLength = 128;
        const WideString secretKeyBstr(L"removed");
        crypt->SecretKey = crypt->GenerateSecretKey(secretKeyBstr.c_bstr());
    crypt->EncodingMode = L"base64";

    Variant vInData;
    int bounds[2] = {0,inData->Size-1};
    vInData = VarArrayCreate(bounds,1,varByte);

    byte bData;
    inData->Position = 0;

    for(int i = VarArrayLowBound(vInData, 1); i <= VarArrayHighBound(vInData,1); i++)
    {
        inData->ReadBuffer(&bData,1);
        VarArrayPut(vInData, bData,&i,0);
    }

    Variant vOutData = crypt->EncryptBytes(vInData);

    for(int i = VarArrayLowBound(vOutData,1); i <= VarArrayHighBound(vOutData,1); i++)
    {
        bData = VarArrayGet(vOutData,&i,0);
        retValue->Write(&bData,1);
    }

    VarClear(vInData);
    VarClear(vOutData);
    delete crypt;
}

Answer

I tested, but found no memory leak in Chilkat.

However, I did not suspect a memory leak existing within Chilkat in the first place. Here is the reason:
If a memory leak exists within the ActiveX, it could only be in one of two places:

1) Within the ActiveX wrapping.
2) Within the internal C++ implementation.

Here's why #1 is very unlikely. The thin layer that marshals arguments to/from BSTR's and Variant's operates identically across all ActiveX methods. This layer is auto-generated, which means that every single method in every Chilkat ActiveX that uses a Variant would pass it to the underlying C++ implementation in exactly the same way. If a memory leak existed here, it would be a memory leak present in every single method across all Chilkat ActiveX's. Given that the ActiveX's have been in existence for 10 years and have many many thousands of users over that time, this is a bit unlikely.

Here's why #2 is very unlikely. The underlying C++ implementation for every Chilkat class is identical across every supported programming language and operating system. The only difference is in the wrapping. Therefore, if a memory leak in EncryptBytes existed, it would be seen in ALL programming languages across all operating systems. No other Chilkat customers report any memory leak problems.

Given that my testing shows no memory leak, and given that your C++ Builder code is somewhat complex, I can only infer that the memory leak is caused by your application code. Maybe your application code is somehow not correctly using C++ Builder's COM related classes involving Variants.

In my testing, I setup a Chilkat.Crypt2 object (in VBScript) and wrote a loop that calls EncryptBytes millions of times. The memory never grows. If a memory leak existed within the Chilkat ActiveX, it would make no difference whether the ActiveX was tested in VB6, VBScript, PHP, C++ Builder, Delphi, FoxPro, MS Access, or any other programming language that supports ActiveX. If the memory leak existed within Chilkat, any such test would show the memory usage to be steadily increasing as each iteration of the loop executes.