From df2ebd7874bf78e5226c03e8045fcf9a19daf4ad Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 21 Jan 2017 16:03:04 +0300 Subject: Add physfs + zlib unit tests. Also improve error messages in physfsrwops. --- data/test/CMakeLists.txt | 2 + data/test/Makefile.am | 2 + data/test/hide.png | Bin 0 -> 368 bytes data/test/test.zip | Bin 0 -> 2798 bytes src/integrity_unittest.cc | 322 +++++++++++++++++++++++++++++++++++++++++++++- src/utils/physfsrwops.cpp | 52 +++++--- 6 files changed, 360 insertions(+), 18 deletions(-) create mode 100644 data/test/hide.png create mode 100644 data/test/test.zip diff --git a/data/test/CMakeLists.txt b/data/test/CMakeLists.txt index 4a3dbfb63..504a3b85a 100644 --- a/data/test/CMakeLists.txt +++ b/data/test/CMakeLists.txt @@ -5,12 +5,14 @@ SET(FILES arrow_up_S.png dye.png equipmentwindow.xml + hide.png items.xml palette.gpl paths.xml quests.xml serverlistplus.xml simplefile.txt + test.zip testintmap.xml units.xml ) diff --git a/data/test/Makefile.am b/data/test/Makefile.am index 8a3f82be9..ba9cde3e8 100644 --- a/data/test/Makefile.am +++ b/data/test/Makefile.am @@ -7,12 +7,14 @@ test_DATA = \ arrow_up_S.png \ dye.png \ equipmentwindow.xml \ + hide.png \ items.xml \ palette.gpl \ paths.xml \ quests.xml \ serverlistplus.xml \ simplefile.txt \ + test.zip \ testintmap.xml \ units.xml diff --git a/data/test/hide.png b/data/test/hide.png new file mode 100644 index 000000000..d2417669a Binary files /dev/null and b/data/test/hide.png differ diff --git a/data/test/test.zip b/data/test/test.zip new file mode 100644 index 000000000..401d83780 Binary files /dev/null and b/data/test/test.zip differ diff --git a/src/integrity_unittest.cc b/src/integrity_unittest.cc index 54137e6b2..572cc29e6 100644 --- a/src/integrity_unittest.cc +++ b/src/integrity_unittest.cc @@ -27,19 +27,31 @@ #include "input/inputactionmap.h" +#include "resources/image/image.h" + +#include "resources/loaders/imageloader.h" + #include "resources/sdlimagehelper.h" #include "resources/resourcemanager/resourcemanager.h" #include "utils/env.h" +#include "utils/physfsrwops.h" #include "utils/physfstools.h" -#ifndef USE_SDL2 -#include -#endif // USE_SDL2 +#include +#include #include "debug.h" +#ifdef USE_SDL2 +#define PHYSFSINT int64_t +#define PHYSFSSIZE size_t +#else // USE_SDL2 +#define PHYSFSINT int32_t +#define PHYSFSSIZE int +#endif // USE_SDL2 + namespace { class InputActionSortFunctorTest final @@ -61,6 +73,28 @@ namespace InputActionSortFunctorTest inputActionDataSorterTest; } // namespace +static bool compareBuffers(const unsigned char *const buf2) +{ + bool isCorrect(true); + int sz = 0; + unsigned char *buf1 = static_cast( + PhysFs::loadFile("hide.png", sz)); + REQUIRE(buf1 != nullptr); + REQUIRE(sz == 368); + for (int f = 0; f < sz; f ++) + { + if (buf1[f] != buf2[f]) + { + isCorrect = false; + logger->log("Wrong buffer chars: 0x%x vs 0x%x", + buf1[f], + buf2[f]); + } + } + free(buf1); + return isCorrect; +} + TEST_CASE("integrity tests", "integrity") { setEnv("SDL_VIDEODRIVER", "dummy"); @@ -85,6 +119,8 @@ TEST_CASE("integrity tests", "integrity") #endif // USE_SDL2 ActorSprite::load(); + const char *const name1 = "dir/hide.png"; + const int size1 = 368; SECTION("integrity test 1") { @@ -160,6 +196,286 @@ TEST_CASE("integrity tests", "integrity") mKeyTimeMap, InputType::KEYBOARD); } + SECTION("integrity Loader::getImage test 1") + { + Image *const image = Loader::getImage( + "graphics/images/login_wallpaper.png"); + REQUIRE(image != nullptr); + REQUIRE(image->getSDLSurface() != nullptr); + image->decRef(); + } + + SECTION("integrity Loader::getImage test 2") + { + Image *const image = Loader::getImage( + "hide.png"); + REQUIRE(image != nullptr); + REQUIRE(image->getSDLSurface() != nullptr); + image->decRef(); + } + + SECTION("integrity Loader::getImage test 3") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + Image *const image = Loader::getImage( + "dir/brimmedhat.png"); + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(image != nullptr); + REQUIRE(image->getSDLSurface() != nullptr); + image->decRef(); + } + + SECTION("integrity Loader::getImage test 4") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + + SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + if (!rw) + logger->log("Physfs error: %s", PhysFs::getLastError()); + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(rw != nullptr); + unsigned char buf[size1]; + const size_t sz = SDL_RWread(rw, buf, 1, size1); + if (sz != size1) + SDL_RWclose(rw); + REQUIRE(sz == size1); + SDL_RWclose(rw); + REQUIRE(compareBuffers(buf) == true); + } + + SECTION("integrity Loader::getImage test 5") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + + PHYSFS_file *handle = PHYSFS_openRead(name1); + REQUIRE(handle != nullptr); +// int64_t seek = rw->seek(rw, 0, RW_SEEK_END); + const PHYSFS_sint64 len = PHYSFS_fileLength(handle); + REQUIRE(len == size1); + PHYSFSINT pos = static_cast(len); + REQUIRE(static_cast(pos) == len); + REQUIRE(pos >= 0); + REQUIRE(PHYSFS_seek(handle, static_cast(pos)) != 0); + int64_t seek = pos; + + REQUIRE(seek != -1); + +// const int64_t pos1 = rw->seek(rw, 0, RW_SEEK_CUR); + const PHYSFS_sint64 current = PHYSFS_tell(handle); + REQUIRE(current != -1); + REQUIRE(current == size1); + pos = CAST_S32(current); + REQUIRE(static_cast(pos) == current); + REQUIRE(PHYSFS_seek(handle, static_cast(pos)) != 0); + const int64_t pos1 = pos; + + REQUIRE(pos1 == size1); + +// seek = rw->seek(rw, 0, RW_SEEK_SET); + REQUIRE(PHYSFS_seek(handle, static_cast(0)) != 0); + seek = 0; + + REQUIRE(seek != -1); + + unsigned char buf[size1]; + +// const size_t sz = rw->read(rw, buf, 1, pos1); + const PHYSFS_sint64 rc = PHYSFS_read(handle, buf, + CAST_U32(1), + CAST_U32(size1)); + if (rc != static_cast(size1)) + { + logger->log("PHYSFS_read %d bytes", rc); + if (!PHYSFS_eof(handle)) + { + logger->log("PhysicsFS read error: %s", + PHYSFS_getLastError()); + } +// rw->close(rw); + REQUIRE(PHYSFS_close(handle) != 0); + } + const size_t sz = rc; + REQUIRE(sz == size1); + +// rw->close(rw); + REQUIRE(PHYSFS_close(handle) != 0); + + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + } + + SECTION("integrity Loader::getImage test 6") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + + PHYSFS_file *handle = PHYSFS_openRead(name1); + REQUIRE(handle != nullptr); +// int64_t seek = rw->seek(rw, 0, RW_SEEK_END); + const PHYSFS_sint64 len = PHYSFS_fileLength(handle); + PHYSFSINT pos = static_cast(len); + REQUIRE(static_cast(pos) == len); + REQUIRE(pos >= 0); + REQUIRE(PHYSFS_seek(handle, static_cast(pos)) != 0); + int64_t seek = pos; + + if (seek == -1) + { +// rw->close(rw); + REQUIRE(PHYSFS_close(handle) != 0); + } + REQUIRE(seek != -1); + +// const int64_t pos1 = rw->seek(rw, 0, RW_SEEK_CUR); + const PHYSFS_sint64 current = PHYSFS_tell(handle); + REQUIRE(current != -1); + pos = CAST_S32(current); + REQUIRE(static_cast(pos) == current); + REQUIRE(PHYSFS_seek(handle, static_cast(pos)) != 0); + const int64_t pos1 = pos; + + if (pos1 != size1) + { +// rw->close(rw); + REQUIRE(PHYSFS_close(handle) != 0); + } + REQUIRE(pos1 == size1); + +// seek = rw->seek(rw, 0, RW_SEEK_SET); + REQUIRE(PHYSFS_seek(handle, static_cast(0)) != 0); + seek = 0; + + if (seek == -1) + { +// rw->close(rw); + REQUIRE(PHYSFS_close(handle) != 0); + } + REQUIRE(seek != -1); + + unsigned char buf[size1]; + +// const size_t sz = rw->read(rw, buf, 1, pos1); + const PHYSFS_sint64 rc = PHYSFS_read(handle, buf, + CAST_U32(1), + CAST_U32(pos1)); + if (rc != static_cast(pos1)) + { + if (!PHYSFS_eof(handle)) + { + logger->log("PhysicsFS read error1: %s", + PHYSFS_getLastError()); + } + } + const size_t sz = rc; + + if (sz != size1) + { +// rw->close(rw); + logger->log("PhysicsFS read error2: %s", + PHYSFS_getLastError()); + REQUIRE(PHYSFS_close(handle) != 0); + } + REQUIRE(sz == size1); + +// rw->close(rw); + REQUIRE(PHYSFS_close(handle) != 0); + + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(compareBuffers(buf) == true); + } + + SECTION("integrity Loader::getImage test 7") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + + SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + if (!rw) + logger->log("Physfs error: %s", PhysFs::getLastError()); + REQUIRE(rw != nullptr); + int64_t seek = SDL_RWseek(rw, 0, RW_SEEK_END); + if (seek == -1) + SDL_RWclose(rw); + REQUIRE(seek != -1); + const int64_t pos = SDL_RWtell(rw); + if (pos != size1) + SDL_RWclose(rw); + REQUIRE(pos == size1); + + seek = SDL_RWseek(rw, 0, RW_SEEK_SET); + if (seek == -1) + SDL_RWclose(rw); + REQUIRE(seek != -1); + + unsigned char buf[size1]; + const size_t sz = SDL_RWread(rw, buf, 1, pos); + if (sz != size1) + SDL_RWclose(rw); + REQUIRE(sz == size1); + + SDL_RWclose(rw); + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(compareBuffers(buf) == true); + } + + SECTION("integrity Loader::getImage test 8") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + + SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + if (!rw) + logger->log("Physfs error: %s", PhysFs::getLastError()); + REQUIRE(rw != nullptr); + if (IMG_isPNG(rw) == false) + { + SDL_RWclose(rw); + REQUIRE(false); + } + SDL_Surface *const tmpImage = IMG_LoadPNG_RW(rw); + SDL_RWclose(rw); + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(tmpImage != nullptr); + SDL_FreeSurface(tmpImage); + } + + SECTION("integrity Loader::getImage test 9") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + + SDL_RWops *const rw = PHYSFSRWOPS_openRead(name1); + if (!rw) + logger->log("Physfs error: %s", PhysFs::getLastError()); + REQUIRE(rw != nullptr); + Resource *const res = imageHelper->load(rw); + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(res != nullptr); + res->decRef(); + } + + SECTION("integrity Loader::getImage test 10") + { + resourceManager->addToSearchPath("data/test/test.zip", Append_false); + resourceManager->addToSearchPath("../data/test/test.zip", Append_false); + Image *const image = Loader::getImage( + name1); + resourceManager->removeFromSearchPath("data/test/test.zip"); + resourceManager->removeFromSearchPath("../data/test/test.zip"); + REQUIRE(image != nullptr); + REQUIRE(image->getSDLSurface() != nullptr); + image->decRef(); + } + delete client; client = nullptr; diff --git a/src/utils/physfsrwops.cpp b/src/utils/physfsrwops.cpp index cc0ec014b..29a574913 100644 --- a/src/utils/physfsrwops.cpp +++ b/src/utils/physfsrwops.cpp @@ -61,15 +61,17 @@ static PHYSFSINT physfsrwops_seek(SDL_RWops *const rw, const PHYSFSINT offset, const PHYSFS_sint64 current = PHYSFS_tell(handle); if (current == -1) { - SDL_SetError("Can't find position in file: %s", - PHYSFS_getLastError()); + logger->assertLog( + "physfsrwops_seek: Can't find position in file: %s", + PHYSFS_getLastError()); return -1; } /* if */ pos = CAST_S32(current); if (static_cast(pos) != current) { - SDL_SetError("Can't fit current file position in an int!"); + logger->assertLog("physfsrwops_seek: " + "Can't fit current file position in an int!"); return -1; } /* if */ @@ -83,14 +85,16 @@ static PHYSFSINT physfsrwops_seek(SDL_RWops *const rw, const PHYSFSINT offset, const PHYSFS_sint64 len = PHYSFS_fileLength(handle); if (len == -1) { - SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError()); + logger->assertLog("physfsrwops_seek:Can't find end of file: %s", + PHYSFS_getLastError()); return -1; } /* if */ pos = static_cast(len); if (static_cast(pos) != len) { - SDL_SetError("Can't fit end-of-file position in an int!"); + logger->assertLog("physfsrwops_seek: " + "Can't fit end-of-file position in an int!"); return -1; } /* if */ @@ -98,19 +102,21 @@ static PHYSFSINT physfsrwops_seek(SDL_RWops *const rw, const PHYSFSINT offset, } /* else if */ else { - SDL_SetError("Invalid 'whence' parameter."); + logger->assertLog("physfsrwops_seek: Invalid 'whence' parameter."); return -1; } /* else */ if (pos < 0) { - SDL_SetError("Attempt to seek past start of file."); + logger->assertLog("physfsrwops_seek: " + "Attempt to seek past start of file."); return -1; } /* if */ if (!PHYSFS_seek(handle, static_cast(pos))) { - SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); + logger->assertLog("physfsrwops_seek: seek error: %s", + PHYSFS_getLastError()); return -1; } /* if */ @@ -132,7 +138,10 @@ static PHYSFSSIZE physfsrwops_read(SDL_RWops *const rw, if (rc != static_cast(maxnum)) { if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */ - SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); + { + logger->assertLog("physfsrwops_seek: read error: %s", + PHYSFS_getLastError()); + } } /* if */ return CAST_S32(rc); @@ -150,7 +159,10 @@ static PHYSFSSIZE physfsrwops_write(SDL_RWops *const rw, const void *ptr, CAST_U32(size), CAST_U32(num)); if (rc != static_cast(num)) - SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); + { + logger->assertLog("physfsrwops_seek: write error: %s", + PHYSFS_getLastError()); + } return CAST_S32(rc); } /* physfsrwops_write */ @@ -163,14 +175,15 @@ static int physfsrwops_close(SDL_RWops *const rw) rw->hidden.unknown.data1); if (!PHYSFS_close(handle)) { - SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); + logger->assertLog("physfsrwops_seek: close error: %s", + PHYSFS_getLastError()); return -1; } /* if */ SDL_FreeRW(rw); #ifdef DUMP_LEAKED_RESOURCES if (openedRWops <= 0) - logger->log("closing already closed RWops"); + logger->assertLog("physfsrwops_seek: closing already closed RWops"); openedRWops --; #endif // DUMP_LEAKED_RESOURCES #ifdef DEBUG_PHYSFS @@ -195,7 +208,8 @@ static SDL_RWops *create_rwops(PHYSFS_file *const handle) if (!handle) { - SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); + logger->assertLog("physfsrwops_seek: create rwops error: %s", + PHYSFS_getLastError()); } else { @@ -224,9 +238,14 @@ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *const handle) { SDL_RWops *retval = nullptr; if (!handle) - SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops()."); + { + logger->assertLog("physfsrwops_seek: NULL pointer passed to " + "PHYSFSRWOPS_makeRWops()."); + } else + { retval = create_rwops(handle); + } return retval; } /* PHYSFSRWOPS_makeRWops */ @@ -287,7 +306,10 @@ SDL_RWops *PHYSFSRWOPS_openAppend(const char *const fname) void reportRWops() { if (openedRWops) - logger->log("leaking RWops: %d", openedRWops); + { + logger->assertLog("physfsrwops_seek: leaking RWops: %d", + openedRWops); + } } #endif // DUMP_LEAKED_RESOURCES -- cgit v1.2.3-70-g09d2