From 618783d7594fb460f52783ec37d8b832e984b695 Mon Sep 17 00:00:00 2001
From: Jacek Kowalski <Jacek@jacekk.info>
Date: Wed, 11 Jun 2014 20:59:29 +0000
Subject: [PATCH] [mod_kino] Poprawki możliwego użycia niezdefiniowanych zmiennych w skrajnych przypadkach

---
 class/BotSession.php |   95 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/class/BotSession.php b/class/BotSession.php
index cec7f45..61511db 100644
--- a/class/BotSession.php
+++ b/class/BotSession.php
@@ -1,18 +1,29 @@
 <?php
 /**
- * Klasa przechowująca dane użytkownika. Całość przypomina mechanizm sesji w PHP.
+ * Klasa przechowująca dane przekazane przez użytkownika,
+ * w szczególności jego ustawienia.
  */
 class BotSession {
 	private $PDO;
 	
 	/**
 	 * Nazwa modułu, którego zmienne klasa przetwarza
-	 * @var string max. 40 znak�w
+	 * @var string $class max. 40 znaków
 	 */
-	var $class;
+	protected $class = '';
+	protected $class_empty = TRUE;
 	
+	/**
+	 * Pseudo-URL użytkownika.
+	 * @see BotUser
+	 * @var string $user URL użytkownika
+	 */
 	private $user;
-	
+	/**
+	 * Klasa z identyfikatorem użytkownika
+	 * @var BotUser $user_struct
+	 */
+	private $user_struct;
 	
 	/**
 	 * Inicjuje klasę w zależności od użytkownika
@@ -21,10 +32,14 @@
 		$this->user = sha1($user);
 		$this->user_struct = parse_url($user);
 		
-		$this->class = '';
+		$this->class_empty = FALSE;
 	}
 	
 	private function init() {
+		if(strlen($this->class) == 0 && !$this->class_empty) {
+			throw new Exception('Przed użyciem $msg->session należy ustawić nazwę modułu za pomocą metody setClass - patrz "Poradnik tworzenia modułów", dział "Klasa BotMessage", rozdział "Pole $session".');
+		}
+		
 		if($this->PDO) {
 			return NULL;
 		}
@@ -33,6 +48,30 @@
 			$this->PDO = new PDO('sqlite:'.BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
 			$this->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 			$this->PDO->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
+			
+			$st = $this->PDO->query('SELECT value FROM data WHERE class=\'\' AND name=\'_version\'');
+			$row = $st->fetch(PDO::FETCH_ASSOC);
+			if(is_array($row)) {
+				$version = (int)$row['value'];
+			}
+			else
+			{
+				$version = 0;
+			}
+			$st->closeCursor();
+			
+			if($version < 1) {
+				$this->PDO->query('UPDATE data SET class=\'kino\' WHERE class=\'\' AND name=\'kino\'');
+				$this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 1)');
+				$version = 1;
+			}
+			
+			if($version < 4) {
+				$this->PDO->query('DELETE FROM data WHERE class IS NULL AND name=\'user_struct\'');
+				$this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 4)');
+				$version = 4;
+			}
+			
 			return;
 		}
 		
@@ -43,7 +82,7 @@
 			
 			$this->PDO->query(
 				'CREATE TABLE data (
-					class VARCHAR(50),
+					class VARCHAR(50) NOT NULL DEFAULT \'\',
 					name VARCHAR(40) NOT NULL,
 					value TEXT NOT NULL,
 					PRIMARY KEY (
@@ -52,6 +91,8 @@
 					)
 				)'
 			);
+			
+			$this->PDO->query('INSERT INTO data (class, name, value) VALUES (\'\', \'_version\', 4)');
 			
 			$files = glob(BOT_TOPDIR.'/db/*/'.$this->user_struct['user'].'.ggdb');
 			if(!$files) {
@@ -64,7 +105,7 @@
 			foreach($files as $file) {
 				$data = unserialize(file_get_contents($file));
 				foreach($data as $name => $value) {
-					$st->execute(array($this->class, $name, $value));
+					$st->execute(array($this->class, $name, serialize($value)));
 				}
 			}
 			
@@ -82,6 +123,19 @@
 		}
 	}
 	
+	/**
+	 * Ustawia nazwę modułu/klasy, której zmienne będą przetwarzane
+	 * @param string $class Nazwa modułu
+	 */
+	function setClass($class) {
+		$this->class = $class;
+	}
+	
+	/**
+	 * Pobiera zmienną modułu o podanej nazwie (getter).
+	 * @param string $name Nazwa zmiennej
+	 * @return mixed Wartość zmiennej lub NULL
+	 */
 	function __get($name) {
 		$this->init();
 		
@@ -98,6 +152,11 @@
 		}
 	}
 	
+	/**
+	 * Ustawia zmienną o podanej nazwie
+	 * @param string $name Nazwa zmiennej
+	 * @param mixed $value Wartość zmiennej
+	 */
 	function __set($name, $value) {
 		$this->init();
 		
@@ -105,6 +164,11 @@
 		$st->execute(array($this->class, $name, serialize($value)));
 	}
 	
+	/**
+	 * Sprawdza czy podana zmienna została ustawiona.
+	 * @param string $name Nazwa zmiennej
+	 * @return bool Czy zmienna istnieje?
+	 */
 	function __isset($name) {
 		$this->init();
 		
@@ -115,6 +179,10 @@
 		return ($st[0]>0);
 	}
 	
+	/**
+	 * Usuwa zmienną o podanej nazwie
+	 * @param string $name Nazwa zmiennej
+	 */
 	function __unset($name) {
 		$this->init();
 		
@@ -122,6 +190,10 @@
 		$st->execute(array($this->class, $name));
 	}
 	
+	/**
+	 * Zapamiętuje tablicę zmiennych danego modułu
+	 * @param array $array Tablica zmiennych
+	 */
 	function push($array) {
 		$this->PDO->beginTransaction();
 		foreach($array as $name => $value) {
@@ -130,6 +202,10 @@
 		$this->PDO->commit();
 	}
 	
+	/**
+	 * Zwraca wszystkie ustawione zmienne danego modułu
+	 * @return array Lista wszystkich zmiennych
+	 */
 	function pull() {
 		$this->init();
 		
@@ -139,12 +215,15 @@
 		
 		$return = array();
 		foreach($st as $row) {
-			$return[$row['name']] = $row['value'];
+			$return[$row['name']] = unserialize($row['value']);
 		}
 		
 		return $return;
 	}
 	
+	/**
+	 * Usuwa wszystkie zmienne sesyjne danego modułu.
+	 */
 	function truncate() {
 		$this->init();
 		

--
Gitblit v1.9.1