Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

zend_set_local_var() overwrites existing compiled variable (CV) zval without calling zval_ptr_dtor()

Đang mở Phù hợp với người mới
#24,668 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@lazerg đang làm issue này rồi.

Từ ngày 25/10/2026.

  • #24670 của @lazerg — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
82/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c, php
Lĩnh vực
backend

Hướng nghiên cứu

Đọc Zend/zend_execute_API.c, so sánh nhánh biến đã biên dịch của zend_set_local_var() với zend_set_local_var_str() và nhánh bảng ký hiệu. Kiểm tra cách các giá trị zval hiện có được giải phóng trước khi thay thế, sau đó chạy các bài kiểm tra liên quan đến việc gán biến cục bộ và đếm tham chiếu. Công việc hoàn tất khi việc thay thế một biến đã biên dịch có sẵn giá trị giải phóng giá trị trước đó mà không làm ảnh hưởng đến hành vi hiện có.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Bug Status: Needs Triage
Description

In Zend/zend_execute_API.c (lines 1927–1959), when zend_set_local_var(zend_string *name, zval *value, bool force) finds a matching compiled variable (EX_VAR_NUM(str - op_array->vars)), it overwrites *var directly via ZVAL_COPY_VALUE(var, value) without calling zval_ptr_dtor(var) first:

				do {
					if (ZSTR_H(*str) == h &&
					    zend_string_equal_content(*str, name)) {
						zval *var = EX_VAR_NUM(str - op_array->vars);
						ZVAL_COPY_VALUE(var, value);
						return SUCCESS;
					}
					str++;
				} while (str != end);

Compare this with zend_set_local_var_str() immediately below it in Zend/zend_execute_API.c (lines 1978–1987):

				do {
					if (ZSTR_H(*str) == h &&
					    zend_string_equals_cstr(*str, name, len)) {
						zval *var = EX_VAR_NUM(str - op_array->vars);
						zval_ptr_dtor(var);
						ZVAL_COPY_VALUE(var, value);
						return SUCCESS;
					}
					str++;
				} while (str != end);

And in the EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE branch of zend_set_local_var() (line 1954), zend_hash_update_ind(execute_data->symbol_table, name, value) is called, which properly invokes the destructor on the old value. Only the CV branch of zend_set_local_var() (line 1940) omits zval_ptr_dtor(var);, leaking the previous reference-counted value if the CV was already populated.

Suggested Patch
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -1937,6 +1937,7 @@ ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool for
 					if (ZSTR_H(*str) == h &&
 					    zend_string_equal_content(*str, name)) {
 						zval *var = EX_VAR_NUM(str - op_array->vars);
+						zval_ptr_dtor(var);
 						ZVAL_COPY_VALUE(var, value);
 						return SUCCESS;
 					}
PHP Version
PHP 8.4, PHP 8.5, master
Operating System

All

Ngôn ngữ chính
C
Star
40.7k
Fork
8.3k
Merge trung bình
2 ngày 20 giờ
Pull request đã merge (30 ngày)
147

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của php/php-src

Tất cả issue của php/php-src

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.