More fixes for nodelist array access

- testing for null property read
- no zval copying if the type is already long
- memory fix for master
This commit is contained in:
Tjerk Meesters 2014-10-12 12:47:58 +08:00
parent 3e13c6dcb2
commit 37a685ff2b
2 changed files with 57 additions and 22 deletions

View file

@ -1679,16 +1679,30 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
} }
/* }}} end dom_get_nsdecl */ /* }}} end dom_get_nsdecl */
static inline long dom_get_long(zval *offset) /* {{{ */
{
if (Z_TYPE_P(offset) == IS_LONG) {
return Z_LVAL_P(offset);
} else {
zval tmp;
MAKE_COPY_ZVAL(&offset, &tmp);
convert_to_long(&tmp);
return Z_LVAL(tmp);
}
}
/* }}} */
zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */ zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */
{ {
zval *rv, offset_copy; zval *rv, offset_copy = zval_used_for_init;
if (!offset) { if (!offset) {
return NULL; return NULL;
} }
MAKE_COPY_ZVAL(&offset, &offset_copy); ZVAL_LONG(&offset_copy, dom_get_long(offset));
convert_to_long(&offset_copy);
zend_call_method_with_1_params(&object, Z_OBJCE_P(object), NULL, "item", &rv, &offset_copy); zend_call_method_with_1_params(&object, Z_OBJCE_P(object), NULL, "item", &rv, &offset_copy);
@ -1699,23 +1713,18 @@ zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type TSRMLS_DC
int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC) int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC)
{ {
zval *length, offset_copy; long offset = dom_get_long(member);
int ret;
MAKE_COPY_ZVAL(&member, &offset_copy); if (offset < 0) {
convert_to_long(&offset_copy);
if (Z_LVAL(offset_copy) < 0) {
return 0; return 0;
} else {
zval *length = zend_read_property(Z_OBJCE_P(object), object, "length", sizeof("length") - 1, 0 TSRMLS_CC);
int ret = length && offset < Z_LVAL_P(length);
FREE_ZVAL(length);
return ret;
} }
length = zend_read_property(Z_OBJCE_P(object), object, "length", sizeof("length") - 1, 0 TSRMLS_CC);
ret = Z_LVAL(offset_copy) < Z_LVAL_P(length);
FREE_ZVAL(length);
return ret;
} /* }}} end dom_nodelist_has_dimension */ } /* }}} end dom_nodelist_has_dimension */
#endif /* HAVE_DOM */ #endif /* HAVE_DOM */

View file

@ -22,11 +22,21 @@ var_dump($nodes[0]->textContent);
var_dump($nodes[1]->textContent); var_dump($nodes[1]->textContent);
echo "testing offset not a long\n"; echo "testing offset not a long\n";
$offset = ['test'];
var_dump($offset);
var_dump(isset($nodes[$offset]), $nodes[$offset]->textContent);
var_dump($offset);
$something = 'test';
$offset = &$something;
var_dump($offset);
var_dump(isset($nodes[$offset]), $nodes[$offset]->textContent);
var_dump($offset);
$offset = 'test'; $offset = 'test';
var_dump($offset); var_dump($offset);
var_dump($nodes[$offset]->textContent); var_dump(isset($nodes[$offset]), $nodes[$offset]->textContent);
var_dump($offset);
var_dump(isset($nodes[$offset]));
var_dump($offset); var_dump($offset);
echo "testing read_dimension with null offset\n"; echo "testing read_dimension with null offset\n";
@ -49,13 +59,29 @@ string(4) "data"
Notice: Trying to get property of non-object in %s on line %d Notice: Trying to get property of non-object in %s on line %d
NULL NULL
testing offset not a long testing offset not a long
string(4) "test" array(1) {
string(4) "data" [0]=>
string(4) "test"
}
Notice: Trying to get property of non-object in %s on line %d
bool(false)
NULL
array(1) {
[0]=>
string(4) "test"
}
string(4) "test" string(4) "test"
bool(true) bool(true)
string(4) "data"
string(4) "test"
string(4) "test"
bool(true)
string(4) "data"
string(4) "test" string(4) "test"
testing read_dimension with null offset testing read_dimension with null offset
NULL NULL
testing attribute access testing attribute access
string(4) "href" string(4) "href"
==DONE== ==DONE==