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:
parent
096f8d6412
commit
3af5e46b4b
@ -643,14 +643,16 @@ static PyObject *cxoConnection_new(PyTypeObject *type, PyObject *args,
|
|||||||
// string in to the target.
|
// string in to the target.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int cxoConnection_splitComponent(PyObject **sourceObj,
|
static int cxoConnection_splitComponent(PyObject **sourceObj,
|
||||||
PyObject **targetObj, const char *splitString)
|
PyObject **targetObj, const char *splitString, int first)
|
||||||
{
|
{
|
||||||
PyObject *temp, *posObj;
|
PyObject *temp, *posObj;
|
||||||
Py_ssize_t size, pos;
|
Py_ssize_t size, pos;
|
||||||
|
char *methodName;
|
||||||
|
|
||||||
if (!*sourceObj || *targetObj)
|
if (!*sourceObj || *targetObj)
|
||||||
return 0;
|
return 0;
|
||||||
posObj = PyObject_CallMethod(*sourceObj, "find", "s", splitString);
|
methodName = (first) ? "find" : "rfind";
|
||||||
|
posObj = PyObject_CallMethod(*sourceObj, methodName, "s", splitString);
|
||||||
if (!posObj)
|
if (!posObj)
|
||||||
return -1;
|
return -1;
|
||||||
pos = PyInt_AsLong(posObj);
|
pos = PyInt_AsLong(posObj);
|
||||||
@ -742,9 +744,9 @@ static int cxoConnection_init(cxoConnection *conn, PyObject *args,
|
|||||||
conn->dsn = dsnObj;
|
conn->dsn = dsnObj;
|
||||||
|
|
||||||
// perform some parsing, if necessary
|
// perform some parsing, if necessary
|
||||||
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/") < 0)
|
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/", 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@") < 0)
|
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@", 0) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// setup parameters
|
// setup parameters
|
||||||
|
|||||||
@ -144,6 +144,22 @@ class TestCase(TestEnv.BaseTestCase):
|
|||||||
self.assertRaises(cx_Oracle.DatabaseError, connection.changepassword,
|
self.assertRaises(cx_Oracle.DatabaseError, connection.changepassword,
|
||||||
TestEnv.GetMainPassword(), newPassword)
|
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):
|
def testEncodings(self):
|
||||||
"connection with only encoding or nencoding specified should work"
|
"connection with only encoding or nencoding specified should work"
|
||||||
connection = cx_Oracle.connect(TestEnv.GetMainUser(),
|
connection = cx_Oracle.connect(TestEnv.GetMainUser(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user