Skip to content

Instantly share code, notes, and snippets.

@yohgaki
Created November 4, 2016 03:49
Show Gist options
  • Save yohgaki/763044b83192cea3bfa6939503c4f889 to your computer and use it in GitHub Desktop.
Save yohgaki/763044b83192cea3bfa6939503c4f889 to your computer and use it in GitHub Desktop.
Check delimiter and marker chars always, and remove legacy PS_ENCODE_LOOP macro.
diff --git a/ext/session/session.c b/ext/session/session.c
index b2d0236..4b30b96 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -890,19 +890,31 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary) /* {{{ */
smart_str buf = {0};
php_serialize_data_t var_hash;
PS_ENCODE_VARS;
+ HashTable *_ht;
+ int key_type;
PHP_VAR_SERIALIZE_INIT(var_hash);
- PS_ENCODE_LOOP(
- if (key_length > PS_BIN_MAX) continue;
- smart_str_appendc(&buf, (unsigned char) key_length);
- smart_str_appendl(&buf, key, key_length);
- php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
- } else {
- if (key_length > PS_BIN_MAX) continue;
- smart_str_appendc(&buf, (unsigned char) (key_length & PS_BIN_UNDEF));
- smart_str_appendl(&buf, key, key_length);
- );
+ _ht = Z_ARRVAL_P(PS(http_session_vars));
+ 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_EXISTENT;
+ zend_hash_move_forward(_ht)) {
+ if (key_type == HASH_KEY_IS_LONG) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key);
+ continue;
+ }
+ key_length--;
+ if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == FAILURE) {
+ PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ smart_str_free(&buf);
+ php_error_docref(NULL, E_WARNING, "Inconsistent session data state. Should never happen.");
+ return FAILURE;
+ }
+ if (key_length > PS_BIN_MAX) continue;
+ smart_str_appendc(&buf, (unsigned char) key_length);
+ smart_str_appendl(&buf, key, key_length);
+ php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
+ }
if (newlen) {
*newlen = buf.len;
@@ -982,24 +994,36 @@ PS_SERIALIZER_ENCODE_FUNC(php) /* {{{ */
smart_str buf = {0};
php_serialize_data_t var_hash;
PS_ENCODE_VARS;
+ HashTable *_ht;
+ int key_type;
PHP_VAR_SERIALIZE_INIT(var_hash);
- PS_ENCODE_LOOP(
- smart_str_appendl(&buf, key, key_length);
- if (memchr(key, PS_DELIMITER, key_length) || memchr(key, PS_UNDEF_MARKER, key_length)) {
- PHP_VAR_SERIALIZE_DESTROY(var_hash);
- smart_str_free(&buf);
- return FAILURE;
- }
- smart_str_appendc(&buf, PS_DELIMITER);
-
- php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
- } else {
- smart_str_appendc(&buf, PS_UNDEF_MARKER);
- smart_str_appendl(&buf, key, key_length);
- smart_str_appendc(&buf, PS_DELIMITER);
- );
+ _ht = Z_ARRVAL_P(PS(http_session_vars));
+ 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_EXISTENT;
+ zend_hash_move_forward(_ht)) {
+ if (key_type == HASH_KEY_IS_LONG) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key);
+ continue;
+ }
+ key_length--;
+ if (memchr(key, PS_DELIMITER, key_length) || memchr(key, PS_UNDEF_MARKER, key_length)) {
+ PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ smart_str_free(&buf);
+ php_error_docref(NULL, E_NOTICE, "php session serializer cannot have delimitter or undef marker char in key string");
+ return FAILURE;
+ }
+ if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == FAILURE) {
+ PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ smart_str_free(&buf);
+ php_error_docref(NULL, E_WARNING, "Inconsistent session data state. Should never happen.");
+ return FAILURE;
+ }
+ smart_str_appendl(&buf, key, key_length);
+ smart_str_appendc(&buf, PS_DELIMITER);
+ php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
+ }
if (newlen) {
*newlen = buf.len;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment