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
*** ../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 ///