Blob Blame History Raw
diff --git a/src/dome/DomeCoreXeq.cpp b/src/dome/DomeCoreXeq.cpp
index 29a8b7bd..af7a1238 100644
--- a/src/dome/DomeCoreXeq.cpp
+++ b/src/dome/DomeCoreXeq.cpp
@@ -1649,7 +1649,10 @@ int DomeCore::dome_getspaceinfo(DomeReq &req) {
 int DomeCore::calculateChecksum(DomeReq &req, std::string lfn, Replica replica, std::string checksumtype, bool updateLfnChecksum, bool forcerecalc = false) {
   // create queue entry
   GenPrioQueueItem::QStatus qstatus = GenPrioQueueItem::Waiting;
-  std::string namekey = lfn + "[#]" + replica.rfn + "[#]" + checksumtype;
+  std::stringstream s; // encode checksum data in key
+  s << lfn << "[#]" << replica.rfn + "[#]" << checksumtype << "[#]"
+    << lfn.length() << "[#]" << replica.rfn.length() << "[#]" << checksumtype.length();
+  std::string namekey = s.str();
   
   
   
diff --git a/src/dome/DomeStatus.cpp b/src/dome/DomeStatus.cpp
index cd174900..7969119a 100644
--- a/src/dome/DomeStatus.cpp
+++ b/src/dome/DomeStatus.cpp
@@ -633,21 +633,28 @@ void DomeStatus::tickChecksums() {
                   
       // parse queue item contents
       std::vector<std::string> qualifiers = next->qualifiers;
-      std::vector<std::string> namekey = DomeUtils::split(next->namekey, "[#]");
+      std::vector<std::string> namekey = DomeUtils::rsplit(next->namekey, "[#]", 3);
                   
-      if(namekey.size() != 3) {
+      if(namekey.size() != 4) {
         Log(Logger::Lvl1, domelogmask, domelogname, "INCONSISTENCY in the internal checksum queue. Invalid namekey: " << next->namekey);
         continue;
       }
-                  
+      int lfn_length = atoi(namekey[1].c_str());
+      int rfn_length = atoi(namekey[2].c_str());
+      int checksumtype_length = atoi(namekey[3].c_str());
+      if (lfn_length + 3 + rfn_length + 3 + checksumtype_length != (int) namekey[0].length()) {
+        Log(Logger::Lvl1, domelogmask, domelogname, "INCONSISTENCY in the internal checksum queue. Invalid namekey: " << next->namekey);
+        continue;
+      }
+
       if(qualifiers.size() != 5) {
         Log(Logger::Lvl1, domelogmask, domelogname, "INCONSISTENCY in the internal checksum queue. Invalid size of qualifiers: " << qualifiers.size());
         continue;
       }
-                  
-      lfn = namekey[0];
-      rfn = namekey[1];
-      checksumtype = namekey[2];
+
+      lfn = namekey[0].substr(0, lfn_length);
+      rfn = namekey[0].substr(lfn_length+3, rfn_length);
+      checksumtype = namekey[0].substr(lfn_length+3+rfn_length+3, checksumtype_length);
                   
       server = qualifiers[1];
       updateLfnChecksum = DomeUtils::str_to_bool(qualifiers[2]);
diff --git a/src/utils/DomeUtils.h b/src/utils/DomeUtils.h
index 9e1a9cd3..3e0e03b4 100644
--- a/src/utils/DomeUtils.h
+++ b/src/utils/DomeUtils.h
@@ -78,6 +78,20 @@ inline std::vector<std::string> split(std::string data, std::string token) {
     return output;
 }
 
+inline std::vector<std::string> rsplit(std::string data, std::string token, int max=-1) {
+  std::vector<std::string> output;
+  for (int cnt = 0; ; cnt++) {
+    size_t start = data.rfind(token);
+    if (start == std::string::npos || cnt == max) {
+      output.insert(output.begin(), data.substr(0, data.length()));
+      break;
+    }
+    output.insert(output.begin(), data.substr(start+token.length(), data.length()-start));
+    data = data.substr(0, start);
+  }
+  return output;
+}
+
 inline void mkdirp(const std::string& path)   {
   std::vector<std::string> parts = split(path, "/");
   std::ostringstream tocreate(parts[0]);
diff --git a/tests/dpm/dpm-tester.py b/tests/dpm/dpm-tester.py
index 0d637b61..6d6e30c9 100755
--- a/tests/dpm/dpm-tester.py
+++ b/tests/dpm/dpm-tester.py
@@ -1179,7 +1179,7 @@ def single_protocol_tests(args, scope):
     orch.add_nested(play_with_file(scope, tester, "/etc/services", "{0}/services".format(target)))
 
     if scope != "srm":
-        evil_filename = """evil filename-!@#%^_-+=:][}{><'" #$&*)("""
+        evil_filename = """evil filename[#]-!@#%^_-+=:][}{><'" #$&*)("""
         orch.add_nested(play_with_file(scope, tester, "/etc/services", path_join(target, evil_filename)))
 
         if args.dir_accounting: