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 qualifiers = next->qualifiers; - std::vector namekey = DomeUtils::split(next->namekey, "[#]"); + std::vector 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 split(std::string data, std::string token) { return output; } +inline std::vector rsplit(std::string data, std::string token, int max=-1) { + std::vector 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 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: