]> granicus.if.org Git - php/commitdiff
Fix handling of session user module custom handlers.
authorSara Golemon <pollita@php.net>
Thu, 15 May 2014 21:00:15 +0000 (14:00 -0700)
committerSara Golemon <pollita@php.net>
Sun, 6 Jul 2014 16:40:35 +0000 (09:40 -0700)
According to the documentation, returning TRUE from
user based session handlers should indicate success,
while returning FALSE should indicate failure.

The existing logic relied on casting the return value
to an integer and returning that from the function.
However, the internal handlers use SUCCESS/FAILURE
where SUCCESS == 0, and FAILURE == -1, so the following
behavior map occurs:

  return false; => return 0; => return SUCCESS
  return true; => return 1; => return <undefined>

Since the session API checks against FAILURE,
both boolean responses wind up appearing like "not FAILURE".

This diff reasserts boolean responses to behave as
documented and introduces some special handling
for integer responses of 0 and -1 so that code can be
written for older and newer versions of PHP.

NEWS
ext/session/mod_user.c

diff --git a/NEWS b/NEWS
index 50ae0467861d5909fd844ecb9d9667f1ba0478bf..1badfb85794eadda3249b4008487c1ddb645c409 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ PHP                                                                        NEWS
 
 - Standard:
   . Removed call_user_method() and call_user_method_array() functions. (Kalle)
+  . Fix user session handlers (See rfc:session.user.return-value). (Sara)
 
 - XSL:
   . Fixed bug #64776 (The XSLT extension is not thread safe). (Mike)
index 5573d4cdfd7338bbaca9aa5fea5fe6c1ff910d94..6720987580925068a42548f3652b31ee4d5eb4d6 100644 (file)
@@ -68,12 +68,22 @@ static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
 
 #define PSF(a) PS(mod_user_names).name.ps_##a
 
-#define FINISH                                                         \
-       if (retval) {                                                   \
-               convert_to_long(retval);                        \
-               ret = Z_LVAL_P(retval);                         \
-               zval_ptr_dtor(&retval);                         \
-       }                                                                               \
+#define FINISH \
+       if (retval) { \
+               if (Z_TYPE_P(retval) == IS_BOOL) { \
+                       ret = Z_BVAL_P(retval) ? SUCCESS : FAILURE; \
+                }  else if ((Z_TYPE_P(retval) == IS_LONG) && (Z_LVAL_P(retval) == -1)) { \
+                       /* BC for clever users - Deprecate me */ \
+                       ret = FAILURE; \
+               } else if ((Z_TYPE_P(retval) == IS_LONG) && (Z_LVAL_P(retval) == 0)) { \
+                       /* BC for clever users - Deprecate me */ \
+                       ret = SUCCESS; \
+               } else { \
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session callback expects true/false return value"); \
+                       ret = FAILURE; \
+               } \
+               zval_ptr_dtor(&retval); \
+       } \
        return ret
 
 PS_OPEN_FUNC(user)