To: vim_dev@googlegroups.com Subject: Patch 7.3.1077 Fcc: outbox From: Bram Moolenaar 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 *** ../vim-7.3.1076/src/if_py_both.h 2013-05-30 19:01:20.000000000 +0200 --- src/if_py_both.h 2013-05-30 21:53:00.000000000 +0200 *************** *** 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; } *** ../vim-7.3.1076/src/version.c 2013-05-30 21:42:09.000000000 +0200 --- src/version.c 2013-05-30 21:49:50.000000000 +0200 *************** *** 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 ///