Correct parsing of connect string so that the last @ symbol is searched for

instead of the first @ symbol; otherwise, passwords containing an @ symbol will
result in the incorrect DSN being extracted
(https://github.com/oracle/python-cx_Oracle/issues/290).
This commit is contained in:
Anthony Tuininga 2019-03-28 10:46:15 -06:00
parent 096f8d6412
commit 3af5e46b4b
2 changed files with 22 additions and 4 deletions

View File

@ -643,14 +643,16 @@ static PyObject *cxoConnection_new(PyTypeObject *type, PyObject *args,
// string in to the target.
//-----------------------------------------------------------------------------
static int cxoConnection_splitComponent(PyObject **sourceObj,
PyObject **targetObj, const char *splitString)
PyObject **targetObj, const char *splitString, int first)
{
PyObject *temp, *posObj;
Py_ssize_t size, pos;
char *methodName;
if (!*sourceObj || *targetObj)
return 0;
posObj = PyObject_CallMethod(*sourceObj, "find", "s", splitString);
methodName = (first) ? "find" : "rfind";
posObj = PyObject_CallMethod(*sourceObj, methodName, "s", splitString);
if (!posObj)
return -1;
pos = PyInt_AsLong(posObj);
@ -742,9 +744,9 @@ static int cxoConnection_init(cxoConnection *conn, PyObject *args,
conn->dsn = dsnObj;
// perform some parsing, if necessary
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/") < 0)
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/", 1) < 0)
return -1;
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@") < 0)
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@", 0) < 0)
return -1;
// setup parameters

View File

@ -144,6 +144,22 @@ class TestCase(TestEnv.BaseTestCase):
self.assertRaises(cx_Oracle.DatabaseError, connection.changepassword,
TestEnv.GetMainPassword(), newPassword)
def testParsePassword(self):
"test connecting with password containing / and @ symbols"
sysRandom = random.SystemRandom()
chars = list(sysRandom.choice(string.ascii_letters) for i in range(20))
chars[4] = "/"
chars[8] = "@"
newPassword = "".join(chars)
connection = TestEnv.GetConnection()
connection.changepassword(TestEnv.GetMainPassword(), newPassword)
try:
arg = "%s/%s@%s" % (TestEnv.GetMainUser(), newPassword,
TestEnv.GetConnectString())
cx_Oracle.connect(arg)
finally:
connection.changepassword(newPassword, TestEnv.GetMainPassword())
def testEncodings(self):
"connection with only encoding or nencoding specified should work"
connection = cx_Oracle.connect(TestEnv.GetMainUser(),