ID: 15044
User updated by: [EMAIL PROTECTED]
Reported By: [EMAIL PROTECTED]
Old Status: Feedback
Status: Open
Bug Type: Reproducible crash
Operating System: Redhat 7.1/Windows ME
PHP Version: 4.1.1
New Comment:

> Is MySQL return NULL for null fields? Then you 
> MUST NOT return NULL, but return ''.

You have identified the problem.  The fields in my database are defined
as "NOT NULL".  However, the record may not exist (this is certainly
true the first time around) causing mysql_fetch to return a non-array
value.  My code would then subscript this non-array and return an unset
value, which is equivalent to returning a NULL field.  Yet again I am
caught by the "almost-equivalence" of unset values and '' values.  

I checked out the idea by changing my read function to return '' if the
row doesn't exist or the DB field is unset.  The problem went away.

It is interesting to note that the use of the non-existent index did
*not* result in the normal warning (I run with all warnings turned on).
 In this case mysql_fetch returned a boolean type (false), which was
then subscripted.  No warning about incompatible types or a
non-existent index was given.  Probably some sort of warning should be
generated when idiots like me do such silly things.

> Are you having the same proboem with RH7.1 and 
> windows?

Yes, and the solution derived from your suggestion works on both.

As far as I am concerned, this issue is closed.  I would suggest,
though, that whatever calls session_read be a bit more defensive and
protect itself against unset return values.

Thank you.


Previous Comments:
------------------------------------------------------------------------

[2002-01-15 20:01:15] [EMAIL PROTECTED]

FYI, I don't have problem with user save handler with PostgreSQL at
all.
Is MySQL return NULL for null fields? Then you MUST NOT return NULL,
but return ''.

Are you having the same proboem with RH7.1 and windows?
Could you send backtrace from RH7.1, it may help.

------------------------------------------------------------------------

[2002-01-15 08:34:22] [EMAIL PROTECTED]

Thanks for the "die" tip.

I am not supplying a serializer, but instead am depending on the one
supplied by default.  My assumption, which seems to be born out in
practice, is that "write" is given already-serialized data and that
"read" is expected to return this same serialized data.  The issue is,
of course, that the first "read" doesn't have anything to return since
"write" hasn't yet been called.

I can't pretend to understand what is happening.  What is certain is
that the behavior changed from 4.0.6 to 4.1.0.  What seems to be true
is that ensuring that read gives back *something* in correct serialized
format corrects the problem.  I suspect a relationship with
constructing the new $_SESSION array, but can't prove it.

------------------------------------------------------------------------

[2002-01-15 08:11:16] [EMAIL PROTECTED]

That's strange. read should treat '' well.
That is your serializer?


BTW, don't use die(), but return error (false) except for read.

------------------------------------------------------------------------

[2002-01-15 06:34:43] [EMAIL PROTECTED]

PHP crashes reliably under windows ME and semi-reliably under Linux
when using user-registered session-handling w/mysql, or at least using
*my* session-handling code.  The problem begins if there are no session
variables defined; that is the session_read function returns an empty
string.  As far as I can tell, in this case the $_SESSION array is
created in some strange state and the session_write function is never
called.  Under Windows ME, the CGI process dies with an access
violation near the end of processing; the page is 1/2 displayed.  Under
Linux, the apache/php process segfaults around 25% of the time.  This
behavior did not occur using php.4.0.6 and earlier.

There is some interaction with register_globals.  If I turned
register_globals on, the frequency of the crash under linux was halved,
but php under windows continued to crash reliably.  I was unable to
find any pattern under linux.

The work-around is to never return '' from the session_read function. 
After making this change, the crashes under Windows and Linux stopped
and joy was returned to my world.

It is, of course, possible that I am misusing the session-handling
feature.  If this is the case, please let me know and accept my
apologies for what becomes a semi-bogus bug report.

Note that the script consisting of the session registration code
included below and "phpinfo()" provoked the crash.
============
Configuration information: Windows
- Windows ME
- apache 1.3.20 binary release
- PHP 4.1.1 full binary release, configured as CGI
============
Configuration information: Linux.
- Redhat 7.1, updated.
- Apache 1.3.22 (also tried with 1.3.19)
- PHP 4.1.1, compiled as module (also tried 4.1.0)
============
php configure script:
./configure \
    --with-mysql=/usr \
    --enable-sysvsem \
    --enable-sysvshm \
    --enable-debugger \
    --enable-force-cgi-redirect \
    --disable-short-tags \
    --prefix=/home/php \
    --with-config-file-path=/home/php \
    --with-exec-dir=/home/php/bin \
    --enable-discard-path \
    --with-oci8=/home/oracle/app/oracle/product/8.0.5 \
    --with-apache=/usr/src/local/apache_1.3.22 \
    --with-ldap
============
apache configure script:
./configure --prefix=/usr \
 --with-layout=RedHat \
 --enable-module=all \
 --enable-shared=max \
 --disable-rule=WANTHSREGEX \
 --disable-module=auth_dbm \
 --enable-suexec \
 --suexec-caller=web \
 --suexec-docroot=/home/httpd/html \
 --suexec-logfile=/var/log/httpd/suexec.log \
 --suexec-userdir=public_web \
 --suexec-uidmin=500 \
 --suexec-gidmin=100 \
 --suexec-safepath=/usr/local/bin:/usr/bin:/bin \
 --activate-module=src/modules/php4/libphp4.a \
 --activate-module=src/modules/auth_mysql/libauth_mysql.a
============
My session-handling code:

include_once "open_db.php";
function mySession_open ($save_path, $session_name) {
        if (isset ($_COOKIE['AUPcatalog'])) {
                session_id($_COOKIE['AUPcatalog']);
        }
        return true;
}

function mySession_close() {
    return true;
}

function mySession_read ($key) {
        $sess = mysql_query ("select ps_vars from phpsessions where
ps_sessionid = '$key'") or die (mysql_error());
        $v = mysql_fetch_array ($sess, MYSQL_ASSOC);
        if (!isset ($v['ps_vars']) || $v['ps_vars'] == '')
                return "F1F2F3|i:1;";   // must return something, apparently!
        return $v['ps_vars'];
}

function mySession_write ($key, $val) {
        mysql_query ("update phpsessions set ps_vars='$val',
ps_lasttouched=UNIX_TIMESTAMP() where ps_sessionid = '$key'") or die
(mysql_error());
        if (mysql_affected_rows() == 0) {
                mysql_query ("insert phpsessions set ps_vars='$val',
ps_lasttouched=UNIX_TIMESTAMP(), ps_sessionid = '$key'");
        }
        return true;
}

function mySession_destroy ($key) {
        mysql_query ("delete from mycourses where mc_sessionid = '$key'");
        mysql_query ("delete from phpsessions where ps_sessionid = '$key'");
    return true;
}

function mySession_gc ($maxlifetime) {
        $sessions = mysql_query ("select ps_sessionid from phpsessions where
ps_lasttouched < UNIX_TIMESTAMP() - $maxlifetime") or die
(mysql_error());
        while ($sess = mysql_fetch_array($sessions, MYSQL_ASSOC)) {
                if ($sess['ps_sessionid'] == session_id()) {
                        continue;
                }
                mySession_destroy ($sess['ps_sessionid']);
        }
    return true;
}

session_module_name ("user");
session_set_save_handler ("mySession_open", "mySession_close",
"mySession_read", "mySession_write", "mySession_destroy",
"mySession_gc");
 
session_name ("AUPcatalog");
session_start();
============

------------------------------------------------------------------------



Edit this bug report at http://bugs.php.net/?id=15044&edit=1


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to