Req #41286 [Asn->Ver]: Variant VT_ARRAY of VT_UI1
Edit report at https://bugs.php.net/bug.php?id=41286&edit=1
ID: 41286
Updated by: cmb@php.net
Reported by: milman at gmx dot de
Summary: Variant VT_ARRAY of VT_UI1
-Status: Assigned
+Status: Verified
Type: Feature/Change Request
Package: COM related
Operating System: Windows
PHP Version: Next Minor Version
-Assigned To: cmb
+Assigned To:
Block user comment: N
Private report: N
New Comment:
I had a closer look, and indeed, creating new typed array variants
is not supported. E.g.
new variant([1, 2, 3], VT_ARRAY|VT_UI1)
first creates an array of variants from the given PHP array, and
later calls VariantChangeType()[1] attemting to convert the array
of variants to an array of bytes; but that can't work, since
| Arrays of one type cannot be converted to arrays of another type
| with this function.
This is also noted in the sources[2], by the way.
variant_set_type() and variant_cast() have the same issue; the
docs[3] already point out that variant_cast() is just a wrapper
for VariantChangeType().
There is, however, a potential alternative, namely using a PHP
string to construct (or convert to) the variant:
new variant('p=1', VT_ARRAY|VT_UI1)
This gives an array of *6* bytes, though, since internally the PHP
string is converted to BSTR, which is an array of WCHAR (16 byte
values), and apparently VariantChangeType() is quirky when
converting from VT_BSTR to VT_ARRAY|VT_UI1 (VectorFromBstr()[4]
shows the same behavior, though). So for little-endian
architectures, every even element has the value zero. Since it is
not allowed to unset() elements of a variant array, there is no
way to remove the unwanted elements, so this alternative is not
helpful either.
I see a few options to better support these kinds of array, but
I'm not yet sure which one to pursue. I'm also not quite sure
whether the current behavior is a bug, or whether it merely
can/should be improved.
[1] <https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-variantchangetype>
[2] <https://github.com/php/php-src/blob/php-7.3.15RC1/ext/com_dotnet/com_variant.c#L473-L474>
[3] <https://www.php.net/manual/en/function.variant-cast.php>
[4] <https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-vectorfrombstr>
Previous Comments:
------------------------------------------------------------------------
[2019-10-18 11:49:11] girgias@php.net
Assigning to cmb for review as he's the new maintainer for COM.
------------------------------------------------------------------------
[2017-02-13 23:46:21] muithimwema at gmail dot com
I am having the same error. See my post on Stack Overflow here http://stackoverflow.com/questions/42189245/how-to-pass-an-array-of-bytes-reference-to-a-com-object-method
------------------------------------------------------------------------
[2009-03-26 18:53:57] kaisellgren at gmail dot com
I am experiencing same problems.
$rng = new DOTNET("mscorlib",
"System.Security.Cryptography.RNGCryptoServiceProvider");
$arr = array(0);
$v = new VARIANT($arr,VT_ARRAY | VT_UI1);
$rng->GetBytes($v);
unset($rng);
It throws an error: Fatal error: Uncaught exception 'com_exception' with message
'Variant type conversion failed: Type mismatch.
------------------------------------------------------------------------
[2007-05-04 17:12:28] milman at gmx dot de
Description:
------------
for calling navigate2 you need to pass array of byte.
that is not possible.
Reproduce code:
---------------
<?php
$ie = new COM("InternetExplorer.Application");
$ie->Visible = true;
$ie->Height = 500 ;
$ie->Width = 700 ;
$post = array (ord('p'),ord('='),ord('1')) ;
$v = new VARIANT($post, VT_ARRAY|VT_UI1);
//postdata need to be array of byte
$ie->Navigate2("http://host/web/echo_request.php",0,'',$v)
;
?>
Expected result:
----------------
posting data to web-server
Actual result:
--------------
com_exception
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=41286&edit=1
Thread (5 messages)