Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion src/Type/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,19 @@ class ObjectType implements TypeWithClassName, SubtractableType
use UndecidedComparisonTypeTrait;
use NonGeneralizableTypeTrait;

private const EXTRA_OFFSET_CLASSES = ['SimpleXMLElement', 'DOMNodeList', 'Threaded'];
private const EXTRA_OFFSET_CLASSES = [
'DOMNamedNodeMap', // Only read and existence
'Dom\NamedNodeMap', // Only read and existence
'DOMNodeList', // Only read and existence
'Dom\NodeList', // Only read and existence
'Dom\HTMLCollection', // Only read and existence
'Dom\DtdNamedNodeMap', // Only read and existence
'PDORow', // Only read and existence
'ResourceBundle', // Only read
'FFI\CData', // Very funky and weird
'SimpleXMLElement',
'Threaded',
];

private ?Type $subtractedType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -898,4 +898,30 @@ public function testBug2634(): void
$this->analyse([__DIR__ . '/data/bug-2634.php'], []);
}

public function testInternalClassesWithOverloadedOffsetAccess(): void
{
$this->analyse([__DIR__ . '/data/internal-classes-overload-offset-access.php'], []);
}

public function testInternalClassesWithOverloadedOffsetAccess84(): void
{
if (PHP_VERSION_ID < 80400) {
$this->markTestSkipped('Test requires PHP 8.4.');
}
$this->analyse([__DIR__ . '/data/internal-classes-overload-offset-access-php84.php'], []);
}

public function testInternalClassesWithOverloadedOffsetAccessInvalid(): void
{
$this->analyse([__DIR__ . '/data/internal-classes-overload-offset-access-invalid.php'], []);
}

public function testInternalClassesWithOverloadedOffsetAccessInvalid84(): void
{
if (PHP_VERSION_ID < 80400) {
$this->markTestSkipped('Test requires PHP 8.4.');
}
$this->analyse([__DIR__ . '/data/internal-classes-overload-offset-access-invalid-php84.php'], []);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* All of these offset accesses are invalid
* ++ and -- are also disallowed in general are they operate "by ref"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* ++ and -- are also disallowed in general are they operate "by ref"
* ++ and -- are also disallowed in general as they operate "by ref"

*/
namespace InternalClassesOverloadOffsetAccessInvalid\Php84;

function test1(\DOMNamedNodeMap $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test2(\Dom\NamedNodeMap $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test3(\DOMNodeList $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test4(\Dom\NodeList $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test5(\Dom\HTMLCollection $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test6(\Dom\DtdNamedNodeMap $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test7(\PDORow $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test8(\ResourceBundle $v): void
{
if ($v[0]) {
var_dump($v[0]);
}
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
var_dump($v['name']);
var_dump($v[0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/**
* All of these offset accesses are invalid
* ++ and -- are also disallowed in general are they operate "by ref"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* ++ and -- are also disallowed in general are they operate "by ref"
* ++ and -- are also disallowed in general as they operate "by ref"

*/
namespace InternalClassesOverloadOffsetAccessInvalid;

function test1(\DOMNamedNodeMap $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test3(\DOMNodeList $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test7(\PDORow $v): void
{
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
}

function test8(\ResourceBundle $v): void
{
if ($v[0]) {
var_dump($v[0]);
}
$v[] = 'append';
$v[0] = 'update';
$v[0] .= ' and again';
$r1 = &$v[0];
unset($v[0]);
var_dump($r1);
var_dump($v['name']);
var_dump($v[0]);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace InternalClassesOverloadOffsetAccess\Php84;

function test1(\DOMNamedNodeMap $v): void
{
if ($v['attribute_name']) {
var_dump($v['attribute_name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test2(\Dom\NamedNodeMap $v): void
{
if ($v['attribute_name']) {
var_dump($v['attribute_name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test3(\DOMNodeList $v): void
{
if ($v[0]) {
var_dump($v[0]);
}
}

function test4(\Dom\NodeList $v): void
{
//var_dump($v['attribute_name']);
if ($v[0]) {
var_dump($v[0]);
}
}

function test5(\Dom\HTMLCollection $v): void
{
if ($v['name']) {
var_dump($v['name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test6(\Dom\DtdNamedNodeMap $v): void
{
if ($v['name']) {
var_dump($v['name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test7(\PDORow $v): void
{
if ($v['name']) {
var_dump($v['name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test8(\ResourceBundle $v): void
{
var_dump($v['name']);
var_dump($v[0]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace InternalClassesOverloadOffsetAccess;

function test1(\DOMNamedNodeMap $v): void
{
if ($v['attribute_name']) {
var_dump($v['attribute_name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test3(\DOMNodeList $v): void
{
if ($v[0]) {
var_dump($v[0]);
}
}

function test7(\PDORow $v): void
{
if ($v['name']) {
var_dump($v['name']);
}
if ($v[0]) {
var_dump($v[0]);
}
}

function test8(\ResourceBundle $v): void
{
var_dump($v['name']);
var_dump($v[0]);
}

Loading