Python dictionaries are sparse so we cannot use pos as an index.

When converting sudo options from a dictionary to a tuple we need
to track the current index into the tuple separately from the
position of the dictionary entry.
This commit is contained in:
Todd C. Miller
2020-04-09 08:34:29 -06:00
parent 324b237245
commit 57cef10ce9
2 changed files with 3 additions and 5 deletions

View File

@@ -1548,7 +1548,6 @@ main(int argc, char *argv[])
RUN_TEST(check_example_policy_plugin_version_display(true));
RUN_TEST(check_example_policy_plugin_version_display(false));
// FIXME - sudo.options_from_dict fails for these two on python 3.4
RUN_TEST(check_example_policy_plugin_accepted_execution());
RUN_TEST(check_example_policy_plugin_failed_execution());
RUN_TEST(check_example_policy_plugin_denied_execution());

View File

@@ -215,14 +215,13 @@ python_sudo_options_from_dict(PyObject *py_self, PyObject *py_args)
goto cleanup;
PyObject *py_key = NULL, *py_value = NULL; // -> borrowed references
Py_ssize_t pos = 0;
while (PyDict_Next(py_config_dict, &pos, &py_key, &py_value)) {
Py_ssize_t i = pos - 1; // python counts from 1, terrible :(
Py_ssize_t i, pos = 0;
for (i = 0; PyDict_Next(py_config_dict, &pos, &py_key, &py_value); i++) {
PyObject *py_config = PyUnicode_FromFormat("%S%s%S", py_key, "=", py_value);
if (py_config == NULL)
goto cleanup;
/* Dictionaries are sparse so we cannot use pos as an index. */
if (PyTuple_SetItem(py_result, i, py_config) != 0) { // this steals a reference, even on error
goto cleanup;
}