Skip to content

[BUG]: Segfault caused in Phalcon\Mvc\Model::toArray #16498

Closed
@FredericSchwarz

Description

Hello everyone,

I noticed a segfault in our Phalcon application which occurs after a call to Phalcon\Mvc\Model::toArray() on a model that doesn't have getters for all of its properties.

Steps to reproduce the behavior:

CREATE TABLE my_model
(
    col1 text null,
    col2 text null,
    col3 text null,
    col4 text null
);
class MyModel extends Model
{
    protected $col1;
    protected $col2;
    protected $col3;
    protected $col4;

    public function initialize(): void
    {
        $this->setSource('my_model');
    }

    public function getCol1()
    {
        return $this->col1;
    }
}
$item = new MyModel([
    'col1' => 'test',
    'col2' => 'test',
    'col3' => 'test',
    'col4' => 'test'
]);

$item->toArray(); // segfault happens at some point after this call

// the actual code here is not important, we just need some
// memory allocations
for($i = 0; $i < 10; $i++) {
    $item->toArray();
}

Expected behavior
The application doesn't segfault.

Details

  • Phalcon version: 5.5.0
  • PHP Version: 8.1.27
  • Operating System: Centos 7
  • Installation type: installing via package manager
  • Zephir version (if any):
  • Server: Nginx (happens also on CLI)

Additional context
The problem seems to be located in this if statement (https://github.com/phalcon/cphalcon/blob/master/phalcon/Mvc/Model.zep#L3324C1-L3330C14):

if method_exists(this, method) {
    let data[attributeField] = this->{method}();
} elseif fetch value, this->{attributeField} {
    let data[attributeField] = value;
} else {
    let data[attributeField] = null;
}

Changing the above code to:

if method_exists(this, method) {
    let data[attributeField] = this->{method}();
} elseif fetch value, this->{attributeField} {
    let data[attributeField] = value;
} else {
    let data[attributeField] = null;
}
let value = null;

fixes the problem.

From looking at the produced C code my guess is that the call to ZEPHIR_OBS_NVAR(&value) introduced by the fetch is causing issues when used in a loop:
(https://github.com/phalcon/cphalcon/blob/master/ext/phalcon/mvc/model.zep.c#L5652C1)

ZEPHIR_OBS_NVAR(&value);
if ((zephir_method_exists(this_ptr, &method)  == SUCCESS)) {
    ZEPHIR_CALL_METHOD_ZVAL(&_18$$22, this_ptr, &method, NULL, 0);
    zephir_check_call_status();
    zephir_array_update_zval(&data, &attributeField, &_18$$22, PH_COPY | PH_SEPARATE);
} else if (zephir_fetch_property_zval(&value, this_ptr, &attributeField, PH_SILENT_CC)) {
    zephir_array_update_zval(&data, &attributeField, &value, PH_COPY | PH_SEPARATE);
} else {
    zephir_array_update_zval(&data, &attributeField, &__$null, PH_COPY | PH_SEPARATE);
}

Hope this helps.

Metadata

Assignees

Labels

5.0The issues we want to solve in the 5.0 releasebugA bug reportstatus: highHigh

Type

No type

Projects

  • Status

    Released

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions