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: