Merged in bugfix/PMCORE-646 (pull request #7319)
PMCORE-646 Special characters in oracle connection passwords causes bad behavior Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
committed by
Julio Cesar Laura Avendaño
commit
2632a58d63
@@ -171,4 +171,54 @@ class SystemTest extends TestCase
|
|||||||
|
|
||||||
$this->assertArrayHasKey("proxy_pass", $result);
|
$this->assertArrayHasKey("proxy_pass", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents a set of connection strings that make up the dsn string.
|
||||||
|
* https://processmaker.atlassian.net/browse/PMCORE-574
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function dsnConections()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
["oci8", "user1", "das#4dba", "localhost", "1521", "testDatabase?encoding=utf8"],
|
||||||
|
["mssql", "user1", "Sample12345!@#", "localhost", "1433", "testDatabase?encoding=utf8"],
|
||||||
|
["mysqli", "user1", "123*/.abc-+", "localhost", "3306", "testDatabase?encoding=utf8"],
|
||||||
|
["mysqli", "user1", "123*/.abc-+", "localhost", "", "testDatabase?encoding=utf8"],
|
||||||
|
["sqlite", "user1", "das#4dba", "localhost", "", "testDatabase?encoding=utf8"],
|
||||||
|
["sybase", "user1", "123!das#4dba", "localhost", "1433", "testDatabase?encoding=utf8"],
|
||||||
|
["sybase", "user1", "123!das@#4dba", "localhost", "1433", "testDatabase?encoding=utf8"],
|
||||||
|
["sybase", "user1", "123!das@#4db@a", "localhost", "1433", "testDatabase?encoding=utf8"],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This tests the parsing of the dsn string.
|
||||||
|
* @test
|
||||||
|
* @dataProvider dsnConections
|
||||||
|
* @covers \Creole::parseDSN()
|
||||||
|
* @covers \ProcessMaker\Core\System::parseUrlWithNotEncodedPassword()
|
||||||
|
*/
|
||||||
|
public function it_should_return_parse_url_for_dsn_string_with_special_characters($scheme, $user, $password, $host, $port, $database)
|
||||||
|
{
|
||||||
|
$hostname = $host;
|
||||||
|
if (!empty($port)) {
|
||||||
|
$hostname = $host . ":" . $port;
|
||||||
|
}
|
||||||
|
$dsn = $scheme . "://" . $user . ":" . $password . "@" . $hostname . "/" . $database;
|
||||||
|
$result = System::parseUrlWithNotEncodedPassword($dsn);
|
||||||
|
$this->assertEquals($scheme, $result["scheme"]);
|
||||||
|
$this->assertEquals($user, $result["user"]);
|
||||||
|
$this->assertEquals($password, $result["pass"]);
|
||||||
|
$this->assertEquals($host, $result["host"]);
|
||||||
|
if (!empty($port)) {
|
||||||
|
$this->assertEquals($port, $result["port"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dsn = $scheme;
|
||||||
|
$result = System::parseUrlWithNotEncodedPassword($dsn);
|
||||||
|
$this->assertEmpty($result["scheme"]);
|
||||||
|
$this->assertEmpty($result["user"]);
|
||||||
|
$this->assertEmpty($result["pass"]);
|
||||||
|
$this->assertEmpty($result["host"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
thirdparty/creole/Creole.php
vendored
6
thirdparty/creole/Creole.php
vendored
@@ -28,6 +28,8 @@ include_once 'creole/Connection.php';
|
|||||||
|
|
||||||
@ini_set('track_errors', true);
|
@ini_set('track_errors', true);
|
||||||
|
|
||||||
|
use ProcessMaker\Core\System;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the class that manages the database drivers.
|
* This is the class that manages the database drivers.
|
||||||
*
|
*
|
||||||
@@ -309,6 +311,10 @@ class Creole {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$info = parse_url($dsn);
|
$info = parse_url($dsn);
|
||||||
|
if ($info === false) {
|
||||||
|
$info = System::parseUrlWithNotEncodedPassword($dsn);
|
||||||
|
}
|
||||||
|
|
||||||
$info['pass'] = urldecode($info['pass']);
|
$info['pass'] = urldecode($info['pass']);
|
||||||
if (count($info) === 1) { // if there's only one element in result, then it must be the phptype
|
if (count($info) === 1) { // if there's only one element in result, then it must be the phptype
|
||||||
$parsed['phptype'] = array_pop($info);
|
$parsed['phptype'] = array_pop($info);
|
||||||
|
|||||||
@@ -1695,4 +1695,50 @@ class System
|
|||||||
}
|
}
|
||||||
return (object) $result;
|
return (object) $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse an url with not encoded password that break the native “parse_url” function.
|
||||||
|
* @param string $dsn
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function parseUrlWithNotEncodedPassword(string $dsn): array
|
||||||
|
{
|
||||||
|
$default = [
|
||||||
|
'scheme' => '',
|
||||||
|
'host' => '',
|
||||||
|
'port' => '',
|
||||||
|
'user' => '',
|
||||||
|
'pass' => '',
|
||||||
|
'path' => '',
|
||||||
|
'query' => '',
|
||||||
|
];
|
||||||
|
$separator = "://";
|
||||||
|
$colon = ":";
|
||||||
|
$at = "@";
|
||||||
|
|
||||||
|
$result = explode($separator, $dsn, 2);
|
||||||
|
if (empty($result[0]) || empty($result[1])) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
$scheme = $result[0];
|
||||||
|
$urlWithoutScheme = $result[1];
|
||||||
|
|
||||||
|
$colonPosition = strpos($urlWithoutScheme, $colon);
|
||||||
|
$user = substr($urlWithoutScheme, 0, $colonPosition);
|
||||||
|
|
||||||
|
$withoutUser = substr($urlWithoutScheme, $colonPosition + 1);
|
||||||
|
$atPosition = strrpos($withoutUser, $at);
|
||||||
|
$pass = substr($urlWithoutScheme, $colonPosition + 1, $atPosition);
|
||||||
|
|
||||||
|
$withoutPass = substr($withoutUser, $atPosition + 1);
|
||||||
|
|
||||||
|
$fixedDsn = $scheme . $separator . $user . $colon . urlencode($pass) . $at . $withoutPass;
|
||||||
|
|
||||||
|
$parseDsn = parse_url($fixedDsn);
|
||||||
|
if ($parseDsn === false) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
$parseDsn["pass"] = urldecode($parseDsn["pass"]);
|
||||||
|
return $parseDsn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user