| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.1077 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.1077 |
| Problem: Python: Allocating dict the wrong way, causing a crash. |
| Solution: Use py_dict_alloc(). Fix some exception problems. (ZyX) |
| Files: src/if_py_both.h |
| |
| |
| |
| |
| |
| *** 26,56 **** |
| |
| #define PyErr_SetVim(str) PyErr_SetString(VimError, str) |
| |
| #define INVALID_BUFFER_VALUE ((buf_T *)(-1)) |
| #define INVALID_WINDOW_VALUE ((win_T *)(-1)) |
| #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1)) |
| |
| - #define DICTKEY_DECL \ |
| - PyObject *dictkey_todecref = NULL; |
| - #define DICTKEY_GET(err, decref) \ |
| - if (!(key = StringToChars(keyObject, &dictkey_todecref))) \ |
| - { \ |
| - if (decref) \ |
| - { \ |
| - Py_DECREF(keyObject); \ |
| - } \ |
| - return err; \ |
| - } \ |
| - if (decref && !dictkey_todecref) \ |
| - dictkey_todecref = keyObject; \ |
| - if (*key == NUL) \ |
| - { \ |
| - PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \ |
| - return err; \ |
| - } |
| - #define DICTKEY_UNREF \ |
| - Py_XDECREF(dictkey_todecref); |
| - |
| typedef void (*rangeinitializer)(void *); |
| typedef void (*runner)(const char *, void * |
| #ifdef PY_CAN_RECURSE |
| --- 26,38 ---- |
| |
| #define PyErr_SetVim(str) PyErr_SetString(VimError, str) |
| |
| + #define RAISE_NO_EMPTY_KEYS PyErr_SetString(PyExc_ValueError, \ |
| + _("empty keys are not allowed")) |
| + |
| #define INVALID_BUFFER_VALUE ((buf_T *)(-1)) |
| #define INVALID_WINDOW_VALUE ((win_T *)(-1)) |
| #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1)) |
| |
| typedef void (*rangeinitializer)(void *); |
| typedef void (*runner)(const char *, void * |
| #ifdef PY_CAN_RECURSE |
| |
| *** 1016,1023 **** |
| dictitem_T *di; |
| dict_T *dict = self->dict; |
| hashitem_T *hi; |
| ! |
| ! DICTKEY_DECL |
| |
| if (flags & DICT_FLAG_HAS_DEFAULT) |
| { |
| --- 998,1004 ---- |
| dictitem_T *di; |
| dict_T *dict = self->dict; |
| hashitem_T *hi; |
| ! PyObject *todecref; |
| |
| if (flags & DICT_FLAG_HAS_DEFAULT) |
| { |
| |
| *** 1030,1040 **** |
| if (flags & DICT_FLAG_RETURN_BOOL) |
| defObject = Py_False; |
| |
| ! DICTKEY_GET(NULL, 0) |
| |
| hi = hash_find(&dict->dv_hashtab, key); |
| |
| ! DICTKEY_UNREF |
| |
| if (HASHITEM_EMPTY(hi)) |
| { |
| --- 1011,1028 ---- |
| if (flags & DICT_FLAG_RETURN_BOOL) |
| defObject = Py_False; |
| |
| ! if (!(key = StringToChars(keyObject, &todecref))) |
| ! return NULL; |
| ! |
| ! if (*key == NUL) |
| ! { |
| ! RAISE_NO_EMPTY_KEYS; |
| ! return NULL; |
| ! } |
| |
| hi = hash_find(&dict->dv_hashtab, key); |
| |
| ! Py_XDECREF(todecref); |
| |
| if (HASHITEM_EMPTY(hi)) |
| { |
| |
| *** 1173,1179 **** |
| typval_T tv; |
| dict_T *dict = self->dict; |
| dictitem_T *di; |
| ! DICTKEY_DECL |
| |
| if (dict->dv_lock) |
| { |
| --- 1161,1167 ---- |
| typval_T tv; |
| dict_T *dict = self->dict; |
| dictitem_T *di; |
| ! PyObject *todecref; |
| |
| if (dict->dv_lock) |
| { |
| |
| *** 1181,1187 **** |
| return -1; |
| } |
| |
| ! DICTKEY_GET(-1, 0) |
| |
| di = dict_find(dict, key, -1); |
| |
| --- 1169,1181 ---- |
| return -1; |
| } |
| |
| ! if (!(key = StringToChars(keyObject, &todecref))) |
| ! return -1; |
| ! if (*key == NUL) |
| ! { |
| ! RAISE_NO_EMPTY_KEYS; |
| ! return -1; |
| ! } |
| |
| di = dict_find(dict, key, -1); |
| |
| |
| *** 1191,1197 **** |
| |
| if (di == NULL) |
| { |
| ! DICTKEY_UNREF |
| PyErr_SetObject(PyExc_KeyError, keyObject); |
| return -1; |
| } |
| --- 1185,1191 ---- |
| |
| if (di == NULL) |
| { |
| ! Py_XDECREF(todecref); |
| PyErr_SetObject(PyExc_KeyError, keyObject); |
| return -1; |
| } |
| |
| *** 1208,1213 **** |
| --- 1202,1208 ---- |
| { |
| if (!(di = dictitem_alloc(key))) |
| { |
| + Py_XDECREF(todecref); |
| PyErr_NoMemory(); |
| return -1; |
| } |
| |
| *** 1216,1222 **** |
| |
| if (dict_add(dict, di) == FAIL) |
| { |
| ! DICTKEY_UNREF |
| vim_free(di); |
| dictitem_free(di); |
| PyErr_SetVim(_("failed to add key to dictionary")); |
| --- 1211,1217 ---- |
| |
| if (dict_add(dict, di) == FAIL) |
| { |
| ! Py_XDECREF(todecref); |
| vim_free(di); |
| dictitem_free(di); |
| PyErr_SetVim(_("failed to add key to dictionary")); |
| |
| *** 1226,1232 **** |
| else |
| clear_tv(&di->di_tv); |
| |
| ! DICTKEY_UNREF |
| |
| copy_tv(&tv, &di->di_tv); |
| clear_tv(&tv); |
| --- 1221,1227 ---- |
| else |
| clear_tv(&di->di_tv); |
| |
| ! Py_XDECREF(todecref); |
| |
| copy_tv(&tv, &di->di_tv); |
| clear_tv(&tv); |
| |
| *** 2202,2218 **** |
| int flags; |
| long numval; |
| char_u *stringval; |
| ! DICTKEY_DECL |
| |
| if (self->Check(self->from)) |
| return NULL; |
| |
| ! DICTKEY_GET(NULL, 0) |
| |
| flags = get_option_value_strict(key, &numval, &stringval, |
| self->opt_type, self->from); |
| |
| ! DICTKEY_UNREF |
| |
| if (flags == 0) |
| { |
| --- 2197,2219 ---- |
| int flags; |
| long numval; |
| char_u *stringval; |
| ! PyObject *todecref; |
| |
| if (self->Check(self->from)) |
| return NULL; |
| |
| ! if (!(key = StringToChars(keyObject, &todecref))) |
| ! return NULL; |
| ! if (*key == NUL) |
| ! { |
| ! RAISE_NO_EMPTY_KEYS; |
| ! return NULL; |
| ! } |
| |
| flags = get_option_value_strict(key, &numval, &stringval, |
| self->opt_type, self->from); |
| |
| ! Py_XDECREF(todecref); |
| |
| if (flags == 0) |
| { |
| |
| *** 2329,2340 **** |
| int flags; |
| int opt_flags; |
| int r = 0; |
| ! DICTKEY_DECL |
| |
| if (self->Check(self->from)) |
| return -1; |
| |
| ! DICTKEY_GET(-1, 0) |
| |
| flags = get_option_value_strict(key, NULL, NULL, |
| self->opt_type, self->from); |
| --- 2330,2347 ---- |
| int flags; |
| int opt_flags; |
| int r = 0; |
| ! PyObject *todecref; |
| |
| if (self->Check(self->from)) |
| return -1; |
| |
| ! if (!(key = StringToChars(keyObject, &todecref))) |
| ! return -1; |
| ! if (*key == NUL) |
| ! { |
| ! RAISE_NO_EMPTY_KEYS; |
| ! return -1; |
| ! } |
| |
| flags = get_option_value_strict(key, NULL, NULL, |
| self->opt_type, self->from); |
| |
| *** 2342,2348 **** |
| if (flags == 0) |
| { |
| PyErr_SetObject(PyExc_KeyError, keyObject); |
| ! DICTKEY_UNREF |
| return -1; |
| } |
| |
| --- 2349,2355 ---- |
| if (flags == 0) |
| { |
| PyErr_SetObject(PyExc_KeyError, keyObject); |
| ! Py_XDECREF(todecref); |
| return -1; |
| } |
| |
| |
| *** 2352,2371 **** |
| { |
| PyErr_SetString(PyExc_ValueError, |
| _("unable to unset global option")); |
| ! DICTKEY_UNREF |
| return -1; |
| } |
| else if (!(flags & SOPT_GLOBAL)) |
| { |
| PyErr_SetString(PyExc_ValueError, _("unable to unset option " |
| "without global value")); |
| ! DICTKEY_UNREF |
| return -1; |
| } |
| else |
| { |
| unset_global_local_option(key, self->from); |
| ! DICTKEY_UNREF |
| return 0; |
| } |
| } |
| --- 2359,2378 ---- |
| { |
| PyErr_SetString(PyExc_ValueError, |
| _("unable to unset global option")); |
| ! Py_XDECREF(todecref); |
| return -1; |
| } |
| else if (!(flags & SOPT_GLOBAL)) |
| { |
| PyErr_SetString(PyExc_ValueError, _("unable to unset option " |
| "without global value")); |
| ! Py_XDECREF(todecref); |
| return -1; |
| } |
| else |
| { |
| unset_global_local_option(key, self->from); |
| ! Py_XDECREF(todecref); |
| return 0; |
| } |
| } |
| |
| *** 2396,2402 **** |
| else |
| { |
| PyErr_SetString(PyExc_TypeError, _("object must be integer")); |
| ! DICTKEY_UNREF |
| return -1; |
| } |
| |
| --- 2403,2409 ---- |
| else |
| { |
| PyErr_SetString(PyExc_TypeError, _("object must be integer")); |
| ! Py_XDECREF(todecref); |
| return -1; |
| } |
| |
| |
| *** 2418,2424 **** |
| r = -1; |
| } |
| |
| ! DICTKEY_UNREF |
| |
| return r; |
| } |
| --- 2425,2431 ---- |
| r = -1; |
| } |
| |
| ! Py_XDECREF(todecref); |
| |
| return r; |
| } |
| |
| *** 4528,4534 **** |
| PyObject *valObject; |
| Py_ssize_t iter = 0; |
| |
| ! if (!(dict = dict_alloc())) |
| return -1; |
| |
| tv->v_type = VAR_DICT; |
| --- 4535,4541 ---- |
| PyObject *valObject; |
| Py_ssize_t iter = 0; |
| |
| ! if (!(dict = py_dict_alloc())) |
| return -1; |
| |
| tv->v_type = VAR_DICT; |
| |
| *** 4553,4558 **** |
| --- 4560,4566 ---- |
| { |
| dict_unref(dict); |
| Py_XDECREF(todecref); |
| + RAISE_NO_EMPTY_KEYS; |
| return -1; |
| } |
| |
| |
| *** 4600,4606 **** |
| PyObject *keyObject; |
| PyObject *valObject; |
| |
| ! if (!(dict = dict_alloc())) |
| return -1; |
| |
| tv->v_type = VAR_DICT; |
| --- 4608,4614 ---- |
| PyObject *keyObject; |
| PyObject *valObject; |
| |
| ! if (!(dict = py_dict_alloc())) |
| return -1; |
| |
| tv->v_type = VAR_DICT; |
| |
| *** 4637,4642 **** |
| --- 4645,4651 ---- |
| Py_DECREF(iterator); |
| Py_XDECREF(todecref); |
| dict_unref(dict); |
| + RAISE_NO_EMPTY_KEYS; |
| return -1; |
| } |
| |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 1077, |
| /**/ |
| |
| -- |
| The History of every major Galactic Civilization tends to pass through |
| three distinct and recognizable phases, those of Survival, Inquiry and |
| Sophistication, otherwise known as the How, Why and Where phases. |
| For instance, the first phase is characterized by the question 'How can |
| we eat?' the second by the question 'Why do we eat?' and the third by |
| the question 'Where shall we have lunch?' |
| -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |