Skip to content

[PHP 8.0.25] Function JIT may skip implicit type conversion in some cases, causing an error #9885

@mszabo-wikia

Description

@mszabo-wikia

Description

Hello,

We observed that the following code throws a TypeError when function JIT is enabled:

<?php
class ContentReviewLiveRevisionStorage implements LiveRevisionStorage {
	private const CURRENT_REVIEWED_REVISIONS_TABLE = 'current_reviewed_revisions';

	private $lb;

	public function __construct( ILoadBalancer $lb ) {
		$this->lb = $lb;
	}

	public function getRevisionID( int $wikiId, int $pageId ): ?int {
		$dbr = $this->lb->getConnection( DB_REPLICA );

		$revision = $dbr->selectField(
			self::CURRENT_REVIEWED_REVISIONS_TABLE,
			'revision_id',
			[
				'wiki_id' => $wikiId,
				'page_id' => $pageId,
			]
		);

		return $revision === false ? null : $revision;
	}
}

selectField in this context ultimately ends up calling mysqli::query and mysqli::fetch_row, then returns the first element from the result row via reset().[1]

Due to the data types in the table, $revision will then either be a numeric string, or false. Thus, it should be implicitly convertible to int if it is a numeric string, since strict types are not enabled here—but with function JIT, this method instead throws:

TypeError from line 28 of /extensions/fandom/FandomIncludes/src/ResourceLoader/Storage/ContentReviewLiveRevisionStorage.php: Fandom\Includes\ResourceLoader\Storage\ContentReviewLiveRevisionStorage::getRevisionID(): Return value must be of type ?int, string returned

This error does not occur with tracing JIT.

I attempted to create a reproduction class that would do something similar (query a table via mysqli, fetch the first item of a result row using reset() and return $value === false ? null : $value from a method declared to return ?int), then invoked this in a loop. Unfortunately I was unable to reproduce the error with the synthetic attempt. I will update this issue if I do manage to somehow create a consistent reproducer.

Thanks in advance!


[1] https://github.com/wikimedia/mediawiki/blob/e9f9d892ab4cb5f8befc9e2b6753c97e26c2bb46/includes/libs/rdbms/database/Database.php#L1839

PHP Version

PHP 8.0.25

Opcache config

opcache.memory_consumption=512;
opcache.interned_strings_buffer=64;
opcache.max_accelerated_files=20000;
opcache.validate_timestamps=0;
opcache.jit=function
opcache.jit_buffer_size=128M

Operating System

Debian Bullseye-based container image on Ubuntu Bionic guest

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions