mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix property access of PHP objects wrapped in variant
First, we fix the long standing issue that property access throws a
`com_exception` ("0x80020003: member not found), because the `HRESULT`
was not properly set after accessing the property.
Next, we fix an issue introduced as of PHP 7.0.0, where the string
length for write access had been properly adapted, but the string
length for read access had been overlooked.
Then we fix an issue introduced as of PHP 8.0.0, where new `HashTable`s
no longer set `nNextFreeElement` to zero, but to `ZEND_LONG_MIN`. This
doesn't work well with the `DISPID` lookup, which is a `LONG`.
Finally we fix a potential double-free due to erroneously destroying
the return value of `zend_read_property()`.
Closes GH-16331.
This commit is contained in:
3
NEWS
3
NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.5.0alpha1
|
||||
|
||||
- COM:
|
||||
. Fix property access of PHP objects wrapped in variant. (cmb)
|
||||
|
||||
- DOM:
|
||||
. Added Dom\Element::$outerHTML. (nielsdos)
|
||||
|
||||
|
||||
@@ -258,9 +258,11 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex(
|
||||
* and expose it as a COM exception */
|
||||
|
||||
if (wFlags & DISPATCH_PROPERTYGET) {
|
||||
retval = zend_read_property(Z_OBJCE(disp->object), Z_OBJ(disp->object), Z_STRVAL_P(name), Z_STRLEN_P(name)+1, 1, &rv);
|
||||
retval = zend_read_property(Z_OBJCE(disp->object), Z_OBJ(disp->object), Z_STRVAL_P(name), Z_STRLEN_P(name), 1, &rv);
|
||||
ret = S_OK;
|
||||
} else if (wFlags & DISPATCH_PROPERTYPUT) {
|
||||
zend_update_property(Z_OBJCE(disp->object), Z_OBJ(disp->object), Z_STRVAL_P(name), Z_STRLEN_P(name), ¶ms[0]);
|
||||
ret = S_OK;
|
||||
} else if (wFlags & DISPATCH_METHOD) {
|
||||
zend_try {
|
||||
retval = &rv;
|
||||
@@ -305,7 +307,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex(
|
||||
VariantInit(pvarRes);
|
||||
php_com_variant_from_zval(pvarRes, retval, COMG(code_page));
|
||||
}
|
||||
zval_ptr_dtor(retval);
|
||||
// zval_ptr_dtor(retval); // TODO needed for function calls?
|
||||
} else if (pvarRes) {
|
||||
VariantInit(pvarRes);
|
||||
}
|
||||
@@ -425,7 +427,7 @@ static void generate_dispids(php_dispatchex *disp)
|
||||
zend_string *name = NULL;
|
||||
zval *tmp, tmp2;
|
||||
int keytype;
|
||||
zend_ulong pid;
|
||||
zend_long pid;
|
||||
|
||||
if (disp->dispid_to_name == NULL) {
|
||||
ALLOC_HASHTABLE(disp->dispid_to_name);
|
||||
@@ -458,8 +460,8 @@ static void generate_dispids(php_dispatchex *disp)
|
||||
|
||||
/* add the mappings */
|
||||
ZVAL_STR_COPY(&tmp2, name);
|
||||
pid = zend_hash_next_free_element(disp->dispid_to_name);
|
||||
zend_hash_index_update(disp->dispid_to_name, pid, &tmp2);
|
||||
zend_hash_next_index_insert(disp->dispid_to_name, &tmp2);
|
||||
pid = zend_hash_next_free_element(disp->dispid_to_name) - 1;
|
||||
|
||||
ZVAL_LONG(&tmp2, pid);
|
||||
zend_hash_update(disp->name_to_dispid, name, &tmp2);
|
||||
@@ -493,8 +495,8 @@ static void generate_dispids(php_dispatchex *disp)
|
||||
|
||||
/* add the mappings */
|
||||
ZVAL_STR_COPY(&tmp2, name);
|
||||
pid = zend_hash_next_free_element(disp->dispid_to_name);
|
||||
zend_hash_index_update(disp->dispid_to_name, pid, &tmp2);
|
||||
zend_hash_next_index_insert(disp->dispid_to_name, &tmp2);
|
||||
pid = zend_hash_next_free_element(disp->dispid_to_name) - 1;
|
||||
|
||||
ZVAL_LONG(&tmp2, pid);
|
||||
zend_hash_update(disp->name_to_dispid, name, &tmp2);
|
||||
|
||||
33
ext/com_dotnet/tests/variant_variation2.phpt
Normal file
33
ext/com_dotnet/tests/variant_variation2.phpt
Normal file
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Testing reading and writing of properties
|
||||
--EXTENSIONS--
|
||||
com_dotnet
|
||||
--FILE--
|
||||
<?php
|
||||
class MyClass {
|
||||
public $foo = "foo";
|
||||
public string $bar = "bar";
|
||||
}
|
||||
|
||||
$o = new MyClass();
|
||||
$v = new variant($o);
|
||||
var_dump($v->foo);
|
||||
var_dump($v->bar);
|
||||
$v->foo = "new foo";
|
||||
var_dump($v->foo instanceof variant);
|
||||
var_dump((string) $v->foo);
|
||||
var_dump($o->foo instanceof variant);
|
||||
var_dump((string) $o->foo);
|
||||
$v->bar = "new bar";
|
||||
var_dump($v->bar);
|
||||
var_dump($o->bar);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "foo"
|
||||
string(3) "bar"
|
||||
bool(true)
|
||||
string(7) "new foo"
|
||||
bool(true)
|
||||
string(7) "new foo"
|
||||
string(7) "new bar"
|
||||
string(7) "new bar"
|
||||
Reference in New Issue
Block a user