]> granicus.if.org Git - php/commitdiff
More fixes for nodelist array access
authorTjerk Meesters <datibbaw@php.net>
Sun, 12 Oct 2014 04:47:58 +0000 (12:47 +0800)
committerTjerk Meesters <datibbaw@php.net>
Sun, 12 Oct 2014 04:47:58 +0000 (12:47 +0800)
- testing for null property read
- no zval copying if the type is already long
- memory fix for master

ext/dom/php_dom.c
ext/dom/tests/bug67949.phpt

index ead6983ec2b25e646eb088f6ebae993cfdf6a551..4e035c764045af2f4331d065ff69f68107b2e2ef 100644 (file)
@@ -1679,16 +1679,30 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
 }
 /* }}} 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 *rv, offset_copy;
+       zval *rv, offset_copy = zval_used_for_init;
 
        if (!offset) {
                return NULL;
        }
 
-       MAKE_COPY_ZVAL(&offset, &offset_copy);
-       convert_to_long(&offset_copy);
+       ZVAL_LONG(&offset_copy, dom_get_long(offset));
 
        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)
 {
-       zval *length, offset_copy;
-       int ret;
-
-       MAKE_COPY_ZVAL(&member, &offset_copy);
-       convert_to_long(&offset_copy);
+       long offset = dom_get_long(member);
 
-       if (Z_LVAL(offset_copy) < 0) {
+       if (offset < 0) {
                return 0;
-       }
-
-       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);
+       } 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);
+               FREE_ZVAL(length);
 
-       return ret;
+               return ret;
+       }
 } /* }}} end dom_nodelist_has_dimension */
 
 #endif /* HAVE_DOM */
index fc29881ca76a9d0a23f9d690160deb1d3e2d8fbc..e4eb6f724fb3253d10234e3b5d3f2f90c7c56ed3 100644 (file)
@@ -22,11 +22,21 @@ var_dump($nodes[0]->textContent);
 var_dump($nodes[1]->textContent);
 
 echo "testing offset not a long\n";
-$offset = 'test';
+$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);
-var_dump($nodes[$offset]->textContent);
+
+$offset = 'test';
 var_dump($offset);
-var_dump(isset($nodes[$offset]));
+var_dump(isset($nodes[$offset]), $nodes[$offset]->textContent);
 var_dump($offset);
 
 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
 NULL
 testing offset not a long
+array(1) {
+  [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"
+bool(true)
 string(4) "data"
 string(4) "test"
+string(4) "test"
 bool(true)
+string(4) "data"
 string(4) "test"
 testing read_dimension with null offset
 NULL
 testing attribute access
 string(4) "href"
 ==DONE==
+