Terrasync: update fixes.

- Fix a nasty issue when updating existing repositories, which could
cause repository corruption and hence repeated re-syncs.
This commit is contained in:
James Turner
2014-01-07 14:24:01 +00:00
parent 1bd9a440e8
commit 61df58d651
3 changed files with 31 additions and 30 deletions
+23 -24
View File
@@ -106,12 +106,13 @@ namespace {
const char* SVN_ADD_FILE_TAG = SVN_NS "add-file"; const char* SVN_ADD_FILE_TAG = SVN_NS "add-file";
const char* SVN_TXDELTA_TAG = SVN_NS "txdelta"; const char* SVN_TXDELTA_TAG = SVN_NS "txdelta";
const char* SVN_SET_PROP_TAG = SVN_NS "set-prop"; const char* SVN_SET_PROP_TAG = SVN_NS "set-prop";
const char* SVN_PROP_TAG = SVN_NS "prop";
const char* SVN_DELETE_ENTRY_TAG = SVN_NS "delete-entry"; const char* SVN_DELETE_ENTRY_TAG = SVN_NS "delete-entry";
const char* SVN_DAV_MD5_CHECKSUM = SUBVERSION_DAV_NS ":md5-checksum"; const char* SVN_DAV_MD5_CHECKSUM = SUBVERSION_DAV_NS ":md5-checksum";
const char* DAV_HREF_TAG = DAV_NS "href"; const char* DAV_HREF_TAG = DAV_NS "href";
const char* DAV_CHECKED_IN_TAG = SVN_NS "checked-in"; const char* DAV_CHECKED_IN_TAG = DAV_NS "checked-in";
const int svn_txdelta_source = 0; const int svn_txdelta_source = 0;
@@ -173,7 +174,7 @@ namespace {
while (_ptr < pEnd) { while (_ptr < pEnd) {
int op = ((*_ptr >> 6) & 0x3); int op = ((*_ptr >> 6) & 0x3);
if (op >= 3) { if (op >= 3) {
SG_LOG(SG_IO, SG_INFO, "SVNDeltaWindow: bad opcode:" << op); SG_LOG(SG_IO, SG_INFO, "SVNDeltaWindow: bad opcode:" << op);
return false; return false;
} }
@@ -195,12 +196,14 @@ namespace {
} }
if (op == svn_txdelta_target) { if (op == svn_txdelta_target) {
while (length > 0) { // this is inefficent, but ranges can overlap.
output.push_back(output[offset++]); while (length > 0) {
--length; output.push_back(output[offset++]);
} --length;
}
} else if (op == svn_txdelta_new) { } else if (op == svn_txdelta_new) {
output.insert(output.end(), newData, newData + length); output.insert(output.end(), newData, newData + length);
newData += length;
} else if (op == svn_txdelta_source) { } else if (op == svn_txdelta_source) {
source.seekg(offset); source.seekg(offset);
char* sourceBuf = (char*) malloc(length); char* sourceBuf = (char*) malloc(length);
@@ -208,6 +211,9 @@ namespace {
source.read(sourceBuf, length); source.read(sourceBuf, length);
output.insert(output.end(), sourceBuf, sourceBuf + length); output.insert(output.end(), sourceBuf, sourceBuf + length);
free(sourceBuf); free(sourceBuf);
} else {
SG_LOG(SG_IO, SG_WARN, "bad opcode logic");
return false;
} }
} // of instruction loop } // of instruction loop
@@ -270,9 +276,9 @@ public:
SGPath filePath(Dir(currentPath).file(fileName)); SGPath filePath(Dir(currentPath).file(fileName));
currentPath = filePath; currentPath = filePath;
DAVResource* res = currentDir->collection()->childWithName(fileName); if (!filePath.exists()) {
if (!res || !filePath.exists()) { fail(SVNRepository::SVN_ERROR_FILE_NOT_FOUND);
// set error condition return;
} }
inFile = true; inFile = true;
@@ -302,10 +308,12 @@ public:
} else if (!strcmp(name, SVN_DELETE_ENTRY_TAG)) { } else if (!strcmp(name, SVN_DELETE_ENTRY_TAG)) {
string entryName(attrs.getValue("name")); string entryName(attrs.getValue("name"));
deleteEntry(entryName); deleteEntry(entryName);
} else if (!strcmp(name, DAV_CHECKED_IN_TAG) || !strcmp(name, DAV_HREF_TAG)) { } else if (!strcmp(name, DAV_CHECKED_IN_TAG) ||
!strcmp(name, DAV_HREF_TAG) ||
!strcmp(name, SVN_PROP_TAG)) {
// don't warn on these ones // don't warn on these ones
} else { } else {
//std::cerr << "unhandled element:" << name << std::endl; //SG_LOG(SG_IO, SG_WARN, "SVNReportParser: unhandled tag:" << name);
} }
} // of startElement } // of startElement
@@ -389,15 +397,9 @@ public:
fail(SVNRepository::SVN_ERROR_TXDELTA); fail(SVNRepository::SVN_ERROR_TXDELTA);
} }
} else if (!strcmp(name, SVN_ADD_FILE_TAG)) { } else if (!strcmp(name, SVN_ADD_FILE_TAG)) {
finishFile(currentDir->addChildFile(currentPath.file())); finishFile(currentPath);
} else if (!strcmp(name, SVN_OPEN_FILE_TAG)) { } else if (!strcmp(name, SVN_OPEN_FILE_TAG)) {
DAVResource* res = currentDir->collection()->childWithName(currentPath.file()); finishFile(currentPath);
if (!res) {
SG_LOG(SG_IO, SG_WARN, "SVN open-file: unknown: " << currentPath);
fail(SVNRepository::SVN_ERROR_IO);
return;
}
finishFile(res);
} else if (!strcmp(name, SVN_ADD_DIRECTORY_TAG)) { } else if (!strcmp(name, SVN_ADD_DIRECTORY_TAG)) {
// pop directory // pop directory
currentPath = currentPath.dir(); currentPath = currentPath.dir();
@@ -417,7 +419,6 @@ public:
} else if (!strcmp(name, SVN_DAV_MD5_CHECKSUM)) { } else if (!strcmp(name, SVN_DAV_MD5_CHECKSUM)) {
// validate against (presumably) just written file // validate against (presumably) just written file
if (decodedFileMd5 != md5Sum) { if (decodedFileMd5 != md5Sum) {
SG_LOG(SG_GENERAL, SG_INFO, "checksum fail on:" << currentPath);
fail(SVNRepository::SVN_ERROR_CHECKSUM); fail(SVNRepository::SVN_ERROR_CHECKSUM);
} }
} else if (!strcmp(name, SVN_OPEN_DIRECTORY_TAG)) { } else if (!strcmp(name, SVN_OPEN_DIRECTORY_TAG)) {
@@ -433,11 +434,9 @@ public:
} }
} }
void finishFile(DAVResource* res) void finishFile(const SGPath& path)
{ {
res->setVersionName(currentVersionName); currentPath = path.dir();
res->setMD5(md5Sum);
currentPath = currentPath.dir();
inFile = false; inFile = false;
} }
+3 -3
View File
@@ -229,8 +229,8 @@ protected:
_failed = true; _failed = true;
} else { } else {
SG_LOG(SG_IO, SG_WARN, "SVN: request for:" << url() << SG_LOG(SG_IO, SG_WARN, "SVN: request for:" << url() <<
" return code " << responseCode()); " got HTTP status " << responseCode());
_repo->updateFailed(this, SVNRepository::SVN_ERROR_SOCKET); _repo->updateFailed(this, SVNRepository::SVN_ERROR_HTTP);
_failed = true; _failed = true;
} }
} }
@@ -248,7 +248,7 @@ protected:
SVNRepository::ResultCode err = _parser.parseXML(s, n); SVNRepository::ResultCode err = _parser.parseXML(s, n);
if (err) { if (err) {
_failed = true; _failed = true;
SG_LOG(SG_IO, SG_WARN, _repo->p << ": SVN: request for:" << url() << " failed:" << err); SG_LOG(SG_IO, SG_WARN, this << ": SVN: request for:" << url() << " failed:" << err);
_repo->updateFailed(this, err); _repo->updateFailed(this, err);
_repo = NULL; _repo = NULL;
} }
+3 -1
View File
@@ -61,7 +61,9 @@ public:
SVN_ERROR_XML, SVN_ERROR_XML,
SVN_ERROR_TXDELTA, SVN_ERROR_TXDELTA,
SVN_ERROR_IO, SVN_ERROR_IO,
SVN_ERROR_CHECKSUM SVN_ERROR_CHECKSUM,
SVN_ERROR_FILE_NOT_FOUND,
SVN_ERROR_HTTP
}; };
ResultCode failure() const; ResultCode failure() const;