diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index 7fd20b99deb..b997a2bdcff 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -45,7 +45,7 @@ typedef struct ps_sd { void *data; size_t datalen; /* amount of valid data */ size_t alloclen; /* amount of allocated memory for data */ - char key[1]; /* inline key */ + zend_string *key; } ps_sd; typedef struct { @@ -64,14 +64,15 @@ static ps_mm *ps_mm_instance = NULL; # define ps_mm_debug(a) #endif -static inline uint32_t ps_sd_hash(const char *data, size_t len) +static inline uint32_t ps_sd_hash(const zend_string *data) { uint32_t h; - const char *e = data + len; + const char *data_char = ZSTR_VAL(data); + const char *e = ZSTR_VAL(data) + ZSTR_LEN(data); - for (h = 2166136261U; data < e; ) { + for (h = 2166136261U; data_char < e; ) { h *= 16777619; - h ^= *data++; + h ^= *data_char++; } return h; @@ -106,22 +107,19 @@ static void hash_split(ps_mm *data) data->hash_max = nmax; } -static ps_sd *ps_sd_new(ps_mm *data, const char *key) +static ps_sd *ps_sd_new(ps_mm *data, zend_string *key) { uint32_t hv, slot; ps_sd *sd; - size_t keylen; - keylen = strlen(key); - - sd = mm_malloc(data->mm, sizeof(ps_sd) + keylen); + sd = mm_malloc(data->mm, sizeof(ps_sd) + ZSTR_LEN(key)); if (!sd) { php_error_docref(NULL, E_WARNING, "mm_malloc failed, avail %ld, err %s", mm_available(data->mm), mm_error()); return NULL; } - hv = ps_sd_hash(key, keylen); + hv = ps_sd_hash(key); slot = hv & data->hash_max; sd->ctime = 0; @@ -129,7 +127,7 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key) sd->data = NULL; sd->alloclen = sd->datalen = 0; - memcpy(sd->key, key, keylen + 1); + sd->key = zend_string_copy(key); sd->next = data->hash[slot]; data->hash[slot] = sd; @@ -142,7 +140,7 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key) } } - ps_mm_debug(("inserting %s(%p) into slot %d\n", key, sd, slot)); + ps_mm_debug(("inserting %s(%p) into slot %d\n", ZSTR_VAL(key), sd, slot)); return sd; } @@ -151,7 +149,7 @@ static void ps_sd_destroy(ps_mm *data, ps_sd *sd) { uint32_t slot; - slot = ps_sd_hash(sd->key, strlen(sd->key)) & data->hash_max; + slot = ps_sd_hash(sd->key) & data->hash_max; if (data->hash[slot] == sd) { data->hash[slot] = sd->next; @@ -168,20 +166,21 @@ static void ps_sd_destroy(ps_mm *data, ps_sd *sd) if (sd->data) { mm_free(data->mm, sd->data); } + zend_string_release(sd->key); mm_free(data->mm, sd); } -static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, bool rw) +static ps_sd *ps_sd_lookup(ps_mm *data, const zend_string *key, bool rw) { uint32_t hv, slot; ps_sd *ret, *prev; - hv = ps_sd_hash(key, strlen(key)); + hv = ps_sd_hash(key); slot = hv & data->hash_max; for (prev = NULL, ret = data->hash[slot]; ret; prev = ret, ret = ret->next) { - if (ret->hv == hv && !strcmp(ret->key, key)) { + if (ret->hv == hv && zend_string_equals(ret->key, key)) { break; } } @@ -196,12 +195,12 @@ static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, bool rw) data->hash[slot] = ret; } - ps_mm_debug(("lookup(%s): ret=%p,hv=%u,slot=%d\n", key, ret, hv, slot)); + ps_mm_debug(("lookup(%s): ret=%p,hv=%u,slot=%d\n", ZSTR_VAL(key), ret, hv, slot)); return ret; } -static zend_result ps_mm_key_exists(ps_mm *data, const char *key) +static zend_result ps_mm_key_exists(ps_mm *data, const zend_string *key) { ps_sd *sd; @@ -349,7 +348,7 @@ PS_READ_FUNC(mm) /* If there is an ID and strict mode, verify existence */ if (PS(use_strict_mode) - && ps_mm_key_exists(data, key->val) == FAILURE) { + && ps_mm_key_exists(data, key) == FAILURE) { /* key points to PS(id), but cannot change here. */ if (key) { efree(PS(id)); @@ -366,7 +365,7 @@ PS_READ_FUNC(mm) PS(session_status) = php_session_active; } - sd = ps_sd_lookup(data, PS(id)->val, 0); + sd = ps_sd_lookup(data, PS(id), 0); if (sd) { *val = zend_string_init(sd->data, sd->datalen, 0); ret = SUCCESS; @@ -384,10 +383,10 @@ PS_WRITE_FUNC(mm) mm_lock(data->mm, MM_LOCK_RW); - sd = ps_sd_lookup(data, key->val, 1); + sd = ps_sd_lookup(data, key, 1); if (!sd) { - sd = ps_sd_new(data, key->val); - ps_mm_debug(("new entry for %s\n", key->val)); + sd = ps_sd_new(data, key); + ps_mm_debug(("new entry for %s\n", ZSTR_VAL(key))); } if (sd) { @@ -423,7 +422,7 @@ PS_DESTROY_FUNC(mm) mm_lock(data->mm, MM_LOCK_RW); - sd = ps_sd_lookup(data, key->val, 0); + sd = ps_sd_lookup(data, key, 0); if (sd) { ps_sd_destroy(data, sd); } @@ -454,7 +453,7 @@ PS_GC_FUNC(mm) for (sd = *ohash; sd; sd = next) { next = sd->next; if (sd->ctime < limit) { - ps_mm_debug(("purging %s\n", sd->key)); + ps_mm_debug(("purging %s\n", ZSTR_VAL(sd->key))); ps_sd_destroy(data, sd); (*nrdels)++; } @@ -475,7 +474,7 @@ PS_CREATE_SID_FUNC(mm) do { sid = php_session_create_id((void **)&data); /* Check collision */ - if (ps_mm_key_exists(data, sid->val) == SUCCESS) { + if (ps_mm_key_exists(data, sid) == SUCCESS) { if (sid) { zend_string_release_ex(sid, 0); sid = NULL;