Factor Compute(File|String)MD5 into cmCryptoHash helper
Define an abstract API around the backend hash algorithm. Expose ifstream errors to HashFile callers. Always try opening the file. Succeed only if the end of file is reached without error.
This commit is contained in:
parent
a9e686d68b
commit
ed7cef5634
|
@ -129,6 +129,8 @@ SET(SRCS
|
||||||
cmComputeLinkInformation.h
|
cmComputeLinkInformation.h
|
||||||
cmComputeTargetDepends.h
|
cmComputeTargetDepends.h
|
||||||
cmComputeTargetDepends.cxx
|
cmComputeTargetDepends.cxx
|
||||||
|
cmCryptoHash.cxx
|
||||||
|
cmCryptoHash.h
|
||||||
cmCustomCommand.cxx
|
cmCustomCommand.cxx
|
||||||
cmCustomCommand.h
|
cmCustomCommand.h
|
||||||
cmCustomCommandGenerator.cxx
|
cmCustomCommandGenerator.cxx
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*============================================================================
|
||||||
|
CMake - Cross Platform Makefile Generator
|
||||||
|
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||||
|
|
||||||
|
Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
see accompanying file Copyright.txt for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the License for more information.
|
||||||
|
============================================================================*/
|
||||||
|
#include "cmCryptoHash.h"
|
||||||
|
|
||||||
|
#include <cmsys/MD5.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmCryptoHash::HashString(const char* input)
|
||||||
|
{
|
||||||
|
this->Initialize();
|
||||||
|
this->Append(reinterpret_cast<unsigned char const*>(input),
|
||||||
|
static_cast<int>(strlen(input)));
|
||||||
|
return this->Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmCryptoHash::HashFile(const char* file)
|
||||||
|
{
|
||||||
|
std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
|
||||||
|
if(!fin)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Initialize();
|
||||||
|
|
||||||
|
// Should be efficient enough on most system:
|
||||||
|
const int bufferSize = 4096;
|
||||||
|
char buffer[bufferSize];
|
||||||
|
unsigned char const* buffer_uc =
|
||||||
|
reinterpret_cast<unsigned char const*>(buffer);
|
||||||
|
// This copy loop is very sensitive on certain platforms with
|
||||||
|
// slightly broken stream libraries (like HPUX). Normally, it is
|
||||||
|
// incorrect to not check the error condition on the fin.read()
|
||||||
|
// before using the data, but the fin.gcount() will be zero if an
|
||||||
|
// error occurred. Therefore, the loop should be safe everywhere.
|
||||||
|
while(fin)
|
||||||
|
{
|
||||||
|
fin.read(buffer, bufferSize);
|
||||||
|
if(int gcount = static_cast<int>(fin.gcount()))
|
||||||
|
{
|
||||||
|
this->Append(buffer_uc, gcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fin.eof())
|
||||||
|
{
|
||||||
|
return this->Finalize();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmCryptoHashMD5::~cmCryptoHashMD5()
|
||||||
|
{
|
||||||
|
cmsysMD5_Delete(this->MD5);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmCryptoHashMD5::Initialize()
|
||||||
|
{
|
||||||
|
cmsysMD5_Initialize(this->MD5);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
|
||||||
|
{
|
||||||
|
cmsysMD5_Append(this->MD5, buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmCryptoHashMD5::Finalize()
|
||||||
|
{
|
||||||
|
char md5out[32];
|
||||||
|
cmsysMD5_FinalizeHex(this->MD5, md5out);
|
||||||
|
return std::string(md5out, 32);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*============================================================================
|
||||||
|
CMake - Cross Platform Makefile Generator
|
||||||
|
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||||
|
|
||||||
|
Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
see accompanying file Copyright.txt for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the License for more information.
|
||||||
|
============================================================================*/
|
||||||
|
#ifndef cmCryptoHash_h
|
||||||
|
#define cmCryptoHash_h
|
||||||
|
|
||||||
|
#include "cmStandardIncludes.h"
|
||||||
|
|
||||||
|
class cmCryptoHash
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string HashString(const char* input);
|
||||||
|
std::string HashFile(const char* file);
|
||||||
|
protected:
|
||||||
|
virtual void Initialize()=0;
|
||||||
|
virtual void Append(unsigned char const*, int)=0;
|
||||||
|
virtual std::string Finalize()=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class cmCryptoHashMD5: public cmCryptoHash
|
||||||
|
{
|
||||||
|
struct cmsysMD5_s* MD5;
|
||||||
|
public:
|
||||||
|
cmCryptoHashMD5();
|
||||||
|
~cmCryptoHashMD5();
|
||||||
|
protected:
|
||||||
|
virtual void Initialize();
|
||||||
|
virtual void Append(unsigned char const* buf, int sz);
|
||||||
|
virtual std::string Finalize();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -54,7 +54,7 @@
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||||
# include <memory> // auto_ptr
|
# include <memory> // auto_ptr
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <cmsys/MD5.h>
|
# include "cmCryptoHash.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CMAKE_USE_ELF_PARSER)
|
#if defined(CMAKE_USE_ELF_PARSER)
|
||||||
|
@ -1197,48 +1197,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
||||||
bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
|
bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
|
||||||
{
|
{
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||||
if(!cmSystemTools::FileExists(source))
|
cmCryptoHashMD5 md5;
|
||||||
{
|
std::string str = md5.HashFile(source);
|
||||||
return false;
|
strncpy(md5out, str.c_str(), 32);
|
||||||
}
|
return !str.empty();
|
||||||
|
|
||||||
// Open files
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
||||||
cmsys_ios::ifstream fin(source, cmsys_ios::ios::binary | cmsys_ios::ios::in);
|
|
||||||
#else
|
|
||||||
cmsys_ios::ifstream fin(source);
|
|
||||||
#endif
|
|
||||||
if(!fin)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsysMD5* md5 = cmsysMD5_New();
|
|
||||||
cmsysMD5_Initialize(md5);
|
|
||||||
|
|
||||||
// Should be efficient enough on most system:
|
|
||||||
const int bufferSize = 4096;
|
|
||||||
char buffer[bufferSize];
|
|
||||||
unsigned char const* buffer_uc =
|
|
||||||
reinterpret_cast<unsigned char const*>(buffer);
|
|
||||||
// This copy loop is very sensitive on certain platforms with
|
|
||||||
// slightly broken stream libraries (like HPUX). Normally, it is
|
|
||||||
// incorrect to not check the error condition on the fin.read()
|
|
||||||
// before using the data, but the fin.gcount() will be zero if an
|
|
||||||
// error occurred. Therefore, the loop should be safe everywhere.
|
|
||||||
while(fin)
|
|
||||||
{
|
|
||||||
fin.read(buffer, bufferSize);
|
|
||||||
if(int gcount = static_cast<int>(fin.gcount()))
|
|
||||||
{
|
|
||||||
cmsysMD5_Append(md5, buffer_uc, gcount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmsysMD5_FinalizeHex(md5, md5out);
|
|
||||||
cmsysMD5_Delete(md5);
|
|
||||||
|
|
||||||
fin.close();
|
|
||||||
return true;
|
|
||||||
#else
|
#else
|
||||||
(void)source;
|
(void)source;
|
||||||
(void)md5out;
|
(void)md5out;
|
||||||
|
@ -1250,13 +1212,8 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
|
||||||
std::string cmSystemTools::ComputeStringMD5(const char* input)
|
std::string cmSystemTools::ComputeStringMD5(const char* input)
|
||||||
{
|
{
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||||
char md5out[32];
|
cmCryptoHashMD5 md5;
|
||||||
cmsysMD5* md5 = cmsysMD5_New();
|
return md5.HashString(input);
|
||||||
cmsysMD5_Initialize(md5);
|
|
||||||
cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1);
|
|
||||||
cmsysMD5_FinalizeHex(md5, md5out);
|
|
||||||
cmsysMD5_Delete(md5);
|
|
||||||
return std::string(md5out, 32);
|
|
||||||
#else
|
#else
|
||||||
(void)input;
|
(void)input;
|
||||||
cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error");
|
cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error");
|
||||||
|
|
Loading…
Reference in New Issue