Issues with zend_test's `zend_call_method()`

Aperta
#25,405 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
47/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
c, php

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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

Lingua principale
C
Stelle
41.8k
Fork
8.5k
Merge medio
2g 13h
PR unite (30g)
145

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di php/php-src

Tutte le issue di php/php-src

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.