bpo-41074: Fix support of non-ASCII names and SQL in msilib. (GH-21126)
* Fix support of non-ASCII names in functions OpenDatabase() and init_database(). * Fix support of non-ASCII SQL in method Database.OpenView().
This commit is contained in:
parent
152f0b8bee
commit
55939b1708
|
@ -1,13 +1,13 @@
|
||||||
""" Test suite for the code in msilib """
|
""" Test suite for the code in msilib """
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import TESTFN, import_module, unlink
|
from test.support import TESTFN, FS_NONASCII, import_module, unlink
|
||||||
msilib = import_module('msilib')
|
msilib = import_module('msilib')
|
||||||
import msilib.schema
|
import msilib.schema
|
||||||
|
|
||||||
|
|
||||||
def init_database():
|
def init_database():
|
||||||
path = TESTFN + '.msi'
|
path = TESTFN + (FS_NONASCII or '') + '.msi'
|
||||||
db = msilib.init_database(
|
db = msilib.init_database(
|
||||||
path,
|
path,
|
||||||
msilib.schema,
|
msilib.schema,
|
||||||
|
@ -42,6 +42,16 @@ class MsiDatabaseTestCase(unittest.TestCase):
|
||||||
)
|
)
|
||||||
self.addCleanup(unlink, db_path)
|
self.addCleanup(unlink, db_path)
|
||||||
|
|
||||||
|
def test_view_non_ascii(self):
|
||||||
|
db, db_path = init_database()
|
||||||
|
view = db.OpenView("SELECT 'ß-розпад' FROM Property")
|
||||||
|
view.Execute(None)
|
||||||
|
record = view.Fetch()
|
||||||
|
self.assertEqual(record.GetString(1), 'ß-розпад')
|
||||||
|
view.Close()
|
||||||
|
db.Close()
|
||||||
|
self.addCleanup(unlink, db_path)
|
||||||
|
|
||||||
def test_summaryinfo_getproperty_issue1104(self):
|
def test_summaryinfo_getproperty_issue1104(self):
|
||||||
db, db_path = init_database()
|
db, db_path = init_database()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Fixed support of non-ASCII names in functions :func:`msilib.OpenDatabase`
|
||||||
|
and :func:`msilib.init_database` and non-ASCII SQL in method
|
||||||
|
:meth:`msilib.Database.OpenView`.
|
12
PC/_msi.c
12
PC/_msi.c
|
@ -872,14 +872,14 @@ static PyObject*
|
||||||
msidb_openview(msiobj *msidb, PyObject *args)
|
msidb_openview(msiobj *msidb, PyObject *args)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
char *sql;
|
const wchar_t *sql;
|
||||||
MSIHANDLE hView;
|
MSIHANDLE hView;
|
||||||
msiobj *result;
|
msiobj *result;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s:OpenView", &sql))
|
if (!PyArg_ParseTuple(args, "u:OpenView", &sql))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((status = MsiDatabaseOpenView(msidb->h, sql, &hView)) != ERROR_SUCCESS)
|
if ((status = MsiDatabaseOpenViewW(msidb->h, sql, &hView)) != ERROR_SUCCESS)
|
||||||
return msierror(status);
|
return msierror(status);
|
||||||
|
|
||||||
result = PyObject_New(struct msiobj, &msiview_Type);
|
result = PyObject_New(struct msiobj, &msiview_Type);
|
||||||
|
@ -998,18 +998,18 @@ static PyTypeObject msidb_Type = {
|
||||||
static PyObject* msiopendb(PyObject *obj, PyObject *args)
|
static PyObject* msiopendb(PyObject *obj, PyObject *args)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
char *path;
|
const wchar_t *path;
|
||||||
int persist;
|
int persist;
|
||||||
MSIHANDLE h;
|
MSIHANDLE h;
|
||||||
msiobj *result;
|
msiobj *result;
|
||||||
if (!PyArg_ParseTuple(args, "si:MSIOpenDatabase", &path, &persist))
|
if (!PyArg_ParseTuple(args, "ui:MSIOpenDatabase", &path, &persist))
|
||||||
return NULL;
|
return NULL;
|
||||||
/* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
|
/* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
|
||||||
MsiOpenDatabase may treat the value as a pointer, leading to unexpected
|
MsiOpenDatabase may treat the value as a pointer, leading to unexpected
|
||||||
behavior. */
|
behavior. */
|
||||||
if (Py_INVALID_PERSIST(persist))
|
if (Py_INVALID_PERSIST(persist))
|
||||||
return msierror(ERROR_INVALID_PARAMETER);
|
return msierror(ERROR_INVALID_PARAMETER);
|
||||||
status = MsiOpenDatabase(path, (LPCSTR)(SIZE_T)persist, &h);
|
status = MsiOpenDatabaseW(path, (LPCWSTR)(SIZE_T)persist, &h);
|
||||||
if (status != ERROR_SUCCESS)
|
if (status != ERROR_SUCCESS)
|
||||||
return msierror(status);
|
return msierror(status);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue