Issues with zend_test's `zend_call_method()`

未关闭
#25,405 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
47/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
c, php

调研方向

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.

由索引模型根据 Issue 内容生成。

描述

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

主要语言
C
星标
41.8k
派生
8.5k
平均合并
2 天 13 小时
30 天内合并 PR
145

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

php/php-src 的其他 Issue

查看 php/php-src 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。