@@ -232,36 +232,39 @@ typedef struct {
232
232
233
233
#define MAX_STR 512
234
234
235
- void php_set_session_var (char * name , size_t namelen , zval * state_val PSLS_DC )
235
+ void php_set_session_var (char * name , size_t namelen , zval * state_val , HashTable * var_hash PSLS_DC )
236
236
{
237
- zval * state_val_copy ;
238
237
PLS_FETCH ();
239
238
ELS_FETCH ();
240
239
241
- ALLOC_ZVAL (state_val_copy );
242
- * state_val_copy = * state_val ;
243
- zval_copy_ctor (state_val_copy );
244
- state_val_copy -> refcount = 0 ;
245
-
246
240
if (PG (register_globals )) {
247
241
zval * * old_symbol ;
248
- if (zend_hash_find (& EG (symbol_table ),name ,namelen + 1 ,(void * )& old_symbol ) == SUCCESS ) {
242
+ if (zend_hash_find (& EG (symbol_table ),name ,namelen + 1 ,(void * )& old_symbol ) == SUCCESS ) {
249
243
/*
250
244
There where old one, we need to replace it accurately.
251
245
hash_update in zend_set_hash_symbol is not good, because
252
246
it will leave referenced variables (such as local instances
253
247
of a global variable) dangling.
248
+
249
+ BTW: if you use register_globals references between
250
+ session-vars won't work because of this very reason!
254
251
*/
252
+
255
253
256
- REPLACE_ZVAL_VALUE (old_symbol ,state_val_copy ,0 );
257
- FREE_ZVAL (state_val_copy );
254
+ REPLACE_ZVAL_VALUE (old_symbol ,state_val ,1 );
255
+
256
+ /* the following line will muck with the reference-table used for
257
+ * unserialisation
258
+ */
259
+
260
+ PHP_VAR_UNSERIALIZE_ZVAL_CHANGED (var_hash ,state_val ,* old_symbol );
258
261
259
262
zend_set_hash_symbol (* old_symbol , name , namelen , 1 , 1 , Z_ARRVAL_P (PS (http_session_vars )));
260
263
} else {
261
- zend_set_hash_symbol (state_val_copy , name , namelen , 1 , 2 , Z_ARRVAL_P (PS (http_session_vars )), & EG (symbol_table ));
264
+ zend_set_hash_symbol (state_val , name , namelen , 1 , 2 , Z_ARRVAL_P (PS (http_session_vars )), & EG (symbol_table ));
262
265
}
263
266
} else {
264
- zend_set_hash_symbol (state_val_copy , name , namelen , 0 , 1 , Z_ARRVAL_P (PS (http_session_vars )));
267
+ zend_set_hash_symbol (state_val , name , namelen , 0 , 1 , Z_ARRVAL_P (PS (http_session_vars )));
265
268
}
266
269
}
267
270
@@ -329,7 +332,6 @@ PS_SERIALIZER_DECODE_FUNC(php_binary)
329
332
330
333
PHP_VAR_UNSERIALIZE_INIT (var_hash );
331
334
332
- MAKE_STD_ZVAL (current );
333
335
for (p = val ; p < endptr ; ) {
334
336
namelen = * p & (~PS_BIN_UNDEF );
335
337
has_value = * p & PS_BIN_UNDEF ? 0 : 1 ;
@@ -339,15 +341,16 @@ PS_SERIALIZER_DECODE_FUNC(php_binary)
339
341
p += namelen + 1 ;
340
342
341
343
if (has_value ) {
344
+ MAKE_STD_ZVAL (current );
342
345
if (php_var_unserialize (& current , & p , endptr , & var_hash )) {
343
- php_set_session_var (name , namelen , current PSLS_CC );
344
- zval_dtor (current );
346
+ php_set_session_var (name , namelen , current , & var_hash PSLS_CC );
345
347
}
348
+ zval_ptr_dtor (& current );
346
349
}
347
350
PS_ADD_VARL (name , namelen );
348
351
efree (name );
349
352
}
350
- FREE_ZVAL ( current );
353
+
351
354
PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
352
355
353
356
return SUCCESS ;
@@ -405,7 +408,6 @@ PS_SERIALIZER_DECODE_FUNC(php)
405
408
406
409
PHP_VAR_UNSERIALIZE_INIT (var_hash );
407
410
408
- MAKE_STD_ZVAL (current );
409
411
for (p = q = val ; (p < endptr ) && (q = memchr (p , PS_DELIMITER , endptr - p )); p = q ) {
410
412
if (p [0 ] == PS_UNDEF_MARKER ) {
411
413
p ++ ;
@@ -419,17 +421,18 @@ PS_SERIALIZER_DECODE_FUNC(php)
419
421
q ++ ;
420
422
421
423
if (has_value ) {
424
+ MAKE_STD_ZVAL (current );
422
425
if (php_var_unserialize (& current , & q , endptr , & var_hash )) {
423
- php_set_session_var (name , namelen , current PSLS_CC );
424
- zval_dtor (current );
426
+ php_set_session_var (name , namelen , current , & var_hash PSLS_CC );
425
427
}
428
+ zval_ptr_dtor (& current );
426
429
}
427
430
PS_ADD_VARL (name , namelen );
428
431
efree (name );
429
432
}
430
- FREE_ZVAL (current );
431
433
432
434
PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
435
+
433
436
return SUCCESS ;
434
437
}
435
438
@@ -543,18 +546,20 @@ static void php_session_save_current_state(PSLS_D)
543
546
int vallen ;
544
547
int ret = FAILURE ;
545
548
char * variable ;
549
+ ulong variable_len ;
546
550
ulong num_key ;
551
+ HashPosition pos ;
547
552
PLS_FETCH ();
548
553
549
554
if (!PG (register_globals )) {
550
555
if (!PS (http_session_vars )) {
551
556
return ;
552
557
}
553
-
554
- for (zend_hash_internal_pointer_reset (Z_ARRVAL_P (PS (http_session_vars )));
555
- zend_hash_get_current_key (Z_ARRVAL_P (PS (http_session_vars )), & variable , & num_key , 1 ) == HASH_KEY_IS_STRING ;
556
- zend_hash_move_forward (Z_ARRVAL_P (PS (http_session_vars )))) {
557
- PS_ADD_VAR (variable );
558
+
559
+ for (zend_hash_internal_pointer_reset_ex (Z_ARRVAL_P (PS (http_session_vars )), & pos );
560
+ zend_hash_get_current_key_ex (Z_ARRVAL_P (PS (http_session_vars )), & variable , & variable_len , & num_key , 0 , & pos ) == HASH_KEY_IS_STRING ;
561
+ zend_hash_move_forward_ex (Z_ARRVAL_P (PS (http_session_vars )), & pos )) {
562
+ PS_ADD_VARL (variable , variable_len - 1 );
558
563
}
559
564
}
560
565
0 commit comments