Magento2: setup:di:compile breaks on 0 indexed object arrays

Created on 6 Mar 2017  路  3Comments  路  Source: magento/magento2

Array arguments defined containing 0-indexed object items break setup:di:compile with the following exception:

  [Exception]                                                                                                                                                            
  Warning: ltrim() expects parameter 1 to be string, array given in setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/BackslashTrim.php on line 61

A sample di.xml breaking down:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="SomeType" type="\Magento\Framework\DataObject">
        <arguments>
            <argument name="data" xsi:type="array">
                <item name="0" xsi:type="object">\Magento\Framework\DataObject</item>
            </argument>
        </arguments>
    </virtualType>
</config>

NOTE the <item name="0" xsi:type="object">SomeInterface</item> which is a 0-indexed object item referring to an interface.

Normally the code should not be executed on array because lines 65-67 trigger a recursive call on array values. However ltrim can be called on array if the condition in_array($key, ['_i_', '_ins_']) evaluates to true and $value is array. This does evaluate to true for $key = 0, which can happen when resolving array parameters. Surprisingly expression in_array(0, ['_i_', '_ins_']) evaluates to true, because each value in array ['_i_', '_ins_'] will be converted to integer when the needle is of type integer. 0 is therefore always is in ['_i_', '_ins_'].

With the sample di.xml the code will eventually be called with:

>> print_r($argument);
Array
(
    [0] => Array
        (
            [_i_] => \Magento\Framework\DataObject
        )

)

>> print_r($key);
0

Which causes the crash.

Preconditions

  1. Magento 2.1.4
  2. PHP 7.0.15

Steps to reproduce

  1. Insert virtual attribute declaration from sample di.xml into any module.
  2. execute setup:di:compile

Expected result

  1. Dependencies are compiled

Actual result

  [Exception]                                                                                                                                                            
  Warning: ltrim() expects parameter 1 to be string, array given in setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/BackslashTrim.php on line 61
Fixed in 2.2.x Confirmed Format is valid Reproduced on 2.1.x bug report

Most helpful comment

@yariksheptykin, thank you for your report.
The issue is already fixed in 2.2.3

All 3 comments

I had this same problem:

<type name="VENDOR\MODULE\Model\Test">
    <arguments>
        <argument name="factories"  xsi:type="array">
            <item name="0" xsi:type="object">VENDOR\MODULE\Model\Somemodel</item>
            <item name="1" xsi:type="object">VENDOR\MODULE\Model\OtherModel</item>
        </argument>
    </arguments>
</type>

I needed to change enumeration on array starting from 1 instead of 0 to fix it.
Magento 2.1.6

@yariksheptykin, thank you for your report.
The issue is already fixed in 2.2.3

@magento-engcom-team If you point me to the right commits I can create a backport for 2.1. Why do you close issues when they're not fixed in their original branch?

Was this page helpful?
0 / 5 - 0 ratings