From: rich at kastle dot com
Operating system: Windows NT 4.0 SP6
PHP version: 4.3.2RC1
PHP Bug Type: COM related
Bug description: COM functions which raise exceptions are invoked twice
If php_COM_invoke receives an error as a result of trying to invoke a COM
method via C_TYPEINFO_VT(obj)->Invoke, it assumes that the dispatch failed
and tries again using C_DISPATCH_VT(obj)->Invoke.
However, if the first Invoke succeeds (i.e. actually call into the object
method) but the method raises a COM exception, it returns
DISP_E_EXCEPTION. php_COM_invoke will then call the same method again
using C_DISPATCH_VT.
(In my particular case, the COM method was performing some subsequent
phases of a larger DB transaction, encountered a deadlock, then rolled
back the DB transaction and reported the event by raising an exception.
php_COM_invoke swallowed the exception without report and invoked the
method again, which, this time, did not encounter the same deadlock,
leaving my code without knowledge that a deadlock had caused some of my DB
updates to be rolled back. It took me four days to figure out what in the
world was happening.)
Here's a diff against COM.c which checks for DISP_E_EXCEPTION as a special
case. (This diff is against 4.3.2RC1 but AFAICS this error has existed
all along.)
diff -r temp/php-4.3.2RC1\ext\com\COM.c php-4.3.2RC1\ext\com\COM.c
128,129c128,130
< hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj),
dispIdMember,
&IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult,
&ExceptInfo, &ArgErr);
< if (SUCCEEDED(hr)) {
---
> if(hr != DISP_E_EXCEPTION) {
> hr =
> C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember,
&IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult,
&ExceptInfo, &ArgErr);
> if (SUCCEEDED(hr)) {
131,137c132,139
< * ITypLib doesn't work
< * Release ITypeLib and fall back to IDispatch
< */
<
< C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj));
< C_HASTLIB(obj) = FALSE;
< C_TYPEINFO(obj) = NULL;
---
> * ITypLib doesn't work
> * Release ITypeLib and fall back to IDispatch
> */
>
>
> C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj));
> C_HASTLIB(obj) = FALSE;
> C_TYPEINFO(obj) = NULL;
> }
--
Edit bug report at http://bugs.php.net/?id=22899&edit=1
--
Try a CVS snapshot: http://bugs.php.net/fix.php?id=22899&r=trysnapshot
Fixed in CVS: http://bugs.php.net/fix.php?id=22899&r=fixedcvs
Fixed in release: http://bugs.php.net/fix.php?id=22899&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=22899&r=needtrace
Try newer version: http://bugs.php.net/fix.php?id=22899&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=22899&r=support
Expected behavior: http://bugs.php.net/fix.php?id=22899&r=notwrong
Not enough info: http://bugs.php.net/fix.php?id=22899&r=notenoughinfo
Submitted twice: http://bugs.php.net/fix.php?id=22899&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=22899&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=22899&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=22899&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=22899&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=22899&r=gnused