Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.2.2] [CRASH] Fix segmentation fault in zend_std_write_property for PHP 5.4+ #1004

Closed
wants to merge 59 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
349d92f
Fix #910, 914
sjinks Jul 25, 2013
e6dd0c6
The root memory frame survives across requests
sjinks Jul 24, 2013
fab2bec
Do not restore stack too many times
sjinks Jul 25, 2013
8a13e56
Fix bug in phalcon_escape_multi() introduced in 1ce094c60dd4a4ef674cb…
sjinks Jul 25, 2013
161a521
Fix #908
sjinks Jul 25, 2013
f629393
Commented out listenLowSeverity()
sjinks Jul 25, 2013
aa5ca68
Fix invalid memory reads when GC is on
sjinks Jul 25, 2013
df85c04
Fix #701
sjinks Jul 25, 2013
3b216f9
Bumped version to 1.2.2
sjinks Jul 25, 2013
f67f165
Regenerated builds
sjinks Jul 25, 2013
6ad7360
Merge branch '1.2.1-sj' of git://github.com/sjinks/cphalcon into sjin…
niden Jul 25, 2013
123d5ae
Regenerated Builds
niden Jul 25, 2013
d6c3e08
Updated changelog for 1.2.2
sjinks Jul 25, 2013
7086ac4
Add scale to decimal
dreamsxin Jul 26, 2013
35a696e
reset format
dreamsxin Jul 26, 2013
ae32615
reset format
dreamsxin Jul 26, 2013
b73de86
push db/dialect/postgresql.c
dreamsxin Jul 26, 2013
d688e90
use PHALCON_OBS_NVAR
dreamsxin Jul 26, 2013
10b90b2
Update unit-tests/DbDescribeTest.php
dreamsxin Jul 26, 2013
e0671a3
Update sqlite.c
dreamsxin Jul 26, 2013
a3550b4
Update mysql.c
dreamsxin Jul 26, 2013
975e8bd
Merge pull request #935 from dreamsxin/decimal_scale
Jul 27, 2013
cffb538
Fix bug #826
dreamsxin Jul 27, 2013
255e062
Merge pull request #941 from dreamsxin/paginator_adapter_model
Jul 29, 2013
dbf610a
Fix bug #951
dreamsxin Jul 31, 2013
8e916c6
Fix bug #951
dreamsxin Jul 31, 2013
7d7a268
Update manager function output param
dreamsxin Jul 31, 2013
c25d130
addJs/addCss call resource __construct add param type
dreamsxin Jul 31, 2013
22ad839
Updated
dreamsxin Jul 31, 2013
5e0af70
reset call resource __construct param
dreamsxin Jul 31, 2013
ec7602c
Format
dreamsxin Jul 31, 2013
33abf69
Update manager.h
dreamsxin Jul 31, 2013
0590af0
Merge pull request #957 from dreamsxin/assets951
Jul 31, 2013
cf034fb
'New' means 'new', not 'clone'
sjinks Jul 31, 2013
36b9458
Fix #938
sjinks Jul 31, 2013
ef56f77
Added unit test
sjinks Jul 31, 2013
f2eb8d5
Fixed tests
sjinks Jul 31, 2013
fdff06d
Merge pull request #966 from sjinks/has_many_to_many
Aug 1, 2013
4d70804
unused variable ‘i’
sjinks Aug 1, 2013
f8a0f75
‘marker’ may be used uninitialized in this function
sjinks Aug 1, 2013
328d88e
‘uidx’ may be used uninitialized in this function
sjinks Aug 1, 2013
634c1f6
‘regexp_length’ may be used uninitialized in this function
sjinks Aug 1, 2013
60da6fa
variable may be used uninitialized in this function
sjinks Aug 1, 2013
2980d24
‘parser.tmp_state’ may be used uninitialized in this function
sjinks Aug 1, 2013
fdaa645
‘marker’ may be used uninitialized in this function
sjinks Aug 1, 2013
2b8f420
‘phql_key’ may be used uninitialized in this function
sjinks Aug 1, 2013
e740ecb
Regenerated builds
sjinks Aug 1, 2013
b04d46b
Merge pull request #967 from sjinks/compiler-warnings
Aug 1, 2013
cc1fe15
Fix #980
sjinks Aug 2, 2013
9d72ad3
Unit test
sjinks Aug 2, 2013
134186b
Merge pull request #982 from sjinks/issue-980-1.2.2
Aug 2, 2013
45fbecb
Fix segfault when GC is on
sjinks Aug 3, 2013
a2c5980
Merge pull request #985 from sjinks/segfault-config-1.2.2
Aug 3, 2013
ba1371e
Fix typo in the method name
sjinks Aug 4, 2013
2c43eab
Test case
sjinks Aug 4, 2013
7915b80
Merge pull request #995 from sjinks/annotations_adapter_1.2.2
Aug 5, 2013
6e9f67c
Test case
sjinks Aug 5, 2013
627c213
Fix unrelated bug in Phalcon\Config
sjinks Aug 5, 2013
b1b58cb
Fix #1000
sjinks Aug 5, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 103 additions & 112 deletions ext/mvc/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,56 @@ PHALCON_INIT_CLASS(Phalcon_Mvc_Model){
return SUCCESS;
}

/**
* <code>
* private function getMessagesFromModel($model, $target)
* {
* $messages = $model->getMessages();
* foreach ($messages as $message) {
* if (is_object($message)) {
* $message->setModel($target);
* }
*
* $this->appendMessage($message);
* }
* }
* </code>
*/
static int phalcon_mvc_model_get_messages_from_model(zval *this_ptr, zval *model, zval *target TSRMLS_DC)
{
zval *messages, **message;
HashPosition hp;

ALLOC_INIT_ZVAL(messages);

if (
phalcon_call_method_params_w(messages, model, SL("getmessages"), 0, NULL, zend_inline_hash_func(SS("getmessages")), 1 TSRMLS_CC) == FAILURE
|| Z_TYPE_P(messages) != IS_ARRAY
) {
zval_ptr_dtor(&messages);
return FAILURE;
}

for (
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(messages), &hp);
zend_hash_get_current_data_ex(Z_ARRVAL_P(messages), (void**)&message, &hp) == SUCCESS && !EG(exception);
zend_hash_move_forward_ex(Z_ARRVAL_P(messages), &hp)
) {
zval *params[1];

if (Z_TYPE_PP(message) == IS_OBJECT) {
params[0] = target;
phalcon_call_method_params_w(NULL, *message, SL("setmodel"), 1, params, zend_inline_hash_func(SS("setmodel")), 1 TSRMLS_CC);
}

params[0] = *message;
phalcon_call_method_params_w(NULL, this_ptr, SL("appendmessage"), 1, params, zend_inline_hash_func(SS("appendmessage")), 1 TSRMLS_CC);
}

zval_ptr_dtor(&messages);
return likely(!EG(exception)) ? SUCCESS : FAILURE;
}

/**
* Phalcon\Mvc\Model constructor
*
Expand Down Expand Up @@ -1311,7 +1361,7 @@ PHP_METHOD(Phalcon_Mvc_Model, _exists){
phalcon_read_property_zval(&value, this_ptr, attribute_field, PH_NOISY_CC);

/**
* We count how many fields are empty, if all fields are empy we don't perform an
* We count how many fields are empty, if all fields are empty we don't perform an
* 'exist' check
*/
if (PHALCON_IS_EMPTY(value)) {
Expand All @@ -1333,7 +1383,7 @@ PHP_METHOD(Phalcon_Mvc_Model, _exists){
PHALCON_CONCAT_VS(pk_condition, escaped_field, " = ?");
if (!phalcon_array_isset(bind_data_types, field)) {
PHALCON_INIT_NVAR(exception_message);
PHALCON_CONCAT_SVS(exception_message, "Column '", field, "' isn't part of the table columns");
PHALCON_CONCAT_SVS(exception_message, "Column '", field, "' isn't a part of the table columns");
PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message);
return;
}
Expand Down Expand Up @@ -3100,7 +3150,7 @@ PHP_METHOD(Phalcon_Mvc_Model, _doLowInsert){
*/
if (!phalcon_array_isset(bind_data_types, field)) {
PHALCON_INIT_NVAR(exception_message);
PHALCON_CONCAT_SVS(exception_message, "Column '", field, "' have not defined a bind data type");
PHALCON_CONCAT_SVS(exception_message, "Column '", field, "' has not defined a bind data type");
PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message);
return;
}
Expand Down Expand Up @@ -3515,9 +3565,9 @@ PHP_METHOD(Phalcon_Mvc_Model, _preSaveRelatedRecords){
zval *connection, *related, *nesting, *class_name;
zval *manager, *record = NULL, *name = NULL, *relation = NULL, *type = NULL, *columns = NULL;
zval *referenced_model = NULL, *referenced_fields = NULL;
zval *status = NULL, *messages = NULL, *message = NULL, *referenced_value = NULL;
HashTable *ah0, *ah1;
HashPosition hp0, hp1;
zval *status = NULL, *referenced_value = NULL;
HashTable *ah0;
HashPosition hp0;
zval **hd;

PHALCON_MM_GROW();
Expand Down Expand Up @@ -3593,28 +3643,8 @@ PHP_METHOD(Phalcon_Mvc_Model, _preSaveRelatedRecords){
/**
* Get the validation messages generated by the referenced model
*/
PHALCON_INIT_NVAR(messages);
phalcon_call_method(messages, record, "getmessages");

phalcon_is_iterable(messages, &ah1, &hp1, 0, 0);

while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) {

PHALCON_GET_HVALUE(message);

/**
* Set the related model
*/
if (Z_TYPE_P(record) == IS_OBJECT) {
phalcon_call_method_p1_noret(message, "setmodel", record);
}

/**
* Appends the messages to the current model
*/
phalcon_call_method_p1_noret(this_ptr, "appendmessage", message);

zend_hash_move_forward_ex(ah1, &hp1);
if (phalcon_mvc_model_get_messages_from_model(this_ptr, record, record TSRMLS_CC) == FAILURE) {
RETURN_MM();
}

/**
Expand Down Expand Up @@ -3656,21 +3686,24 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
zval *manager, *record = NULL, *name = NULL, *relation = NULL, *type = NULL, *columns = NULL;
zval *referenced_model = NULL, *referenced_fields = NULL;
zval *related_records = NULL, *exception_message = NULL;
zval *value = NULL, *is_through = NULL, *new_instance = NULL, *intermediate_model_name = NULL;
zval *value = NULL, *is_through = NULL, *new_instance, *intermediate_model_name = NULL;
zval *intermediate_fields = NULL, *intermediate_referenced_fields = NULL;
zval *record_after = NULL, *intermediate_model = NULL, *intermediate_value = NULL;
zval *status = NULL, *messages = NULL, *message = NULL;
HashTable *ah0, *ah1, *ah2, *ah3;
HashPosition hp0, hp1, hp2, hp3;
zval *status = NULL;
HashTable *ah0, *ah1;
HashPosition hp0, hp1;
zval **hd;

phalcon_fetch_params(0, 2, 0, &connection, &related);

PHALCON_MM_GROW();

phalcon_fetch_params(1, 2, 0, &connection, &related);

PHALCON_INIT_VAR(nesting);
ZVAL_BOOL(nesting, 0);
ZVAL_FALSE(nesting);

PHALCON_INIT_VAR(new_instance);
ZVAL_TRUE(new_instance);

PHALCON_INIT_VAR(class_name);
phalcon_get_class(class_name, this_ptr, 0 TSRMLS_CC);

Expand Down Expand Up @@ -3702,12 +3735,10 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
continue;
}

if (Z_TYPE_P(record) != IS_OBJECT) {
if (Z_TYPE_P(record) != IS_ARRAY) {
phalcon_call_method_p1_noret(connection, "rollback", nesting);
PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "Only objects/arrays can be stored as part of has-many/has-one/has-many-to-many relations");
return;
}
if (Z_TYPE_P(record) != IS_OBJECT && Z_TYPE_P(record) != IS_ARRAY) {
phalcon_call_method_p1_noret(connection, "rollback", nesting);
PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "Only objects/arrays can be stored as part of has-many/has-one/has-many-to-many relations");
return;
}

PHALCON_INIT_NVAR(columns);
Expand All @@ -3718,6 +3749,7 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){

PHALCON_INIT_NVAR(referenced_fields);
phalcon_call_method(referenced_fields, relation, "getreferencedfields");

if (Z_TYPE_P(columns) == IS_ARRAY) {
phalcon_call_method_p1_noret(connection, "rollback", nesting);
PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "Not implemented");
Expand All @@ -3730,7 +3762,7 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
if (Z_TYPE_P(record) == IS_OBJECT) {
PHALCON_INIT_NVAR(related_records);
array_init_size(related_records, 1);
phalcon_array_append(&related_records, record, PH_SEPARATE);
phalcon_array_append(&related_records, record, 0);
} else {
PHALCON_CPY_WRT(related_records, record);
}
Expand Down Expand Up @@ -3760,9 +3792,6 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
* Get the rest of intermediate model info
*/
if (zend_is_true(is_through)) {
PHALCON_INIT_NVAR(new_instance);
ZVAL_BOOL(new_instance, 1);

PHALCON_INIT_NVAR(intermediate_model_name);
phalcon_call_method(intermediate_model_name, relation, "getintermediatemodel");

Expand All @@ -3788,7 +3817,30 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
* Assign the value to the
*/
phalcon_call_method_p2_noret(record_after, "writeattribute", referenced_fields, value);
} else {
}

/**
* Save the record and get messages
*/
PHALCON_INIT_NVAR(status);
phalcon_call_method(status, record_after, "save");
if (!zend_is_true(status)) {

/**
* Get the validation messages generated by the referenced model
*/
if (phalcon_mvc_model_get_messages_from_model(this_ptr, record_after, record TSRMLS_CC) == FAILURE) {
RETURN_MM();
}

/**
* Rollback the implicit transaction
*/
phalcon_call_method_p1_noret(connection, "rollback", nesting);
RETURN_MM_FALSE;
}

if (zend_is_true(is_through)) {
/**
* Create a new instance of the intermediate model
*/
Expand Down Expand Up @@ -3821,30 +3873,10 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
/**
* Get the validation messages generated by the referenced model
*/
PHALCON_INIT_NVAR(messages);
phalcon_call_method(messages, intermediate_model, "getmessages");

phalcon_is_iterable(messages, &ah2, &hp2, 0, 0);

while (zend_hash_get_current_data_ex(ah2, (void**) &hd, &hp2) == SUCCESS) {

PHALCON_GET_HVALUE(message);

/**
* Set the related model
*/
if (Z_TYPE_P(message) == IS_OBJECT) {
phalcon_call_method_p1_noret(message, "setmodel", record);
}

/**
* Appends the messages to the current model
*/
phalcon_call_method_p1_noret(this_ptr, "appendmessage", message);

zend_hash_move_forward_ex(ah2, &hp2);
if (phalcon_mvc_model_get_messages_from_model(this_ptr, intermediate_model, record TSRMLS_CC) == FAILURE) {
RETURN_MM();
}

/**
* Rollback the implicit transaction
*/
Expand All @@ -3853,47 +3885,6 @@ PHP_METHOD(Phalcon_Mvc_Model, _postSaveRelatedRecords){
}
}

/**
* Save the record and get messages
*/
PHALCON_INIT_NVAR(status);
phalcon_call_method(status, record_after, "save");
if (!zend_is_true(status)) {

/**
* Get the validation messages generated by the referenced model
*/
PHALCON_INIT_NVAR(messages);
phalcon_call_method(messages, record_after, "getmessages");

phalcon_is_iterable(messages, &ah3, &hp3, 0, 0);

while (zend_hash_get_current_data_ex(ah3, (void**) &hd, &hp3) == SUCCESS) {

PHALCON_GET_HVALUE(message);

/**
* Set the related model
*/
if (Z_TYPE_P(message) == IS_OBJECT) {
phalcon_call_method_p1_noret(message, "setmodel", record);
}

/**
* Appends the messages to the current model
*/
phalcon_call_method_p1_noret(this_ptr, "appendmessage", message);

zend_hash_move_forward_ex(ah3, &hp3);
}

/**
* Rollback the implicit transaction
*/
phalcon_call_method_p1_noret(connection, "rollback", nesting);
RETURN_MM_FALSE;
}

zend_hash_move_forward_ex(ah1, &hp1);
}

Expand Down Expand Up @@ -4056,8 +4047,8 @@ PHP_METHOD(Phalcon_Mvc_Model, save){
if (zend_is_true(schema)) {
PHALCON_INIT_VAR(table);
array_init_size(table, 2);
phalcon_array_append(&table, schema, PH_SEPARATE);
phalcon_array_append(&table, source, PH_SEPARATE);
phalcon_array_append(&table, schema, 0);
phalcon_array_append(&table, source, 0);
} else {
PHALCON_CPY_WRT(table, source);
}
Expand Down
16 changes: 11 additions & 5 deletions ext/mvc/model/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Manager, getLastInitialized){
PHP_METHOD(Phalcon_Mvc_Model_Manager, load){

zval *model_name, *new_instance = NULL, *initialized;
zval *lowercased, *model, *cloned, *dependency_injector;
zval *lowercased, *model, *dependency_injector;
zval *exception_message;
zend_class_entry *ce0;

Expand All @@ -344,11 +344,17 @@ PHP_METHOD(Phalcon_Mvc_Model_Manager, load){
PHALCON_OBS_VAR(model);
phalcon_array_fetch(&model, initialized, lowercased, PH_NOISY);
if (zend_is_true(new_instance)) {
PHALCON_INIT_VAR(cloned);
if (phalcon_clone(cloned, model TSRMLS_CC) == FAILURE) {
return;
PHALCON_OBS_VAR(dependency_injector);
phalcon_read_property_this(&dependency_injector, this_ptr, SL("_dependencyInjector"), PH_NOISY_CC);

ce0 = Z_OBJCE_P(model);
object_init_ex(return_value, ce0);

if (phalcon_has_constructor(return_value TSRMLS_CC)) {
phalcon_call_method_p2_noret(return_value, "__construct", dependency_injector, this_ptr);
}
RETURN_CCTOR(cloned);

RETURN_MM();
}

RETURN_CCTOR(model);
Expand Down
Loading