diff --git a/.gitignore b/.gitignore index d7d6930..a743071 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /build/ +/build-test/ /prefix/ /linux-build/ /CMakeUserPresets.json diff --git a/include/ifc/dom/node.hxx b/include/ifc/dom/node.hxx index 5512cb7..a90dc0d 100644 --- a/include/ifc/dom/node.hxx +++ b/include/ifc/dom/node.hxx @@ -184,6 +184,8 @@ namespace ifc::util { std::string ref(const symbolic::Identity& id); std::set referenced_nodes; + // Track indices currently being processed to detect cycles + std::set processing_types; private: using NodeMap = std::map; diff --git a/src/ifc-dom/types.cxx b/src/ifc-dom/types.cxx index 6c87be8..dff8897 100644 --- a/src/ifc-dom/types.cxx +++ b/src/ifc-dom/types.cxx @@ -159,9 +159,19 @@ namespace ifc::util { std::string get_string_if_possible(Loader& ctx, TypeIndex index) { - if (not null(index)) - return ctx.reader.visit(index, TypeTranslator{ctx}); - return "no-type"; + if (null(index)) + return "no-type"; + + // Check for cycles to prevent infinite recursion + if (ctx.processing_types.find(index) != ctx.processing_types.end()) { + return "..." + to_string(index); // Return a reference to break the cycle + } + + // Track this index while processing + ctx.processing_types.insert(index); + auto result = ctx.reader.visit(index, TypeTranslator{ctx}); + ctx.processing_types.erase(index); + return result; } // Load types as full blown nodes.