Session: Use zend_string* consistently for key in mod_mm

This commit is contained in:
George Peter Banyard 2022-05-27 16:15:29 +01:00
parent f872972584
commit 8a1ca99aab

View file

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