From 23f4d22b9bf1f930793fd1549ae2da6b403941f4 Mon Sep 17 00:00:00 2001 From: Bartek Bok Date: Tue, 24 Jul 2012 23:40:43 +0200 Subject: [PATCH] Make Python.Cheat little bit safer --- .../pfConsole/pfConsoleCommands.cpp | 18 ++-- .../FeatureLib/pfPython/cyPythonInterface.cpp | 88 ++++++++++++++++++- .../FeatureLib/pfPython/cyPythonInterface.h | 8 ++ 3 files changed, 105 insertions(+), 9 deletions(-) diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp index 5de7f52d..25affac6 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp @@ -7042,16 +7042,18 @@ PF_CONSOLE_CMD( Python, "string functions, ...", // Params "Run a cheat command" ) { - const char* extraParms = ""; + std::string extraParms; if (numParams > 1) - extraParms = params[1]; - // now evaluate this mess they made - PyObject* mymod = PythonInterface::FindModule("__main__"); + { + extraParms = "("; + extraParms.append(params[1]); + extraParms.append(",)"); + } + else + extraParms = "()"; + + PythonInterface::RunFunctionSafe("xCheat", params[0], extraParms.c_str()); - // create the line to execute the file - char runline[256]; - sprintf(runline,"import xCheat;xCheat.%s('%s')", (const char*)params[0],extraParms); - PythonInterface::RunString(runline,mymod); std::string output; // get the messages PythonInterface::getOutputAndReset(&output); diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp index ecc19344..214a62ae 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp @@ -1718,6 +1718,20 @@ void PythonInterface::WriteToStdErr(const char* text) } } +PyObject* PythonInterface::ImportModule(const char* module) +{ + PyObject* result = nil; + PyObject* name = PyString_FromString(module); + + if (name != nil) + { + result = PyImport_Import(name); + Py_DECREF(name); + } + + return result; +} + ///////////////////////////////////////////////////////////////////////////// // // Function : FindModule @@ -2061,6 +2075,78 @@ hsBool PythonInterface::RunPYC(PyObject* code, PyObject* module) return true; } +///////////////////////////////////////////////////////////////////////////// +// +// Function : RunFunction +// PARAMETERS : module - module name to run 'name' in +// : name - name of function +// : args - tuple with arguments +// +// +PyObject* PythonInterface::RunFunction(PyObject* module, const char* name, PyObject* args) +{ + if (module == NULL) + return NULL; + + PyObject* function = PyObject_GetAttrString(module, const_cast(name)); + + PyObject* result = NULL; + if (function != nil) + { + result = PyObject_Call(function, args, NULL); + Py_DECREF(function); + } + + return result; +} + +PyObject* PythonInterface::ParseArgs(const char* args) +{ + PyObject* result = NULL; + PyObject* scope = PyDict_New(); + if (scope) + { + //- Py_eval_input makes this function accept only single expresion (not statement) + //- When using empty scope, functions and classes like 'file' or '__import__' are not visible + result = PyRun_String(args, Py_eval_input, scope, NULL); + Py_DECREF(scope); + } + + return result; +} + +bool PythonInterface::RunFunctionSafe(const char* module, const char* function, const char* args) +{ + PyObject* moduleObj = ImportModule(module); + bool result = false; + if (moduleObj) + { + PyObject* argsObj = ParseArgs(args); + if (argsObj) + { + PyObject* callResult = RunFunction(moduleObj, function, argsObj); + if (callResult) + { + result = true; + Py_DECREF(callResult); + } + + Py_DECREF(argsObj); + } + Py_DECREF(moduleObj); + } + + if (!result) + { + PyErr_Print(); + + if (Py_FlushLine()) + PyErr_Clear(); + } + + return result; +} + ///////////////////////////////////////////////////////////////////////////// // // Function : GetpyKeyFromPython @@ -2073,4 +2159,4 @@ pyKey* PythonInterface::GetpyKeyFromPython(PyObject* pkey) if (!pyKey::Check(pkey)) return nil; return pyKey::ConvertFrom(pkey); -} \ No newline at end of file +} diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h index f34ead55..1d3e67ed 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h @@ -138,6 +138,8 @@ public: // Writes 'text' to stderr specified in the python interface static void WriteToStdErr(const char* text); + static PyObject* ImportModule(const char* module); + // Find module. If it doesn't exist then don't create, return nil. static PyObject* FindModule(char* module); @@ -219,6 +221,12 @@ public: // static hsBool RunPYC(PyObject* code, PyObject* module); + static PyObject* RunFunction(PyObject* module, const char* name, PyObject* args); + + static PyObject* ParseArgs(const char* args); + + static bool RunFunctionSafe(const char* module, const char* function, const char* args); + ///////////////////////////////////////////////////////////////////////////// // // Function : GetpyKeyFromPython