diff options
author | Jose <jose@zeroc.com> | 2015-02-17 17:08:54 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2015-02-17 17:08:54 +0100 |
commit | 21c1ba295bc813f35a638b3867234c63dac1816e (patch) | |
tree | d4e82f25daf0030375094f734cf4c5ad2d55fdf2 /cpp/src/IcePatch2 | |
parent | ICE-6306 added checks to javascript for byte/short/int (diff) | |
download | ice-21c1ba295bc813f35a638b3867234c63dac1816e.tar.bz2 ice-21c1ba295bc813f35a638b3867234c63dac1816e.tar.xz ice-21c1ba295bc813f35a638b3867234c63dac1816e.zip |
Fixed (ICE-5740) - IcePatch2 has issues with 'large' files.
Diffstat (limited to 'cpp/src/IcePatch2')
-rwxr-xr-x | cpp/src/IcePatch2/.depend.mak | 9 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Calc.cpp | 25 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Client.cpp | 5 | ||||
-rw-r--r-- | cpp/src/IcePatch2/FileServerI.cpp | 128 | ||||
-rw-r--r-- | cpp/src/IcePatch2/FileServerI.h | 29 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Server.cpp | 6 |
6 files changed, 138 insertions, 64 deletions
diff --git a/cpp/src/IcePatch2/.depend.mak b/cpp/src/IcePatch2/.depend.mak index 3f54f21e89f..53f280e4dc9 100755 --- a/cpp/src/IcePatch2/.depend.mak +++ b/cpp/src/IcePatch2/.depend.mak @@ -7,9 +7,10 @@ FileServerI.obj: \ "$(includedir)\IceUtil\Shared.h" \ "$(includedir)\IceUtil\Handle.h" \ "$(includedir)\IceUtil\Exception.h" \ + "$(includedir)\IceUtil\StringUtil.h" \ "$(includedir)\IceUtil\ScopedArray.h" \ "FileServerI.h" \ - "$(includedir)\IcePatch2\Util.h" \ + "..\..\src\IcePatch2Lib\Util.h" \ "$(includedir)\Ice\Ice.h" \ "$(includedir)\IceUtil\PushDisableWarnings.h" \ "$(includedir)\Ice\Config.h" \ @@ -242,7 +243,7 @@ Server.obj: \ "$(includedir)\Ice\NativePropertiesAdmin.h" \ "$(includedir)\Ice\Metrics.h" \ "FileServerI.h" \ - "$(includedir)\IcePatch2\Util.h" \ + "..\..\src\IcePatch2Lib\Util.h" \ "$(includedir)\IcePatch2\FileInfo.h" \ "$(includedir)\IcePatch2\Config.h" \ "$(includedir)\IcePatch2\FileServer.h" \ @@ -365,7 +366,7 @@ Client.obj: \ "$(includedir)\Ice\NativePropertiesAdmin.h" \ "$(includedir)\Ice\Metrics.h" \ "$(includedir)\Ice\Service.h" \ - "$(includedir)\IcePatch2\Util.h" \ + "..\..\src\IcePatch2Lib\Util.h" \ "$(includedir)\IcePatch2\FileInfo.h" \ "$(includedir)\IcePatch2\Config.h" \ "$(includedir)\IcePatch2\ClientUtil.h" \ @@ -385,7 +386,7 @@ Calc.obj: \ "$(includedir)\IceUtil\Handle.h" \ "$(includedir)\IceUtil\StringUtil.h" \ "..\..\src\IceUtil\FileUtil.h" \ - "$(includedir)\IcePatch2\Util.h" \ + "..\..\src\IcePatch2Lib\Util.h" \ "$(includedir)\Ice\Ice.h" \ "$(includedir)\IceUtil\PushDisableWarnings.h" \ "$(includedir)\Ice\Config.h" \ diff --git a/cpp/src/IcePatch2/Calc.cpp b/cpp/src/IcePatch2/Calc.cpp index 81939702e79..e04f4825731 100644 --- a/cpp/src/IcePatch2/Calc.cpp +++ b/cpp/src/IcePatch2/Calc.cpp @@ -10,26 +10,27 @@ #include <IceUtil/Options.h> #include <IceUtil/StringUtil.h> #include <IceUtil/FileUtil.h> -#include <IcePatch2/Util.h> +#include <IcePatch2Lib/Util.h> #include <iterator> using namespace std; using namespace Ice; using namespace IcePatch2; +using namespace IcePatch2Internal; -struct FileInfoPathLess: public binary_function<const FileInfo&, const FileInfo&, bool> +struct FileInfoPathLess: public binary_function<const LargeFileInfo&, const LargeFileInfo&, bool> { bool - operator()(const FileInfo& lhs, const FileInfo& rhs) + operator()(const LargeFileInfo& lhs, const LargeFileInfo& rhs) { return lhs.path < rhs.path; } }; -struct IFileInfoPathEqual: public binary_function<const FileInfo&, const FileInfo&, bool> +struct IFileInfoPathEqual: public binary_function<const LargeFileInfo&, const LargeFileInfo&, bool> { bool - operator()(const FileInfo& lhs, const FileInfo& rhs) + operator()(const LargeFileInfo& lhs, const LargeFileInfo& rhs) { if(lhs.path.size() != rhs.path.size()) { @@ -48,10 +49,10 @@ struct IFileInfoPathEqual: public binary_function<const FileInfo&, const FileInf } }; -struct IFileInfoPathLess: public binary_function<const FileInfo&, const FileInfo&, bool> +struct IFileInfoPathLess: public binary_function<const LargeFileInfo&, const LargeFileInfo&, bool> { bool - operator()(const FileInfo& lhs, const FileInfo& rhs) + operator()(const LargeFileInfo& lhs, const LargeFileInfo& rhs) { for(string::size_type i = 0; i < lhs.path.size() && i < rhs.path.size(); ++i) { @@ -233,7 +234,7 @@ main(int argc, char* argv[]) p->erase(0, absDataDirWithSlash.size()); } - FileInfoSeq infoSeq; + LargeFileInfoSeq infoSeq; if(fileSeq.empty()) { @@ -249,7 +250,7 @@ main(int argc, char* argv[]) for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p) { - FileInfoSeq partialInfoSeq; + LargeFileInfoSeq partialInfoSeq; CalcCB calcCB; if(!getFileInfoSeqSubDir(absDataDir, *p, compress, verbose ? &calcCB : 0, partialInfoSeq)) @@ -257,7 +258,7 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } - FileInfoSeq newInfoSeq; + LargeFileInfoSeq newInfoSeq; newInfoSeq.reserve(infoSeq.size()); set_difference(infoSeq.begin(), @@ -285,11 +286,11 @@ main(int argc, char* argv[]) if(caseInsensitive) { - FileInfoSeq newInfoSeq = infoSeq; + LargeFileInfoSeq newInfoSeq = infoSeq; sort(newInfoSeq.begin(), newInfoSeq.end(), IFileInfoPathLess()); string ex; - FileInfoSeq::iterator p = newInfoSeq.begin(); + LargeFileInfoSeq::iterator p = newInfoSeq.begin(); while((p = adjacent_find(p, newInfoSeq.end(), IFileInfoPathEqual())) != newInfoSeq.end()) { do diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp index 347d1e1c8f6..8ef166ab0d0 100644 --- a/cpp/src/IcePatch2/Client.cpp +++ b/cpp/src/IcePatch2/Client.cpp @@ -10,7 +10,7 @@ #include <IceUtil/Options.h> #include <IceUtil/StringUtil.h> #include <Ice/Application.h> -#include <IcePatch2/Util.h> +#include <IcePatch2Lib/Util.h> #include <IcePatch2/ClientUtil.h> #ifdef _WIN32 @@ -23,6 +23,7 @@ using namespace std; using namespace Ice; using namespace IcePatch2; +using namespace IcePatch2Internal; class TextPatcherFeedback : public PatcherFeedback { @@ -282,7 +283,7 @@ Client::run(int argc, char* argv[]) try { PatcherFeedbackPtr feedback = new TextPatcherFeedback; - PatcherPtr patcher = new Patcher(communicator(), feedback); + PatcherPtr patcher = PatcherFactory::create(communicator(), feedback); aborted = !patcher->prepare(); diff --git a/cpp/src/IcePatch2/FileServerI.cpp b/cpp/src/IcePatch2/FileServerI.cpp index a423f280871..822d621ccb2 100644 --- a/cpp/src/IcePatch2/FileServerI.cpp +++ b/cpp/src/IcePatch2/FileServerI.cpp @@ -9,6 +9,7 @@ #include <IceUtil/DisableWarnings.h> #include <IceUtil/FileUtil.h> +#include <IceUtil/StringUtil.h> #include <IceUtil/ScopedArray.h> #include <IcePatch2/FileServerI.h> @@ -21,8 +22,9 @@ using namespace std; using namespace Ice; using namespace IcePatch2; +using namespace IcePatch2Internal; -IcePatch2::FileServerI::FileServerI(const std::string& dataDir, const FileInfoSeq& infoSeq) : +IcePatch2::FileServerI::FileServerI(const std::string& dataDir, const LargeFileInfoSeq& infoSeq) : _dataDir(dataDir), _tree0(FileTree0()) { FileTree0& tree0 = const_cast<FileTree0&>(_tree0); @@ -30,7 +32,17 @@ IcePatch2::FileServerI::FileServerI(const std::string& dataDir, const FileInfoSe } FileInfoSeq -IcePatch2::FileServerI::getFileInfoSeq(Int node0, const Current&) const +IcePatch2::FileServerI::getFileInfoSeq(Int node0, const Current& c) const +{ + LargeFileInfoSeq largeFiles = getLargeFileInfoSeq(node0, c); + FileInfoSeq files; + files.resize(largeFiles.size()); + transform(largeFiles.begin(), largeFiles.end(), files.begin(), toFileInfo); + return files; +} + +LargeFileInfoSeq +IcePatch2::FileServerI::getLargeFileInfoSeq(Int node0, const Current&) const { if(node0 < 0 || node0 > 255) { @@ -63,12 +75,56 @@ void IcePatch2::FileServerI::getFileCompressed_async(const AMD_FileServer_getFileCompressedPtr& cb, const string& pa, Int pos, Int num, const Current&) const { - if(IceUtilInternal::isAbsolutePath(pa)) + try + { + vector<Byte> buffer; + getFileCompressedInternal(pa, pos, num, buffer, false); + if(buffer.empty()) + { + cb->ice_response(make_pair<const Byte*, const Byte*>(0, 0)); + } + else + { + cb->ice_response(make_pair<const Byte*, const Byte*>(&buffer[0], &buffer[0] + buffer.size())); + } + } + catch(const std::exception& ex) { - FileAccessException ex; - ex.reason = "illegal absolute path `" + pa + "'"; cb->ice_exception(ex); - return; + } +} + +void +IcePatch2::FileServerI::getLargeFileCompressed_async(const AMD_FileServer_getLargeFileCompressedPtr& cb, + const string& pa, Long pos, Int num, const Current&) const +{ + try + { + vector<Byte> buffer; + getFileCompressedInternal(pa, pos, num, buffer, true); + if(buffer.empty()) + { + cb->ice_response(make_pair<const Byte*, const Byte*>(0, 0)); + } + else + { + cb->ice_response(make_pair<const Byte*, const Byte*>(&buffer[0], &buffer[0] + buffer.size())); + } + + } + catch(const std::exception& ex) + { + cb->ice_exception(ex); + } +} + +void +IcePatch2::FileServerI::getFileCompressedInternal(const std::string& pa, Ice::Long pos, Ice::Int num, + vector<Byte>& buffer, bool largeFile) const +{ + if(IceUtilInternal::isAbsolutePath(pa)) + { + throw FileAccessException(string("illegal absolute path `") + pa + "'"); } string path = simplify(pa); @@ -77,31 +133,35 @@ IcePatch2::FileServerI::getFileCompressed_async(const AMD_FileServer_getFileComp path.find("/../") != string::npos || (path.size() >= 3 && (path.substr(0, 3) == "../" || path.substr(path.size() - 3, 3) == "/.."))) { - FileAccessException ex; - ex.reason = "illegal `..' component in path `" + path + "'"; - cb->ice_exception(ex); - return; + throw FileAccessException(string("illegal `..' component in path `") + path + "'"); } - -#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) - pair<const Byte*, const Byte*> ret(static_cast<const Byte*>(nullptr), static_cast<const Byte*>(nullptr)); -#else - pair<const Byte*, const Byte*> ret(0, 0); -#endif if(num <= 0 || pos < 0) { - cb->ice_response(ret); return; } - - int fd = IceUtilInternal::open(_dataDir + '/' + path + ".bz2", O_RDONLY|O_BINARY); + + string absolutePath = _dataDir + '/' + path + ".bz2"; + int fd = IceUtilInternal::open(absolutePath, O_RDONLY|O_BINARY); if(fd == -1) { - FileAccessException ex; - ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno); - cb->ice_exception(ex); - return; + throw FileAccessException(string("cannot open `") + path + "' for reading: " + strerror(errno)); + } + + if(!largeFile) + { + IceUtilInternal::structstat buf; + if(IceUtilInternal::stat(absolutePath, &buf) == -1) + { + throw FileAccessException(string("cannot stat `") + path + "':\n" + IceUtilInternal::lastErrorToString()); + } + + if(buf.st_size > 0x7FFFFFFF) + { + ostringstream os; + os << "cannot encode size `" << buf.st_size << "' for file `" << path << "' as Ice::Int" << endl; + throw FileAccessException(os.str()); + } } if( @@ -117,32 +177,22 @@ IcePatch2::FileServerI::getFileCompressed_async(const AMD_FileServer_getFileComp ostringstream posStr; posStr << pos; - FileAccessException ex; - ex.reason = "cannot seek position " + posStr.str() + " in file `" + path + "': " + strerror(errno); - cb->ice_exception(ex); - return; + throw FileAccessException("cannot seek position " + posStr.str() + " in file `" + path + "': " + + strerror(errno)); } - IceUtil::ScopedArray<Byte> bytes(new Byte[num]); + buffer.resize(num); #ifdef _WIN32 int r; - if((r = _read(fd, bytes.get(), static_cast<unsigned int>(num))) == -1) + if((r = _read(fd, &buffer[0], static_cast<unsigned int>(num))) == -1) #else ssize_t r; - if((r = read(fd, bytes.get(), static_cast<size_t>(num))) == -1) + if((r = read(fd, &buffer[0], static_cast<size_t>(num))) == -1) #endif { IceUtilInternal::close(fd); - - FileAccessException ex; - ex.reason = "cannot read `" + path + "': " + strerror(errno); - cb->ice_exception(ex); - return; + throw FileAccessException("cannot read `" + path + "': " + strerror(errno)); } IceUtilInternal::close(fd); - - ret.first = bytes.get(); - ret.second = ret.first + r; - cb->ice_response(ret); } diff --git a/cpp/src/IcePatch2/FileServerI.h b/cpp/src/IcePatch2/FileServerI.h index ca78be38d34..df4c7cf7a45 100644 --- a/cpp/src/IcePatch2/FileServerI.h +++ b/cpp/src/IcePatch2/FileServerI.h @@ -10,7 +10,7 @@ #ifndef ICE_PATCH2_FILE_SERVER_I_H #define ICE_PATCH2_FILE_SERVER_I_H -#include <IcePatch2/Util.h> +#include <IcePatch2Lib/Util.h> #include <IcePatch2/FileServer.h> namespace IcePatch2 @@ -20,21 +20,40 @@ class FileServerI : public FileServer { public: - FileServerI(const std::string&, const FileInfoSeq&); + FileServerI(const std::string&, const LargeFileInfoSeq&); FileInfoSeq getFileInfoSeq(Ice::Int, const Ice::Current&) const; + + LargeFileInfoSeq + getLargeFileInfoSeq(Ice::Int, const Ice::Current&) const; ByteSeqSeq getChecksumSeq(const Ice::Current&) const; Ice::ByteSeq getChecksum(const Ice::Current&) const; - void getFileCompressed_async(const AMD_FileServer_getFileCompressedPtr&, const std::string&, Ice::Int pos, - Ice::Int num, const Ice::Current&) const; + void getFileCompressed_async(const AMD_FileServer_getFileCompressedPtr&, + const std::string&, + Ice::Int, + Ice::Int, + const Ice::Current&) const; + + void getLargeFileCompressed_async(const AMD_FileServer_getLargeFileCompressedPtr&, + const std::string&, + Ice::Long, + Ice::Int, + const Ice::Current&) const; private: + + void + getFileCompressedInternal(const std::string&, + Ice::Long, + Ice::Int, + std::vector<Ice::Byte>&, + bool) const; const std::string _dataDir; - const FileTree0 _tree0; + const IcePatch2Internal::FileTree0 _tree0; }; } diff --git a/cpp/src/IcePatch2/Server.cpp b/cpp/src/IcePatch2/Server.cpp index e2ff5a61a6b..89f2f0454ef 100644 --- a/cpp/src/IcePatch2/Server.cpp +++ b/cpp/src/IcePatch2/Server.cpp @@ -10,13 +10,15 @@ #include <IceUtil/Options.h> #include <IceUtil/StringUtil.h> #include <IceUtil/FileUtil.h> +#include <IceUtil/DisableWarnings.h> #include <Ice/Service.h> #include <IcePatch2/FileServerI.h> -#include <IcePatch2/Util.h> +#include <IcePatch2Lib/Util.h> using namespace std; using namespace Ice; using namespace IcePatch2; +using namespace IcePatch2Internal; namespace IcePatch2 { @@ -96,7 +98,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status) return false; } - FileInfoSeq infoSeq; + LargeFileInfoSeq infoSeq; try { |