mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
MFH: ws + sync
This commit is contained in:
parent
82c49a50f4
commit
9ece649f7c
5 changed files with 201 additions and 229 deletions
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| PHP Version 5 |
|
| PHP Version 5 |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
|
@ -86,7 +86,7 @@ static int ps_files_valid_key(const char *key)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = p - key;
|
len = p - key;
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, cons
|
||||||
const char *p;
|
const char *p;
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
key_len = strlen(key);
|
key_len = strlen(key);
|
||||||
if (key_len <= data->dirdepth ||
|
if (key_len <= data->dirdepth ||
|
||||||
buflen < (strlen(data->basedir) + 2 * data->dirdepth + key_len + 5 + sizeof(FILE_PREFIX))) {
|
buflen < (strlen(data->basedir) + 2 * data->dirdepth + key_len + 5 + sizeof(FILE_PREFIX))) {
|
||||||
|
@ -120,18 +120,18 @@ static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, cons
|
||||||
memcpy(buf + n, key, key_len);
|
memcpy(buf + n, key, key_len);
|
||||||
n += key_len;
|
n += key_len;
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void ps_files_close(ps_files *data)
|
static void ps_files_close(ps_files *data)
|
||||||
{
|
{
|
||||||
if (data->fd != -1) {
|
if (data->fd != -1) {
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
/* On Win32 locked files that are closed without being explicitly unlocked
|
/* On Win32 locked files that are closed without being explicitly unlocked
|
||||||
will be unlocked only when "system resources become available". */
|
will be unlocked only when "system resources become available". */
|
||||||
flock(data->fd, LOCK_UN);
|
flock(data->fd, LOCK_UN);
|
||||||
|
@ -177,13 +177,12 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
S_ISLNK(sbuf.st_mode) &&
|
S_ISLNK(sbuf.st_mode) &&
|
||||||
(
|
(
|
||||||
php_check_open_basedir(buf TSRMLS_CC) ||
|
php_check_open_basedir(buf TSRMLS_CC) ||
|
||||||
(PG(safe_mode) && !php_checkuid(buf, NULL, CHECKUID_CHECK_FILE_AND_DIR))
|
(PG(safe_mode) && !php_checkuid(buf, NULL, CHECKUID_CHECK_FILE_AND_DIR))
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
close(data->fd);
|
close(data->fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -200,8 +199,7 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "open(%s, O_RDWR) failed: %s (%d)", buf,
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "open(%s, O_RDWR) failed: %s (%d)", buf, strerror(errno), errno);
|
||||||
strerror(errno), errno);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,7 +228,7 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
|
||||||
/* Prepare buffer (dirname never changes) */
|
/* Prepare buffer (dirname never changes) */
|
||||||
memcpy(buf, dirname, dirname_len);
|
memcpy(buf, dirname, dirname_len);
|
||||||
buf[dirname_len] = PHP_DIR_SEPARATOR;
|
buf[dirname_len] = PHP_DIR_SEPARATOR;
|
||||||
|
|
||||||
while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) {
|
while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) {
|
||||||
/* does the file start with our prefix? */
|
/* does the file start with our prefix? */
|
||||||
if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) {
|
if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) {
|
||||||
|
@ -245,7 +243,7 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
|
||||||
buf[dirname_len + entry_len + 1] = '\0';
|
buf[dirname_len + entry_len + 1] = '\0';
|
||||||
|
|
||||||
/* check whether its last access was more than maxlifet ago */
|
/* check whether its last access was more than maxlifet ago */
|
||||||
if (VCWD_STAT(buf, &sbuf) == 0 &&
|
if (VCWD_STAT(buf, &sbuf) == 0 &&
|
||||||
#ifdef NETWARE
|
#ifdef NETWARE
|
||||||
(now - sbuf.st_mtime.tv_sec) > maxlifetime) {
|
(now - sbuf.st_mtime.tv_sec) > maxlifetime) {
|
||||||
#else
|
#else
|
||||||
|
@ -285,7 +283,7 @@ PS_OPEN_FUNC(files)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* split up input parameter */
|
/* split up input parameter */
|
||||||
last = save_path;
|
last = save_path;
|
||||||
p = strchr(save_path, ';');
|
p = strchr(save_path, ';');
|
||||||
|
@ -305,7 +303,7 @@ PS_OPEN_FUNC(files)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
filemode = strtol(argv[1], NULL, 8);
|
filemode = strtol(argv[1], NULL, 8);
|
||||||
|
@ -316,17 +314,16 @@ PS_OPEN_FUNC(files)
|
||||||
}
|
}
|
||||||
save_path = argv[argc - 1];
|
save_path = argv[argc - 1];
|
||||||
|
|
||||||
data = emalloc(sizeof(*data));
|
data = ecalloc(1, sizeof(*data));
|
||||||
memset(data, 0, sizeof(*data));
|
|
||||||
|
|
||||||
data->fd = -1;
|
data->fd = -1;
|
||||||
data->dirdepth = dirdepth;
|
data->dirdepth = dirdepth;
|
||||||
data->filemode = filemode;
|
data->filemode = filemode;
|
||||||
data->basedir_len = strlen(save_path);
|
data->basedir_len = strlen(save_path);
|
||||||
data->basedir = estrndup(save_path, data->basedir_len);
|
data->basedir = estrndup(save_path, data->basedir_len);
|
||||||
|
|
||||||
PS_SET_MOD_DATA(data);
|
PS_SET_MOD_DATA(data);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +384,7 @@ PS_READ_FUNC(files)
|
||||||
efree(*val);
|
efree(*val);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,11 +398,8 @@ PS_WRITE_FUNC(files)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Truncate file if the amount of new data is smaller than the existing data set. */
|
||||||
* truncate file, if the amount of new data is smaller than
|
|
||||||
* the existing data set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (vallen < (int)data->st_size) {
|
if (vallen < (int)data->st_size) {
|
||||||
ftruncate(data->fd, 0);
|
ftruncate(data->fd, 0);
|
||||||
}
|
}
|
||||||
|
@ -440,11 +434,10 @@ PS_DESTROY_FUNC(files)
|
||||||
|
|
||||||
if (data->fd != -1) {
|
if (data->fd != -1) {
|
||||||
ps_files_close(data);
|
ps_files_close(data);
|
||||||
|
|
||||||
if (VCWD_UNLINK(buf) == -1) {
|
if (VCWD_UNLINK(buf) == -1) {
|
||||||
/* This is a little safety check for instances when we are dealing with a regenerated session
|
/* This is a little safety check for instances when we are dealing with a regenerated session
|
||||||
* that was not yet written to disk
|
* that was not yet written to disk. */
|
||||||
*/
|
|
||||||
if (!VCWD_ACCESS(buf, F_OK)) {
|
if (!VCWD_ACCESS(buf, F_OK)) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -454,14 +447,14 @@ PS_DESTROY_FUNC(files)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
PS_GC_FUNC(files)
|
PS_GC_FUNC(files)
|
||||||
{
|
{
|
||||||
PS_FILES_DATA;
|
PS_FILES_DATA;
|
||||||
|
|
||||||
/* we don't perform any cleanup, if dirdepth is larger than 0.
|
/* we don't perform any cleanup, if dirdepth is larger than 0.
|
||||||
we return SUCCESS, since all cleanup should be handled by
|
we return SUCCESS, since all cleanup should be handled by
|
||||||
an external entity (i.e. find -ctime x | xargs rm) */
|
an external entity (i.e. find -ctime x | xargs rm) */
|
||||||
|
|
||||||
if (data->dirdepth == 0) {
|
if (data->dirdepth == 0) {
|
||||||
*nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC);
|
*nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| PHP Version 5 |
|
| PHP Version 5 |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
|
@ -42,9 +42,7 @@
|
||||||
/* For php_uint32 */
|
/* For php_uint32 */
|
||||||
#include "ext/standard/basic_functions.h"
|
#include "ext/standard/basic_functions.h"
|
||||||
|
|
||||||
/*
|
/* This list holds all data associated with one session. */
|
||||||
* this list holds all data associated with one session
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct ps_sd {
|
typedef struct ps_sd {
|
||||||
struct ps_sd *next;
|
struct ps_sd *next;
|
||||||
|
@ -67,21 +65,21 @@ typedef struct {
|
||||||
static ps_mm *ps_mm_instance = NULL;
|
static ps_mm *ps_mm_instance = NULL;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define ps_mm_debug(a) printf a
|
# define ps_mm_debug(a) printf a
|
||||||
#else
|
#else
|
||||||
#define ps_mm_debug(a)
|
# define ps_mm_debug(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline php_uint32 ps_sd_hash(const char *data, int len)
|
static inline php_uint32 ps_sd_hash(const char *data, int len)
|
||||||
{
|
{
|
||||||
php_uint32 h;
|
php_uint32 h;
|
||||||
const char *e = data + len;
|
const char *e = data + len;
|
||||||
|
|
||||||
for (h = 2166136261U; data < e; ) {
|
for (h = 2166136261U; data < e; ) {
|
||||||
h *= 16777619;
|
h *= 16777619;
|
||||||
h ^= *data++;
|
h ^= *data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,10 +89,10 @@ static void hash_split(ps_mm *data)
|
||||||
ps_sd **nhash;
|
ps_sd **nhash;
|
||||||
ps_sd **ohash, **ehash;
|
ps_sd **ohash, **ehash;
|
||||||
ps_sd *ps, *next;
|
ps_sd *ps, *next;
|
||||||
|
|
||||||
nmax = ((data->hash_max + 1) << 1) - 1;
|
nmax = ((data->hash_max + 1) << 1) - 1;
|
||||||
nhash = mm_calloc(data->mm, nmax + 1, sizeof(*data->hash));
|
nhash = mm_calloc(data->mm, nmax + 1, sizeof(*data->hash));
|
||||||
|
|
||||||
if (!nhash) {
|
if (!nhash) {
|
||||||
/* no further memory to expand hash table */
|
/* no further memory to expand hash table */
|
||||||
return;
|
return;
|
||||||
|
@ -119,9 +117,9 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key)
|
||||||
php_uint32 hv, slot;
|
php_uint32 hv, slot;
|
||||||
ps_sd *sd;
|
ps_sd *sd;
|
||||||
int keylen;
|
int keylen;
|
||||||
|
|
||||||
keylen = strlen(key);
|
keylen = strlen(key);
|
||||||
|
|
||||||
sd = mm_malloc(data->mm, sizeof(ps_sd) + keylen);
|
sd = mm_malloc(data->mm, sizeof(ps_sd) + keylen);
|
||||||
if (!sd) {
|
if (!sd) {
|
||||||
TSRMLS_FETCH();
|
TSRMLS_FETCH();
|
||||||
|
@ -132,24 +130,25 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key)
|
||||||
|
|
||||||
hv = ps_sd_hash(key, keylen);
|
hv = ps_sd_hash(key, keylen);
|
||||||
slot = hv & data->hash_max;
|
slot = hv & data->hash_max;
|
||||||
|
|
||||||
sd->ctime = 0;
|
sd->ctime = 0;
|
||||||
sd->hv = hv;
|
sd->hv = hv;
|
||||||
sd->data = NULL;
|
sd->data = NULL;
|
||||||
sd->alloclen = sd->datalen = 0;
|
sd->alloclen = sd->datalen = 0;
|
||||||
|
|
||||||
memcpy(sd->key, key, keylen + 1);
|
memcpy(sd->key, key, keylen + 1);
|
||||||
|
|
||||||
sd->next = data->hash[slot];
|
sd->next = data->hash[slot];
|
||||||
data->hash[slot] = sd;
|
data->hash[slot] = sd;
|
||||||
|
|
||||||
data->hash_cnt++;
|
data->hash_cnt++;
|
||||||
|
|
||||||
if (!sd->next) {
|
if (!sd->next) {
|
||||||
if (data->hash_cnt >= data->hash_max)
|
if (data->hash_cnt >= data->hash_max) {
|
||||||
hash_split(data);
|
hash_split(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ps_mm_debug(("inserting %s(%p) into slot %d\n", key, sd, slot));
|
ps_mm_debug(("inserting %s(%p) into slot %d\n", key, sd, slot));
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
|
@ -161,19 +160,22 @@ static void ps_sd_destroy(ps_mm *data, ps_sd *sd)
|
||||||
|
|
||||||
slot = ps_sd_hash(sd->key, strlen(sd->key)) & data->hash_max;
|
slot = ps_sd_hash(sd->key, strlen(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;
|
||||||
else {
|
} else {
|
||||||
ps_sd *prev;
|
ps_sd *prev;
|
||||||
|
|
||||||
/* There must be some entry before the one we want to delete */
|
/* There must be some entry before the one we want to delete */
|
||||||
for (prev = data->hash[slot]; prev->next != sd; prev = prev->next);
|
for (prev = data->hash[slot]; prev->next != sd; prev = prev->next);
|
||||||
prev->next = sd->next;
|
prev->next = sd->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->hash_cnt--;
|
data->hash_cnt--;
|
||||||
if (sd->data)
|
|
||||||
|
if (sd->data) {
|
||||||
mm_free(data->mm, sd->data);
|
mm_free(data->mm, sd->data);
|
||||||
|
}
|
||||||
|
|
||||||
mm_free(data->mm, sd);
|
mm_free(data->mm, sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,22 +186,25 @@ static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, int rw)
|
||||||
|
|
||||||
hv = ps_sd_hash(key, strlen(key));
|
hv = ps_sd_hash(key, strlen(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 && !strcmp(ret->key, key)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ret && rw && ret != data->hash[slot]) {
|
if (ret && rw && ret != data->hash[slot]) {
|
||||||
/* Move the entry to the top of the linked list */
|
/* Move the entry to the top of the linked list */
|
||||||
|
if (prev) {
|
||||||
if (prev)
|
|
||||||
prev->next = ret->next;
|
prev->next = ret->next;
|
||||||
|
}
|
||||||
|
|
||||||
ret->next = data->hash[slot];
|
ret->next = data->hash[slot];
|
||||||
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", key, ret, hv, slot));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,14 +241,17 @@ static void ps_mm_destroy(ps_mm *data)
|
||||||
/* This function is called during each module shutdown,
|
/* This function is called during each module shutdown,
|
||||||
but we must not release the shared memory pool, when
|
but we must not release the shared memory pool, when
|
||||||
an Apache child dies! */
|
an Apache child dies! */
|
||||||
if (data->owner != getpid()) return;
|
if (data->owner != getpid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (h = 0; h < data->hash_max + 1; h++)
|
for (h = 0; h < data->hash_max + 1; h++) {
|
||||||
for (sd = data->hash[h]; sd; sd = next) {
|
for (sd = data->hash[h]; sd; sd = next) {
|
||||||
next = sd->next;
|
next = sd->next;
|
||||||
ps_sd_destroy(data, sd);
|
ps_sd_destroy(data, sd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mm_free(data->mm, data->hash);
|
mm_free(data->mm, data->hash);
|
||||||
mm_destroy(data->mm);
|
mm_destroy(data->mm);
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -258,17 +266,17 @@ PHP_MINIT_FUNCTION(ps_mm)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1);
|
ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1);
|
||||||
if (!ps_mm_instance) {
|
if (!ps_mm_instance) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(euid_len = slprintf(euid, sizeof(euid), "%d", geteuid()))) {
|
if (!(euid_len = slprintf(euid, sizeof(euid), "%d", geteuid()))) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Directory + '/' + File + Module Name + Effective UID + \0 */
|
/* Directory + '/' + File + Module Name + Effective UID + \0 */
|
||||||
ps_mm_path = emalloc(save_path_len + 1 + (sizeof(PS_MM_FILE) - 1) + mod_name_len + euid_len + 1);
|
ps_mm_path = emalloc(save_path_len + 1 + (sizeof(PS_MM_FILE) - 1) + mod_name_len + euid_len + 1);
|
||||||
|
|
||||||
memcpy(ps_mm_path, PS(save_path), save_path_len);
|
memcpy(ps_mm_path, PS(save_path), save_path_len);
|
||||||
if (PS(save_path)[save_path_len - 1] != DEFAULT_SLASH) {
|
if (PS(save_path)[save_path_len - 1] != DEFAULT_SLASH) {
|
||||||
ps_mm_path[save_path_len] = DEFAULT_SLASH;
|
ps_mm_path[save_path_len] = DEFAULT_SLASH;
|
||||||
|
@ -282,15 +290,15 @@ PHP_MINIT_FUNCTION(ps_mm)
|
||||||
ps_mm_path[save_path_len + euid_len] = '\0';
|
ps_mm_path[save_path_len + euid_len] = '\0';
|
||||||
|
|
||||||
ret = ps_mm_initialize(ps_mm_instance, ps_mm_path);
|
ret = ps_mm_initialize(ps_mm_instance, ps_mm_path);
|
||||||
|
|
||||||
efree(ps_mm_path);
|
efree(ps_mm_path);
|
||||||
|
|
||||||
if (ret != SUCCESS) {
|
if (ret != SUCCESS) {
|
||||||
free(ps_mm_instance);
|
free(ps_mm_instance);
|
||||||
ps_mm_instance = NULL;
|
ps_mm_instance = NULL;
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
php_session_register_module(&ps_mod_mm);
|
php_session_register_module(&ps_mod_mm);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -307,12 +315,12 @@ PHP_MSHUTDOWN_FUNCTION(ps_mm)
|
||||||
PS_OPEN_FUNC(mm)
|
PS_OPEN_FUNC(mm)
|
||||||
{
|
{
|
||||||
ps_mm_debug(("open: ps_mm_instance=%p\n", ps_mm_instance));
|
ps_mm_debug(("open: ps_mm_instance=%p\n", ps_mm_instance));
|
||||||
|
|
||||||
if (!ps_mm_instance)
|
if (!ps_mm_instance) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
|
}
|
||||||
PS_SET_MOD_DATA(ps_mm_instance);
|
PS_SET_MOD_DATA(ps_mm_instance);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +338,7 @@ PS_READ_FUNC(mm)
|
||||||
int ret = FAILURE;
|
int ret = FAILURE;
|
||||||
|
|
||||||
mm_lock(data->mm, MM_LOCK_RD);
|
mm_lock(data->mm, MM_LOCK_RD);
|
||||||
|
|
||||||
sd = ps_sd_lookup(data, key, 0);
|
sd = ps_sd_lookup(data, key, 0);
|
||||||
if (sd) {
|
if (sd) {
|
||||||
*vallen = sd->datalen;
|
*vallen = sd->datalen;
|
||||||
|
@ -341,7 +349,7 @@ PS_READ_FUNC(mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
mm_unlock(data->mm);
|
mm_unlock(data->mm);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,8 +368,9 @@ PS_WRITE_FUNC(mm)
|
||||||
|
|
||||||
if (sd) {
|
if (sd) {
|
||||||
if (vallen >= sd->alloclen) {
|
if (vallen >= sd->alloclen) {
|
||||||
if (data->mm)
|
if (data->mm) {
|
||||||
mm_free(data->mm, sd->data);
|
mm_free(data->mm, sd->data);
|
||||||
|
}
|
||||||
sd->alloclen = vallen + 1;
|
sd->alloclen = vallen + 1;
|
||||||
sd->data = mm_malloc(data->mm, sd->alloclen);
|
sd->data = mm_malloc(data->mm, sd->alloclen);
|
||||||
|
|
||||||
|
@ -379,7 +388,7 @@ PS_WRITE_FUNC(mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
mm_unlock(data->mm);
|
mm_unlock(data->mm);
|
||||||
|
|
||||||
return sd ? SUCCESS : FAILURE;
|
return sd ? SUCCESS : FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,28 +396,29 @@ PS_DESTROY_FUNC(mm)
|
||||||
{
|
{
|
||||||
PS_MM_DATA;
|
PS_MM_DATA;
|
||||||
ps_sd *sd;
|
ps_sd *sd;
|
||||||
|
|
||||||
mm_lock(data->mm, MM_LOCK_RW);
|
mm_lock(data->mm, MM_LOCK_RW);
|
||||||
|
|
||||||
sd = ps_sd_lookup(data, key, 0);
|
sd = ps_sd_lookup(data, key, 0);
|
||||||
if (sd)
|
if (sd) {
|
||||||
ps_sd_destroy(data, sd);
|
ps_sd_destroy(data, sd);
|
||||||
|
}
|
||||||
|
|
||||||
mm_unlock(data->mm);
|
mm_unlock(data->mm);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
PS_GC_FUNC(mm)
|
PS_GC_FUNC(mm)
|
||||||
{
|
{
|
||||||
PS_MM_DATA;
|
PS_MM_DATA;
|
||||||
time_t limit;
|
time_t limit;
|
||||||
ps_sd **ohash, **ehash;
|
ps_sd **ohash, **ehash;
|
||||||
ps_sd *sd, *next;
|
ps_sd *sd, *next;
|
||||||
|
|
||||||
*nrdels = 0;
|
*nrdels = 0;
|
||||||
ps_mm_debug(("gc\n"));
|
ps_mm_debug(("gc\n"));
|
||||||
|
|
||||||
time(&limit);
|
time(&limit);
|
||||||
|
|
||||||
limit -= maxlifetime;
|
limit -= maxlifetime;
|
||||||
|
@ -416,7 +426,7 @@ PS_GC_FUNC(mm)
|
||||||
mm_lock(data->mm, MM_LOCK_RW);
|
mm_lock(data->mm, MM_LOCK_RW);
|
||||||
|
|
||||||
ehash = data->hash + data->hash_max + 1;
|
ehash = data->hash + data->hash_max + 1;
|
||||||
for (ohash = data->hash; ohash < ehash; ohash++)
|
for (ohash = data->hash; ohash < ehash; ohash++) {
|
||||||
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) {
|
||||||
|
@ -425,9 +435,10 @@ PS_GC_FUNC(mm)
|
||||||
(*nrdels)++;
|
(*nrdels)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mm_unlock(data->mm);
|
mm_unlock(data->mm);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,39 +26,31 @@ ps_module ps_mod_user = {
|
||||||
PS_MOD(user)
|
PS_MOD(user)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SESS_ZVAL_LONG(val, a) \
|
#define SESS_ZVAL_LONG(val, a) \
|
||||||
{ \
|
{ \
|
||||||
MAKE_STD_ZVAL(a); \
|
MAKE_STD_ZVAL(a); \
|
||||||
Z_TYPE_P(a) = IS_LONG; \
|
ZVAL_LONG(a, val); \
|
||||||
Z_LVAL_P(a) = val; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SESS_ZVAL_STRING(vl, a) \
|
#define SESS_ZVAL_STRING(vl, a) \
|
||||||
{ \
|
{ \
|
||||||
int len = strlen(vl); \
|
char *__vl = vl; \
|
||||||
MAKE_STD_ZVAL(a); \
|
SESS_ZVAL_STRINGN(__vl, strlen(__vl), a); \
|
||||||
Z_TYPE_P(a) = IS_STRING; \
|
|
||||||
Z_STRLEN_P(a) = len; \
|
|
||||||
Z_STRVAL_P(a) = estrndup(vl, len); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SESS_ZVAL_STRINGN(vl, ln, a) \
|
#define SESS_ZVAL_STRINGN(vl, ln, a) \
|
||||||
{ \
|
{ \
|
||||||
MAKE_STD_ZVAL(a); \
|
MAKE_STD_ZVAL(a); \
|
||||||
Z_TYPE_P(a) = IS_STRING; \
|
ZVAL_STRINGL(a, vl, ln, 1); \
|
||||||
Z_STRLEN_P(a) = ln; \
|
|
||||||
Z_STRVAL_P(a) = estrndup(vl, ln); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
|
static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
zval *retval = NULL;
|
zval *retval = NULL;
|
||||||
|
|
||||||
MAKE_STD_ZVAL(retval);
|
MAKE_STD_ZVAL(retval);
|
||||||
if (call_user_function(EG(function_table), NULL, func, retval,
|
if (call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC) == FAILURE) {
|
||||||
argc, argv TSRMLS_CC) == FAILURE) {
|
|
||||||
zval_ptr_dtor(&retval);
|
zval_ptr_dtor(&retval);
|
||||||
retval = NULL;
|
retval = NULL;
|
||||||
}
|
}
|
||||||
|
@ -70,24 +62,23 @@ static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STDVARS1 \
|
#define STDVARS1 \
|
||||||
zval *retval; \
|
zval *retval; \
|
||||||
int ret = FAILURE
|
int ret = FAILURE
|
||||||
|
|
||||||
#define STDVARS \
|
#define STDVARS \
|
||||||
STDVARS1; \
|
STDVARS1; \
|
||||||
char *mdata = PS_GET_MOD_DATA(); \
|
char *mdata = PS_GET_MOD_DATA(); \
|
||||||
if (!mdata) \
|
if (!mdata) { return FAILURE; }
|
||||||
return FAILURE
|
|
||||||
|
|
||||||
#define PSF(a) PS(mod_user_names).name.ps_##a
|
#define PSF(a) PS(mod_user_names).name.ps_##a
|
||||||
|
|
||||||
#define FINISH \
|
#define FINISH \
|
||||||
if (retval) { \
|
if (retval) { \
|
||||||
convert_to_long(retval); \
|
convert_to_long(retval); \
|
||||||
ret = Z_LVAL_P(retval); \
|
ret = Z_LVAL_P(retval); \
|
||||||
zval_ptr_dtor(&retval); \
|
zval_ptr_dtor(&retval); \
|
||||||
} \
|
} \
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
PS_OPEN_FUNC(user)
|
PS_OPEN_FUNC(user)
|
||||||
|
@ -95,21 +86,20 @@ PS_OPEN_FUNC(user)
|
||||||
zval *args[2];
|
zval *args[2];
|
||||||
static char dummy = 0;
|
static char dummy = 0;
|
||||||
STDVARS1;
|
STDVARS1;
|
||||||
|
|
||||||
SESS_ZVAL_STRING(save_path, args[0]);
|
SESS_ZVAL_STRING((char*)save_path, args[0]);
|
||||||
SESS_ZVAL_STRING(session_name, args[1]);
|
SESS_ZVAL_STRING((char*)session_name, args[1]);
|
||||||
|
|
||||||
retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
|
retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
/* This is necessary to fool the session module. Yes, it's safe to
|
/* This is necessary to fool the session module. Yes, it's safe to
|
||||||
* use a static. Neither mod_user nor the session module itself will
|
* use a static. Neither mod_user nor the session module itself will
|
||||||
* ever touch this pointer. It could be set to 0xDEADBEEF for all the
|
* ever touch this pointer. It could be set to 0xDEADBEEF for all the
|
||||||
* difference it makes, but for the sake of paranoia it's set to some
|
* difference it makes, but for the sake of paranoia it's set to some
|
||||||
* valid value.
|
* valid value. */
|
||||||
*/
|
|
||||||
PS_SET_MOD_DATA(&dummy);
|
PS_SET_MOD_DATA(&dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
FINISH;
|
FINISH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,10 +119,10 @@ PS_READ_FUNC(user)
|
||||||
zval *args[1];
|
zval *args[1];
|
||||||
STDVARS;
|
STDVARS;
|
||||||
|
|
||||||
SESS_ZVAL_STRING(key, args[0]);
|
SESS_ZVAL_STRING((char*)key, args[0]);
|
||||||
|
|
||||||
retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC);
|
retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC);
|
||||||
|
|
||||||
if (retval) {
|
if (retval) {
|
||||||
if (Z_TYPE_P(retval) == IS_STRING) {
|
if (Z_TYPE_P(retval) == IS_STRING) {
|
||||||
*val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
*val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
||||||
|
@ -149,9 +139,9 @@ PS_WRITE_FUNC(user)
|
||||||
{
|
{
|
||||||
zval *args[2];
|
zval *args[2];
|
||||||
STDVARS;
|
STDVARS;
|
||||||
|
|
||||||
SESS_ZVAL_STRING(key, args[0]);
|
SESS_ZVAL_STRING((char*)key, args[0]);
|
||||||
SESS_ZVAL_STRINGN(val, vallen, args[1]);
|
SESS_ZVAL_STRINGN((char*)val, vallen, args[1]);
|
||||||
|
|
||||||
retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC);
|
retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC);
|
||||||
|
|
||||||
|
@ -163,7 +153,7 @@ PS_DESTROY_FUNC(user)
|
||||||
zval *args[1];
|
zval *args[1];
|
||||||
STDVARS;
|
STDVARS;
|
||||||
|
|
||||||
SESS_ZVAL_STRING(key, args[0]);
|
SESS_ZVAL_STRING((char*)key, args[0]);
|
||||||
|
|
||||||
retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC);
|
retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC);
|
||||||
|
|
||||||
|
|
|
@ -220,18 +220,18 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC);
|
||||||
zval **struc;
|
zval **struc;
|
||||||
|
|
||||||
#define PS_ENCODE_LOOP(code) do { \
|
#define PS_ENCODE_LOOP(code) do { \
|
||||||
HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); \
|
HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); \
|
||||||
int key_type; \
|
int key_type; \
|
||||||
\
|
\
|
||||||
for (zend_hash_internal_pointer_reset(_ht); \
|
for (zend_hash_internal_pointer_reset(_ht); \
|
||||||
(key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
|
(key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
|
||||||
zend_hash_move_forward(_ht)) { \
|
zend_hash_move_forward(_ht)) { \
|
||||||
if (key_type == HASH_KEY_IS_LONG) { \
|
if (key_type == HASH_KEY_IS_LONG) { \
|
||||||
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \
|
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \
|
||||||
continue; \
|
continue; \
|
||||||
} \
|
} \
|
||||||
key_length--; \
|
key_length--; \
|
||||||
if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) { \
|
if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) { \
|
||||||
code; \
|
code; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -132,15 +132,12 @@ PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) /* {{{ */
|
||||||
zval **sym_track = NULL;
|
zval **sym_track = NULL;
|
||||||
|
|
||||||
IF_SESSION_VARS() {
|
IF_SESSION_VARS() {
|
||||||
zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1,
|
zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, (void *) &sym_track);
|
||||||
(void *) &sym_track);
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Set up a proper reference between $_SESSION["x"] and $x. */
|
||||||
* Set up a proper reference between $_SESSION["x"] and $x.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (PG(register_globals)) {
|
if (PG(register_globals)) {
|
||||||
zval **sym_global = NULL;
|
zval **sym_global = NULL;
|
||||||
|
@ -180,13 +177,12 @@ PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php
|
||||||
{
|
{
|
||||||
if (PG(register_globals)) {
|
if (PG(register_globals)) {
|
||||||
zval **old_symbol;
|
zval **old_symbol;
|
||||||
if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) {
|
if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) {
|
||||||
if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) {
|
if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* A global symbol with the same name exists already. That
|
||||||
* A global symbol with the same name exists already. That
|
|
||||||
* symbol might have been created by other means (e.g. $_GET).
|
* symbol might have been created by other means (e.g. $_GET).
|
||||||
*
|
*
|
||||||
* hash_update in zend_set_hash_symbol is not good, because
|
* hash_update in zend_set_hash_symbol is not good, because
|
||||||
|
@ -194,16 +190,13 @@ PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php
|
||||||
* of a global variable) dangling.
|
* of a global variable) dangling.
|
||||||
*
|
*
|
||||||
* BTW: if you use register_globals references between
|
* BTW: if you use register_globals references between
|
||||||
* session-vars won't work because of this very reason!
|
* session-vars won't work because of this very reason! */
|
||||||
*/
|
|
||||||
|
|
||||||
REPLACE_ZVAL_VALUE(old_symbol,state_val,1);
|
REPLACE_ZVAL_VALUE(old_symbol,state_val,1);
|
||||||
|
|
||||||
/*
|
/* The following line will update the reference table used for
|
||||||
* The following line will update the reference table used for
|
* unserialization. It is optional, because some storage
|
||||||
* unserialization. It is optional, because some storage
|
* formats may not be able to represent references. */
|
||||||
* formats may not be able to represent references.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (var_hash) {
|
if (var_hash) {
|
||||||
PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash,state_val,*old_symbol);
|
PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash,state_val,*old_symbol);
|
||||||
|
@ -224,23 +217,18 @@ PHPAPI int php_get_session_var(char *name, size_t namelen, zval ***state_var TSR
|
||||||
int ret = FAILURE;
|
int ret = FAILURE;
|
||||||
|
|
||||||
IF_SESSION_VARS() {
|
IF_SESSION_VARS() {
|
||||||
ret = zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name,
|
ret = zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, (void **) state_var);
|
||||||
namelen+1, (void **) state_var);
|
|
||||||
|
|
||||||
/*
|
/* If register_globals is enabled, and
|
||||||
* If register_globals is enabled, and
|
|
||||||
* if there is an entry for the slot in $_SESSION, and
|
* if there is an entry for the slot in $_SESSION, and
|
||||||
* if that entry is still set to NULL, and
|
* if that entry is still set to NULL, and
|
||||||
* if the global var exists, then
|
* if the global var exists, then
|
||||||
* we prefer the same key in the global sym table
|
* we prefer the same key in the global sym table. */
|
||||||
*/
|
|
||||||
|
|
||||||
if (PG(register_globals) && ret == SUCCESS
|
if (PG(register_globals) && ret == SUCCESS && Z_TYPE_PP(*state_var) == IS_NULL) {
|
||||||
&& Z_TYPE_PP(*state_var) == IS_NULL) {
|
|
||||||
zval **tmp;
|
zval **tmp;
|
||||||
|
|
||||||
if (zend_hash_find(&EG(symbol_table), name, namelen + 1,
|
if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
|
||||||
(void **) &tmp) == SUCCESS) {
|
|
||||||
*state_var = tmp;
|
*state_var = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,7 +275,7 @@ static char *php_session_encode(int *newlen TSRMLS_DC) /* {{{ */
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode non-existent session");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode non-existent session");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -378,17 +366,15 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
if (zend_hash_find(&EG(symbol_table), "_SERVER",
|
if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
|
||||||
sizeof("_SERVER"), (void **) &array) == SUCCESS &&
|
|
||||||
Z_TYPE_PP(array) == IS_ARRAY &&
|
Z_TYPE_PP(array) == IS_ARRAY &&
|
||||||
zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR",
|
zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS
|
||||||
sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS) {
|
) {
|
||||||
remote_addr = Z_STRVAL_PP(token);
|
remote_addr = Z_STRVAL_PP(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* maximum 15+19+19+10 bytes */
|
/* maximum 15+19+19+10 bytes */
|
||||||
spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "",
|
spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
|
||||||
tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
|
|
||||||
|
|
||||||
switch (PS(hash_func)) {
|
switch (PS(hash_func)) {
|
||||||
case PS_HASH_FUNC_MD5:
|
case PS_HASH_FUNC_MD5:
|
||||||
|
@ -527,8 +513,7 @@ new_session:
|
||||||
/* Question: if you create a SID here, should you also try to read data?
|
/* Question: if you create a SID here, should you also try to read data?
|
||||||
* I'm not sure, but while not doing so will remove one session operation
|
* I'm not sure, but while not doing so will remove one session operation
|
||||||
* it could prove usefull for those sites which wish to have "default"
|
* it could prove usefull for those sites which wish to have "default"
|
||||||
* session information
|
* session information. */
|
||||||
*/
|
|
||||||
php_session_track_init(TSRMLS_C);
|
php_session_track_init(TSRMLS_C);
|
||||||
PS(invalid_session_id) = 0;
|
PS(invalid_session_id) = 0;
|
||||||
if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {
|
if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {
|
||||||
|
@ -556,11 +541,10 @@ static int migrate_global(HashTable *ht, HashPosition *pos TSRMLS_DC) /* {{{ */
|
||||||
|
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case HASH_KEY_IS_STRING:
|
case HASH_KEY_IS_STRING:
|
||||||
if (zend_hash_find(&EG(symbol_table), str, str_len,
|
if (zend_hash_find(&EG(symbol_table), str, str_len, (void **) &val) == SUCCESS &&
|
||||||
(void **) &val) == SUCCESS
|
val && Z_TYPE_PP(val) != IS_NULL
|
||||||
&& val && Z_TYPE_PP(val) != IS_NULL) {
|
) {
|
||||||
ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val,
|
ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val, Z_REFCOUNT_PP(val) + 1, 1);
|
||||||
Z_REFCOUNT_PP(val) + 1 , 1);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -587,11 +571,11 @@ static void php_session_save_current_state(TSRMLS_D) /* {{{ */
|
||||||
|
|
||||||
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||||
|
|
||||||
while (zend_hash_get_current_data_ex(ht,
|
while (zend_hash_get_current_data_ex(ht, (void **) &val, &pos) != FAILURE) {
|
||||||
(void **) &val, &pos) != FAILURE) {
|
|
||||||
if (Z_TYPE_PP(val) == IS_NULL) {
|
if (Z_TYPE_PP(val) == IS_NULL) {
|
||||||
if (migrate_global(ht, &pos TSRMLS_CC))
|
if (migrate_global(ht, &pos TSRMLS_CC)) {
|
||||||
do_warn = 1;
|
do_warn = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
zend_hash_move_forward_ex(ht, &pos);
|
zend_hash_move_forward_ex(ht, &pos);
|
||||||
}
|
}
|
||||||
|
@ -648,6 +632,8 @@ static PHP_INI_MH(OnUpdateSaveHandler) /* {{{ */
|
||||||
} else {
|
} else {
|
||||||
err_type = E_ERROR;
|
err_type = E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do not output error when restoring ini options. */
|
||||||
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
|
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
|
||||||
php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find save handler '%s'", new_value);
|
php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find save handler '%s'", new_value);
|
||||||
}
|
}
|
||||||
|
@ -674,6 +660,8 @@ static PHP_INI_MH(OnUpdateSerializer) /* {{{ */
|
||||||
} else {
|
} else {
|
||||||
err_type = E_ERROR;
|
err_type = E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do not output error when restoring ini options. */
|
||||||
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
|
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
|
||||||
php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find serialization handler '%s'", new_value);
|
php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find serialization handler '%s'", new_value);
|
||||||
}
|
}
|
||||||
|
@ -723,6 +711,7 @@ static PHP_INI_MH(OnUpdateSaveDir) /* {{{ */
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
|
OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1002,10 +991,7 @@ static ps_serializer ps_serializers[MAX_SERIALIZERS + 1] = {
|
||||||
PS_SERIALIZER_ENTRY(php_binary)
|
PS_SERIALIZER_ENTRY(php_binary)
|
||||||
};
|
};
|
||||||
|
|
||||||
PHPAPI int php_session_register_serializer(
|
PHPAPI int php_session_register_serializer(const char *name, int (*encode)(PS_SERIALIZER_ENCODE_ARGS), int (*decode)(PS_SERIALIZER_DECODE_ARGS)) /* {{{ */
|
||||||
const char *name,
|
|
||||||
int (*encode)(PS_SERIALIZER_ENCODE_ARGS),
|
|
||||||
int (*decode)(PS_SERIALIZER_DECODE_ARGS)) /* {{{ */
|
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1090,9 +1076,9 @@ static inline void strcpy_gmt(char *ubuf, time_t *when) /* {{{ */
|
||||||
}
|
}
|
||||||
|
|
||||||
n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */
|
n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */
|
||||||
week_days[tm.tm_wday], tm.tm_mday,
|
week_days[tm.tm_wday], tm.tm_mday,
|
||||||
month_names[tm.tm_mon], tm.tm_year + 1900,
|
month_names[tm.tm_mon], tm.tm_year + 1900,
|
||||||
tm.tm_hour, tm.tm_min,
|
tm.tm_hour, tm.tm_min,
|
||||||
tm.tm_sec);
|
tm.tm_sec);
|
||||||
memcpy(ubuf, buf, n);
|
memcpy(ubuf, buf, n);
|
||||||
ubuf[n] = '\0';
|
ubuf[n] = '\0';
|
||||||
|
@ -1188,8 +1174,7 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
|
||||||
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
|
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
|
||||||
|
|
||||||
if (output_start_filename) {
|
if (output_start_filename) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)",
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno);
|
||||||
output_start_filename, output_start_lineno);
|
|
||||||
} else {
|
} else {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");
|
||||||
}
|
}
|
||||||
|
@ -1229,8 +1214,7 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
|
||||||
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
|
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
|
||||||
|
|
||||||
if (output_start_filename) {
|
if (output_start_filename) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)",
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)", output_start_filename, output_start_lineno);
|
||||||
output_start_filename, output_start_lineno);
|
|
||||||
} else {
|
} else {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent");
|
||||||
}
|
}
|
||||||
|
@ -1400,17 +1384,14 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
|
||||||
|
|
||||||
lensess = strlen(PS(session_name));
|
lensess = strlen(PS(session_name));
|
||||||
|
|
||||||
/*
|
/* Cookies are preferred, because initially
|
||||||
* Cookies are preferred, because initially
|
* cookie and get variables will be available. */
|
||||||
* cookie and get variables will be available.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!PS(id)) {
|
if (!PS(id)) {
|
||||||
if (PS(use_cookies) && zend_hash_find(&EG(symbol_table), "_COOKIE",
|
if (PS(use_cookies) && zend_hash_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE"), (void **) &data) == SUCCESS &&
|
||||||
sizeof("_COOKIE"), (void **) &data) == SUCCESS &&
|
|
||||||
Z_TYPE_PP(data) == IS_ARRAY &&
|
Z_TYPE_PP(data) == IS_ARRAY &&
|
||||||
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name),
|
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
|
||||||
lensess + 1, (void **) &ppid) == SUCCESS) {
|
) {
|
||||||
PPID2SID;
|
PPID2SID;
|
||||||
PS(apply_trans_sid) = 0;
|
PS(apply_trans_sid) = 0;
|
||||||
PS(send_cookie) = 0;
|
PS(send_cookie) = 0;
|
||||||
|
@ -1418,36 +1399,34 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PS(use_only_cookies) && !PS(id) &&
|
if (!PS(use_only_cookies) && !PS(id) &&
|
||||||
zend_hash_find(&EG(symbol_table), "_GET",
|
zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &data) == SUCCESS &&
|
||||||
sizeof("_GET"), (void **) &data) == SUCCESS &&
|
|
||||||
Z_TYPE_PP(data) == IS_ARRAY &&
|
Z_TYPE_PP(data) == IS_ARRAY &&
|
||||||
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name),
|
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
|
||||||
lensess + 1, (void **) &ppid) == SUCCESS) {
|
) {
|
||||||
PPID2SID;
|
PPID2SID;
|
||||||
PS(send_cookie) = 0;
|
PS(send_cookie) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PS(use_only_cookies) && !PS(id) &&
|
if (!PS(use_only_cookies) && !PS(id) &&
|
||||||
zend_hash_find(&EG(symbol_table), "_POST",
|
zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &data) == SUCCESS &&
|
||||||
sizeof("_POST"), (void **) &data) == SUCCESS &&
|
|
||||||
Z_TYPE_PP(data) == IS_ARRAY &&
|
Z_TYPE_PP(data) == IS_ARRAY &&
|
||||||
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name),
|
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
|
||||||
lensess + 1, (void **) &ppid) == SUCCESS) {
|
) {
|
||||||
PPID2SID;
|
PPID2SID;
|
||||||
PS(send_cookie) = 0;
|
PS(send_cookie) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the REQUEST_URI symbol for a string of the form
|
/* Check the REQUEST_URI symbol for a string of the form
|
||||||
'<session-name>=<session-id>' to allow URLs of the form
|
* '<session-name>=<session-id>' to allow URLs of the form
|
||||||
http://yoursite/<session-name>=<session-id>/script.php */
|
* http://yoursite/<session-name>=<session-id>/script.php */
|
||||||
|
|
||||||
if (!PS(use_only_cookies) && !PS(id) && PG(http_globals)[TRACK_VARS_SERVER] &&
|
if (!PS(use_only_cookies) && !PS(id) && PG(http_globals)[TRACK_VARS_SERVER] &&
|
||||||
zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI",
|
zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &data) == SUCCESS &&
|
||||||
sizeof("REQUEST_URI"), (void **) &data) == SUCCESS &&
|
|
||||||
Z_TYPE_PP(data) == IS_STRING &&
|
Z_TYPE_PP(data) == IS_STRING &&
|
||||||
(p = strstr(Z_STRVAL_PP(data), PS(session_name))) &&
|
(p = strstr(Z_STRVAL_PP(data), PS(session_name))) &&
|
||||||
p[lensess] == '=') {
|
p[lensess] == '='
|
||||||
|
) {
|
||||||
char *q;
|
char *q;
|
||||||
|
|
||||||
p += lensess + 1;
|
p += lensess + 1;
|
||||||
|
@ -1457,17 +1436,17 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether the current request was referred to by
|
/* Check whether the current request was referred to by
|
||||||
an external site which invalidates the previously found id */
|
* an external site which invalidates the previously found id. */
|
||||||
|
|
||||||
if (PS(id) &&
|
if (PS(id) &&
|
||||||
PS(extern_referer_chk)[0] != '\0' &&
|
PS(extern_referer_chk)[0] != '\0' &&
|
||||||
PG(http_globals)[TRACK_VARS_SERVER] &&
|
PG(http_globals)[TRACK_VARS_SERVER] &&
|
||||||
zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER",
|
zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER"), (void **) &data) == SUCCESS &&
|
||||||
sizeof("HTTP_REFERER"), (void **) &data) == SUCCESS &&
|
|
||||||
Z_TYPE_PP(data) == IS_STRING &&
|
Z_TYPE_PP(data) == IS_STRING &&
|
||||||
Z_STRLEN_PP(data) != 0 &&
|
Z_STRLEN_PP(data) != 0 &&
|
||||||
strstr(Z_STRVAL_PP(data), PS(extern_referer_chk)) == NULL) {
|
strstr(Z_STRVAL_PP(data), PS(extern_referer_chk)) == NULL
|
||||||
|
) {
|
||||||
efree(PS(id));
|
efree(PS(id));
|
||||||
PS(id) = NULL;
|
PS(id) = NULL;
|
||||||
PS(send_cookie) = 1;
|
PS(send_cookie) = 1;
|
||||||
|
@ -1540,8 +1519,7 @@ static PHP_FUNCTION(session_set_cookie_params)
|
||||||
zend_bool secure = 0, httponly = 0;
|
zend_bool secure = 0, httponly = 0;
|
||||||
|
|
||||||
if (!PS(use_cookies) ||
|
if (!PS(use_cookies) ||
|
||||||
zend_parse_parameters(argc TSRMLS_CC, "Z|ssbb", &lifetime, &path, &path_len,
|
zend_parse_parameters(argc TSRMLS_CC, "Z|ssbb", &lifetime, &path, &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
|
||||||
&domain, &domain_len, &secure, &httponly) == FAILURE) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1566,7 +1544,7 @@ static PHP_FUNCTION(session_set_cookie_params)
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto array session_get_cookie_params(void)
|
/* {{{ proto array session_get_cookie_params(void)
|
||||||
Return the session cookie parameters */
|
Return the session cookie parameters */
|
||||||
static PHP_FUNCTION(session_get_cookie_params)
|
static PHP_FUNCTION(session_get_cookie_params)
|
||||||
{
|
{
|
||||||
if (zend_parse_parameters_none() == FAILURE) {
|
if (zend_parse_parameters_none() == FAILURE) {
|
||||||
|
@ -1830,7 +1808,8 @@ static void php_register_var(zval** entry TSRMLS_DC)
|
||||||
convert_to_string_ex(entry);
|
convert_to_string_ex(entry);
|
||||||
|
|
||||||
if ((strcmp(Z_STRVAL_PP(entry), "HTTP_SESSION_VARS") != 0) &&
|
if ((strcmp(Z_STRVAL_PP(entry), "HTTP_SESSION_VARS") != 0) &&
|
||||||
(strcmp(Z_STRVAL_PP(entry), "_SESSION") != 0)) {
|
(strcmp(Z_STRVAL_PP(entry), "_SESSION") != 0)
|
||||||
|
) {
|
||||||
PS_ADD_VARL(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
|
PS_ADD_VARL(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1923,9 +1902,8 @@ static PHP_FUNCTION(session_unset)
|
||||||
|
|
||||||
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||||
|
|
||||||
while (zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key,
|
while (zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING) {
|
||||||
0, &pos) == HASH_KEY_IS_STRING) {
|
zend_delete_global_variable(str, str_len - 1 TSRMLS_CC);
|
||||||
zend_delete_global_variable(str, str_len-1 TSRMLS_CC);
|
|
||||||
zend_hash_move_forward_ex(ht, &pos);
|
zend_hash_move_forward_ex(ht, &pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2113,7 +2091,7 @@ static const zend_function_entry session_functions[] = {
|
||||||
PHP_FE(session_get_cookie_params, arginfo_session_void)
|
PHP_FE(session_get_cookie_params, arginfo_session_void)
|
||||||
PHP_FE(session_write_close, arginfo_session_void)
|
PHP_FE(session_write_close, arginfo_session_void)
|
||||||
PHP_FALIAS(session_commit, session_write_close, arginfo_session_void)
|
PHP_FALIAS(session_commit, session_write_close, arginfo_session_void)
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue