Issues with zend_test's `zend_call_method()`

Ouverte
#25,405 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
47/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
c, php
Domaine
backend, testing-qa

Piste de recherche

Start by reading the zend_call_method() declaration and its call path through Zend/zend_API.h, Zend/zend_interfaces.c, and ext/zend_test/test.c, which the issue's trace identifies. Reproduce the examples on PHP 8.6-dev and check how non-static methods are handled when no object is supplied. Done means invalid calls are handled safely instead of causing fatal errors, assertions, or a crash.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Bug Extension: zend_test Status: Verified

Discovered while filing #25404 - separate from the missing zend_return_unwrap_ref():

<?php

class Demo {
	public function returnTrue() {
		var_dump($this);
		return true;
	}
}

var_dump(zend_call_method(Demo::class, 'returnTrue'));

reports

Fatal error: Uncaught Error: Using $this when not in object context in /var/www/html/test.php:5
Stack trace:
#0 [internal function]: Demo::returnTrue()
#1 /var/www/html/test.php(10): zend_call_method('Demo', 'returnTrue')
#2 {main}
  thrown in /var/www/html/test.php on line 5

it looks like the claim at
https://github.com/php/php-src/blob/0dbc4a7953a8aca38d0cf04fa4fb4ac076f00419/Zend/zend_API.h#L921-L922
that the function must be a free function or static isn't validated anywhere. Having this wrong error message is the nicest of the existing issues:

<?php

class Demo {
	public mixed $v = true;
	public function &returnsRef() { return $this->v; }
}

var_dump(zend_call_method(Demo::class, 'returnsRef'));

results in

php: /usr/src/php86/Zend/zend_execute.c:3619: void zend_fetch_property_address(zval *, const zval *, uint32_t, const zval *, uint32_t, void **, int, uint32_t, zend_property_info **, const zend_op *, zend_execute_data *): Assertion `((intptr_t)(prop_offset) < 0)' failed.
Aborted (core dumped)

and

<?php

class Demo {
	public mixed $v = true;
	public function returnsProp() { return $this->v; }
}

var_dump(zend_call_method(Demo::class, 'returnsProp'));

results in

php: Zend/zend_vm_execute.h:33374: const zend_op *ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(zend_execute_data *, const zend_op *): Assertion `((intptr_t)(prop_offset) < 0)' failed.
Aborted (core dumped)

and

<?php

class Demo {
	public function callsMethod() { return $this->method(); }
	public function method() { return 5; }
}

var_dump(zend_call_method(Demo::class, 'callsMethod'));

results in

AddressSanitizer:DEADLYSIGNAL
=================================================================
==7243==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000004 (pc 0x558b6eead9b7 bp 0x7ffd89cf4290 sp 0x7ffd89cf3fa0 T0)
==7243==The signal is caused by a READ memory access.
==7243==Hint: address points to the zero page.
    #0 0x558b6eead9b7 in ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER /usr/src/php86/Zend/zend_vm_execute.h:34430:6
    #1 0x558b6ed7ad12 in execute_ex /usr/src/php86/Zend/zend_vm_execute.h:110653:12
    #2 0x558b6ed5384f in zend_call_function /usr/src/php86/Zend/zend_execute_API.c:1082:3
    #3 0x558b6ed5613e in zend_call_known_function_ex /usr/src/php86/Zend/zend_execute_API.c:1187:23
    #4 0x558b6f0588a3 in zend_call_known_function /usr/src/php86/Zend/zend_API.h:930:2
    #5 0x558b6f0587b9 in zend_call_method /usr/src/php86/Zend/zend_interfaces.c:82:2
    #6 0x558b6e95ca0b in zif_zend_call_method /usr/src/php86/ext/zend_test/test.c:1106:2
    #7 0x558b6eee71f1 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /usr/src/php86/Zend/zend_vm_execute.h:1393:2
    #8 0x558b6ed7ad12 in execute_ex /usr/src/php86/Zend/zend_vm_execute.h:110653:12
    #9 0x558b6ed7b6fb in zend_execute /usr/src/php86/Zend/zend_vm_execute.h:116091:2
    #10 0x558b6f18abb0 in zend_execute_script /usr/src/php86/Zend/zend.c:1984:3
    #11 0x558b6e981a46 in php_execute_script_ex /usr/src/php86/main/main.c:2657:13
    #12 0x558b6e981fb8 in php_execute_script /usr/src/php86/main/main.c:2697:9
    #13 0x558b6f1929ca in do_cli /usr/src/php86/sapi/cli/php_cli.c:944:5
    #14 0x558b6f18f93d in do_php_cli /usr/src/php86/sapi/cli/php_cli.c:1361:18
    #15 0x558b6f18ebc1 in main /usr/src/php86/sapi/cli/php_cli_main.c:18:9
    #16 0x7f3639846249 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #17 0x7f3639846304 in __libc_start_main csu/../csu/libc-start.c:360:3
    #18 0x558b6d206e70 in _start (/usr/src/php86/sapi/cli/php+0x806e70) (BuildId: 9f1f4d5e7ed941691028bbb54bd03a466bbdab55)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/src/php86/Zend/zend_vm_execute.h:34430:6 in ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER
==7243==ABORTING

testing against PHP 8.6-dev, 0dbc4a7953a8aca38d0cf04fa4fb4ac076f00419

Langage dominant
C
Étoiles
41.8k
Forks
8.5k
Merge moyen
2 j 13 h
PR mergées (30 j)
145

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de php/php-src

Toutes les issues de php/php-src

Issues similaires

Plus d'issues C

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.