php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #22899 COM functions which raise exceptions are invoked twice
Submitted: 2003-03-26 07:51 UTC Modified: 2003-03-27 13:57 UTC
From: rich at kastle dot com Assigned:
Status: Closed Package: COM related
PHP Version: 4.3.2RC1 OS: Windows NT 4.0 SP6
Private report: No CVE-ID: None
 [2003-03-26 07:51 UTC] rich at kastle dot com
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;
> 					}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-03-27 02:50 UTC] phanto@php.net
can you please send an unified diff (diff -u) per mail directly to me.
 [2003-03-27 02:51 UTC] phanto@php.net
change status.
 [2003-03-27 13:57 UTC] phanto@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.

commited.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 20:01:29 2024 UTC