summaryrefslogtreecommitdiffstats
path: root/core/variant.cpp
diff options
context:
space:
mode:
authorHein-Pieter van Braam-Stewart <hp@tmm.cx>2019-04-20 01:57:29 +0200
committerHein-Pieter van Braam-Stewart <hp@tmm.cx>2019-04-20 02:01:55 +0200
commit8b1e297fc6567ead2c400199348d89e17b552899 (patch)
tree7cc302337a56767015ae4b716cc2ac8fae57c557 /core/variant.cpp
parent8e652a1400ee20b99cf4829e8b4883fe3f254d59 (diff)
downloadredot-engine-8b1e297fc6567ead2c400199348d89e17b552899.tar.gz
Don't crash on printing nested types
When adding an Array or Dictionary to itself operator String() got in an infinite loop. This commit adds a stack to operator String() (Through the use of a new 'stringify method'). This stack keeps track of all unique Arrays and Dictionaries it has seen. When a duplicate is found only a static string is printed '[...]' or '{...}'. This mirror Python's behavior in a similar case.
Diffstat (limited to 'core/variant.cpp')
-rw-r--r--core/variant.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/core/variant.cpp b/core/variant.cpp
index 6c54faf233..1bc3cff505 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1415,7 +1415,12 @@ struct _VariantStrPair {
};
Variant::operator String() const {
+ List<const void *> stack;
+ return stringify(stack);
+}
+
+String Variant::stringify(List<const void *> &stack) const {
switch (type) {
case NIL: return "Null";
@@ -1467,6 +1472,12 @@ Variant::operator String() const {
case DICTIONARY: {
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
+ if (stack.find(d.id())) {
+ return "{...}";
+ }
+
+ stack.push_back(d.id());
+
//const String *K=NULL;
String str("{");
List<Variant> keys;
@@ -1477,8 +1488,9 @@ Variant::operator String() const {
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
_VariantStrPair sp;
- sp.key = String(E->get());
- sp.value = d[E->get()];
+ sp.key = E->get().stringify(stack);
+ sp.value = d[E->get()].stringify(stack);
+
pairs.push_back(sp);
}
@@ -1561,12 +1573,19 @@ Variant::operator String() const {
case ARRAY: {
Array arr = operator Array();
+ if (stack.find(arr.id())) {
+ return "[...]";
+ }
+ stack.push_back(arr.id());
+
String str("[");
for (int i = 0; i < arr.size(); i++) {
if (i)
str += ", ";
- str += String(arr[i]);
- };
+
+ str += arr[i].stringify(stack);
+ }
+
str += "]";
return str;