8000 [VarDumper] Fix FFI caster test · symfony/symfony@8594b2f · GitHub
[go: up one dir, main page]

Skip to content

Commit 8594b2f

Browse files
[VarDumper] Fix FFI caster test
1 parent 7b53770 commit 8594b2f

File tree

2 files changed

+14
-18
lines changed

2 files changed

+14
-18
lines changed

src/Symfony/Component/VarDumper/Caster/FFICaster.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,21 @@ private static function castFFIPointer(Stub $stub, CType $type, ?CData $data = n
115115
private static function castFFIStringValue(CData $data): string|CutStub
116116
{
117117
$result = [];
118+
$ffi = \FFI::cdef(<<<C
119+
size_t zend_get_page_size(void);
120+
C);
118121

119-
for ($i = 0; $i < self::MAX_STRING_LENGTH; ++$i) {
122+
$pageSize = $ffi->zend_get_page_size();
123+
124+
// get cdata address
125+
$start = $ffi->cast('uintptr_t', $ffi->cast('char*', $data))->cdata;
126+
// accessing memory in the same page as $start is safe
127+
$max = min(self::MAX_STRING_LENGTH, ($start | ($pageSize - 1)) - $start);
128+
129+
for ($i = 0; $i < $max; ++$i) {
120130
$result[$i] = $data[$i];
121131

122-
if ("\0" === $result[$i]) {
132+
if ("\0" === $data[$i]) {
123133
return implode('', $result);
124134
}
125135
}

src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\VarDumper\Tests\Caster;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use Symfony\Component\VarDumper\Caster\FFICaster;
1615
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
1716

1817
/**
@@ -191,34 +190,21 @@ public function testCastCuttedPointerToChar()
191190
PHP, $pointer);
192191
}
193192

194-
/**
195-
* It is worth noting that such a test can cause SIGSEGV, as it breaks
196-
* into "foreign" memory. However, this is only theoretical, since
197-
* memory is allocated within the PHP process and almost always "garbage
198-
* data" will be read from the PHP process itself.
199-
*
200-
* If this test fails for some reason, please report it: We may have to
201-
* disable the dumping of strings ("char*") feature in VarDumper.
202-
*
203-
* @see FFICaster::castFFIStringValue()
204-
*/
205193
public function testCastNonTrailingCharPointer()
206194
{
207195
$actualMessage = 'Hello World!';
208196
$actualLength = \strlen($actualMessage);
209197

210-
$string = \FFI::cdef()->new('char['.$actualLength.']');
198+
$string = \FFI::cdef()->new('char['.($actualLength + 1).']');
211199
$pointer = \FFI::addr($string[0]);
212-
213200
\FFI::memcpy($pointer, $actualMessage, $actualLength);
214201

215-
// Remove automatically addition of the trailing "\0" and remove trailing "\0"
216202
$pointer = \FFI::cdef()->cast('char*', \FFI::cdef()->cast('void*', $pointer));
217203
$pointer[$actualLength] = "\x01";
218204

219205
$this->assertDumpMatchesFormat(<<<PHP
220206
FFI\CData<char*> size 8 align 8 {
221-
cdata: "$actualMessage%s"
207+
cdata: %A"$actualMessage%s"
222208
}
223209
PHP, $pointer);
224210
}

0 commit comments

Comments
 (0)
0