# COM extension defects: Possible patch for defect 35464

- Thread: https://externals.io/message/27656
- Original archive: https://news-web.php.net/php.internals/27656
- Started by Andy Wharmby on 2007-01-25T16:58:54+00:00
- Messages: 1
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #27656 — Andy Wharmby — 2007-01-25T16:58:54+00:00

URL: https://externals.io/message/27656#27656

Hi Internals
    Attached is a suggested patch for  COM defect 35464 
(http://bugs.php.net/bug.php?id=34564)  Any comments;  good or bad welcome.
Regards
    Andy

Andy Wharmby
IBM United Kingdom Limited
Winchester, England SO21 2JN
E-mail: andy_wharmby@uk.ibm.com

COM defect 35464
================

The following details 2 reasons why in/out parameters don't work; one 
caused by a problem with tetscase another a defect in COM extension code.
The testcase supplied by the raiser implements the DWebBrowserEvents2 
interface to register an handler for the BeforeNaviagte2 event. This
 handler is passed  just one in/out parameter;  a VARIANT_BOOL which can 
be set to `TRUE` by the handler to cancel the navigation operation.
Doing so  in PHP currently has no affect,  for the 2 reasons I will 
describe below,  so the  navigation completes and the specified page is
displayed by IE.

Issue 1
======
The users code is attempting to modify the variant directly in PHP code 
as follows:

    $cancel = true;

rather than using the COM method variant_set as follows:

    variant_set($cancel, true);

With this correction to the PHP script in place the variant for $cancel 
is correctly changed to `TRUE` but IE still navigates to the requested page
so the modification is having no effect. The reason for this is the 
subject of issue 2 below.
 
Issue 2
======
When an event notification is received by the COM extension 
disp_invokeex() processes the incoming parameters (variants)  by taking 
each one
and wrapping it in a php_com_dotnet_object object. At this time a COPY 
of the incoming variant is embedded into the php_com_dotnet_object so we
immediately have 2 copies of the variant  and it is this copy in the 
php_com_dotnet_object which is processed (get and set) by the PHP code.
I see no code that checks for modification to our copy in the 
php_com_dotnet_object before returning to the caller (in this case IE) 
so modification
to in/out parameters by the PHP code has no affect.

Given that the code copies an incoming variant in php_com_wrap_variant() 
I would have expected to see some code prior to return in disp_invokeex()
which checks for  modifications to in/out  parameters and copies any 
modified values back to the callers copy of the variant.

I have hacked some code as follows:     
    com_wrapper.c: http://www.pastebin.ca/328026
    com_variant.c:  http://www.pastebin.ca/328022
    com_misc.c: http://www.pastebin.ca/328025
    php_com_dotnet_internal.h: http://www.pastebin.ca/328027
    
The new code works as follows:
(1) When a variant is modified by a call to variant_set() in 
com_variant.c a new flag (obj->modified)  is set in the 
php_com_dotnet_object.

(2) After a successful call to a event handler new code  in 
com_wrapper.c function disp_invokeex() checks each of the event 
handlers  arguments
 (php_com_dotnet_object's ) to see if any of their embedded variants 
have been modified. If so and the argument passed into the event handler was
 passed by reference then the value in the embedded variant is copied to 
the callers copy by a call to a new function  php_com_copy_variant()
defined in com_variant.c.

With this patch applied when the supplied testcase is run the navigation 
is now cancelled as expected.
