case ZEND_ITER_PLAIN_ARRAY:
/* good old fashioned foreach on an array */
fe_ht = HASH_OF(array);
- if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
- /* reached end of iteration */
- EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
- return 0; /* CHECK_ME */
+ if (Z_TYPE_P(array) == IS_OBJECT) {
+ char *class_name, *prop_name;
+ zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
+
+ do {
+ if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
+ /* reached end of iteration */
+ EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
+ return 0; /* CHECK_ME */
+ }
+ key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
+
+ zend_hash_move_forward(fe_ht);
+ } while (zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
+ unmangle_property_name(str_key, &class_name, &prop_name);
+ str_key_len = strlen(prop_name);
+ str_key = estrndup(prop_name, str_key_len);
+ str_key_len++;
+ } else {
+ if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
+ /* reached end of iteration */
+ EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
+ return 0; /* CHECK_ME */
+ }
+ key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
+ zend_hash_move_forward(fe_ht);
}
- key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
break;
case ZEND_ITER_OBJECT:
}
zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
- if (!iter) {
- zend_hash_move_forward(fe_ht);
- }
-
NEXT_OPCODE();
}
}
-static inline int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce TSRMLS_DC)
+static int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce TSRMLS_DC)
{
switch (property_info->flags & ZEND_ACC_PPP_MASK) {
case ZEND_ACC_PUBLIC:
}
return 0;
case ZEND_ACC_PRIVATE:
- if (ce==EG(scope)) {
+ if (ce==EG(scope) && EG(scope)) {
return 1;
} else {
return 0;
return 0;
}
-static inline zend_property_info *zend_get_property_info(zend_object *zobj, zval *member TSRMLS_DC)
+static inline zend_property_info *zend_get_property_info(zend_object *zobj, zval *member, int silent TSRMLS_DC)
{
zend_property_info *property_info = NULL;
zend_property_info *scope_property_info;
} else if (property_info) {
if (denied_access) {
/* Information was available, but we were denied access. Error out. */
+ if (silent) {
+ return NULL;
+ }
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), zobj->ce->name, Z_STRVAL_P(member));
} else {
/* fall through, return property_info... */
}
+ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name TSRMLS_DC)
+{
+ zend_property_info *property_info;
+ char *class_name, *prop_name;
+ zval member;
+
+ unmangle_property_name(prop_info_name, &class_name, &prop_name);
+ ZVAL_STRING(&member, prop_name, 0);
+ property_info = zend_get_property_info(zobj, &member, 1 TSRMLS_CC);
+ if (!property_info) {
+ return FAILURE;
+ }
+ if (prop_info_name[0] == '\0' && prop_info_name[1] != '*' && !(property_info->flags & ZEND_ACC_PRIVATE)) {
+ /* we we're looking for a private prop but found a non private one of the same name */
+ return FAILURE;
+ }
+ return zend_verify_property_access(property_info, zobj->ce TSRMLS_CC) ? SUCCESS : FAILURE;
+}
+
zval *zend_std_read_property(zval *object, zval *member, zend_bool silent TSRMLS_DC)
{
zend_object *zobj;
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
#endif
- property_info = zend_get_property_info(zobj, member TSRMLS_CC);
+ property_info = zend_get_property_info(zobj, member, 0 TSRMLS_CC);
if (zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
if (zobj->ce->__get && !zobj->in_get) {
member = &tmp_member;
}
- property_info = zend_get_property_info(zobj, member TSRMLS_CC);
+ property_info = zend_get_property_info(zobj, member, 0 TSRMLS_CC);
if (zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) {
if (*variable_ptr == value) {
fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
#endif
- property_info = zend_get_property_info(zobj, member TSRMLS_CC);
+ property_info = zend_get_property_info(zobj, member, 0 TSRMLS_CC);
if (zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
zval *new_zval;
member = &tmp_member;
}
- property_info = zend_get_property_info(zobj, member TSRMLS_CC);
+ property_info = zend_get_property_info(zobj, member, 0 TSRMLS_CC);
zend_hash_del(zobj->properties, property_info->name, property_info->name_length+1);
if (member == &tmp_member) {
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
#endif
- property_info = zend_get_property_info(zobj, member TSRMLS_CC);
+ property_info = zend_get_property_info(zobj, member, 0 TSRMLS_CC);
if (zend_hash_find(zobj->properties, property_info->name, property_info->name_length+1, (void **) &value) == SUCCESS) {
if (check_empty) {