summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandot <mabingyao@gmail.com>2014-07-11 16:59:58 +0800
committerandot <mabingyao@gmail.com>2014-07-11 16:59:58 +0800
commitbf88eac6d32771891c8335e56f0d3fde6d53edd8 (patch)
tree09d5e79e4bc77570770d14e2c50dc4b287198d76
parent28578382589dab25ea5fbd35b7754687706abc07 (diff)
Fixed a bug of HashIterator
The old implementation of HashIterator can't support `"\0"` prefix key. I think the array and the object is different. Maybe the user didn't want to get the private property of an object. but in an array, `"\0"` prefix key doesn't mean private key. so we should return `"\0"` prefix key when it is an array.
-rw-r--r--zend/hashiterator.h16
-rw-r--r--zend/value.cpp4
2 files changed, 13 insertions, 7 deletions
diff --git a/zend/hashiterator.h b/zend/hashiterator.h
index b1f409f..36c3d6c 100644
--- a/zend/hashiterator.h
+++ b/zend/hashiterator.h
@@ -29,7 +29,7 @@ public:
* @param first Should it start on the first position?
* @param tsrm_ls
*/
- HashIterator(HashTable *hashtable, bool first) : _table(hashtable)
+ HashIterator(HashTable *hashtable, bool first, bool is_array = false) : _table(hashtable), _is_array(is_array)
{
// reset the hash pointer to the internal position
if (hashtable && first)
@@ -56,7 +56,7 @@ public:
* @param tsrm_ls
*/
HashIterator(const HashIterator &that TSRMLS_DC) :
- _table(that._table), _position(that._position)
+ _table(that._table), _position(that._position), _is_array(that._is_array)
{
// read current position
read();
@@ -166,7 +166,13 @@ private:
* @var HashPosition
*/
Bucket *_position = nullptr;
-
+
+ /**
+ * Is a hash interator in array
+ * @var bool
+ */
+ bool _is_array = false;
+
/**
* The current key and value
* @var std::pair
@@ -207,7 +213,7 @@ private:
// numeric keys are the easiest ones
if (type == HASH_KEY_IS_LONG) key = (int64_t)num_key;
- else key = string_key;
+ else key = std::string(string_key, str_len - 1);
#endif
@@ -223,7 +229,7 @@ private:
// if the key is private (it starts with a null character) we should return
// false to report that the object is not in a completely valid state
- return !_current.first.isString() || _current.first.rawValue()[0];
+ return _is_array || !_current.first.isString() || _current.first.rawValue()[0];
}
/**
diff --git a/zend/value.cpp b/zend/value.cpp
index 9a1a5db..352e90d 100644
--- a/zend/value.cpp
+++ b/zend/value.cpp
@@ -1626,7 +1626,7 @@ std::map<std::string,Php::Value> Value::mapValue() const
ValueIterator Value::createIterator(bool begin) const
{
// check type
- if (isArray()) return ValueIterator(new HashIterator(Z_ARRVAL_P(_val), begin));
+ if (isArray()) return ValueIterator(new HashIterator(Z_ARRVAL_P(_val), begin, true));
// get access to the hast table
if (isObject())
@@ -1647,7 +1647,7 @@ ValueIterator Value::createIterator(bool begin) const
else
{
// construct a regular iterator
- return ValueIterator(new HashIterator(Z_OBJ_HT_P(_val)->get_properties(_val TSRMLS_CC), begin));
+ return ValueIterator(new HashIterator(Z_OBJPROP_P(_val), begin));
}
}