Attached is a patch for a memory leak that occurs when setting a COM
property to a string value. According to Microsoft, when passing
parameters to Invoke
(http://msdn.microsoft.com/library/en-us/automat/htm/chap5_3kz7.asp):
"The calling code is responsible for releasing all strings and objects
referred to by rgvarg[ ] [the parameters passed to the Invoke call] or
placed in *pVarResult. As with other parameters that are passed by
value, if the invoked member must maintain access to a string after
returning, you should copy the string."
An example of this can be seen in the following code from MSDN (second
code block of
http://msdn.microsoft.com/library/en-us/automat/htm/chap3_76p4.asp):
hr = pdisp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, wFlags,
&dispparams, pvRet, pexcepinfo, pnArgErr);
cleanup:
// Clean up any arguments that need it.
if (dispparams.cArgs != 0)
{
VARIANTARG * pvarg = dispparams.rgvarg;
UINT cArgs = dispparams.cArgs;
while (cArgs--)
{
switch (pvarg->vt)
{
case VT_BSTR:
VariantClear(pvarg);
break;
}
++pvarg;
}
}
delete dispparams.rgvarg;
The 4.3.2RC2 version of do_COM_propput() in ext/COM/COM.c, however,
only efrees the parameter array without first checking if the property
was a string that needs to be freed by the caller. The attached patch
checks for a VT_BSTR parameter and calls VariantClear() if approprate.
Without this patch the following HTML/PHP page will grow a 4.3.2RC2
(under IIS5/PHP4ISAPI) processes memory usage without bound:
<?php
$xml = new COM("MSXML.DOMDocument");
$element = $xml->createElement("test");
$element->text = str_repeat("this is a text string!", 1000);
$val_a = com_get($element, "text");
$element->Release();
$xml->Release();
echo "val_a = {$val_a}<br><br>";
?>
With this patch in place there are no memory leaks when this code is
left to run.
Michael Sisolak
msisolak@yahoo.com
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.
http://search.yahoo.com