php / php/php-src

Hashtable initialized at extension module level gets corrupted in processing first request itself

Open
#11,783 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

Here my struct member zend_long is persistent at each request but not hashtable keys and values, However a strange thing is number of elements are consistent but values are corrupted.

The following code:


ZEND_BEGIN_MODULE_GLOBALS(myextension)
{
struct {
        zend_long  matcher;
        HashTable *list;
    }mystruct;
    
}
my_ctor()
{
ALLOC_HASHTABLE(myextension_G(mystruct.list));
    zend_hash_init(myextension_G(mystruct.list), 0, NULL, ZVAL_PTR_DTOR, 0);  // tried with changing last param as 1 too  to keep it persistent but no change
parse_mystruct_value_from_ini();
}
//This is the method to populate values in my hash table from customized ini settings.
static void parse_mystruct_value_from_ini()
{
char *list = emalloc(strlen(INI_STR("structlist")) + 1);
    strcpy(list, INI_STR("structlist"));

if (strlen(list) > 0) {
char *token = strtok(mystrcut_list_ini, ",");
while (token != NULL) {
            zval * token_zval = NULL;
           ZVAL_NULL(token_zval);
            ZVAL_STRING(token_zval, token,1);
            zend_compat_hash_next_index_insert(myextesion_G(mystruct.list), token_zval);
}

ZEND_INIT_MODULE_GLOBALS(my extension , my_ctor(), NULL)

Resulted in this output:
when I try to print the values in request code, th values are corrupted.

Trying to print the value something like this

ZEND_HASH_FOREACH_KEY_VAL(myextension_G(mystruct.list), idx,key, zval)
    {
        print("*** Lets print global struct list = %s  ****** \n" , Z_STRVAL_P(zval));

    }
    ZEND_HASH_FOREACH_END();

*** Lets print global struct list inside request process =   ****** 

 *** Lets print global struct  list inside request process   = xterm  ****** 

 *** Lets print global struct  list inside  request process  = TERM  ****** 

PHP Version

PHP 8.1.12

Operating System

Ubuntu 20.0.4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the shown module-global constructor, zend_hash_init call, and request-side ZEND_HASH_FOREACH_KEY_VAL loop; reproduce the first-request behavior on PHP 8.1.12. Trace the hash table and zval lifetimes from INI parsing through request processing, and consider the issue done when the stored strings remain valid and print correctly during the first request.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.