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>
diff --git a/src/vim9class.c b/src/vim9class.c
index cf2af61..78f5ab8 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -3873,7 +3873,9 @@
}
/*
- * Return a textual representation of object "obj"
+ * Return a textual representation of object "obj".
+ * "obj" must not be NULL.
+ * May return NULL.
*/
char_u *
object2string(
@@ -3890,47 +3892,58 @@
== OK
&& rettv.vval.v_string != NULL)
return rettv.vval.v_string;
+
+ int ok = OK;
+ class_T *cl = obj->obj_class;
+ garray_T ga;
+ ga_init2(&ga, 1, 50);
+
+ if (cl != NULL && IS_ENUM(cl))
+ {
+ ga_concat(&ga, (char_u *)"enum ");
+ ga_concat(&ga, cl->class_name);
+ char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string;
+ ga_concat(&ga, (char_u *)".");
+ ga_concat(&ga, enum_name);
+ }
else
{
- garray_T ga;
- ga_init2(&ga, 1, 50);
-
- class_T *cl = obj == NULL ? NULL : obj->obj_class;
- if (cl != NULL && IS_ENUM(cl))
- {
- ga_concat(&ga, (char_u *)"enum ");
- ga_concat(&ga, cl->class_name);
- char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string;
- ga_concat(&ga, (char_u *)".");
- ga_concat(&ga, enum_name);
- }
- else
- {
- ga_concat(&ga, (char_u *)"object of ");
- ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]"
- : cl->class_name);
- }
- if (cl != NULL)
- {
- ga_concat(&ga, (char_u *)" {");
- for (int i = 0; i < cl->class_obj_member_count; ++i)
- {
- if (i > 0)
- ga_concat(&ga, (char_u *)", ");
- ocmember_T *m = &cl->class_obj_members[i];
- ga_concat(&ga, m->ocm_name);
- ga_concat(&ga, (char_u *)": ");
- char_u *tf = NULL;
- ga_concat(&ga, echo_string_core(
- (typval_T *)(obj + 1) + i,
- &tf, numbuf, copyID, echo_style,
- restore_copyID, composite_val));
- vim_free(tf);
- }
- ga_concat(&ga, (char_u *)"}");
- }
- return ga.ga_data;
+ ga_concat(&ga, (char_u *)"object of ");
+ ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]"
+ : cl->class_name);
}
+ if (cl != NULL)
+ {
+ ga_concat(&ga, (char_u *)" {");
+ for (int i = 0; i < cl->class_obj_member_count; ++i)
+ {
+ if (i > 0)
+ ga_concat(&ga, (char_u *)", ");
+ ocmember_T *m = &cl->class_obj_members[i];
+ ga_concat(&ga, m->ocm_name);
+ ga_concat(&ga, (char_u *)": ");
+ char_u *tf = NULL;
+ char_u *s = echo_string_core((typval_T *)(obj + 1) + i,
+ &tf, numbuf, copyID, echo_style,
+ restore_copyID, composite_val);
+ if (s != NULL)
+ ga_concat(&ga, s);
+ vim_free(tf);
+ if (s == NULL || did_echo_string_emsg)
+ {
+ ok = FAIL;
+ break;
+ }
+ line_breakcheck();
+ }
+ ga_concat(&ga, (char_u *)"}");
+ }
+ if (ok == FAIL)
+ {
+ vim_free(ga.ga_data);
+ return NULL;
+ }
+ return (char_u *)ga.ga_data;
}
/*