improved the security of size determination for file lists (suppresses a small bug that caused a chain reaction ending in crash of client peers when downloading file lists)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2945 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-05-18 21:15:22 +00:00
parent 6fbf0d4bbe
commit 0cc8fcdbac

View File

@ -33,6 +33,8 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <fstream> #include <fstream>
#include <sys/stat.h>
#include <errno.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <util/rsthreads.h> #include <util/rsthreads.h>
@ -920,21 +922,11 @@ int FileIndex::saveIndex(std::string filename, std::string &fileHash, uint64_t &
{ {
unsigned char sha_buf[SHA_DIGEST_LENGTH]; unsigned char sha_buf[SHA_DIGEST_LENGTH];
std::string filenametmp = filename + ".tmp" ; std::string filenametmp = filename + ".tmp" ;
std::ofstream file (filenametmp.c_str(), std::ofstream::binary);
std::ostringstream oss; std::ostringstream oss;
size = 0 ; size = 0 ;
fileHash = "" ; fileHash = "" ;
if (!file)
{
#ifdef FI_DEBUG
std::cerr << "FileIndex::saveIndex error opening file: " << filename;
std::cerr << std::endl;
#endif
return 0;
}
/* print version and header */ /* print version and header */
oss << "# FileIndex version 0.1" << std::endl; oss << "# FileIndex version 0.1" << std::endl;
oss << "# Dir: d name, path, parent, size, modtime, pop, updtime;" << std::endl; oss << "# Dir: d name, path, parent, size, modtime, pop, updtime;" << std::endl;
@ -985,17 +977,33 @@ int FileIndex::saveIndex(std::string filename, std::string &fileHash, uint64_t &
fileHash = tmpout.str(); fileHash = tmpout.str();
/* finally, save to file */ /* finally, save to file */
file << oss.str();
/* get the size out */ FILE *file = fopen(filenametmp.c_str(), "wb");
size=file.tellp(); if (file == NULL)
file.close(); {
std::cerr << "FileIndex::saveIndex error opening file for writting: " << filename << ". Giving up." << std::endl;
return 0;
}
fprintf(file,"%s",oss.str().c_str()) ;
fclose(file);
// Use a temp file name so that the file is never half saved. // Use a temp file name so that the file is never half saved.
// //
if(!RsDirUtil::renameFile(filenametmp,filename)) if(!RsDirUtil::renameFile(filenametmp,filename))
return false ; return false ;
/* get the size out */
struct stat64 buf;
if(-1 == stat64(filename.c_str(), &buf))
{
std::cerr << "Can't determine size of file " << filename << ": errno = " << errno << std::endl ;
return false ;
}
size=buf.st_size;
return true; return true;
} }