Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 76 additions & 49 deletions ext/session/mod_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,48 +45,47 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
}
}

#define STDVARS \
zval retval; \
zend_result ret = FAILURE

#define PSF(a) PS(mod_user_names).name.ps_##a

#define FINISH \
if (Z_TYPE(retval) != IS_UNDEF) { \
if (Z_TYPE(retval) == IS_TRUE) { \
ret = SUCCESS; \
} else if (Z_TYPE(retval) == IS_FALSE) { \
ret = FAILURE; \
} else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == -1)) { \
if (!EG(exception)) { \
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_type_name(&retval)); \
} \
ret = FAILURE; \
} else if ((Z_TYPE(retval) == IS_LONG) && (Z_LVAL(retval) == 0)) { \
if (!EG(exception)) { \
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_type_name(&retval)); \
} \
ret = SUCCESS; \
} else { \
if (!EG(exception)) { \
zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_type_name(&retval)); \
} \
ret = FAILURE; \
zval_ptr_dtor(&retval); \
} \
} \
return ret
#define PSF(a) PS(mod_user_names).ps_##a

static zend_result verify_bool_return_type_userland_calls(const zval* value)
{
/* Exit or exception in userland call */
if (Z_TYPE_P(value) == IS_UNDEF) {
return FAILURE;
}
if (Z_TYPE_P(value) == IS_TRUE) {
return SUCCESS;
}
if (Z_TYPE_P(value) == IS_FALSE) {
return FAILURE;
}
if ((Z_TYPE_P(value) == IS_LONG) && (Z_LVAL_P(value) == -1)) {
/* TODO Why are exception cheked? */
if (!EG(exception)) {
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_type_name(value));
}
return FAILURE;
}
if ((Z_TYPE_P(value) == IS_LONG) && (Z_LVAL_P(value) == 0)) {
/* TODO Why are exception cheked? */
if (!EG(exception)) {
php_error_docref(NULL, E_DEPRECATED, "Session callback must have a return value of type bool, %s returned", zend_zval_type_name(value));
}
return SUCCESS;
}
if (!EG(exception)) {
zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_type_name(value)); \
}
return FAILURE;
}

PS_OPEN_FUNC(user)
{
zval args[2];
STDVARS;

if (Z_ISUNDEF(PSF(open))) {
php_error_docref(NULL, E_WARNING, "User session functions are not defined");
zval retval;
zend_result ret = FAILURE;

return FAILURE;
}
ZEND_ASSERT(!Z_ISUNDEF(PSF(open)));

ZVAL_STRING(&args[0], (char*)save_path);
ZVAL_STRING(&args[1], (char*)session_name);
Expand All @@ -103,13 +102,18 @@ PS_OPEN_FUNC(user)

PS(mod_user_implemented) = 1;

FINISH;
ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}

PS_CLOSE_FUNC(user)
{
bool bailout = 0;
STDVARS;
zval retval;
zend_result ret = FAILURE;

ZEND_ASSERT(!Z_ISUNDEF(PSF(close)));

if (!PS(mod_user_implemented)) {
/* already closed */
Expand All @@ -131,13 +135,18 @@ PS_CLOSE_FUNC(user)
zend_bailout();
}

FINISH;
ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}

PS_READ_FUNC(user)
{
zval args[1];
STDVARS;
zval retval;
zend_result ret = FAILURE;

ZEND_ASSERT(!Z_ISUNDEF(PSF(read)));

ZVAL_STR_COPY(&args[0], key);

Expand All @@ -157,33 +166,45 @@ PS_READ_FUNC(user)
PS_WRITE_FUNC(user)
{
zval args[2];
STDVARS;
zval retval;
zend_result ret = FAILURE;

ZEND_ASSERT(!Z_ISUNDEF(PSF(write)));

ZVAL_STR_COPY(&args[0], key);
ZVAL_STR_COPY(&args[1], val);

ps_call_handler(&PSF(write), 2, args, &retval);

FINISH;
ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}

PS_DESTROY_FUNC(user)
{
zval args[1];
STDVARS;
zval retval;
zend_result ret = FAILURE;

ZEND_ASSERT(!Z_ISUNDEF(PSF(destroy)));

ZVAL_STR_COPY(&args[0], key);

ps_call_handler(&PSF(destroy), 1, args, &retval);

FINISH;
ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}

PS_GC_FUNC(user)
{
zval args[1];
zval retval;

ZEND_ASSERT(!Z_ISUNDEF(PSF(gc)));

ZVAL_LONG(&args[0], maxlifetime);

ps_call_handler(&PSF(gc), 1, args, &retval);
Expand Down Expand Up @@ -236,13 +257,16 @@ PS_VALIDATE_SID_FUNC(user)
/* maintain backwards compatibility */
if (!Z_ISUNDEF(PSF(validate_sid))) {
zval args[1];
STDVARS;
zval retval;
zend_result ret = FAILURE;

ZVAL_STR_COPY(&args[0], key);

ps_call_handler(&PSF(validate_sid), 1, args, &retval);

FINISH;
ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}

/* dummy function defined by PS_MOD */
Expand All @@ -252,7 +276,8 @@ PS_VALIDATE_SID_FUNC(user)
PS_UPDATE_TIMESTAMP_FUNC(user)
{
zval args[2];
STDVARS;
zval retval;
zend_result ret = FAILURE;

ZVAL_STR_COPY(&args[0], key);
ZVAL_STR_COPY(&args[1], val);
Expand All @@ -264,5 +289,7 @@ PS_UPDATE_TIMESTAMP_FUNC(user)
ps_call_handler(&PSF(write), 2, args, &retval);
}

FINISH;
ret = verify_bool_return_type_userland_calls(&retval);
zval_ptr_dtor(&retval);
return ret;
}
24 changes: 10 additions & 14 deletions ext/session/php_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#define PHP_SESSION_VERSION PHP_VERSION

/* save handler macros */
#define PS_NUM_APIS 9
#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name
#define PS_CLOSE_ARGS void **mod_data
#define PS_READ_ARGS void **mod_data, zend_string *key, zend_string **val, zend_long maxlifetime
Expand Down Expand Up @@ -160,19 +159,16 @@ typedef struct _php_ps_globals {
zend_long gc_maxlifetime;
int module_number;
zend_long cache_expire;
union {
zval names[PS_NUM_APIS];
struct {
zval ps_open;
zval ps_close;
zval ps_read;
zval ps_write;
zval ps_destroy;
zval ps_gc;
zval ps_create_sid;
zval ps_validate_sid;
zval ps_update_timestamp;
} name;
struct {
zval ps_open;
zval ps_close;
zval ps_read;
zval ps_write;
zval ps_destroy;
zval ps_gc;
zval ps_create_sid;
zval ps_validate_sid;
zval ps_update_timestamp;
} mod_user_names;
bool mod_user_implemented;
bool mod_user_is_open;
Expand Down
Loading