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.