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

Reply via email to