View Issue Details

IDProjectCategoryView StatusLast Update
0002287XdebugUncategorizedpublic2024-10-04 14:33
Reporterbkdotcom Assigned To 
PrioritynormalSeveritycrashReproducibilityalways
Status newResolutionopen 
PlatformXdebug v3.4.0alpha2-deOSOSXOS Version12.7.6
Summary0002287: zend_mm_heap corrupted in develop mode
Description

Reflecting a class containing new php 8.4 features (property hooks / asymmetric-visibility) with xdebug.mode = develop leads to

zend_mm_heap corrupted
Abort trap: 6

Steps To Reproduce
<?php

/**
 * PHP 8.4 property hooks & asymmetric visibility
 */
class NewFeatures
{
    public protected(set) ?string $name;
    protected private(set) ?int $age;

    // public static array $static = [];

    public ?string $backedGetOnly {
        get => $this->backedGetOnly;
    }

    public ?string $backedSetOnly {
        set (?string $value) {
            $this->backedSetOnly = $value;
        }
    }

    public ?string $backedGetAndSet {
        set (?string $value) {
            $this->backedGetAndSet = $value;
        }

        get => $this->backedGetAndSet;
    }

    public $things = [];

    public string $virtualGetOnly {
        get => \implode(', ', $this->things);
    }

    public string $virtualSetOnly {
        set (string $value) {
            $this->things[] = $value;
        }
    }

    public string $virtualGetAndSet {
        set (string $value) {
            $this->things[] = $value;
        }

        get => \implode(', ', $this->things);
    }
}

$newFeatures = new NewFeatures();

$refObj = new ReflectionObject($newFeatures);
$refProps = $refObj->getProperties();

foreach ($refProps as $refProp) {
    propInfo($refProp, $newFeatures);
}

echo 'the end' . "\n\n";

function propInfo(ReflectionProperty $refProperty, $obj)
{
    $info = array(
        'hooks' => \array_keys($refProperty->getHooks()),
        'isVirtual' => $refProperty->isVirtual(), // at least one hook and none of the hooks reference the property
        'value' => null,
    );
    $isWriteOnly = $info['isVirtual'] && \in_array('get', $info['hooks'], true) === false;
    if ($isWriteOnly) {
        return;
    }
    $refProperty->setAccessible(true);
    if ($refProperty->isInitialized($obj)) {
        try {
            $info['value'] = $refProperty->isStatic() === false && $refProperty->isVirtual() === false
                ? $refProperty->getRawValue($obj)
                : $refProperty->getValue($obj);
        } catch (\Error $e) {
            echo 'Error: ' . $e->getMessage() . "\n";
        }
    }
}
Additional Information

commenting out any one of the properties and the script will complete... some sort of internal buffer issue?!

TagsNo tags attached.
Operating Systemosx
PHP Version8.4-dev

Activities

bkdotcom

2024-09-06 13:21

reporter   ~0007050

sorry about the formatting... I don't see and option to fix/edit it :|

derick

2024-10-04 14:33

administrator   ~0007053

Attachment for reproducing script.

2287.php (2,036 bytes)   
<?php

/**
 * PHP 8.4 property hooks & asymmetric visibility
 */
class NewFeatures
{
    public protected(set) ?string $name;
    protected private(set) ?int $age;

    // public static array $static = [];

    public ?string $backedGetOnly {
        get => $this->backedGetOnly;
    }

    public ?string $backedSetOnly {
        set (?string $value) {
            $this->backedSetOnly = $value;
        }
    }

    public ?string $backedGetAndSet {
        set (?string $value) {
            $this->backedGetAndSet = $value;
        }

        get => $this->backedGetAndSet;
    }

    public $things = [];

    public string $virtualGetOnly {
        get => \implode(', ', $this->things);
    }

    public string $virtualSetOnly {
        set (string $value) {
            $this->things[] = $value;
        }
    }

    public string $virtualGetAndSet {
        set (string $value) {
            $this->things[] = $value;
        }

        get => \implode(', ', $this->things);
    }
}

$newFeatures = new NewFeatures();

$refObj = new ReflectionObject($newFeatures);
$refProps = $refObj->getProperties();

foreach ($refProps as $refProp) {
    propInfo($refProp, $newFeatures);
}

echo 'the end' . "\n\n";

function propInfo(ReflectionProperty $refProperty, $obj)
{
    $info = array(
        'hooks' => \array_keys($refProperty->getHooks()),
        'isVirtual' => $refProperty->isVirtual(), // at least one hook and none of the hooks reference the property
        'value' => null,
    );
    $isWriteOnly = $info['isVirtual'] && \in_array('get', $info['hooks'], true) === false;
    if ($isWriteOnly) {
        return;
    }
    $refProperty->setAccessible(true);
    if ($refProperty->isInitialized($obj)) {
        try {
            $info['value'] = $refProperty->isStatic() === false && $refProperty->isVirtual() === false
                ? $refProperty->getRawValue($obj)
                : $refProperty->getValue($obj);
        } catch (\Error $e) {
            echo 'Error: ' . $e->getMessage() . "\n";
        }
    }
}
2287.php (2,036 bytes)   

Issue History

Date Modified Username Field Change
2024-09-05 21:04 bkdotcom New Issue
2024-09-06 13:21 bkdotcom Note Added: 0007050
2024-10-04 14:32 derick Steps to Reproduce Updated
2024-10-04 14:33 derick Note Added: 0007053
2024-10-04 14:33 derick File Added: 2287.php