Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Moving forward.

  • Loading branch information...
commit c76bb8f39d3619fd706c4e0d1effc2d7be865cdb 1 parent 6c75fa7
@tricky tricky authored
View
34 php_memcached.c
@@ -619,7 +619,6 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
num_keys = zend_hash_num_elements(Z_ARRVAL_P(keys));
mkeys = safe_emalloc(num_keys, sizeof(*mkeys), 0);
mkeys_len = safe_emalloc(num_keys, sizeof(*mkeys_len), 0);
- mkeys_copy = safe_emalloc(num_keys, sizeof(*mkeys_copy), 0);
array_init(return_value);
/*
@@ -629,23 +628,24 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(keys));
zend_hash_get_current_data(Z_ARRVAL_P(keys), (void**)&entry) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(keys))) {
- int use_copy = 0;
- zval entry_copy, *entry_copy_ptr;
+ zval copy, *copy_ptr;
if (Z_TYPE_PP(entry) != IS_STRING) {
- /* TODO(tricky): should we instead be using a zval array for copies?
- * if zval structure changes, this might leed to a leak */
- INIT_ZVAL(entry_copy);
- zend_make_printable_zval(*entry, &entry_copy, &use_copy);
- if (use_copy) {
- entry_copy_ptr = &entry_copy;
- entry = &entry_copy_ptr;
- mkeys_copy[mkeys_ncopy] = Z_STRVAL(entry_copy);
- mkeys_ncopy++;
+ /* this should be relatively uncommon, defer allocation */
+ if (UNEXPECTED(mkeys_copy == NULL)) {
+ mkeys_copy = safe_emalloc(num_keys, sizeof(*mkeys_copy), 0);
}
+
+ MAKE_COPY_ZVAL(entry, &copy);
+ convert_to_string(&copy);
+
+ mkeys_copy[mkeys_ncopy] = Z_STRVAL(copy);
+ copy_ptr = ©
+ entry = &copy_ptr;
+ mkeys_ncopy++;
}
- if (Z_STRLEN_PP(entry) > 0) {
+ if (Z_TYPE_PP(entry) == IS_STRING && Z_STRLEN_PP(entry) > 0) {
mkeys[i] = Z_STRVAL_PP(entry);
mkeys_len[i] = Z_STRLEN_PP(entry);
@@ -664,7 +664,9 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
for (i = 0; i < mkeys_ncopy; i++) {
efree(mkeys_copy[i]);
}
- efree(mkeys_copy);
+ if (mkeys_copy) {
+ efree(mkeys_copy);
+ }
return;
}
@@ -696,7 +698,9 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
for (i = 0; i < mkeys_ncopy; i++) {
efree(mkeys_copy[i]);
}
- efree(mkeys_copy);
+ if (mkeys_copy) {
+ efree(mkeys_copy);
+ }
/*
* Iterate through the result set and create the result array. The CAS tokens are
View
10 tests/deletemulti.phpt
@@ -48,16 +48,16 @@ foreach ($retval as $key => $value) {
?>
--EXPECT--
array(5) {
+ ["foo"]=>
+ string(8) "foo-data"
+ ["bar"]=>
+ string(8) "bar-data"
["baz"]=>
string(8) "baz-data"
["lol"]=>
string(8) "lol-data"
["kek"]=>
string(8) "kek-data"
- ["foo"]=>
- string(8) "foo-data"
- ["bar"]=>
- string(8) "bar-data"
}
array(5) {
["foo"]=>
@@ -100,4 +100,4 @@ array(5) {
array(0) {
}
nothere NOT FOUND
-nothere2 NOT FOUND
View
73 tests/experimental/getdelayed_nonstring_keys.phpt
@@ -0,0 +1,73 @@
+--TEST--
+Memcached getDelayed non string keys
+--SKIPIF--
+<?php if (!extension_loaded("memcached")) print "skip"; ?>
+--FILE--
+<?php
+$m = new Memcached();
+$m->addServer('localhost', 11211, 1);
+
+class Bar {
+ public function __toString() {
+ return 'bar';
+ }
+}
+
+$data = array(
+ 'foo' => 'foo-data',
+ 'bar' => 'bar-data',
+ 3 => '3-data',
+);
+
+foreach ($data as $k => $v) {
+ $m->set($k, $v, 3600);
+}
+
+function myfunc() {
+ $datas = func_get_args();
+ if (isset($datas[1])) {
+ unset($datas[1]['cas']);
+ var_dump($datas[1]);
+ }
+}
+
+$keys = array('foo',
+ $k = new Bar(),
+ 3,
+);
+
+$m->getDelayed($keys, false, 'myfunc');
+
+if ($keys[0] !== 'foo') {
+ echo "String 'foo' was coerced to: ";
+ var_dump($keys[0]);
+}
+
+if (!$keys[1] instanceof Bar) {
+ echo "Object was coerced to: ";
+ var_dump($keys[1]);
+}
+
+if ($keys[2] !== 3) {
+ echo "Integer 3 was coerced to: ";
+ var_dump($keys[2]);
+}
+--EXPECT--
+array(2) {
+ ["key"]=>
+ string(3) "foo"
+ ["value"]=>
+ string(8) "foo-data"
+}
+array(2) {
+ ["key"]=>
+ string(3) "bar"
+ ["value"]=>
+ string(8) "bar-data"
+}
+array(2) {
+ ["key"]=>
+ string(1) "3"
+ ["value"]=>
+ string(6) "3-data"
+}
View
47 tests/experimental/getmulti.phpt
@@ -0,0 +1,47 @@
+--TEST--
+Memcached::getMulti()
+--SKIPIF--
+<?php if (!extension_loaded("memcached")) print "skip"; ?>
+--FILE--
+<?php
+$m = new Memcached();
+$m->addServer('localhost', 11211, 1);
+
+class Foo {
+ function __toString() {
+ return 'a-foo';
+ }
+}
+
+$data = array();
+for ($i = 0; $i < 1000; $i++) {
+ $data['key' . $i] = 'value' . $i;
+}
+$data['a-foo'] = 'a-last';
+var_dump($m->setMulti($data));
+
+$keys = array_keys($data);
+$keys['last'] = new Foo();
+
+$v = $m->getMulti($keys);
+var_dump(is_array($v));
+var_dump($m->getResultCode() == Memcached::RES_SUCCESS);
+if (is_array($v)) {
+ foreach ($v as $key => $value) {
+ if (!isset($data[$key]) or $value !== $data[$key]) {
+ echo "mismatch \$data['$key'] = \n";
+ var_dump($data[$key]);
+ var_dump($value);
+ }
+ }
+} else {
+ echo "Result not an array\n";
+}
+
+var_dump(is_object($keys['last']));
+
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
Please sign in to comment.
Something went wrong with that request. Please try again.