Allow relative paths in sqlite PDO DSN, fixes #115

This commit is contained in:
Bartek Fabiszewski 2020-03-30 12:26:29 +02:00
parent 2f6603a18f
commit 3a7fcc73d1
5 changed files with 75 additions and 7 deletions

View File

@ -58,6 +58,27 @@ class DbTest extends TestCase {
$this->assertEquals($fileName, uDb::getDbName("sqlite:$fileName"));
}
}
public function testNormalizeDsn() {
$testDbName = "testDbName";
$nonSqlite = [
"mysql:host=db.example.com;port=3306;dbname=$testDbName",
"mysql:host=db.example.com;dbname=$testDbName;port=3306",
"mysql:dbname=$testDbName;host=db.example.com;port=3306",
"mysql:unix_socket=/tmp/mysql.sock;dbname=$testDbName;charset=utf8",
"pgsql:host=localhost;port=5432;dbname=$testDbName;user=myuser;password=mypass",
"pgsql:host=db.example.com port=31075 dbname=$testDbName",
"pgsql:host=db.example.com port=31075 dbname=$testDbName user=myuser password=mypass",
];
foreach ($nonSqlite as $dsn) {
$this->assertEquals($dsn, uDb::normalizeDsn($dsn));
}
$this->assertEquals("sqlite:" . realpath(ROOT_DIR . "/index.php"), uDb::normalizeDsn("sqlite:index.php"));
$this->assertEquals("sqlite:" . realpath(ROOT_DIR . "/index.php"), uDb::normalizeDsn("sqlite:helpers/../index.php"));
$this->assertNotEquals("sqlite:" . realpath(ROOT_DIR . "/index.php"), uDb::normalizeDsn("sqlite:../index.php"));
}
}
?>

View File

@ -99,5 +99,21 @@ class UtilsTest extends TestCase {
unset($_SERVER["HTTPS"]);
$this->assertEquals($expected, $result);
}
public function testIsAbsolutePath() {
$this->assertTrue(uUtils::isAbsolutePath("/foo"));
$this->assertTrue(uUtils::isAbsolutePath("/foo/bar"));
$this->assertTrue(uUtils::isAbsolutePath("/"));
$this->assertTrue(uUtils::isAbsolutePath("/."));
$this->assertTrue(uUtils::isAbsolutePath("\\"));
$this->assertTrue(uUtils::isAbsolutePath("C:\\\\foo"));
$this->assertTrue(uUtils::isAbsolutePath("Z:\\\\FOO/BAR"));
$this->assertFalse(uUtils::isAbsolutePath("foo"));
$this->assertFalse(uUtils::isAbsolutePath("foo/bar"));
$this->assertFalse(uUtils::isAbsolutePath("./foo"));
$this->assertFalse(uUtils::isAbsolutePath("../"));
$this->assertFalse(uUtils::isAbsolutePath(".\\foo"));
}
}
?>

View File

@ -17,6 +17,8 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
require_once(ROOT_DIR . "/helpers/utils.php");
/**
* PDO wrapper
*/
@ -122,7 +124,7 @@
}
include($configFile);
if (isset($dbdsn)) {
self::$dbdsn = $dbdsn;
self::$dbdsn = self::normalizeDsn($dbdsn);
}
if (isset($dbuser)) {
self::$dbuser = $dbuser;
@ -241,5 +243,24 @@
}
return $name;
}
/**
* Normalize DSN.
* Make sure sqlite DSN file path is absolute
* @param $dsn string DSN
* @return string Normalized DSN
*/
public static function normalizeDsn($dsn) {
if (stripos($dsn, "sqlite") !== 0) {
return $dsn;
}
$arr = explode(":", $dsn, 2);
if (count($arr) < 2 || empty($arr[1]) || uUtils::isAbsolutePath($arr[1])) {
return $dsn;
}
$scheme = $arr[0];
$path = dirname(__DIR__) . DIRECTORY_SEPARATOR . $arr[1];
return $scheme . ":" . realpath(dirname($path)) . DIRECTORY_SEPARATOR . basename(($path));
}
}
?>

View File

@ -39,6 +39,14 @@
return min($upload_max_filesize, $post_max_size, $memory_limit);
}
/**
* @param $path string Path
* @return bool True if is absolute
*/
public static function isAbsolutePath($path) {
return $path[0] === '/' || $path[0] === '\\' || preg_match('/^[a-zA-Z]:\\\\/', $path);
}
/**
* Get number of bytes from ini parameter.
* Optionally parses shorthand byte values (G, M, B)

View File

@ -30,6 +30,13 @@ if (version_compare(PHP_VERSION, "5.5.0", "<")) {
}
define("ROOT_DIR", dirname(__DIR__));
require_once(ROOT_DIR . "/helpers/db.php");
require_once(ROOT_DIR . "/helpers/config.php");
require_once(ROOT_DIR . "/helpers/lang.php");
require_once(ROOT_DIR . "/helpers/user.php");
require_once(ROOT_DIR . "/helpers/utils.php");
$dbConfig = ROOT_DIR . "/config.php";
$dbConfigLoaded = false;
$configDSN = "";
@ -40,16 +47,11 @@ if (file_exists($dbConfig)) {
/** @noinspection PhpIncludeInspection */
include($dbConfig);
$dbConfigLoaded = true;
if (isset($dbdsn)) { $configDSN = $dbdsn; }
if (isset($dbdsn)) { $configDSN = uDb::normalizeDsn($dbdsn); }
if (isset($dbuser)) { $configUser = $dbuser; }
if (isset($dbpass)) { $configPass = $dbpass; }
if (isset($dbprefix)) { $configPrefix = $dbprefix; }
}
require_once(ROOT_DIR . "/helpers/db.php");
require_once(ROOT_DIR . "/helpers/config.php");
require_once(ROOT_DIR . "/helpers/lang.php");
require_once(ROOT_DIR . "/helpers/user.php");
require_once(ROOT_DIR . "/helpers/utils.php");
$command = uUtils::postString("command");
$language = uUtils::getString("lang", "en");