summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmFileCommand.cxx89
-rw-r--r--Source/cmFileCommand.h8
-rw-r--r--Tests/CMakeTests/FileDownloadTest.cmake.in53
3 files changed, 111 insertions, 39 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 5103d39..b0c1070 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -10,6 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmFileCommand.h"
+#include "cmCryptoHash.h"
#include "cmake.h"
#include "cmHexFileConverter.h"
#include "cmInstallType.h"
@@ -2666,7 +2667,9 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
long inactivity_timeout = 0;
std::string verboseLog;
std::string statusVar;
- std::string expectedMD5sum;
+ std::string expectedHash;
+ std::string hashMatchMSG;
+ cmsys::auto_ptr<cmCryptoHash> hash;
bool showProgress = false;
while(i != args.end())
@@ -2725,48 +2728,67 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
return false;
}
- expectedMD5sum = cmSystemTools::LowerCase(*i);
+ hash = cmsys::auto_ptr<cmCryptoHash>(cmCryptoHash::New("MD5"));
+ hashMatchMSG = "MD5 sum";
+ expectedHash = cmSystemTools::LowerCase(*i);
}
else if(*i == "SHOW_PROGRESS")
{
showProgress = true;
}
+ else if(*i == "EXPECTED_HASH")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ hash = cmsys::auto_ptr<cmCryptoHash>(cmCryptoHash::New(i->c_str()));
+ if(!hash.get())
+ {
+ std::string err = "DOWNLOAD bad SHA type: ";
+ err += *i;
+ this->SetError(err.c_str());
+ return false;
+ }
+ hashMatchMSG = *i;
+ hashMatchMSG += " hash";
+
+ ++i;
+ }
+ if(i != args.end())
+ {
+ expectedHash = cmSystemTools::LowerCase(*i);
+ }
+ else
+ {
+ this->SetError("DOWNLOAD missing time for EXPECTED_HASH.");
+ return false;
+ }
+ }
++i;
}
-
- // If file exists already, and caller specified an expected md5 sum,
- // and the existing file already has the expected md5 sum, then simply
+ // If file exists already, and caller specified an expected md5 or sha,
+ // and the existing file already has the expected hash, then simply
// return.
//
- if(cmSystemTools::FileExists(file.c_str()) &&
- !expectedMD5sum.empty())
+ if(cmSystemTools::FileExists(file.c_str()) && hash.get())
{
- char computedMD5[32];
-
- if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5))
- {
- this->SetError("DOWNLOAD cannot compute MD5 sum on pre-existing file");
- return false;
- }
-
- std::string actualMD5sum = cmSystemTools::LowerCase(
- std::string(computedMD5, 32));
-
- if (expectedMD5sum == actualMD5sum)
+ std::string msg;
+ std::string actualHash = hash->HashFile(file.c_str());
+ if(actualHash == expectedHash)
{
+ msg = "returning early; file already exists with expected ";
+ msg += hashMatchMSG;
+ msg += "\"";
if(statusVar.size())
{
cmOStringStream result;
- result << (int)0 << ";\""
- "returning early: file already exists with expected MD5 sum\"";
+ result << (int)0 << ";\"" << msg;
this->Makefile->AddDefinition(statusVar.c_str(),
result.str().c_str());
}
-
return true;
}
}
-
// Make sure parent directory exists so we can write to the file
// as we receive downloaded bits from curl...
//
@@ -2798,7 +2820,6 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
}
cURLEasyGuard g_curl(curl);
-
::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
check_curl_result(res, "DOWNLOAD cannot set url: ");
@@ -2888,26 +2909,22 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
// Verify MD5 sum if requested:
//
- if (!expectedMD5sum.empty())
+ if (hash.get())
{
- char computedMD5[32];
-
- if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5))
+ std::string actualHash = hash->HashFile(file.c_str());
+ if (actualHash.size() == 0)
{
- this->SetError("DOWNLOAD cannot compute MD5 sum on downloaded file");
+ this->SetError("DOWNLOAD cannot compute hash on downloaded file");
return false;
}
- std::string actualMD5sum = cmSystemTools::LowerCase(
- std::string(computedMD5, 32));
-
- if (expectedMD5sum != actualMD5sum)
+ if (expectedHash != actualHash)
{
cmOStringStream oss;
- oss << "DOWNLOAD MD5 mismatch" << std::endl
+ oss << "DOWNLOAD HASH mismatch" << std::endl
<< " for file: [" << file << "]" << std::endl
- << " expected MD5 sum: [" << expectedMD5sum << "]" << std::endl
- << " actual MD5 sum: [" << actualMD5sum << "]" << std::endl
+ << " expected hash: [" << expectedHash << "]" << std::endl
+ << " actual hash: [" << actualHash << "]" << std::endl
;
this->SetError(oss.str().c_str());
return false;
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index ced26c4..ca2bdfd 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -83,6 +83,7 @@ public:
" file(TO_NATIVE_PATH path result)\n"
" file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n"
" [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n"
+ " [EXPECTED_HASH MD5|SHA1|SHA224|SHA256|SHA384|SHA512 hash]\n"
" [EXPECTED_MD5 sum])\n"
" file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
" [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
@@ -168,11 +169,12 @@ public:
"timeout after time seconds, time should be specified as an integer. "
"The INACTIVITY_TIMEOUT specifies an integer number of seconds of "
"inactivity after which the operation should terminate. "
- "If EXPECTED_MD5 sum is specified, the operation will verify that the "
- "downloaded file's actual md5 sum matches the expected value. If it "
+ "If EXPECTED_HASH is specified, the operation will verify that the "
+ "downloaded file's actual hash matches the expected value. If it "
"does not match, the operation fails with an error. "
+ "(EXPECTED_MD5 is short-hand for EXPECTED_HASH MD5.) "
"If SHOW_PROGRESS is specified, progress information will be printed "
- "as status messages until the operation is complete."
+ "as status messages until the operation is complete. "
"\n"
"UPLOAD will upload the given file to the given URL. "
"If LOG var is specified a log of the upload will be put in var. "
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 9dc2ebb..3f0ab50 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -38,6 +38,59 @@ file(DOWNLOAD
${dir}/file3.png
TIMEOUT 2
STATUS status
+ EXPECTED_HASH SHA1 50c614fc28b39c1281d0517bb6d5858b4359c9b7
+ )
+
+message(STATUS "FileDownload:5")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_HASH SHA224 73cd5f442b04e8320e4f907f8e1b21d4befff98b5bd77bc32526ea68
+ )
+
+message(STATUS "FileDownload:6")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_HASH SHA256 2e067f6c09cbc7cd619c8fbcc44eb64cd6b45a95e4cddb3a585eee1f731c4da9
+ )
+
+message(STATUS "FileDownload:7")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_HASH SHA384 398bf41902a7251c30e522b307e3e41e3fb617c765b3feaa99b2f7d063894708ad399267ccc25d877437a10e5e890d35
+ )
+
+message(STATUS "FileDownload:8")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_HASH SHA512 c51854d21052713968b849c2b4263cf54be03bc3a7e9847a6c71c6c8d1d13cd805fe1b9fa95f9ba1d0a5631513974f6fae21e34ab5b171d94bad48df5f073e48
+ )
+message(STATUS "FileDownload:9")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_HASH MD5 d16778650db435bda3a8c3435c3ff5d1
+ )
+
+message(STATUS "FileDownload:10")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
EXPECTED_MD5 d16778650db435bda3a8c3435c3ff5d1
)
message(STATUS "${status}")