fix(generator): ensure all generated C values are returned as strings

- Modified genCValue method to always return string type instead of mixed
- Changed float values to be cast to string in genCValue method
- Updated boolean values to return '1'/'0' strings instead of integers
- Fixed getInternalScalarConstantValue return type to string only
- Added explicit string casting for literal string keys in Translator
- Added comprehensive tests for C value generation ensuring source code strings
- Added comments explaining integer-string array key handling in literalStrings
pull/45/head
韩天峰 3 weeks ago
parent 8dd33c1400
commit 9d1ba7ee7a
  1. 14
      phpunit/src/CompilerBaseApiTest.php
  2. 6
      src/Generator/Utils.php
  3. 2
      src/Parser/ConstantExpressionTrait.php
  4. 5
      src/Translator.php

@ -216,6 +216,20 @@ class CompilerBaseApiTest extends TestCase
$this->assertSame('ZEND_LONG_MIN', $this->invokeMethod('genCValue', PHP_INT_MIN));
}
public function testGeneratedCValuesAreAlwaysSourceCodeStrings(): void
{
$this->assertSame((string) M_E, $this->invokeMethod('genCValue', M_E));
$this->assertSame('1', $this->invokeMethod('genCValue', true));
$this->assertSame('0', $this->invokeMethod('genCValue', false));
$code = $this->invokeMethod(
'parseConstFetch',
new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('M_E'))
);
$this->assertIsString($code);
$this->assertSame((string) M_E, $code);
}
public function testWindowsIntegerLiteralSuffixForInternalConstants(): void
{
$this->setPropertyValue('platform', new Windows());

@ -25,16 +25,16 @@ trait Utils
return $value . $this->getPlatform()->getIntegerLiteralSuffix();
}
protected function genCValue(mixed $value): mixed
protected function genCValue(mixed $value): string
{
if (is_int($value)) {
return $this->genIntegerLiteral($value);
}
if (is_float($value)) {
return $value;
return (string) $value;
}
if (is_bool($value)) {
return $value ? 1 : 0;
return $value ? '1' : '0';
}
if (is_string($value)) {
return $this->genCharPtr($value);

@ -147,7 +147,7 @@ trait ConstantExpressionTrait
return $this->isInternalConstant($name) && is_scalar($this->internalConstants[$name]);
}
protected function getInternalScalarConstantValue(string $name): string|int|float
protected function getInternalScalarConstantValue(string $name): string
{
$value = $this->internalConstants[$name];
if (is_int($value)) {

@ -822,7 +822,10 @@ CODE;
if ($this->literalStrings) {
$code .= Type::STR . ' ' . self::LITERAL_STRINGS . '[] = {' . PHP_EOL;
foreach ($this->literalStrings as $str => $index) {
$code .= Type::STR . '{ZEND_STRL("' . $this->escapeString($str) . '"), true}, // [' . $index . ']' . PHP_EOL;
// PHP converts canonical integer-string array keys (for
// example "0" and "-1") to int. literalStrings only accepts
// strings, so restore the original key type at this boundary.
$code .= Type::STR . '{ZEND_STRL("' . $this->escapeString((string) $str) . '"), true}, // [' . $index . ']' . PHP_EOL;
}
$code .= '};' . PHP_EOL . PHP_EOL;
} else {

Loading…
Cancel
Save