Twig icon indicating copy to clipboard operation
Twig copied to clipboard

do not dump callables

Open chx opened this issue 2 years ago • 1 comments

Not all callables can be dumped by var_export.

For example https://github.com/symfony/symfony/issues/46209 but there can be any other issues.

It doesn't add much I believe -- the structure is visible without it. I wish there was a better way but apparently there is not. var_export simply falls into an infinite loop in some cases. PHP does not want to fix this and recommends print_r/var_dump instead: https://github.com/php/php-src/issues/8456

chx avatar Apr 28 '22 22:04 chx

Reproducing this is really , really hard, I wish had a simpler reproduction. But, running this script with bash does work if a PHP with all the sufficient extension is installed (pdo_sqlite is perhaps the only slightly unusual one):

composer create-project drupal/recommended-project twig-3694
cd twig-3694
composer require drush/drush
drush -y si --db-url=sqlite://.test.db minimal
cat > web/bug.php << 'EOD'
<?php

$twig = \Drupal::service('twig');
$string = '{{ foobar }}';
$stream = $twig->tokenize(new \Twig\Source($string, '{# inline_template_start #}'));
$nodes = $twig->parse($stream);
$twig->compile($nodes);
print $nodes;
EOD
drush scr bug.php

Results in infinite [warning] var_export does not handle circular references Node.php:56. It's probably possible to create a more minimal reproduction script but I am not sure what use of that would be -- this demonstrates that sometimes var_export falls into an infinite loop. It's like math, an existence proof should be enough :)

Applying my simple fix and re-running drush scr bug.php results in:

Twig\Node\ModuleNode(index: NULL, embedded_templates: array ()
  body: Twig\Node\BodyNode(
          0: Twig\Node\PrintNode(
               expr: Twig\Node\Expression\FilterExpression(name: 'drupal_escape', type: 'filter', needs_environment: true, needs_context: false, arguments: array (), is_variadic: false
                       node: Twig\Node\CheckToStringNode(
                               expr: Twig\Node\Expression\NameExpression(name: 'foobar', is_defined_test: false, ignore_strict_check: false, always_defined: false)
                             )
                       filter: Twig\Node\Expression\ConstantExpression(value: 'drupal_escape')
                       arguments: Twig\Node\Node(
                                    0: Twig\Node\Expression\ConstantExpression(value: 'html')
                                    1: Twig\Node\Expression\ConstantExpression(value: NULL)
                                    2: Twig\Node\Expression\ConstantExpression(value: true)
                                  )
                     )
             )
        )
  blocks: Twig\Node\Node()
  macros: Twig\Node\Node()
  traits: Twig\Node\Node()
  display_start: Twig\Node\Node()
  display_end: Twig\Node\Node()
  constructor_start: Twig\Node\Node()
  constructor_end: Twig\Node\Node(
                     0: Twig\Node\CheckSecurityCallNode()
                     1: Twig\Node\Node()
                   )
  class_end: Twig\Node\Node(
               0: Twig\Node\CheckSecurityNode()
               1: Twig\Node\Node()
             )
)

chx avatar Apr 28 '22 23:04 chx