session_setstr in session.c attempts to remove the old entry before adding the new one, but it removes from session.nums instead of session.strs:
|
void session_setstr(const char* name, const char* value) |
|
{ |
|
/* FIXME: use _set when bglibs 1.103 is released */ |
|
session_strs_remove(&session.nums, &name); |
|
if (session_strs_add(&session.strs, &name, &value) == 0) |
|
die_oom(111); |
|
} |
Compare with session_setnum, which is correct:
|
void session_setnum(const char* name, unsigned long value) |
|
{ |
|
/* FIXME: use _set when bglibs 1.103 is released */ |
|
session_nums_remove(&session.nums, &name); |
|
if (session_nums_add(&session.nums, &name, &value) == 0) |
|
die_oom(111); |
|
} |
When session_setstr is called for a key that already exists, the remove is a no-op (the key isn't in session.nums). The subsequent session_strs_add calls ghash_add, which does not check for duplicates — it inserts a second entry at the next available slot via linear probing. session_getstr calls ghash_find, which scans forward from the hash position and returns the first match — i.e., the original (stale) entry, not the newly added one.
The result is that session_setstr silently fails to update: the old value is returned by all subsequent session_getstr calls, and duplicate entries accumulate in the hash table.
A workaround does exist; by calling session_delstr(name) before session_setstr(name, value). session_delstr correctly removes from session.strs.
session_setstrin session.c attempts to remove the old entry before adding the new one, but it removes fromsession.numsinstead ofsession.strs:mailfront/session.c
Lines 118 to 124 in 07d683b
Compare with
session_setnum, which is correct:mailfront/session.c
Lines 144 to 150 in 07d683b
When
session_setstris called for a key that already exists, the remove is a no-op (the key isn't insession.nums). The subsequentsession_strs_addcallsghash_add, which does not check for duplicates — it inserts a second entry at the next available slot via linear probing.session_getstrcallsghash_find, which scans forward from the hash position and returns the first match — i.e., the original (stale) entry, not the newly added one.The result is that
session_setstrsilently fails to update: the old value is returned by all subsequentsession_getstrcalls, and duplicate entries accumulate in the hash table.A workaround does exist; by calling
session_delstr(name)beforesession_setstr(name, value).session_delstrcorrectly removes fromsession.strs.