diff -ru dnsdist-2.0.3.orig/dnsdist-dynblocks.hh dnsdist-2.0.3.CVE-2026-33597/dnsdist-dynblocks.hh
--- dnsdist-2.0.3.orig/dnsdist-dynblocks.hh	2026-03-12 16:00:00.000000000 +0100
+++ dnsdist-2.0.3.CVE-2026-33597/dnsdist-dynblocks.hh	2026-04-03 15:53:23.655404059 +0200
@@ -65,6 +65,7 @@
   {
   }
 
+  mutable std::string fullname;
   const StatNode& node;
   const StatNode::Stat& self;
   const StatNode::Stat& children;
diff -ru dnsdist-2.0.3.orig/dnsdist-lua-inspection-ffi.cc dnsdist-2.0.3.CVE-2026-33597/dnsdist-lua-inspection-ffi.cc
--- dnsdist-2.0.3.orig/dnsdist-lua-inspection-ffi.cc	2026-03-12 16:00:00.000000000 +0100
+++ dnsdist-2.0.3.CVE-2026-33597/dnsdist-lua-inspection-ffi.cc	2026-04-03 15:53:23.656433894 +0200
@@ -66,9 +66,11 @@
 
 void dnsdist_ffi_stat_node_get_full_name_raw(const dnsdist_ffi_stat_node_t* node, const char** name, size_t* nameSize)
 {
-  const auto& storage = node->node.fullname;
-  *name = storage.c_str();
-  *nameSize = storage.size();
+  if (node->fullname.empty()) {
+    node->fullname = node->node.fullname.toString();
+  }
+  *name = node->fullname.c_str();
+  *nameSize = node->fullname.size();
 }
 
 unsigned int dnsdist_ffi_stat_node_get_children_count(const dnsdist_ffi_stat_node_t* node)
diff -ru dnsdist-2.0.3.orig/dnsdist-lua-inspection.cc dnsdist-2.0.3.CVE-2026-33597/dnsdist-lua-inspection.cc
--- dnsdist-2.0.3.orig/dnsdist-lua-inspection.cc	2026-03-12 16:00:00.000000000 +0100
+++ dnsdist-2.0.3.CVE-2026-33597/dnsdist-lua-inspection.cc	2026-04-03 15:53:23.656512143 +0200
@@ -902,7 +902,7 @@
                                                               [](const StatNode& node) -> unsigned int {
                                                                 return node.children.size();
                                                               });
-  luaCtx.registerMember("fullname", &StatNode::fullname);
+  luaCtx.registerMember<std::string(StatNode::*)>(std::string("fullname"), [](const StatNode& node) -> std::string { return node.fullname.toString(); });
   luaCtx.registerMember("labelsCount", &StatNode::labelsCount);
   luaCtx.registerMember("servfails", &StatNode::Stat::servfails);
   luaCtx.registerMember("nxdomains", &StatNode::Stat::nxdomains);
diff -ru dnsdist-2.0.3.orig/statnode.cc dnsdist-2.0.3.CVE-2026-33597/statnode.cc
--- dnsdist-2.0.3.orig/statnode.cc	2026-03-13 16:12:38.000000000 +0100
+++ dnsdist-2.0.3.CVE-2026-33597/statnode.cc	2026-04-03 15:53:23.656600721 +0200
@@ -57,20 +57,20 @@
   }
 
   auto last = tmp.end() - 1;
-  children[*last].submit(last, tmp.begin(), "", rcode, bytes, remote, 1, hit);
+  children[*last].submit(last, tmp.begin(), g_rootdnsname, rcode, bytes, remote, 1, hit);
 }
 
-/* www.powerdns.com. -> 
+/* www.powerdns.com. ->
    .                 <- fullnames
    com.
    powerdns.com
-   www.powerdns.com. 
+   www.powerdns.com.
 */
 
-void StatNode::submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit)
+void StatNode::submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const DNSName& domain, int rcode, unsigned int bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit)
 {
   //  cerr<<"Submit called for domain='"<<domain<<"': ";
-  //  for(const std::string& n :  labels) 
+  //  for(const std::string& n :  labels)
   //    cerr<<n<<".";
   //  cerr<<endl;
   if (name.empty()) {
@@ -84,13 +84,8 @@
 
   if (end == begin) {
     if (fullname.empty()) {
-      size_t needed = name.size() + 1 + domain.size();
-      if (fullname.capacity() < needed) {
-        fullname.reserve(needed);
-      }
-      fullname = name;
-      fullname.append(".");
-      fullname.append(domain);
+      fullname = domain;
+      fullname.prependRawLabel(name);
       labelsCount = count;
     }
     //    cerr<<"Hit the end, set our fullname to '"<<fullname<<"'"<<endl<<endl;
@@ -119,13 +114,8 @@
   }
   else {
     if (fullname.empty()) {
-      size_t needed = name.size() + 1 + domain.size();
-      if (fullname.capacity() < needed) {
-        fullname.reserve(needed);
-      }
-      fullname = name;
-      fullname.append(".");
-      fullname.append(domain);
+      fullname = domain;
+      fullname.prependRawLabel(name);
       labelsCount = count;
     }
     //    cerr<<"Not yet end, set our fullname to '"<<fullname<<"', recursing"<<endl;
diff -ru dnsdist-2.0.3.orig/statnode.hh dnsdist-2.0.3.CVE-2026-33597/statnode.hh
--- dnsdist-2.0.3.orig/statnode.hh	2026-03-13 16:12:38.000000000 +0100
+++ dnsdist-2.0.3.CVE-2026-33597/statnode.hh	2026-04-03 15:53:23.656632471 +0200
@@ -62,7 +62,7 @@
 
   Stat s;
   std::string name;
-  std::string fullname;
+  DNSName fullname;
   uint8_t labelsCount{0};
 
   void submit(const DNSName& domain, int rcode, unsigned int bytes, bool hit, const std::optional<ComboAddress>& remote);
@@ -75,5 +75,5 @@
   children_t children;
 
 private:
-  void submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit);
+  void submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const DNSName& domain, int rcode, unsigned int bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit);
 };
