StringSource is using "new" operator. Should be deleting the memory or is it auto destroyed?

204 views
Skip to first unread message

Dwight Kulkarni

unread,
Apr 27, 2023, 1:30:58 PM4/27/23
to Crypto++ Users
Hello,

I note an example code sample for b64encode(..).   I note that there are "new" calls inside the constructor(..).

The result is returned in the encoded string.

Do I need to do anything to delete the memory from the new calls ?

What happens to the memory in the variable "encoded", if the variable is passed up to another function and the StringSink is destroyed.

Should I make a copy of encoded and send it on to be safe ?


std::string b64encode(std::string str)
{
std::string encoded;
CryptoPP::StringSource(str, true,
new CryptoPP::Base64Encoder(
new CryptoPP::StringSink(encoded),
false
)
);
return encoded;
}

Jeffrey Walton

unread,
Apr 27, 2023, 1:35:43 PM4/27/23
to cryptop...@googlegroups.com
On Thu, Apr 27, 2023 at 1:31 PM Dwight Kulkarni <dwi...@realtime-7.com> wrote:
>
> I note an example code sample for b64encode(..). I note that there are "new" calls inside the constructor(..).
>
> The result is returned in the encoded string.
>
> Do I need to do anything to delete the memory from the new calls ?
>
> What happens to the memory in the variable "encoded", if the variable is passed up to another function and the StringSink is destroyed.
>
> Should I make a copy of encoded and send it on to be safe ?

https://www.cryptopp.com/wiki/Pipelining#Ownership

Jeff

Dwight Kulkarni

unread,
Apr 27, 2023, 1:57:33 PM4/27/23
to Crypto++ Users
Hi Jeff,

Ok I think those RSA errors with memory are due to this pipelining, because the b64decode(..) b64encode(..) is called every where, and if I understand correctly, the string inside will be destroyed and I have to use the redirector. Can you confirm if you agree with this code change and my understanding of the problem ?

Previous Code:
std::string b64encode(std::string str)
{
std::string encoded;
CryptoPP::StringSource(str, true,
new CryptoPP::Base64Encoder(
new CryptoPP::StringSink(encoded),
false
)
);
return encoded; //encoded will be destroyed once StringSource(..) goes out of scope
}


New Code:

std::string b64encode(std::string str)
{
std::string encoded;
CryptoPP::Base64Encoder df(new CryptoPP::StringSink(encoded),false);
CryptoPP::StringSource(str, true, new Redirector(df) );
return encoded; //encoded won't be destroyed
}


based on this:

CCM< AES, TAG_SIZE >::Decryption d;
d.SetKeyWithIV( key, key.size(), iv, sizeof(iv) );
AuthenticatedDecryptionFilter df( d, new StringSink( recovered ) ); // AuthenticatedDecryptionFilter // Cipher text includes the MAC tag
StringSource ss( cipher, true, new Redirector( df ) ); // StringSource // If the object does not throw, here's the only // opportunity to check the data's integrity
bool b = df.GetLastResult();
if( true == b ) { cout << recovered << endl; }

Jeffrey Walton

unread,
Apr 27, 2023, 2:10:38 PM4/27/23
to cryptop...@googlegroups.com
On Thu, Apr 27, 2023 at 1:57 PM Dwight Kulkarni <dwi...@realtime-7.com> wrote:
>
> Ok I think those RSA errors with memory are due to this pipelining, because the b64decode(..) b64encode(..) is called every where, and if I understand correctly, the string inside will be destroyed and I have to use the redirector. Can you confirm if you agree with this code change and my understanding of the problem ?
>
> Previous Code:
> std::string b64encode(std::string str)
> {
> using namespace CryptoPP;
>
> std::string encoded;
> StringSource(str, true,
> new Base64Encoder(
> new StringSink(encoded),
> false
> )
> );
> return encoded; //encoded will be destroyed once StringSource(..) goes out of scope
> }

This code is Ok.

The variable 'encoded' is not destroyed because it is a reference, and
not a pointer. 'encoded' is a stack variable. It will be destroyed
when the stack frame is cleaned up.

> New Code:
>
> std::string b64encode(std::string str)
> {
> using namespace CryptoPP;
>
> std::string encoded;
> Base64Encoder df(new CryptoPP::StringSink(encoded),false);
> StringSource(str, true, new Redirector(df) );
> return encoded; //encoded won't be destroyed
> }

This code is Ok, too. This code is effectively the same as the first
example. The Base64Encoder is now an automatic variable, and it will
be cleaned up when the destructor runs during stack cleanup.

The variable 'encoded' is not destroyed because it is a reference, and
not a pointer. 'encoded' is a stack variable. It will be destroyed
when the stack frame is cleaned up.

Your memory error lies elsewhere. Run Asan over your program.

Jeff
Reply all
Reply to author
Forward
Message has been deleted
0 new messages