Skip to content
Closed
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
29 changes: 27 additions & 2 deletions lib/JIT/Builtin/OpensslPbkdf2Runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
use PHPLLVM\Value\Function_ as LlvmFunction;

/**
* JIT/AOT openssl_pbkdf2() via HMAC built from {@see __compiler_hash} (#32410).
* JIT/AOT openssl_pbkdf2() via HMAC built from {@see __compiler_hash} (#32410, #32870).
*
* hash() / openssl_digest AOT is green; hash_hmac()/hash_pbkdf2() HashCrypto (HMAC /
* PKCS5_PBKDF2_HMAC) SIGSEGV under AOT. NestedJIT of VmHashNative::hashPbkdf2 also
* SIGSEGVs (#16075). This kernel uses only __compiler_hash + LLVM loops.
*
* Module-local ABI owner (getNamedFunction first): Builtin\Type no longer always-declares
* an empty shell (#32870 / peer #32866) — leftover Type decls mint openssl_pbkdf2.1
* (#31894 / #32122).
*
* php-src: ext/openssl/openssl.c PHP_FUNCTION(openssl_pbkdf2) / PKCS5_PBKDF2_HMAC
*/
final class OpensslPbkdf2Runtime
Expand Down Expand Up @@ -74,12 +78,33 @@ private static function implementIfMissing(Context $context, string $name, calla
return;
}

$fn = $context->lookupFunction($name);
$fn = self::declareAbi($context, $name, $probe);
$emit($context, $fn);
$context->registerFunction($name, $fn);
$context->builder->clearInsertionPosition();
}

private static function declareAbi(Context $context, string $name, ?LlvmFunction $probe): LlvmFunction
{
if (null !== $probe) {
return $probe;
}

$strPtr = $context->getTypeFromString('__string__*');
$i64 = $context->getTypeFromString('int64');
$ft = $context->context->functionType(
$strPtr,
false,
$strPtr,
$strPtr,
$i64,
$i64,
$strPtr
);

return $context->module->addFunction($name, $ft);
}

private static function ensureHex2binFunction(Context $context): void
{
$existing = $context->module->getNamedFunction(self::HEX2BIN_ABI);
Expand Down
17 changes: 5 additions & 12 deletions lib/JIT/Builtin/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -537,18 +537,11 @@ public function register(): void {
);
$fnOpensslDigest = $this->context->module->addFunction('__compiler_openssl_digest', $fntypeOpensslDigest);
$this->context->registerFunction('__compiler_openssl_digest', $fnOpensslDigest);
// openssl_pbkdf2 — HMAC over __compiler_hash (hex) + LLVM hex-decode (#32410)
$fntypeOpensslPbkdf2 = $this->context->context->functionType(
$strPtr,
false,
$strPtr,
$strPtr,
$i64,
$i64,
$strPtr
);
$fnOpensslPbkdf2 = $this->context->module->addFunction('__compiler_openssl_pbkdf2', $fntypeOpensslPbkdf2);
$this->context->registerFunction('__compiler_openssl_pbkdf2', $fnOpensslPbkdf2);
// __compiler_openssl_pbkdf2 always-on shell removed (#32870): NestedJIT/AOT
// bridge is OpensslPbkdf2Runtime (getNamedFunction first; user-script
// openssl_pbkdf2() still ensureLinked from ext/openssl/openssl_pbkdf2.php).
// Leftover Type empty decls vs Runtime ABI drift mint openssl_pbkdf2.1
// (#31894 / #32122).
// __compiler_openssl_get_cipher_methods / __compiler_openssl_get_md_methods always-on
// shells removed (#32451): user-script openssl_get_*_methods() stays
// JitOpensslMethods / OpensslMethodsJitHelper / OpensslCipherRegistry.
Expand Down
2 changes: 1 addition & 1 deletion test/unit/TypeDeadOpensslMethodsAbiRuntimeShrinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function testTypeBuiltinDropsLeftoverAlwaysOnOpensslMethodsAbis(): void
}
$this->assertStringContainsString("addFunction('exit'", $type);
$this->assertStringContainsString("addFunction('abort'", $type);
$this->assertStringContainsString("registerFunction('__compiler_openssl_pbkdf2'", $type);
$this->assertStringContainsString("registerFunction('__compiler_convert_uuencode'", $type);
$this->assertStringContainsString("registerFunction('__compiler_openssl_digest'", $type);
}

Expand Down
78 changes: 78 additions & 0 deletions test/unit/TypeDeadOpensslPbkdf2AbiRuntimeShrinkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace PHPCompiler\Test\Unit;

use PHPUnit\Framework\TestCase;

/**
* Drop leftover always-on openssl_pbkdf2 ABI shell from Builtin\Type (#32870).
*
* NestedJIT/AOT bridge stays OpensslPbkdf2Runtime.
* Runtime owner declares module-locally (getNamedFunction first) so leftover Type
* empty decls cannot mint openssl_pbkdf2.1 (#31894 / #32122).
*/
final class TypeDeadOpensslPbkdf2AbiRuntimeShrinkTest extends TestCase
{
/** @return list<string> */
private function droppedAbis(): array
{
return [
'__compiler_openssl_pbkdf2',
];
}

public function testTypeBuiltinDropsLeftoverAlwaysOnOpensslPbkdf2Abi(): void
{
$type = (string) file_get_contents(__DIR__.'/../../lib/JIT/Builtin/Type.php');
$this->assertStringContainsString('#32870', $type);
foreach ($this->droppedAbis() as $sym) {
$this->assertDoesNotMatchRegularExpression(
'/addFunction\(\s*[\'"]'.preg_quote($sym, '/').'[\'"]/',
$type,
"Builtin\\Type must not always-declare {$sym} (#32870)"
);
$this->assertStringNotContainsString(
"registerFunction('{$sym}'",
$type,
"Builtin\\Type must not always-register {$sym} (#32870)"
);
}
$this->assertStringContainsString("addFunction('exit'", $type);
$this->assertStringContainsString("addFunction('abort'", $type);
$this->assertStringContainsString("registerFunction('__compiler_convert_uuencode'", $type);
$this->assertStringContainsString('OpensslPbkdf2Runtime', $type);
}

public function testRuntimeOwnerDeclaresOpensslPbkdf2AbiModuleLocally(): void
{
$svc = (string) file_get_contents(__DIR__.'/../../lib/JIT/Builtin/OpensslPbkdf2Runtime.php');
$this->assertStringContainsString('#32870', $svc);
$this->assertStringContainsString('declareAbi(', $svc);
$this->assertStringContainsString('getNamedFunction($name)', $svc);
$this->assertStringContainsString('module->addFunction(', $svc);
$this->assertStringNotContainsString('lookupFunction($name)', $svc);
foreach ($this->droppedAbis() as $sym) {
$this->assertStringContainsString($sym, $svc);
}
}

public function testUserScriptBuiltinStillEnsureLinksOpensslPbkdf2Runtime(): void
{
$src = (string) file_get_contents(__DIR__.'/../../ext/openssl/openssl_pbkdf2.php');
$this->assertStringContainsString('OpensslPbkdf2Runtime::ensureLinked', $src);
}

public function testPhpHelpersRemainForDroppedUserScriptBuiltin(): void
{
$this->assertFileExists(__DIR__.'/../../ext/openssl/openssl_pbkdf2.php');
$this->assertFileExists(__DIR__.'/../../ext/openssl/JitOpensslPbkdf2.php');
$this->assertFileDoesNotExist(
dirname(__DIR__, 2).'/lib/AOT/runtime/openssl_pbkdf2.c'
);
$this->assertFileDoesNotExist(
dirname(__DIR__, 2).'/runtime/openssl_pbkdf2.c'
);
}
}