mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.1.0522: Vim9: string(object) hangs for recursive references
Problem: Vim9: string(object) hangs for recursive references Solution: Handle recursive objects specifically, add a hang test and a compare test (Ernie Rael) fixes: #15080 closes: #15082 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
4179f193cc
commit
05ff4e42fb
59
src/eval.c
59
src/eval.c
@@ -6138,6 +6138,58 @@ class_tv2string(typval_T *tv, char_u **tofree)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a textual representation of an Object in "tv".
|
||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||
* When "copyID" is not zero replace recursive object with "...".
|
||||
* When "restore_copyID" is FALSE, repeated items in the object are
|
||||
* replaced with "...". May return NULL.
|
||||
*/
|
||||
static char_u *
|
||||
object_tv2string(
|
||||
typval_T *tv,
|
||||
char_u **tofree,
|
||||
int copyID,
|
||||
int restore_copyID,
|
||||
char_u *numbuf,
|
||||
int echo_style,
|
||||
int composite_val)
|
||||
{
|
||||
char_u *r = NULL;
|
||||
|
||||
object_T *obj = tv->vval.v_object;
|
||||
if (obj == NULL || obj->obj_class == NULL)
|
||||
{
|
||||
*tofree = NULL;
|
||||
r = (char_u *)"object of [unknown]";
|
||||
}
|
||||
else if (copyID != 0 && obj->obj_copyID == copyID
|
||||
&& obj->obj_class->class_obj_member_count != 0)
|
||||
{
|
||||
int n = 25 + strlen((char*)obj->obj_class->class_name);
|
||||
r = alloc(n);
|
||||
if (r != NULL)
|
||||
(void)vim_snprintf((char*)r, n, "object of %s {...}",
|
||||
obj->obj_class->class_name);
|
||||
*tofree = r;
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_copyID;
|
||||
if (restore_copyID)
|
||||
old_copyID = obj->obj_copyID;
|
||||
|
||||
obj->obj_copyID = copyID;
|
||||
*tofree = object2string(obj, numbuf, copyID, echo_style,
|
||||
restore_copyID, composite_val);
|
||||
if (restore_copyID)
|
||||
obj->obj_copyID = old_copyID;
|
||||
r = *tofree;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string with the string representation of a variable.
|
||||
* If the memory is allocated "tofree" is set to it, otherwise NULL.
|
||||
@@ -6169,7 +6221,7 @@ echo_string_core(
|
||||
{
|
||||
// Only give this message once for a recursive call to avoid
|
||||
// flooding the user with errors. And stop iterating over lists
|
||||
// and dicts.
|
||||
// and dicts and objects.
|
||||
did_echo_string_emsg = TRUE;
|
||||
emsg(_(e_variable_nested_too_deep_for_displaying));
|
||||
}
|
||||
@@ -6227,9 +6279,8 @@ echo_string_core(
|
||||
break;
|
||||
|
||||
case VAR_OBJECT:
|
||||
*tofree = r = object2string(tv->vval.v_object, numbuf, copyID,
|
||||
echo_style, restore_copyID,
|
||||
composite_val);
|
||||
r = object_tv2string(tv, tofree, copyID, restore_copyID,
|
||||
numbuf, echo_style, composite_val);
|
||||
break;
|
||||
|
||||
case VAR_FLOAT:
|
||||
|
Reference in New Issue
Block a user