diff --git a/www/admin/class_test.session.php b/www/admin/class_test.session.php index 0f0af7d0..6c1256aa 100644 --- a/www/admin/class_test.session.php +++ b/www/admin/class_test.session.php @@ -17,6 +17,7 @@ if ($DEBUG_ALL) { * @param int $status * @return string */ +/** @phan-suppress-next-line PhanRedefineFunction */ function getSessionStatusString(int $status): string { switch ($status) { @@ -82,7 +83,7 @@ echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "
"; print "[UNSET] Current session id: " . Session::getSessionId() . "
"; print "[UNSET] Current session name: " . Session::getSessionName() . "
"; -print "[UNSET] Current session active: " . Session::checkActiveSession() . "
"; +print "[UNSET] Current session active: " . (Session::checkActiveSession() ? 'Yes' : 'No') . "
"; print "[UNSET] Current session status: " . getSessionStatusString(Session::getSessionStatus()) . "
"; if (isset($_SESSION)) { print "[UNSET] _SESSION is: set
"; @@ -92,22 +93,20 @@ if (isset($_SESSION)) { # print "[UNSET] To set session name valid: " . (Session::checkValidSessionName($session_name) ? 'Valid' : 'Invalid') . "
"; -$session = Session::startSession($session_name); -if ($session === false) { +if (false === ($session = Session::startSession($session_name))) { print "[FAILED] Session start failed: " . Session::getErrorStr() . "
"; } else { print "[SET] Current session id: " . $session . "
"; } // set again -$session = Session::startSession($session_name); -if ($session === false) { +if (false === ($session = Session::startSession($session_name))) { print "[2 FAILED] Session start failed: " . Session::getErrorStr() . "
"; } else { print "[2 SET] Current session id: " . $session . "
"; } print "[SET] Current session id: " . Session::getSessionId() . "
"; print "[SET] Current session name: " . Session::getSessionName() . "
"; -print "[SET] Current session active: " . Session::checkActiveSession() . "
"; +print "[SET] Current session active: " . (Session::checkActiveSession() ? 'Yes' : 'No') . "
"; print "[SET] Current session status: " . getSessionStatusString(Session::getSessionStatus()) . "
"; if (isset($_SESSION)) { print "[SET] _SESSION is: set
"; @@ -126,8 +125,7 @@ print "[READ] Confirm " . $var . " is " . $value . ": " // differnt session name $session_name = 'class-test-session-ALT'; -$session = Session::startSession($session_name); -if ($session === false) { +if (false === ($session = Session::startSession($session_name))) { print "[3 FAILED] Session start failed: " . Session::getErrorStr() . "
"; } else { print "[3 SET] Current session id: " . $session . "
"; @@ -143,8 +141,7 @@ $_SESSION['will_never_be_written'] = 'empty'; // open again $session_name = 'class-test-session'; -$session = Session::startSession($session_name); -if ($session === false) { +if (false === ($session = Session::startSession($session_name))) { print "[4 FAILED] Session start failed: " . Session::getErrorStr() . "
"; } else { print "[4 SET] Current session id: " . $session . "
"; @@ -152,6 +149,20 @@ if ($session === false) { print "[START AGAIN] Current session id: " . Session::getSessionId() . "
"; $_SESSION['will_be_written_again'] = 'Full'; +// close session +Session::writeClose(); +// invalid +$session_name = '123'; +if (false === ($session = Session::startSession($session_name))) { + print "[5 FAILED] Session start failed: " . Session::getErrorStr() . "
"; +} else { + print "[5 SET] Current session id: " . $session . "
"; +} +print "[BAD NAME] Current session id: " . Session::getSessionId() . "
"; +print "[BAD NAME] Current session name: " . Session::getSessionName() . "
"; +print "[BAD NAME] Current session active: " . (Session::checkActiveSession() ? 'Yes' : 'No') . "
"; +print "[BAD NAME] Current session status: " . getSessionStatusString(Session::getSessionStatus()) . "
"; + // error message print $log->printErrorMsg(); diff --git a/www/admin/class_test.session.read.php b/www/admin/class_test.session.read.php index 0434de5c..6a63b066 100644 --- a/www/admin/class_test.session.read.php +++ b/www/admin/class_test.session.read.php @@ -17,6 +17,7 @@ if ($DEBUG_ALL) { * @param int $status * @return string */ +/** @phan-suppress-next-line PhanRedefineFunction */ function getSessionStatusString(int $status): string { switch ($status) { @@ -78,27 +79,25 @@ echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "
"; print "[UNSET] Current session id: " . Session::getSessionId() . "
"; print "[UNSET] Current session name: " . Session::getSessionName() . "
"; -print "[UNSET] Current session active: " . Session::checkActiveSession() . "
"; +print "[UNSET] Current session active: " . (Session::checkActiveSession() ? 'Yes' : 'No') . "
"; print "[UNSET] Current session status: " . getSessionStatusString(Session::getSessionStatus()) . "
"; print "[READ] " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "
"; // start -$session = Session::startSession($session_name); -if ($session === false) { +if (false === ($session = Session::startSession($session_name))) { print "Session start failed: " . Session::getErrorStr() . "
"; } else { print "Current session id: " . $session . "
"; } // set again -$session = Session::startSession($session_name); -if ($session === false) { +if (false === ($session = Session::startSession($session_name))) { print "[2] Session start failed
"; } else { print "[2] Current session id: " . $session . "
"; } print "[SET] Current session id: " . Session::getSessionId() . "
"; print "[SET] Current session name: " . Session::getSessionName() . "
"; -print "[SET] Current session active: " . Session::checkActiveSession() . "
"; +print "[SET] Current session active: " . (Session::checkActiveSession() ? 'Yes' : 'No') . "
"; print "[SET] Current session status: " . getSessionStatusString(Session::getSessionStatus()) . "
"; print "[READ] " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "
"; print "[READ] Confirm " . $var . " is " . $value . ": " diff --git a/www/lib/CoreLibs/Create/Session.php b/www/lib/CoreLibs/Create/Session.php index 5cebe210..07970b62 100644 --- a/www/lib/CoreLibs/Create/Session.php +++ b/www/lib/CoreLibs/Create/Session.php @@ -18,6 +18,9 @@ namespace CoreLibs\Create; class Session { + /** @var string list for errors*/ + private static $error_str = ''; + /** * init a session */ @@ -25,6 +28,41 @@ class Session { } + /** + * Return set error string, empty if none set + * + * @return string Last error string + */ + public static function getErrorStr(): string + { + return self::$error_str; + } + + /** + * check if session name is valid + * + * As from PHP 8.1/8.0/7.4 error + * INVALID CHARS: =,; \t\r\n\013\014 + * NOTE: using . will fail even thought valid + * we allow only alphanumeric with - (dash) and 1 to 128 characters + * + * @param string $session_name any string, not null + * @return bool True for valid, False for invalid + */ + public static function checkValidSessionName(string $session_name): bool + { + // check + if ( + // must only have those + !preg_match('/^[-a-zA-Z0-9]{1,128}$/', $session_name) || + // cannot be only numbers + preg_match('/^[0-9]+$/', $session_name) + ) { + return false; + } + return true; + } + /** * Undocumented function * @@ -35,10 +73,12 @@ class Session { // we can't start sessions on command line if (php_sapi_name() === 'cli') { + self::$error_str = '[SESSION] No sessions in php cli'; return false; } // if session are OFF if (self::getSessionStatus() === PHP_SESSION_DISABLED) { + self::$error_str = '[SESSION] Sessions are disabled'; return false; } // session_status @@ -59,6 +99,11 @@ class Session } // if set, set special session name if (!empty($session_name)) { + // invalid session name, abort + if (!self::checkValidSessionName($session_name)) { + self::$error_str = '[SESSION] Invalid session name: ' . $session_name; + return false; + } session_name($session_name); } // start session @@ -66,6 +111,7 @@ class Session } // if we still have no active session if (!self::checkActiveSession()) { + self::$error_str = '[SESSION] Failed to activate session'; return false; } return self::getSessionId(); @@ -95,7 +141,7 @@ class Session * Checks if there is an active session. * Does not check if we can have a session * - * @return boolean True if there is an active session, else false + * @return bool True if there is an active session, else false */ public static function checkActiveSession(): bool { @@ -106,6 +152,19 @@ class Session } } + /** + * unlock the session file, so concurrent AJAX requests can be done + * NOTE: after this has been called, no changes in _SESSION will be stored + * NOTE: a new session with a different name can be started after this one is called + * if problem, run ob_flush() and flush() too + * + * @return bool True und sucess, false on failure + */ + public static function writeClose(): bool + { + return session_write_close(); + } + /** * get session status * PHP_SESSION_DISABLED if sessions are disabled.