int main() { String exe_path = GetCurrentExecutableDirectory(); TempDirectory temp_dir_1; TempDirectory temp_dir_2; // List of symbols in original libfoo.so and libfoo2.so, respectively. static const char* const kFooSymbols[] = {"Foo", NULL}; static const char* const kFoo2Symbols[] = {"Foo2", NULL}; // Copy libfoo.so to $TMPDIR1/libfoo.so CopyFile("libfoo.so", exe_path.c_str(), "libfoo.so", temp_dir_1.path()); // Copy libfoo2.so to $TMPDIR2/libfoo.so CopyFile("libfoo2.so", exe_path.c_str(), "libfoo.so", temp_dir_2.path()); // Create a new context object. crazy_context_t* context = crazy_context_create(); crazy_library_t* library; // Reset search paths to a non-existing directory. Check that the library // can't be loaded. setenv("LD_LIBRARY_PATH", "/this-directory-does-not-exist", 1); crazy_context_reset_search_paths(context); CheckLibraryCantLoad("libfoo.so", context); // Add the search path to the current executable, this should load the // original // libfoo.so. crazy_context_add_search_path_for_address(context, (void*)&main); CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context); // Reset search paths to use $TMPDIR2 then $TMPDIR1 setenv("LD_LIBRARY_PATH", temp_dir_1.path(), 1); crazy_context_reset_search_paths(context); crazy_context_add_search_path(context, temp_dir_2.path()); // Check that the copy of libfoo2.so is loaded. CheckLibrary("libfoo.so", kFoo2Symbols, kFooSymbols, context); // Reset search paths to use only $TMPDIR1 crazy_context_reset_search_paths(context); // Check that the copy of libfoo.so is loaded. CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context); crazy_context_destroy(context); return 0; }
bool MemFile::open (const std::string &path_, bool uncompress) { MEMORY mem(MAX_IMAGE_SIZE + 1); size_t uRead = 0; // Check if zlib is available #ifdef HAVE_ZLIBSTAT bool have_zlib = true; #elif defined(HAVE_ZLIB) bool have_zlib = CheckLibrary("zlib", "zlibVersion") && zlibVersion()[0] == ZLIB_VERSION[0]; #else bool have_zlib = false; #endif #ifdef HAVE_ZLIB // Try opening as a zip file if (uncompress && have_zlib) { unzFile hfZip = unzOpen(path_.c_str()); if (hfZip) { int nRet; unz_file_info sInfo; uLong ulMaxSize = 0; // Iterate through the contents of the zip looking for a file with a suitable size for (nRet = unzGoToFirstFile(hfZip); nRet == UNZ_OK; nRet = unzGoToNextFile(hfZip)) { char szFile[MAX_PATH]; // Get details of the current file unzGetCurrentFileInfo(hfZip, &sInfo, szFile, MAX_PATH, nullptr, 0, nullptr, 0); // Ignore directories and empty files if (!sInfo.uncompressed_size) continue; // If the file extension is recognised, read the file contents // ToDo: GetFileType doesn't really belong here? if (GetFileType(szFile) != ftUnknown && unzOpenCurrentFile(hfZip) == UNZ_OK) { nRet = unzReadCurrentFile(hfZip, mem, static_cast<unsigned int>(mem.size)); unzCloseCurrentFile(hfZip); break; } // Rememeber the largest uncompressed file size if (sInfo.uncompressed_size > ulMaxSize) ulMaxSize = sInfo.uncompressed_size; } // Did we fail to find a matching extension? if (nRet == UNZ_END_OF_LIST_OF_FILE) { // Loop back over the archive for (nRet = unzGoToFirstFile(hfZip); nRet == UNZ_OK; nRet = unzGoToNextFile(hfZip)) { // Get details of the current file unzGetCurrentFileInfo(hfZip, &sInfo, nullptr, 0, nullptr, 0, nullptr, 0); // Open the largest file found about if (sInfo.uncompressed_size == ulMaxSize && unzOpenCurrentFile(hfZip) == UNZ_OK) { nRet = unzReadCurrentFile(hfZip, mem, static_cast<unsigned int>(mem.size)); unzCloseCurrentFile(hfZip); break; } } } // Close the zip archive unzClose(hfZip); // Stop if something went wrong if (nRet < 0) throw util::exception("zip extraction failed (", nRet, ")"); uRead = nRet; m_compress = Compress::Zip; } else { // Open as gzipped or uncompressed gzFile gf = gzopen(path_.c_str(), "rb"); if (gf == Z_NULL) throw posix_error(errno, path_.c_str()); uRead = gzread(gf, mem, static_cast<unsigned>(mem.size)); m_compress = (gztell(gf) != FileSize(path_)) ? Compress::Gzip : Compress::None; gzclose(gf); } } else #endif // HAVE_ZLIB { // Open as normal file if we couldn't use zlib above FILE *f = fopen(path_.c_str(), "rb"); if (!f) throw posix_error(errno, path_.c_str()); uRead = fread(mem, 1, mem.size, f); fclose(f); m_compress = Compress::None; } // zip compressed? (and not handled above) if (uncompress && mem[0U] == 'P' && mem[1U] == 'K') throw util::exception("zlib (zlib1.dll) is required for zip support"); // gzip compressed? if (uncompress && mem[0U] == 0x1f && mem[1U] == 0x8b && mem[2U] == 0x08) { if (!have_zlib) throw util::exception("zlib (zlib1.dll) is required for gzip support"); #ifdef HAVE_ZLIB MEMORY mem2(MAX_IMAGE_SIZE + 1); uint8_t flags = mem[3]; auto pb = mem.pb + 10, pbEnd = mem.pb + mem.size; if (flags & 0x04) // EXTRA_FIELD { if (pb < pbEnd - 1) pb += 2 + pb[0] + (pb[1] << 8); } if (flags & 0x08 || flags & 0x10) // ORIG_NAME or COMMENT { while (pb < pbEnd && *pb++); } if (flags & 0x02) // HEAD_CRC pb += 2; z_stream stream = {}; stream.next_in = pb; stream.avail_in = (pb < pbEnd) ? static_cast<uInt>(pbEnd - pb) : 0; stream.next_out = mem2.pb; stream.avail_out = mem2.size; auto zerr = inflateInit2(&stream, -MAX_WBITS); if (zerr == Z_OK) { zerr = inflate(&stream, Z_FINISH); inflateEnd(&stream); } if (zerr != Z_STREAM_END) throw util::exception("gzip decompression failed (", zerr, ")"); memcpy(mem.pb, mem2.pb, uRead = stream.total_out); m_compress = Compress::Zip; #endif } // bzip2 compressed? if (uncompress && mem[0U] == 'B' && mem[1U] == 'Z') { #ifdef HAVE_BZIP2 if (!CheckLibrary("bzip2", "BZ2_bzBuffToBuffDecompress")) #endif throw util::exception("libbz2 (bzip2.dll) is required for bzip2 support"); #ifdef HAVE_BZIP2 MEMORY mem2(MAX_IMAGE_SIZE + 1); auto uBzRead = static_cast<unsigned>(mem2.size); auto bzerr = BZ2_bzBuffToBuffDecompress(reinterpret_cast<char *>(mem2.pb), &uBzRead, reinterpret_cast<char *>(mem.pb), uRead, 0, 0); if (bzerr != BZ_OK) throw util::exception("bzip2 decompression failed (", bzerr, ")"); memcpy(mem.pb, mem2.pb, uRead = uBzRead); m_compress = Compress::Bzip2; #endif // HAVE_BZIP2 } if (uRead <= MAX_IMAGE_SIZE) return open(mem.pb, static_cast<int>(uRead), path_); throw util::exception("file size too big"); }