From:             [EMAIL PROTECTED]
Operating system: Win 2K
PHP version:      4.2.3
PHP Bug Type:     Session related
Bug description:  Session and EscapeShellCmd problem

I am using sessions with variables that have passed through
EscapeShellCmd().  The EscapeShellCmd function does its job well and
appends a \ before each special character.  I am also using user defined
session handlers with session_set_save_handler().  Listed below is my
script that executes the session_set_save_handler function along with all
the functions for the session handlers.  The problem occurs when PHP
inserts or updates a value to the session database that has gone through
the EscapeShellCmd function and escaped any special characters.  The
session separator value counts the backslashes even though they are not
posted.  For instance:

/***********************************************/
// If I set a variable 
$test = “b’lah”;
// And then run the EscapeShellCmd function
$test = EscapeShellCmd($test);
// and then register it as a session variable
session_register(“test”);
// then print the variable to see what it looks like
print $test;    # This outputs: b\’lah
/***********************************************/

It adds the session, but counts the backslash as part of the session
separator so that the session variable looks something like this: 

test|s:6:"b'lah";

when it should read:

test|s:5:"b'lah";

Because it says 6, the count of characters is off and all of the session
variables become damaged.

If this is not a bug, and there is an easy solution to this please let me
know, and I apologize for posting here.  I have asked around and am unable
to find an answer.

Thank you for your time and effort.

-Glenn DeVore

P.S. Below is my session handlers script.


/***********************************************/
// This is the session handler script page
/***********************************************/

include("error.inc");
include("db.inc");

// The database connection
// $connection;

// The global variable that holds the table name
// $session_table;

// Returns current time as a number.
// Used for recording the last session access.
//
if (!function_exists('getMicroTime')) {
function getMicroTime()
{
  // microtime() returns the number of seconds
  // since 0:00:00 January 1, 1970 GMT as a
  // microsecond part and a second part.
  // eg: 0.08344800 1000952237
  // Convert the two parts into an array
  $mtime = explode(" ", microtime());

  // Return the addition of the two parts
  // eg: 1000952237.08344800
  return($mtime[1] + $mtime[0]);
}
}


// The session open handler called by PHP whenever
// a session is initialized. Always returns true.
//
if (!function_exists('sessionOpen')) {
function sessionOpen($database_name, $table_name)
{

  // Save the database name in a global variable
  global $connection;
  global $hostName;
  global $username;
  global $password;
  global $session_table;

  if (!($connection = @ mysql_pconnect($hostName,
                                       $username,
                                       $password)))
     showerror();

  if (!mysql_select_db($database_name, $connection))
     showerror();

  // Save the table name in a global variable
  $session_table = $table_name;

  return true;
}
}
// This function is called whenever a session_start()
// call is made and reads the session variables
// Returns "" when a session is not found
//         (serialized)string - session exists
//
if (!function_exists('sessionRead')) {
function sessionRead($sess_id)
{
  // Access the DBMS connection
  global $connection;

  // Access the global variable that holds the name
  // of the table that holds the session variables
  global $session_table;

  // Formulate a query to find the session
  // identified by $sess_id
  $search_query =
    "SELECT * FROM $session_table
      WHERE session_id = '$sess_id'";

  // Execute the query
  if (!($result = @ mysql_query($search_query,
                                $connection)))
     showerror();

  if(mysql_num_rows($result) == 0)
    // No session found - return an empty string
    return "";
  else
  {
    // Found a session - return the serialized string
    $row = mysql_fetch_array($result);
    return $row["session_variable"];
  }
}
}

// This function is called when a session is initialized
// with a session_start() call, when variables are
// registered or unregistered, and when session variables
// are modified. Returns true on success.
//
if (!function_exists('sessionWrite')) {
function sessionWrite($sess_id, $val)
{
  global $connection;
  global $session_table;

  $time_stamp = getMicroTime();

  $search_query =
    "SELECT session_id FROM $session_table
       WHERE session_id = '$sess_id'";

  // Execute the query
  if (!($result = @ mysql_query($search_query,
                                $connection)))
     showerror();

  if(mysql_num_rows($result) == 0)
  {
     // No session found, insert a new one
     $insert_query =
         "INSERT INTO $session_table
          (session_id, session_variable, last_accessed)
           VALUES ('$sess_id', '$val', $time_stamp)";

     if (!mysql_query($insert_query,
                      $connection))
        showerror();
  }
  else
  {
     // Existing session found - Update the
     // session variables
     $update_query =
       "UPDATE $session_table
        SET session_variable = '$val',
            last_accessed = $time_stamp
        WHERE session_id = '$sess_id'";

     if (!mysql_query($update_query,
                      $connection))
        showerror();
  }
  return true;
}
}

// This function is executed on shutdown of the session.
// Always returns true.
//
if (!function_exists('sessionClose')) {
function sessionClose()
{
    return true;
}
}

// This is called whenever the session_destroy()
// function call is made. Returns true if the session
// has successfully been deleted.
//
if (!function_exists('sessionDestroy')) {
function sessionDestroy($sess_id)
{
  global $connection;
  global $session_table;

  $delete_query =
    "DELETE FROM $session_table
      WHERE session_id = '$sess_id'";

  if (!($result = @ mysql_query($delete_query,
                                $connection)))
     showerror();

  return true;
}
}

// This function is called on a session's start up with
// the probability specified in session.gc_probability.
// Performs garbage collection by removing all sessions
// that haven't been updated in the last $max_lifetime
// seconds as set in session.gc_maxlifetime.
// Returns true if the DELETE query succeeded.
//
if (!function_exists('sessionGC')) {
function sessionGC($max_lifetime)
{
  global $connection;
  global $session_table;

  $time_stamp = getMicroTime();

  $delete_query =
    "DELETE FROM $session_table
      WHERE last_accessed < ($time_stamp - $max_lifetime)";

  if (!($result = @ mysql_query($delete_query,
                                $connection)))
     showerror();

  return true;
}
}

// This functiion registers a given URL to have the
// session id sent with the URL, instead of using
// cookies
//
if (!function_exists('registerURL')) {
  function registerURL($URL)
  {
        $sessionId = session_id();
  $registered_URL = $URL . "?PHPSESSION=" . $sessionId;
        return $registered_URL;
  }
}
// Call to register user call back functions.

session_set_save_handler("sessionOpen",
                         "sessionClose",
                         "sessionRead",
                         "sessionWrite",
                         "sessionDestroy",
                         "sessionGC");

/***********************************************/
/***********************************************/
-- 
Edit bug report at http://bugs.php.net/?id=20142&edit=1
-- 
Try a CVS snapshot:         http://bugs.php.net/fix.php?id=20142&r=trysnapshot
Fixed in CVS:               http://bugs.php.net/fix.php?id=20142&r=fixedcvs
Fixed in release:           http://bugs.php.net/fix.php?id=20142&r=alreadyfixed
Need backtrace:             http://bugs.php.net/fix.php?id=20142&r=needtrace
Try newer version:          http://bugs.php.net/fix.php?id=20142&r=oldversion
Not developer issue:        http://bugs.php.net/fix.php?id=20142&r=support
Expected behavior:          http://bugs.php.net/fix.php?id=20142&r=notwrong
Not enough info:            http://bugs.php.net/fix.php?id=20142&r=notenoughinfo
Submitted twice:            http://bugs.php.net/fix.php?id=20142&r=submittedtwice
register_globals:           http://bugs.php.net/fix.php?id=20142&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=20142&r=php3
Daylight Savings:           http://bugs.php.net/fix.php?id=20142&r=dst
IIS Stability:              http://bugs.php.net/fix.php?id=20142&r=isapi

Reply via email to