@@ -955,18 +955,32 @@ static PyTypeObject msidb_Type = {
955955 0 , /*tp_is_gc*/
956956};
957957
958+ #define Py_NOT_PERSIST (x , flag ) \
959+ (x != (int)(flag) && \
960+ x != ((int)(flag) | MSIDBOPEN_PATCHFILE))
961+
962+ #define Py_INVALID_PERSIST (x ) \
963+ (Py_NOT_PERSIST(x, MSIDBOPEN_READONLY) && \
964+ Py_NOT_PERSIST(x, MSIDBOPEN_TRANSACT) && \
965+ Py_NOT_PERSIST(x, MSIDBOPEN_DIRECT) && \
966+ Py_NOT_PERSIST(x, MSIDBOPEN_CREATE) && \
967+ Py_NOT_PERSIST(x, MSIDBOPEN_CREATEDIRECT))
968+
958969static PyObject * msiopendb (PyObject * obj , PyObject * args )
959970{
960971 int status ;
961972 char * path ;
962973 int persist ;
963974 MSIHANDLE h ;
964975 msiobj * result ;
965-
966976 if (!PyArg_ParseTuple (args , "si:MSIOpenDatabase" , & path , & persist ))
967977 return NULL ;
968-
969- status = MsiOpenDatabase (path , (LPCSTR )persist , & h );
978+ /* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
979+ MsiOpenDatabase may treat the value as a pointer, leading to unexpected
980+ behavior. */
981+ if (Py_INVALID_PERSIST (persist ))
982+ return msierror (ERROR_INVALID_PARAMETER );
983+ status = MsiOpenDatabase (path , (LPCSTR )persist , & h );
970984 if (status != ERROR_SUCCESS )
971985 return msierror (status );
972986
0 commit comments