Skip to content

Commit 20190c9

Browse files
author
Andrei Zmievski
committed
Session variables now obey track_vars and gpc_globals settings. If track_vars is on then decoded variables appear in $HTTP_STATE_VARS array. If gpc_globals is on, then session vars are decoded into global variables. If both are on, then globals and $HTTP_STATE_VARS contents are references to each other. The /decoder functions now just need to call php_set_session_var() this behavior. @ -Session vars are now decoded into $HTTP_STATE_VARS[] array and the @ globals, depending on track_vars and gpc_globals settings (Andrei) # Encoding source is currently only globals. We may want to change this # in the future.
1 parent f962a35 commit 20190c9

File tree

3 files changed

+70
-28
lines changed

3 files changed

+70
-28
lines changed

ext/session/php_session.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ typedef struct {
9090
int gc_maxlifetime;
9191
int module_number;
9292
const struct ps_serializer_struct *serializer;
93+
zval *http_state_vars;
9394
} php_ps_globals;
9495

9596
extern zend_module_entry session_module_entry;

ext/session/session.c

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ PHP_INI_BEGIN()
7676
PHP_INI_ENTRY("session.extern_referer_check", "", PHP_INI_ALL, NULL)
7777
PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, NULL)
7878
PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, NULL)
79+
/* Commented out until future discussion */
80+
/* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
7981
PHP_INI_END()
8082

8183
PS_SERIALIZER_FUNCS(php);
@@ -137,32 +139,57 @@ zend_module_entry session_module_entry = {
137139

138140
#define PS_DEL_VAR(name) PS_DEL_VARL(name, strlen(name))
139141

140-
141-
142-
143142
#define ENCODE_VARS \
144143
char *key; \
145144
ulong num_key; \
146-
zval **struc; \
147-
ELS_FETCH()
145+
zval **struc \
146+
PSLS_FETCH(); \
147+
ELS_FETCH();
148148

149149
#define ENCODE_LOOP(code) \
150150
for(zend_hash_internal_pointer_reset(&PS(vars)); \
151151
zend_hash_get_current_key(&PS(vars), &key, &num_key) == HASH_KEY_IS_STRING; \
152152
zend_hash_move_forward(&PS(vars))) { \
153-
if(zend_hash_find(&EG(symbol_table), key, strlen(key) + 1, (void **) &struc) == SUCCESS) { \
153+
if(php_get_session_var(key, strlen(key), &struc PSLS_CC ELS_CC) == SUCCESS) { \
154154
code; \
155155
} \
156156
efree(key); \
157157
}
158158

159+
static void php_set_session_var(char *name, size_t namelen,
160+
zval *state_val PSLS_DC)
161+
{
162+
zval *state_val_copy;
163+
PLS_FETCH();
164+
ELS_FETCH();
159165

166+
state_val_copy = (zval *)emalloc(sizeof(zval));
167+
*state_val_copy = *state_val;
168+
zval_copy_ctor(state_val_copy);
169+
170+
if (PG(gpc_globals) && PG(track_vars)) {
171+
zend_set_hash_symbol(state_val_copy, name, namelen, 1, 2, PS(http_state_vars)->value.ht, &EG(symbol_table));
172+
} else {
173+
if (PG(gpc_globals)) {
174+
zend_set_hash_symbol(state_val_copy, name, namelen, 0, 1, PS(http_state_vars)->value.ht);
175+
}
176+
177+
if (PG(track_vars)) {
178+
zend_set_hash_symbol(state_val_copy, name, namelen, 0, 1, &EG(symbol_table));
179+
}
180+
}
181+
}
182+
183+
static int php_get_session_var(char *name, size_t namelen, zval ***state_var PSLS_DC ELS_DC)
184+
{
185+
return zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **)state_var);
186+
}
160187

161188
PS_SERIALIZER_ENCODE_FUNC(php)
162189
{
163-
pval *buf;
190+
zval *buf;
164191
char strbuf[MAX_STR + 1];
165-
ENCODE_VARS;
192+
ENCODE_VARS
166193

167194
buf = ecalloc(sizeof(*buf), 1);
168195
buf->type = IS_STRING;
@@ -189,11 +216,11 @@ PS_SERIALIZER_DECODE_FUNC(php)
189216
const char *p, *q;
190217
char *name;
191218
const char *endptr = val + vallen;
192-
pval *current;
219+
zval *current;
193220
int namelen;
194221
int has_value;
195-
ELS_FETCH();
196222

223+
current = (zval *) ecalloc(sizeof(zval), 1);
197224
for(p = q = val; (p < endptr) && (q = strchr(p, '|')); p = q) {
198225
if(p[0] == '!') {
199226
p++;
@@ -207,18 +234,15 @@ PS_SERIALIZER_DECODE_FUNC(php)
207234
q++;
208235

209236
if(has_value) {
210-
current = (pval *) ecalloc(sizeof(pval), 1);
211-
212237
if(php_var_unserialize(&current, &q, endptr)) {
213-
zend_hash_update(&EG(symbol_table), name, namelen + 1,
214-
&current, sizeof(current), NULL);
215-
} else {
216-
efree(current);
238+
php_set_session_var(name, namelen, current PSLS_CC);
239+
zval_dtor(current);
217240
}
218241
}
219242
PS_ADD_VAR(name);
220243
efree(name);
221244
}
245+
efree(current);
222246

223247
return SUCCESS;
224248
}
@@ -228,7 +252,7 @@ PS_SERIALIZER_DECODE_FUNC(php)
228252
PS_SERIALIZER_ENCODE_FUNC(wddx)
229253
{
230254
wddx_packet *packet;
231-
ENCODE_VARS;
255+
ENCODE_VARS
232256

233257
packet = _php_wddx_constructor();
234258
if(!packet) return FAILURE;
@@ -259,7 +283,6 @@ PS_SERIALIZER_DECODE_FUNC(wddx)
259283
ulong idx;
260284
int hash_type;
261285
int dofree = 1;
262-
ELS_FETCH();
263286

264287
if(vallen == 0) return FAILURE;
265288

@@ -278,9 +301,7 @@ PS_SERIALIZER_DECODE_FUNC(wddx)
278301
key = tmp;
279302
dofree = 0;
280303
case HASH_KEY_IS_STRING:
281-
zval_add_ref(ent);
282-
zend_hash_update(&EG(symbol_table), key, strlen(key) + 1,
283-
ent, sizeof(ent), NULL);
304+
php_set_session_var(key, strlen(key), ent PSLS_CC)
284305
PS_ADD_VAR(key);
285306
if(dofree) efree(key);
286307
dofree = 1;
@@ -295,6 +316,20 @@ PS_SERIALIZER_DECODE_FUNC(wddx)
295316

296317
#endif
297318

319+
static void php_session_track_init()
320+
{
321+
PSLS_FETCH();
322+
ELS_FETCH();
323+
324+
if (zend_hash_find(&EG(symbol_table), "HTTP_STATE_VARS", sizeof("HTTP_STATE_VARS"),
325+
(void **)&PS(http_state_vars)) == FAILURE || PS(http_state_vars)->type != IS_ARRAY) {
326+
MAKE_STD_ZVAL(PS(http_state_vars));
327+
array_init(PS(http_state_vars));
328+
ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_STATE_VARS", sizeof("HTTP_STATE_VARS"), PS(http_state_vars), 1, 0);
329+
} else
330+
zend_hash_clean(PS(http_state_vars)->value.ht);
331+
}
332+
298333
static char *_php_session_encode(int *newlen PSLS_DC)
299334
{
300335
char *ret = NULL;
@@ -308,6 +343,8 @@ static char *_php_session_encode(int *newlen PSLS_DC)
308343

309344
static void _php_session_decode(const char *val, int vallen PSLS_DC)
310345
{
346+
if (PG(track_vars))
347+
php_session_track_init();
311348
PS(serializer)->decode(val, vallen PSLS_CC);
312349
}
313350

@@ -733,19 +770,19 @@ PHP_FUNCTION(session_id)
733770
/* }}} */
734771

735772

736-
/* {{{ static void php_register_var(zval** entry PSLS_DC) */
737-
static void php_register_var(zval** entry PSLS_DC)
773+
/* {{{ static void php_register_var(zval** entry PSLS_DC PLS_DC) */
774+
static void php_register_var(zval** entry PSLS_DC PLS_DC)
738775
{
739776
zval** value;
740777

741778
if ((*entry)->type == IS_ARRAY) {
742779
zend_hash_internal_pointer_reset((*entry)->value.ht);
743780

744781
while(zend_hash_get_current_data((*entry)->value.ht, (void**)&value) == SUCCESS) {
745-
php_register_var(value PSLS_CC);
782+
php_register_var(value PSLS_CC PLS_DC);
746783
zend_hash_move_forward((*entry)->value.ht);
747784
}
748-
} else {
785+
} else if (!PG(track_vars) || strcmp((*entry)->value.str.val, "HTTP_STATE_VARS") != 0) {
749786
convert_to_string_ex(entry);
750787

751788
PS_ADD_VARL((*entry)->value.str.val, (*entry)->value.str.len);
@@ -762,6 +799,7 @@ PHP_FUNCTION(session_register)
762799
int argc = ARG_COUNT(ht);
763800
int i;
764801
PSLS_FETCH();
802+
PLS_FETCH();
765803

766804
if (argc <= 0) {
767805
RETURN_FALSE;
@@ -780,7 +818,7 @@ PHP_FUNCTION(session_register)
780818
if ((*args[i])->type == IS_ARRAY) {
781819
SEPARATE_ZVAL(args[i]);
782820
}
783-
php_register_var(args[i] PSLS_CC);
821+
php_register_var(args[i] PSLS_CC PLS_DC);
784822
}
785823

786824
efree(args);
@@ -928,6 +966,8 @@ PHP_FUNCTION(session_unset)
928966

929967
static void php_rinit_session_globals(PSLS_D)
930968
{
969+
ELS_FETCH();
970+
931971
PS(mod) = _php_find_ps_module(INI_STR("session.save_handler") PSLS_CC);
932972
PS(serializer) = \
933973
_php_find_ps_serializer(INI_STR("session.serialize_handler") PSLS_CC);
@@ -974,6 +1014,7 @@ void _php_session_auto_start(void *data)
9741014
PHP_RINIT_FUNCTION(session)
9751015
{
9761016
PSLS_FETCH();
1017+
PLS_FETCH();
9771018

9781019
php_rinit_session_globals(PSLS_C);
9791020

@@ -983,7 +1024,7 @@ PHP_RINIT_FUNCTION(session)
9831024
return SUCCESS;
9841025
}
9851026

986-
if(INI_INT("session.auto_start")) {
1027+
if (INI_INT("session.auto_start")) {
9871028
php_register_post_request_startup(_php_session_auto_start, NULL);
9881029
}
9891030

main/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ PHP_INI_BEGIN()
252252
STD_PHP_INI_BOOLEAN("track_vars", "0", PHP_INI_ALL, OnUpdateBool, track_vars, php_core_globals, core_globals)
253253
#endif
254254

255-
STD_PHP_INI_BOOLEAN("gpc_globals", "1", PHP_INI_ALL, OnUpdateBool, gpc_globals, php_core_globals, core_globals)
255+
STD_PHP_INI_BOOLEAN("gpc_globals", "1", PHP_INI_ALL, OnUpdateBool, gpc_globals, php_core_globals, core_globals)
256256
STD_PHP_INI_ENTRY("gpc_order", "GPC", PHP_INI_ALL, OnUpdateStringUnempty, gpc_order, php_core_globals, core_globals)
257257
STD_PHP_INI_ENTRY("arg_separator", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator, php_core_globals, core_globals)
258258
STD_PHP_INI_BOOLEAN("ignore_user_abort", "1", PHP_INI_ALL, OnUpdateBool, ignore_user_abort, php_core_globals, core_globals)

0 commit comments

Comments
 (0)