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:
Serhiy Storchaka 2020-06-25 11:37:12 +03:00 committed by GitHub
parent 152f0b8bee
commit 55939b1708
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 8 deletions

View File

@ -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:

View File

@ -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`.

View File

@ -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);