plugins/python/pyhelpers: add helpers for attribute handling
to simplify code a bit.
This commit is contained in:

committed by
Todd C. Miller

parent
4110800c14
commit
62524416eb
@@ -143,7 +143,7 @@ py_log_last_error(const char *context_message)
|
||||
debug_return;
|
||||
}
|
||||
|
||||
PyObject *py_type, *py_message, *py_traceback;
|
||||
PyObject *py_type = NULL, *py_message = NULL, *py_traceback = NULL;
|
||||
PyErr_Fetch(&py_type, &py_message, &py_traceback);
|
||||
|
||||
char *message = py_message ? py_create_string_rep(py_message) : strdup("(NULL)");
|
||||
@@ -398,7 +398,7 @@ py_get_current_execution_frame(char **file_name, long *line_number, char **funct
|
||||
PyObject *py_err_type = NULL, *py_err_value = NULL, *py_err_traceback = NULL;
|
||||
PyErr_Fetch(&py_err_type, &py_err_value, &py_err_traceback);
|
||||
|
||||
PyObject *py_frame = NULL, *py_lineno = NULL, *py_f_code = NULL,
|
||||
PyObject *py_frame = NULL, *py_f_code = NULL,
|
||||
*py_filename = NULL, *py_function_name = NULL;
|
||||
|
||||
PyObject *py_getframe = PySys_GetObject("_getframe");
|
||||
@@ -409,25 +409,21 @@ py_get_current_execution_frame(char **file_name, long *line_number, char **funct
|
||||
if (py_frame == NULL)
|
||||
goto cleanup;
|
||||
|
||||
py_lineno = PyObject_GetAttrString(py_frame, "f_lineno");
|
||||
if (py_lineno != NULL) {
|
||||
*line_number = PyLong_AsLong(py_lineno);
|
||||
}
|
||||
*line_number = py_object_get_optional_attr_number(py_frame, "f_lineno");
|
||||
|
||||
py_f_code = PyObject_GetAttrString(py_frame, "f_code");
|
||||
py_f_code = py_object_get_optional_attr(py_frame, "f_code", NULL);
|
||||
if (py_f_code != NULL) {
|
||||
py_filename = PyObject_GetAttrString(py_f_code, "co_filename");
|
||||
py_filename = py_object_get_optional_attr(py_f_code, "co_filename", NULL);
|
||||
if (py_filename != NULL)
|
||||
*file_name = strdup(PyUnicode_AsUTF8(py_filename));
|
||||
|
||||
py_function_name = PyObject_GetAttrString(py_f_code, "co_name");
|
||||
py_function_name = py_object_get_optional_attr(py_f_code, "co_name", NULL);
|
||||
if (py_function_name != NULL)
|
||||
*function_name = strdup(PyUnicode_AsUTF8(py_function_name));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
Py_CLEAR(py_frame);
|
||||
Py_CLEAR(py_lineno);
|
||||
Py_CLEAR(py_f_code);
|
||||
Py_CLEAR(py_filename);
|
||||
Py_CLEAR(py_function_name);
|
||||
@@ -447,7 +443,8 @@ py_ctx_reset()
|
||||
}
|
||||
|
||||
int
|
||||
py_sudo_conv(int num_msgs, const struct sudo_conv_message msgs[], struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
|
||||
py_sudo_conv(int num_msgs, const struct sudo_conv_message msgs[],
|
||||
struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
|
||||
{
|
||||
/* Enable suspend during password entry. */
|
||||
struct sigaction sa, saved_sigtstp;
|
||||
@@ -465,3 +462,59 @@ py_sudo_conv(int num_msgs, const struct sudo_conv_message msgs[], struct sudo_co
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
py_object_get_optional_attr(PyObject *py_object, const char *attr, PyObject *py_default)
|
||||
{
|
||||
if (PyObject_HasAttrString(py_object, attr)) {
|
||||
return PyObject_GetAttrString(py_object, attr);
|
||||
}
|
||||
Py_XINCREF(py_default); // whatever we return will have its refcount incremented
|
||||
return py_default;
|
||||
}
|
||||
|
||||
const char *
|
||||
py_object_get_optional_attr_string(PyObject *py_object, const char *attr_name)
|
||||
{
|
||||
PyObject *py_value = py_object_get_optional_attr(py_object, attr_name, NULL);
|
||||
if (py_value == NULL)
|
||||
return NULL;
|
||||
|
||||
const char *value = PyUnicode_AsUTF8(py_value);
|
||||
Py_CLEAR(py_value); // Note, the object still has reference to the attribute
|
||||
return value;
|
||||
}
|
||||
|
||||
long long
|
||||
py_object_get_optional_attr_number(PyObject *py_object, const char *attr_name)
|
||||
{
|
||||
PyObject *py_value = py_object_get_optional_attr(py_object, attr_name, NULL);
|
||||
if (py_value == NULL)
|
||||
return -1;
|
||||
|
||||
long long value = PyLong_AsLongLong(py_value);
|
||||
Py_CLEAR(py_value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
py_object_set_attr_number(PyObject *py_object, const char *attr_name, long long number)
|
||||
{
|
||||
PyObject *py_number = PyLong_FromLong(number);
|
||||
if (py_number == NULL)
|
||||
return;
|
||||
|
||||
PyObject_SetAttrString(py_object, attr_name, py_number);
|
||||
Py_CLEAR(py_number);
|
||||
}
|
||||
|
||||
void
|
||||
py_object_set_attr_string(PyObject *py_object, const char *attr_name, const char *value)
|
||||
{
|
||||
PyObject *py_value = PyUnicode_FromString(value);
|
||||
if (py_value == NULL)
|
||||
return;
|
||||
|
||||
PyObject_SetAttrString(py_object, attr_name, py_value);
|
||||
Py_CLEAR(py_value);
|
||||
}
|
||||
|
@@ -71,6 +71,13 @@ char **py_str_array_from_tuple(PyObject *py_tuple);
|
||||
CPYCHECKER_RETURNS_BORROWED_REF
|
||||
PyObject *py_tuple_get(PyObject *py_tuple, Py_ssize_t index, PyTypeObject *expected_type);
|
||||
|
||||
PyObject *py_object_get_optional_attr(PyObject *py_object, const char *attr, PyObject *py_default);
|
||||
long long py_object_get_optional_attr_number(PyObject *py_object, const char *attr_name);
|
||||
const char *py_object_get_optional_attr_string(PyObject *py_object, const char *attr_name);
|
||||
|
||||
void py_object_set_attr_number(PyObject *py_object, const char *attr_name, long long number);
|
||||
void py_object_set_attr_string(PyObject *py_object, const char *attr_name, const char *value);
|
||||
|
||||
PyObject *py_create_version(unsigned int version);
|
||||
|
||||
void py_debug_python_call(const char *class_name, const char *function_name,
|
||||
|
@@ -35,7 +35,6 @@ _sudo_ConvMessage__Init(PyObject *py_self, PyObject *py_args, PyObject *py_kwarg
|
||||
PyObject *py_empty = PyTuple_New(0);
|
||||
|
||||
struct sudo_conv_message conv_message = { 0, 0, NULL };
|
||||
PyObject *py_msg_type = NULL, *py_timeout = NULL, *py_msg = NULL; // borrowed references
|
||||
|
||||
static char *keywords[] = { "self", "msg_type", "msg", "timeout", NULL };
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args ? py_args : py_empty, py_kwargs, "Ois|i:sudo.ConvMessage", keywords,
|
||||
@@ -46,31 +45,19 @@ _sudo_ConvMessage__Init(PyObject *py_self, PyObject *py_args, PyObject *py_kwarg
|
||||
sudo_debug_printf(SUDO_DEBUG_TRACE, "Parsed arguments: self='%p' msg_type='%d' timeout='%d' msg='%s'",
|
||||
(void *)py_self, conv_message.msg_type, conv_message.timeout, conv_message.msg);
|
||||
|
||||
py_msg_type = PyLong_FromLong(conv_message.msg_type);
|
||||
if (py_msg_type == NULL)
|
||||
py_object_set_attr_number(py_self, "msg_type", conv_message.msg_type);
|
||||
if (PyErr_Occurred())
|
||||
goto cleanup;
|
||||
|
||||
py_timeout = PyLong_FromLong(conv_message.timeout);
|
||||
if (py_timeout == NULL)
|
||||
py_object_set_attr_number(py_self, "timeout", conv_message.timeout);
|
||||
if (PyErr_Occurred())
|
||||
goto cleanup;
|
||||
|
||||
py_msg = PyUnicode_FromString(conv_message.msg);
|
||||
if (py_msg == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (PyObject_SetAttrString(py_self, "msg_type", py_msg_type) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (PyObject_SetAttrString(py_self, "timeout", py_timeout) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (PyObject_SetAttrString(py_self, "msg", py_msg) != 0)
|
||||
py_object_set_attr_string(py_self, "msg", conv_message.msg);
|
||||
if (PyErr_Occurred())
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
Py_CLEAR(py_msg_type);
|
||||
Py_CLEAR(py_timeout);
|
||||
Py_CLEAR(py_msg);
|
||||
Py_CLEAR(py_empty);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
@@ -121,31 +108,19 @@ sudo_module_ConvMessage_to_c(PyObject *py_conv_message, struct sudo_conv_message
|
||||
{
|
||||
debug_decl(sudo_module_ConvMessage_to_c, PYTHON_DEBUG_C_CALLS);
|
||||
|
||||
int rc = SUDO_RC_ERROR;
|
||||
PyObject *py_msg_type = NULL, *py_timeout = NULL, *py_msg = NULL;
|
||||
conv_message->msg_type = (int)py_object_get_optional_attr_number(py_conv_message, "msg_type");
|
||||
if (PyErr_Occurred())
|
||||
debug_return_int(SUDO_RC_ERROR);
|
||||
|
||||
if ((py_msg_type = PyObject_GetAttrString(py_conv_message, "msg_type")) == NULL)
|
||||
goto cleanup;
|
||||
conv_message->msg_type = (int)PyLong_AsLong(py_msg_type);
|
||||
conv_message->timeout = (int)py_object_get_optional_attr_number(py_conv_message, "timeout");
|
||||
if (PyErr_Occurred())
|
||||
debug_return_int(SUDO_RC_ERROR);
|
||||
|
||||
if ((py_timeout = PyObject_GetAttrString(py_conv_message, "timeout")) == NULL)
|
||||
goto cleanup;
|
||||
conv_message->timeout = (int)PyLong_AsLong(py_timeout);
|
||||
conv_message->msg = py_object_get_optional_attr_string(py_conv_message, "msg");
|
||||
if (PyErr_Occurred())
|
||||
debug_return_int(SUDO_RC_ERROR);
|
||||
|
||||
if ((py_msg = PyObject_GetAttrString(py_conv_message, "msg")) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
conv_message->msg = PyUnicode_AsUTF8(py_msg);
|
||||
if (conv_message->msg == NULL)
|
||||
goto cleanup;
|
||||
|
||||
rc = SUDO_RC_OK;
|
||||
|
||||
cleanup:
|
||||
Py_CLEAR(py_msg_type);
|
||||
Py_CLEAR(py_timeout);
|
||||
Py_CLEAR(py_msg);
|
||||
debug_return_int(rc);
|
||||
debug_return_int(SUDO_RC_OK);
|
||||
}
|
||||
|
||||
int
|
||||
|
Reference in New Issue
Block a user