Skip to content

Commit b7151b1

Browse files
committed
Merge branch '0.11.x' into 0.12.x
2 parents cb38549 + 83396ae commit b7151b1

File tree

23 files changed

+667
-236
lines changed

23 files changed

+667
-236
lines changed

.github/workflows/phpunit.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ jobs:
3434
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
3535
restore-keys: ${{ runner.os }}-composer-
3636

37+
- name: Cache Docker images
38+
uses: ScribeMD/[email protected]
39+
with:
40+
key: docker-${{ runner.os }}-${{ hashFiles('Dockerfile-dev','tests/TargetPhpVmProvider.php') }}
41+
3742
- name: Validate composer.json and composer.lock
3843
run: composer validate
3944

@@ -49,7 +54,10 @@ jobs:
4954
- name: Run test suite
5055
run: |
5156
mkdir -p build/logs
52-
./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
57+
composer test-for-ci
58+
59+
- name: Fix absolute paths in the coverage report
60+
run: sed -i "s|<file name=\"/app/|<file name=\"`pwd`/|g" build/logs/clover.xml
5361

5462
- name: Send to coveralls
5563
env:

Dockerfile-dev

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM php:8.1-cli
2+
3+
RUN apt-get update && apt-get install -y \
4+
libffi-dev \
5+
libzip-dev \
6+
&& docker-php-ext-install ffi \
7+
&& docker-php-ext-install pcntl \
8+
&& docker-php-ext-install zip \
9+
&& pecl install pcov \
10+
&& docker-php-ext-enable pcov \
11+
&& rm -rf /var/lib/apt/lists/*
12+
13+
RUN apt-get update -y \
14+
&& apt-get install -y ca-certificates curl gnupg \
15+
&& install -m 0755 -d /etc/apt/keyrings \
16+
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
17+
&& chmod a+r /etc/apt/keyrings/docker.gpg \
18+
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
19+
| tee /etc/apt/sources.list.d/docker.list > /dev/null \
20+
&& apt-get update -y \
21+
&& apt-get install -y docker-ce-cli \
22+
&& rm -rf /var/lib/apt/lists/*
23+
24+
COPY --from=composer /usr/bin/composer /usr/bin/composer
25+
26+
WORKDIR /app
27+
COPY . .
28+
29+
RUN composer install
30+
31+
CMD ["php", "vendor/bin/phpunit", "--colors=always", "--testdox", "--coverage-text", "--coverage-clover=coverage.xml", "--coverage-html=coverage"]

composer.json

+9-2
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,22 @@
4848
},
4949
"autoload-dev": {
5050
"psr-4": {
51-
"Reli\\": "tests"
51+
"Reli\\": "tests",
52+
"Reli\\Command\\": "tests/Command/CommandEnumeratorTestData"
5253
}
5354
},
5455
"bin": [
5556
"reli"
5657
],
5758
"scripts": {
5859
"test": [
59-
"phpunit"
60+
"docker-compose run reli-test"
61+
],
62+
"test-with-coverage": [
63+
"docker-compose run reli-test-with-coverage"
64+
],
65+
"test-for-ci": [
66+
"docker-compose run reli-test-for-ci"
6067
],
6168
"psalm": [
6269
"psalm.phar"

docker-compose.yml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
version: '3.9'
2+
services:
3+
reli-test:
4+
build:
5+
context: .
6+
dockerfile: Dockerfile-dev
7+
pid: "host"
8+
cap_add:
9+
- SYS_PTRACE
10+
security_opt:
11+
- seccomp:unconfined
12+
volumes:
13+
- .:/app
14+
- /var/run/docker.sock:/var/run/docker.sock
15+
- /tmp/reli-test:/tmp/reli-test
16+
container_name: reli-test
17+
command: ["vendor/bin/phpunit" , "--colors=always", "--testdox"]
18+
reli-test-with-coverage:
19+
build:
20+
context: .
21+
dockerfile: Dockerfile-dev
22+
pid: "host"
23+
cap_add:
24+
- SYS_PTRACE
25+
security_opt:
26+
- seccomp:unconfined
27+
volumes:
28+
- .:/app
29+
- /var/run/docker.sock:/var/run/docker.sock
30+
- /tmp/reli-test:/tmp/reli-test
31+
- ./build:/app/build
32+
container_name: reli-test
33+
command: ["vendor/bin/phpunit" , "--colors=always", "--testdox", "--coverage-clover", "build/logs/clover.xml"]
34+
reli-test-for-ci:
35+
build:
36+
context: .
37+
dockerfile: Dockerfile-dev
38+
pid: "host"
39+
cap_add:
40+
- SYS_PTRACE
41+
security_opt:
42+
- seccomp:unconfined
43+
volumes:
44+
- .:/app
45+
- /var/run/docker.sock:/var/run/docker.sock
46+
- /tmp/reli-test:/tmp/reli-test
47+
- ./build:/app/build
48+
container_name: reli-test
49+
command: ["vendor/bin/phpunit" , "--coverage-clover", "build/logs/clover.xml"]

src/Lib/PhpInternals/Headers/v70.h

+11
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ struct _zend_resource {
167167
void *ptr;
168168
};
169169

170+
// zend_compile.h
171+
typedef struct _zend_property_info {
172+
uint32_t offset; /* property offset for object properties or
173+
property index for static properties */
174+
uint32_t flags;
175+
zend_string *name;
176+
zend_string *doc_comment;
177+
zend_class_entry *ce;
178+
} zend_property_info;
179+
180+
// zend_types.h
170181
struct _zend_reference {
171182
zend_refcounted_h gc;
172183
zval val;

src/Lib/PhpInternals/Headers/v71.h

+11
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,17 @@ struct _zend_resource {
169169
void *ptr;
170170
};
171171

172+
// zend_compile.h
173+
typedef struct _zend_property_info {
174+
uint32_t offset; /* property offset for object properties or
175+
property index for static properties */
176+
uint32_t flags;
177+
zend_string *name;
178+
zend_string *doc_comment;
179+
zend_class_entry *ce;
180+
} zend_property_info;
181+
182+
// zend_types.h
172183
struct _zend_reference {
173184
zend_refcounted_h gc;
174185
zval val;

src/Lib/PhpInternals/Headers/v72.h

+11
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,17 @@ struct _zend_resource {
171171

172172
typedef uintptr_t zend_type;
173173

174+
// zend_compile.h
175+
typedef struct _zend_property_info {
176+
uint32_t offset; /* property offset for object properties or
177+
property index for static properties */
178+
uint32_t flags;
179+
zend_string *name;
180+
zend_string *doc_comment;
181+
zend_class_entry *ce;
182+
} zend_property_info;
183+
184+
// zend_types.h
174185
struct _zend_reference {
175186
zend_refcounted_h gc;
176187
zval val;

src/Lib/PhpInternals/Headers/v73.h

+11
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ struct _zend_resource {
168168

169169
typedef uintptr_t zend_type;
170170

171+
// zend_compile.h
172+
typedef struct _zend_property_info {
173+
uint32_t offset; /* property offset for object properties or
174+
property index for static properties */
175+
uint32_t flags;
176+
zend_string *name;
177+
zend_string *doc_comment;
178+
zend_class_entry *ce;
179+
} zend_property_info;
180+
181+
// zend_types.h
171182
struct _zend_reference {
172183
zend_refcounted_h gc;
173184
zval val;

src/Lib/PhpInternals/Types/Zend/V74/ZendArray.php

+31
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,37 @@ public function __get(string $field_name): mixed
3333
};
3434
}
3535

36+
public function dumpFlags(): string
37+
{
38+
$flags = $this->flags;
39+
$flag_names = [];
40+
if ($flags & ((1 << 0) | (1 << 1))) {
41+
$flag_names[] = 'HASH_FLAG_CONSISTENCY';
42+
}
43+
if ($flags & (1 << 2)) {
44+
$flag_names[] = 'HASH_FLAG_PACKED';
45+
}
46+
if ($flags & (1 << 3)) {
47+
$flag_names[] = 'HASH_FLAG_UNINITIALIZED';
48+
}
49+
if ($flags & (1 << 4)) {
50+
$flag_names[] = 'HASH_FLAG_STATIC_KEYS';
51+
}
52+
if ($flags & (1 << 5)) {
53+
$flag_names[] = 'HASH_FLAG_HAS_EMPTY_IND';
54+
}
55+
if ($flags & (1 << 6)) {
56+
$flag_names[] = 'HASH_FLAG_ALLOW_COW_VIOLATION';
57+
}
58+
59+
return implode(' | ', $flag_names);
60+
}
61+
62+
public function isUninitialized(): bool
63+
{
64+
return (bool)($this->flags & (1 << 3));
65+
}
66+
3667
public function getDataSize(): int
3768
{
3869
return $this->nTableSize * self::BUCKET_SIZE_IN_BYTES;

src/Lib/PhpInternals/Types/Zend/ZendArray.php

+1
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ public static function fromCastedCData(CastedCData $casted_cdata, Pointer $point
351351
return new static($casted_cdata, $pointer);
352352
}
353353

354+
/** @return Pointer<ZendArray> */
354355
public function getPointer(): Pointer
355356
{
356357
return $this->pointer;

src/Lib/PhpInternals/Types/Zend/ZendClassEntry.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ public function iteratePropertyInfo(
198198
Dereferencer $dereferencer,
199199
ZendTypeReader $type_reader,
200200
): iterable {
201-
foreach ($this->properties_info->getItemIterator($dereferencer) as $name => $item) {
201+
$property_info = $dereferencer->deref($this->properties_info->getPointer());
202+
foreach ($property_info->getItemIterator($dereferencer) as $name => $item) {
202203
$property_info_pointer = $item->value->getAsPointer(
203204
ZendPropertyInfo::class,
204205
$type_reader->sizeOf(ZendPropertyInfo::getCTypeName()),

src/Lib/PhpInternals/Types/Zend/ZendExecuteData.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,9 @@ public function getRootFrame(
259259

260260
public function getVariableTableAddress(): int
261261
{
262-
return $this->pointer->indexedAt(1)->address;
262+
return (int)($this->pointer->address
263+
+ (int)((($this->pointer->size) + 16 - 1) / 16) * 16
264+
);
263265
}
264266

265267
public function getTotalVariablesNum(Dereferencer $dereferencer): int

src/Lib/PhpProcessReader/CallTraceReader/CallTraceReader.php

+44-3
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@
1515

1616
use Reli\Lib\PhpInternals\Opcodes\OpcodeFactory;
1717
use Reli\Lib\PhpInternals\Types\C\RawDouble;
18+
use Reli\Lib\PhpInternals\Types\Zend\Bucket;
1819
use Reli\Lib\PhpInternals\Types\Zend\Opline;
20+
use Reli\Lib\PhpInternals\Types\Zend\ZendArray;
1921
use Reli\Lib\PhpInternals\Types\Zend\ZendCastedTypeProvider;
20-
use Reli\Lib\PhpInternals\Types\Zend\ZendExecuteData;
2122
use Reli\Lib\PhpInternals\Types\Zend\ZendExecutorGlobals;
22-
use Reli\Lib\PhpInternals\Types\Zend\ZendFunction;
2323
use Reli\Lib\PhpInternals\Types\Zend\ZendOp;
24+
use Reli\Lib\PhpInternals\Types\Zend\Zval;
2425
use Reli\Lib\PhpInternals\ZendTypeReader;
2526
use Reli\Lib\PhpInternals\ZendTypeReaderCreator;
2627
use Reli\Lib\Process\MemoryReader\MemoryReaderInterface;
2728
use Reli\Lib\Process\MemoryReader\MemoryReaderException;
2829
use Reli\Lib\Process\Pointer\Dereferencer;
30+
use Reli\Lib\Process\Pointer\PointedTypeResolver;
2931
use Reli\Lib\Process\Pointer\Pointer;
3032
use Reli\Lib\Process\Pointer\RemoteProcessDereferencer;
3133
use Reli\Lib\Process\ProcessSpecifier;
@@ -62,7 +64,46 @@ private function getDereferencer(int $pid, string $php_version): Dereferencer
6264
new ProcessSpecifier($pid),
6365
new ZendCastedTypeProvider(
6466
$this->getTypeReader($php_version),
65-
)
67+
),
68+
new class ($php_version) implements PointedTypeResolver {
69+
public function __construct(
70+
private string $php_version,
71+
) {
72+
}
73+
74+
public function resolve(string $type_name): string
75+
{
76+
return match ($this->php_version) {
77+
ZendTypeReader::V70,
78+
ZendTypeReader::V71,
79+
ZendTypeReader::V72 => match ($type_name) {
80+
Bucket::class => \Reli\Lib\PhpInternals\Types\Zend\V70\Bucket::class,
81+
ZendArray::class => \Reli\Lib\PhpInternals\Types\Zend\V70\ZendArray::class,
82+
Zval::class => \Reli\Lib\PhpInternals\Types\Zend\V70\Zval::class,
83+
default => $type_name,
84+
},
85+
ZendTypeReader::V73 => match ($type_name) {
86+
Bucket::class => \Reli\Lib\PhpInternals\Types\Zend\V73\Bucket::class,
87+
ZendArray::class => \Reli\Lib\PhpInternals\Types\Zend\V73\ZendArray::class,
88+
Zval::class => \Reli\Lib\PhpInternals\Types\Zend\V73\Zval::class,
89+
default => $type_name,
90+
},
91+
ZendTypeReader::V74 => match ($type_name) {
92+
Bucket::class => \Reli\Lib\PhpInternals\Types\Zend\V74\Bucket::class,
93+
ZendArray::class => \Reli\Lib\PhpInternals\Types\Zend\V74\ZendArray::class,
94+
Zval::class => \Reli\Lib\PhpInternals\Types\Zend\V74\Zval::class,
95+
default => $type_name,
96+
},
97+
ZendTypeReader::V80,
98+
ZendTypeReader::V81 => match ($type_name) {
99+
ZendArray::class => \Reli\Lib\PhpInternals\Types\Zend\V80\ZendArray::class,
100+
default => $type_name,
101+
},
102+
ZendTypeReader::V82,
103+
ZendTypeReader::V83 => $type_name,
104+
};
105+
}
106+
}
66107
);
67108
}
68109

src/Lib/PhpProcessReader/PhpMemoryReader/MemoryLocation/ZendObjectMemoryLocation.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ public static function fromZendObject(
3939
$class_name = $ce->getClassName($dereferencer);
4040
if ($class_name === \Fiber::class) {
4141
$size = $zend_type_reader->sizeOf('zend_fiber');
42-
} elseif ($class_name === \Closure::class) {
42+
} elseif (
43+
$class_name === \Closure::class
44+
and !$zend_type_reader->isPhpVersionLowerThan(ZendTypeReader::V71)
45+
) {
4346
$size = $zend_type_reader->sizeOf('zend_closure');
4447
} else {
4548
$size = $zend_object->getMemorySize($dereferencer);

src/Lib/PhpProcessReader/PhpMemoryReader/MemoryLocationsCollector.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,10 @@ public function collectZendObject(
10551055

10561056
assert(!is_null($object->ce));
10571057
$class_entry = $dereferencer->deref($object->ce);
1058-
if ($class_entry->getClassName($dereferencer) === 'Closure') {
1058+
if (
1059+
$class_entry->getClassName($dereferencer) === 'Closure'
1060+
and !$zend_type_reader->isPhpVersionLowerThan(ZendTypeReader::V71)
1061+
) {
10591062
$closure_context = $this->collectClosure(
10601063
$dereferencer->deref(
10611064
ZendClosure::getPointerFromZendObjectPointer(
@@ -1636,7 +1639,7 @@ private function collectClassDefinition(
16361639
}
16371640

16381641
$methods_context = $this->collectFunctionTable(
1639-
$class_entry->function_table,
1642+
$dereferencer->deref($class_entry->function_table->getPointer()),
16401643
$map_ptr_base,
16411644
$dereferencer,
16421645
$zend_type_reader,
@@ -1647,7 +1650,7 @@ private function collectClassDefinition(
16471650
$class_definition_context->add('methods', $methods_context);
16481651

16491652
$class_constants_context = $this->collectClassConstantsTable(
1650-
$class_entry->constants_table,
1653+
$dereferencer->deref($class_entry->constants_table->getPointer()),
16511654
$map_ptr_base,
16521655
$dereferencer,
16531656
$zend_type_reader,

tests/Command/CommandEnumeratorTestData/Test1Directory/Test1Command.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
declare(strict_types=1);
1313

14-
namespace Reli\Command\CommandEnumeratorTestData\Test1Directory;
14+
namespace Reli\Command\Test1Directory;
1515

16-
final class Test1Command
16+
use Symfony\Component\Console\Command\Command;
17+
18+
final class Test1Command extends Command
1719
{
1820
}

0 commit comments

Comments
 (0)