Skip to content

Commit

Permalink
massive patch fixing memory leaks and segfaults
Browse files Browse the repository at this point in the history
mostly when using STRING_TO_MIXED arrays and foreach

git-svn-id: https://svn.php.net/repository/pecl/judy/trunk@329849 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information
nicolas committed Mar 20, 2013
1 parent 96f83e2 commit 3a687c2
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 79 deletions.
20 changes: 15 additions & 5 deletions judy_arrayaccess.c
Expand Up @@ -107,7 +107,11 @@ PHP_METHOD(judy, offsetSet)

JLI(PValue, intern->array, index);
if (PValue != NULL && PValue != PJERR) {
*(zval **)PValue = value;
if (*PValue != NULL) {
zval *old_value = (zval *)*PValue;
zval_ptr_dtor(&old_value);
}
*PValue = value;
Z_ADDREF_P(*(zval **)PValue);
RETURN_TRUE;
} else {
Expand Down Expand Up @@ -143,8 +147,12 @@ PHP_METHOD(judy, offsetSet)

JSLI(PValue, intern->array, key);
if (PValue != NULL && PValue != PJERR) {
*(zval **)PValue = value;
Z_ADDREF_P(*(zval **)PValue);
if (*PValue != NULL) {
zval *old_value = (zval *)*PValue;
zval_ptr_dtor(&old_value);
}
*PValue = value;
Z_ADDREF_P(value);
intern->counter++;
RETURN_TRUE;
} else {
Expand Down Expand Up @@ -184,7 +192,8 @@ PHP_METHOD(judy, offsetUnset)
Pvoid_t *PValue;
JLG(PValue, intern->array, index);
if (PValue != NULL && PValue != PJERR) {
Z_DELREF_P(*(zval **)PValue);
zval *value = (zval *)*PValue;
zval_ptr_dtor(&value);
JLD(Rc_int, intern->array, index);
}
}
Expand All @@ -204,7 +213,8 @@ PHP_METHOD(judy, offsetUnset)
Pvoid_t *PValue;
JSLG(PValue, intern->array, key);
if (PValue != NULL && PValue != PJERR) {
Z_DELREF_P(*(zval **)PValue);
zval *value = (zval *)*PValue;
zval_ptr_dtor(&value);
JSLD(Rc_int, intern->array, key);
}
}
Expand Down
140 changes: 87 additions & 53 deletions judy_iterator.c
Expand Up @@ -39,7 +39,7 @@ zend_object_iterator *judy_get_iterator(zend_class_entry *ce, zval *object, int
judy_iterator *it = emalloc(sizeof(judy_iterator));

if (by_ref) {
zend_error(E_ERROR, "Iterator invalid in foreach by ref");
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}

Z_ADDREF_P(object);
Expand All @@ -48,7 +48,8 @@ zend_object_iterator *judy_get_iterator(zend_class_entry *ce, zval *object, int
it->intern.funcs = &judy_iterator_funcs;

MAKE_STD_ZVAL(it->key);
MAKE_STD_ZVAL(it->data);
ZVAL_NULL(it->key);
it->data = NULL;

return (zend_object_iterator*) it;
}
Expand All @@ -59,13 +60,13 @@ zend_object_iterator *judy_get_iterator(zend_class_entry *ce, zval *object, int
void judy_iterator_data_dtor(judy_iterator *it)
{
if (it->key) {
//Z_DELREF_P(it->key);
it->key = IS_NULL;
zval_ptr_dtor(&it->key);
it->key = NULL;
}

if (it->data) {
//Z_DELREF_P(it->data);
it->data = IS_NULL;
zval_ptr_dtor(&it->data);
it->data = NULL;
}
}
/* }}} */
Expand All @@ -77,13 +78,7 @@ void judy_iterator_dtor(zend_object_iterator *iterator TSRMLS_DC)
judy_iterator *it = (judy_iterator*) iterator;
zval *intern = (zval*) it->intern.data;

if (it->key) {
zval_ptr_dtor(&it->key);
}

if (it->data) {
zval_ptr_dtor(&it->data);
}
judy_iterator_data_dtor(it);

Z_DELREF_P(intern);

Expand Down Expand Up @@ -119,15 +114,16 @@ int judy_iterator_valid(zend_object_iterator *iterator TSRMLS_DC)
uint8_t key[PHP_JUDY_MAX_LENGTH];
Word_t *PValue;

if (Z_STRVAL_P(it->key) == NULL) {
return FAILURE;
}

char *str = Z_STRVAL_P(it->key);
int i;
for (i = 0; str[i]; i++)
key[i] = str[i];
key[i++] = '\0';
if (Z_TYPE_P(it->key) == IS_STRING) {
int key_len;
key_len = Z_STRLEN_P(it->key) >= PHP_JUDY_MAX_LENGTH ? PHP_JUDY_MAX_LENGTH - 1 : Z_STRLEN_P(it->key);
memcpy(key, Z_STRVAL_P(it->key), key_len);
key[key_len] = '\0';
} else if (Z_TYPE_P(it->key) == IS_NULL) {
key[0] = '\0';
} else {
return FAILURE;
}

JSLG(PValue, object->array, key);
if (PValue != NULL && PValue != PJERR) {
Expand All @@ -145,7 +141,11 @@ void judy_iterator_current_data(zend_object_iterator *iterator,
zval ***data TSRMLS_DC)
{
judy_iterator *it = (judy_iterator*) iterator;
*data = &it->data;
if (it->data) {
*data = &it->data;
} else {
*data = NULL;
}
}
/* }}} */

Expand Down Expand Up @@ -180,6 +180,11 @@ void judy_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC)
{
JUDY_ITERATOR_GET_OBJECT

if (it->data) {
zval_ptr_dtor(&it->data);
it->data = NULL;
}

if (object->type == TYPE_BITSET) {

Word_t index;
Expand All @@ -194,7 +199,9 @@ void judy_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC)
}

if (Rc_int) {
zval_dtor(it->key);
ZVAL_LONG(it->key, index);
MAKE_STD_ZVAL(it->data);
ZVAL_BOOL(it->data, 1);
} else {
judy_iterator_data_dtor(it);
Expand All @@ -209,18 +216,25 @@ void judy_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC)
index = 0;
JLF(*PValue, object->array, index);
} else {
index = Z_LVAL_P(it->key);
index = Z_LVAL_P(it->key);
JLN(PValue, object->array, index);
}

zval_dtor(it->key);
ZVAL_LONG(it->key, index);

JLG(PValue, object->array, index);
if (PValue != NULL && PValue != PJERR) {
if (object->type == TYPE_INT_TO_INT) {
MAKE_STD_ZVAL(it->data);
ZVAL_LONG(it->data, (long)*PValue);
} else {
it->data = *(zval **)PValue;
zval *value = *(zval **)PValue;

MAKE_STD_ZVAL(it->data);
*it->data = *value;
zval_copy_ctor(it->data);
INIT_PZVAL(it->data);
}
} else {
judy_iterator_data_dtor(it);
Expand All @@ -230,36 +244,39 @@ void judy_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC)

uint8_t key[PHP_JUDY_MAX_LENGTH];
Pvoid_t *PValue;
char *prev_key;

prev_key = estrdup(Z_STRVAL_P(it->key));

/* JudySL require null temrinated strings */
if (Z_TYPE_P(it->key) == IS_NULL) {
key[0] = '\0';
JSLF(PValue, object->array, key);
} else {
char *str = Z_STRVAL_P(it->key);
int i;
for (i = 0; str[i]; i++)
key[i] = str[i];
key[i++] = '\0';
JSLN(PValue, object->array, key);
}
if (Z_TYPE_P(it->key) == IS_STRING) {
int key_len;
key_len = Z_STRLEN_P(it->key) >= PHP_JUDY_MAX_LENGTH ? PHP_JUDY_MAX_LENGTH - 1 : Z_STRLEN_P(it->key);
memcpy(key, Z_STRVAL_P(it->key), key_len);
key[key_len] = '\0';

ZVAL_STRING(it->key, (char *)key, 1);
JSLN(PValue, object->array, key);
} else {
key[0] = '\0';
JSLF(PValue, object->array, key);
}

if ((PValue != NULL && PValue != PJERR)) {

zval_dtor(it->key);
ZVAL_STRING(it->key, (char *)key, 1);

JSLG(PValue, object->array, key);
if ((PValue != NULL && PValue != PJERR) && strcmp(prev_key, (char *)key) != 0) {
if (object->type == TYPE_STRING_TO_INT) {
MAKE_STD_ZVAL(it->data);
ZVAL_LONG(it->data, (long)*PValue);
} else {
it->data = *(zval **)PValue;
zval *value = *(zval **)PValue;

MAKE_STD_ZVAL(it->data);
*it->data = *value;
zval_copy_ctor(it->data);
INIT_PZVAL(it->data);
}
} else {
judy_iterator_data_dtor(it);
}

}
}
/* }}} */
Expand All @@ -270,13 +287,19 @@ void judy_iterator_rewind(zend_object_iterator *iterator TSRMLS_DC)
{
JUDY_ITERATOR_GET_OBJECT

if (object->type == TYPE_BITSET) {
if (it->data) {
zval_ptr_dtor(&it->data);
it->data = NULL;
}

if (object->type == TYPE_BITSET) {
Word_t index = 0;
int Rc_int;

J1F(Rc_int, object->array, index);
zval_dtor(it->key);
ZVAL_LONG(it->key, index);
MAKE_STD_ZVAL(it->data);
ZVAL_BOOL(it->data, 1);

} else if (object->type == TYPE_INT_TO_INT || object->type == TYPE_INT_TO_MIXED) {
Expand All @@ -285,37 +308,48 @@ void judy_iterator_rewind(zend_object_iterator *iterator TSRMLS_DC)
Pvoid_t *PValue = NULL;

JLF(PValue, object->array, index);

zval_dtor(it->key);
ZVAL_LONG(it->key, index);

JLG(PValue, object->array, index);
if (PValue != NULL && PValue != PJERR) {
if (object->type == TYPE_INT_TO_INT) {
MAKE_STD_ZVAL(it->data);
ZVAL_LONG(it->data, (long)*PValue);
} else {
it->data = *(zval **)PValue;
zval *value = *(zval **)PValue;

MAKE_STD_ZVAL(it->data);
*it->data = *value;
zval_copy_ctor(it->data);
INIT_PZVAL(it->data);
}
}

} else if (object->type == TYPE_STRING_TO_INT || object->type == TYPE_STRING_TO_MIXED) {

uint8_t key[PHP_JUDY_MAX_LENGTH];
Word_t *PValue;
Pvoid_t *PValue;

/* JudySL require null temrinated strings */
key[0] = '\0';
JSLF(PValue, object->array, key);
ZVAL_STRING(it->key, (const char *) key, 1);

JSLG(PValue, object->array, key);
if (PValue != NULL && PValue != PJERR) {
zval_dtor(it->key);
ZVAL_STRING(it->key, (const char *) key, 1);
if (object->type == TYPE_STRING_TO_INT) {
ZVAL_LONG(it->data, *PValue);
MAKE_STD_ZVAL(it->data);
ZVAL_LONG(it->data, (long)*PValue);
} else {
it->data = *(zval **)PValue;
zval *value = *(zval **)PValue;

MAKE_STD_ZVAL(it->data);
*it->data = *value;
zval_copy_ctor(it->data);
INIT_PZVAL(it->data);
}
}

}
}
/* }}} */
Expand Down

0 comments on commit 3a687c2

Please sign in to comment.