Skip to content

Commit

Permalink
Merged PR 3396: - TEST: Added tests for corrupted data handling durin…
Browse files Browse the repository at this point in the history
…g initialisation.
  • Loading branch information
ben51degrees committed Jan 4, 2021
2 parents cf2ad7c + 7ae557a commit 18d49a9
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
<ClCompile Include="..\..\src\common-cxx\textfile.c" />
<ClCompile Include="..\..\test\EngineDeviceDetectionTests.cpp" />
<ClCompile Include="..\..\test\ExampleDeviceDetectionTests.cpp" />
<ClCompile Include="..\..\test\hash\EngineHashInitTests.cpp" />
<ClCompile Include="..\..\test\hash\ExampleHashFindProfilesTests.cpp" />
<ClCompile Include="..\..\test\hash\ExampleHashMatchForDeviceIdTests.cpp" />
<ClCompile Include="..\..\test\hash\ExampleHashOfflineProcessingTests.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<ClCompile Include="..\..\test\hash\HashMemLeakReloadFromFileTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\test\hash\EngineHashInitTests.cpp">
<ClCompile Include="..\..\test\hash\HashCTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
2 changes: 1 addition & 1 deletion src/common-cxx
Submodule common-cxx updated 1 files
+10 −5 collection.c
1 change: 1 addition & 0 deletions src/hash/EngineHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ EngineHash::EngineHash(
(size_t)length,
exception);
if (status != SUCCESS) {
Free(dataCopy);
throw StatusCodeException(status);
}
EXCEPTION_THROW;
Expand Down
4 changes: 2 additions & 2 deletions src/hash/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ dataSet->t = CollectionCreateFromMemory( \
reader, \
dataSet->header.t); \
if (dataSet->t == NULL) { \
return INVALID_COLLECTION_CONFIG; \
return CORRUPT_DATA; \
}

#define COLLECTION_CREATE_FILE(t,f) \
Expand All @@ -111,7 +111,7 @@ dataSet->t = CollectionCreateFromFile( \
dataSet->header.t, \
f); \
if (dataSet->t == NULL) { \
return INVALID_COLLECTION_CONFIG; \
return CORRUPT_DATA; \
}

/**
Expand Down
312 changes: 312 additions & 0 deletions test/hash/EngineHashInitTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2019 51 Degrees Mobile Experts Limited, 5 Charlotte Close,
* Caversham, Reading, Berkshire, United Kingdom RG4 7BY.
*
* This Original Work is licensed under the European Union Public Licence (EUPL)
* v.1.2 and is subject to its terms as set out below.
*
* If a copy of the EUPL was not distributed with this file, You can obtain
* one at https://opensource.org/licenses/EUPL-1.2.
*
* The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
* amended by the European Commission) shall be deemed incompatible for
* the purposes of the Work and the provisions of the compatibility
* clause in Article 5 of the EUPL shall not apply.
*
* If using the Work as, or as part of, a network application, by
* including the attribution notice(s) required under Article 5 of the EUPL
* in the end user terms of the application under an appropriate heading,
* such notice(s) shall fulfill the requirements of that article.
* ********************************************************************* */

#include "../Constants.hpp"
#include "../EngineDeviceDetectionTests.hpp"
#include "../../src/hash/EngineHash.hpp"
#include <iostream>
#include <fstream>

using namespace FiftyoneDegrees::Common;
using namespace FiftyoneDegrees::DeviceDetection;
using namespace FiftyoneDegrees::DeviceDetection::Hash;

class EngineHashInitTests : public Base {
public:
const char* badVersionFileName = "badVersion.hash";
const char* badDataFileName = "badData.hash";
const char* smallDataFileName = "smallData.hash";
const int32_t badVersion[4] = { 1, 2, 3, 4 };
const int32_t goodVersion[4] = { 4, 1, 0, 0 };
virtual void SetUp() {
Base::SetUp();
writeTestFiles();
}
virtual void TearDown() {
removeTestFiles();
Base::TearDown();
}

/**
* Check that when initializing from a file which has the wrong version,
* the correct error is thrown, and memory is cleaned up.
*/
void wrongDataVersionFile(ConfigHash* config) {
RequiredPropertiesConfig properties;
try {
EngineHash* engine = new EngineHash(badVersionFileName, config, &properties);
FAIL() << L"No exception was thrown";
}
catch (exception & e) {
const char* expected = fiftyoneDegreesStatusGetMessage(
FIFTYONE_DEGREES_STATUS_INCORRECT_VERSION,
NULL);
ASSERT_STREQ(
e.what(),
expected);
fiftyoneDegreesFree((void*)expected);

}
}

/**
* Check that when initializing from a file which has the correct version
* but corrupted data, the correct error is thrown, and memory is cleaned up.
*/
void badDataFile(ConfigHash* config) {
RequiredPropertiesConfig properties;
try {
EngineHash* engine = new EngineHash(badDataFileName, config, &properties);
FAIL() << L"No exception was thrown";
}
catch (exception & e) {
const char* expected = fiftyoneDegreesStatusGetMessage(
FIFTYONE_DEGREES_STATUS_CORRUPT_DATA,
NULL);
ASSERT_STREQ(
e.what(),
expected);
fiftyoneDegreesFree((void*)expected);
}
}

/**
* Check that when initializing from a file which is too small and does not
* contain enough data to fill the header, the correct error is thrown,
* and memory is cleaned up.
*/
void smallDataFile(ConfigHash *config) {
RequiredPropertiesConfig properties;
try {
EngineHash* engine = new EngineHash(smallDataFileName, config, &properties);
FAIL() << L"No exception was thrown";
}
catch (exception & e) {
const char* expected = fiftyoneDegreesStatusGetMessage(
FIFTYONE_DEGREES_STATUS_CORRUPT_DATA,
NULL);
ASSERT_STREQ(
e.what(),
expected);
fiftyoneDegreesFree((void*)expected);

}
}

private:
void writeTestFiles() {
void* garbledHeader =
malloc(sizeof(fiftyoneDegreesDataSetHashHeader));
for (int i = 0; i < sizeof(fiftyoneDegreesDataSetHashHeader); i++) {
((byte*)garbledHeader)[i] = 12;
}

ofstream badVersionFile(badVersionFileName, ios::out | ios::binary);
if (badVersionFile.is_open()) {
badVersionFile.write((char*)badVersion, sizeof(int32_t) * 4);
badVersionFile.write((char*)garbledHeader, sizeof(fiftyoneDegreesDataSetHashHeader));
badVersionFile.close();
}
else {
cout << "Unable to open file";
}

ofstream badDataFile(badDataFileName, ios::out | ios::binary);
if (badDataFile.is_open()) {
badDataFile.write((char*)goodVersion, sizeof(int32_t) * 4);
badDataFile.write((char*)garbledHeader, sizeof(fiftyoneDegreesDataSetHashHeader));
badDataFile.close();
}
else {
cout << "Unable to open file";
}

ofstream smallDataFile(smallDataFileName, ios::out | ios::binary);
if (smallDataFile.is_open()) {
smallDataFile.write((char*)garbledHeader, sizeof(byte));
smallDataFile.close();
}
else {
cout << "Unable to open file";
}
free(garbledHeader);
}
void removeTestFiles() {
if (remove(badVersionFileName) != 0) {
cout << "Error deleting file";
}
if (remove(badDataFileName) != 0) {
cout << "Error deleting file";
}
if (remove(smallDataFileName) != 0) {
cout << "Error deleting file";
}
}
};

#define TEST_WRONG_VERSION_FILE(c) \
TEST_F(EngineHashInitTests,WrongDataVersion_File_##c) { \
ConfigHash config; \
config.set##c(); \
wrongDataVersionFile(&config); \
}

TEST_WRONG_VERSION_FILE(HighPerformance);
TEST_WRONG_VERSION_FILE(LowMemory);
TEST_WRONG_VERSION_FILE(Balanced);
TEST_WRONG_VERSION_FILE(BalancedTemp);

#define TEST_BAD_DATA_FILE(c) \
TEST_F(EngineHashInitTests,BadData_File_##c) { \
ConfigHash config; \
config.set##c(); \
badDataFile(&config); \
}

TEST_BAD_DATA_FILE(HighPerformance);
TEST_BAD_DATA_FILE(LowMemory);
TEST_BAD_DATA_FILE(Balanced);
TEST_BAD_DATA_FILE(BalancedTemp);

#define TEST_SMALL_DATA_FILE(c) \
TEST_F(EngineHashInitTests,SmallData_File_##c) { \
ConfigHash config; \
config.set##c(); \
smallDataFile(&config); \
}

TEST_SMALL_DATA_FILE(HighPerformance);
TEST_SMALL_DATA_FILE(LowMemory);
TEST_SMALL_DATA_FILE(Balanced);
TEST_SMALL_DATA_FILE(BalancedTemp);

/**
* Check that when initializing from memory which has the wrong version,
* the correct error is thrown, and memory is cleaned up.
*/
TEST_F(EngineHashInitTests, WrongDataVersion_Memory) {
ConfigHash config;
RequiredPropertiesConfig properties;
void* mem = fiftyoneDegreesMalloc(sizeof(fiftyoneDegreesDataSetHashHeader));
ifstream file(badVersionFileName, ios::out | ios::binary);
if (file.is_open()) {
file.read((char*)mem, sizeof(fiftyoneDegreesDataSetHashHeader));
file.close();
}
else {
cout << "Unable to open file";
}

try {
EngineHash* engine = new EngineHash(
mem,
(long)sizeof(fiftyoneDegreesDataSetHashHeader),
&config,
&properties);
FAIL() << L"No exception was thrown";
}
catch (exception & e) {
const char* expected = fiftyoneDegreesStatusGetMessage(
FIFTYONE_DEGREES_STATUS_INCORRECT_VERSION,
NULL);
ASSERT_STREQ(
e.what(),
expected);
fiftyoneDegreesFree((void*)expected);
}
fiftyoneDegreesFree(mem);
}

/**
* Check that when initializing from memory which has the correct version
* but corrupted data, the correct error is thrown, and memory is cleaned up.
*/
TEST_F(EngineHashInitTests, BadData_Memory) {
ConfigHash config;
RequiredPropertiesConfig properties;
void* mem = fiftyoneDegreesMalloc(sizeof(fiftyoneDegreesDataSetHashHeader));
ifstream file(badDataFileName, ios::out | ios::binary);
if (file.is_open()) {
file.read((char*)mem, sizeof(fiftyoneDegreesDataSetHashHeader));
file.close();
}
else {
cout << "Unable to open file";
}

try {
EngineHash* engine = new EngineHash(
mem,
(long)sizeof(fiftyoneDegreesDataSetHashHeader),
&config,
&properties);
FAIL() << L"No exception was thrown";
}
catch (exception & e) {
const char* expected = fiftyoneDegreesStatusGetMessage(
FIFTYONE_DEGREES_STATUS_CORRUPT_DATA,
NULL);
ASSERT_STREQ(
e.what(),
expected);
fiftyoneDegreesFree((void*)expected);
}
fiftyoneDegreesFree(mem);
}

/**
* Check that when initializing from memory which is too small and does not
* contain enough data to fill the header, the correct error is thrown,
* and memory is cleaned up.
*/
TEST_F(EngineHashInitTests, SmallData_Memory) {
ConfigHash config;
RequiredPropertiesConfig properties;
void* mem = fiftyoneDegreesMalloc(sizeof(fiftyoneDegreesDataSetHashHeader));
ifstream file(smallDataFileName, ios::out | ios::binary);
if (file.is_open()) {
file.read((char*)mem, sizeof(fiftyoneDegreesDataSetHashHeader));
file.close();
}
else {
cout << "Unable to open file";
}

try {
EngineHash* engine = new EngineHash(
mem,
(long)sizeof(byte),
&config,
&properties);
FAIL() << L"No exception was thrown";
}
catch (exception & e) {
const char* expected = fiftyoneDegreesStatusGetMessage(
FIFTYONE_DEGREES_STATUS_CORRUPT_DATA,
NULL);
ASSERT_STREQ(
e.what(),
expected);
fiftyoneDegreesFree((void*)expected);
}
fiftyoneDegreesFree(mem);
}

0 comments on commit 18d49a9

Please sign in to comment.