Skip to content

Commit

Permalink
More tests, docs and fixes for library_info (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin authored Jan 5, 2025
1 parent e7ad58b commit d4c93c5
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 12 deletions.
14 changes: 7 additions & 7 deletions include/boost/dll/detail/elf_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <cstdint>
#include <cstring>
#include <fstream>
#include <limits>
#include <vector>

#include <boost/throw_exception.hpp>
Expand Down Expand Up @@ -154,14 +153,15 @@ class elf_info {
private:
template <class Integer>
static void checked_seekg(std::ifstream& fs, Integer pos) {
/* TODO: use cmp_less, cmp_greater
if ((std::numeric_limits<std::streamoff>::max)() < pos) {
boost::throw_exception(std::runtime_error("Integral overflow while getting info from ELF file"));
}
if ((std::numeric_limits<std::streamoff>::min)() > pos){
if (pos < 0) {
boost::throw_exception(std::runtime_error("Integral underflow while getting info from ELF file"));
}
*/
if (static_cast<std::streamoff>(pos) < 0) {
boost::throw_exception(std::runtime_error("Integral overflow while getting info from ELF file"));
}

// `seekg` will throw exceptions on an attempt to get outsize of the
// file size.
fs.seekg(static_cast<std::streamoff>(pos));
}

Expand Down
5 changes: 0 additions & 5 deletions include/boost/dll/detail/pe_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include <string> // for std::getline
#include <vector>

#include <boost/assert.hpp>

namespace boost { namespace dll { namespace detail {

// reference:
Expand Down Expand Up @@ -221,7 +219,6 @@ class pe_info {
}

const std::size_t real_offset = get_file_offset(fs, exp_virtual_address, h);
BOOST_ASSERT(real_offset);

fs.seekg(real_offset);
read_raw(fs, exports);
Expand All @@ -230,8 +227,6 @@ class pe_info {
}

static std::size_t get_file_offset(std::ifstream& fs, std::size_t virtual_address, const header_t& h) {
BOOST_ASSERT(virtual_address);

section_t image_section_header;

{ // fs.seekg to the beginning on section headers
Expand Down
4 changes: 4 additions & 0 deletions include/boost/dll/library_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class library_info: private boost::noncopyable {
* \param library_path Path to the binary file from which the info must be extracted.
* \param throw_if_not_native_format Throw an exception if this file format is not
* supported by OS.
* \throws std::exception based exceptions.
*/
explicit library_info(const boost::dll::fs::path& library_path, bool throw_if_not_native_format = true)
: f_(
Expand All @@ -142,6 +143,7 @@ class library_info: private boost::noncopyable {

/*!
* \return List of sections that exist in binary file.
* \throws std::exception based exceptions.
*/
std::vector<std::string> sections() {
switch (fmt_) {
Expand All @@ -158,6 +160,7 @@ class library_info: private boost::noncopyable {

/*!
* \return List of all the exportable symbols from all the sections that exist in binary file.
* \throws std::exception based exceptions.
*/
std::vector<std::string> symbols() {
switch (fmt_) {
Expand All @@ -175,6 +178,7 @@ class library_info: private boost::noncopyable {
/*!
* \param section_name Name of the section from which symbol names must be returned.
* \return List of symbols from the specified section.
* \throws std::exception based exceptions.
*/
std::vector<std::string> symbols(const char* section_name) {
switch (fmt_) {
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ project
[ run shared_library_errors.cpp : : test_library : <test-info>always_show_run_output <link>shared ]
[ run structures_tests.cpp ]
[ run library_info_test.cpp ../example/tutorial4/static_plugin.cpp : : test_library : <test-info>always_show_run_output <link>shared ]
[ run broken_library_info_test.cpp : : : <test-info>always_show_run_output <link>shared ]
[ run empty_library_info_test.cpp : : empty_library : <test-info>always_show_run_output <link>shared ]
[ run ../example/getting_started.cpp : : getting_started_library : <link>shared ]
[ run ../example/tutorial1/tutorial1.cpp : : my_plugin_sum : <link>shared ]
Expand Down
69 changes: 69 additions & 0 deletions test/broken_library_info_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright Antony Polukhin, 2015-2024
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

// For more information, see http://www.boost.org

#include <boost/dll/library_info.hpp>

#include <fstream>
#include <boost/filesystem.hpp>

#include <boost/core/lightweight_test.hpp>

int main(int argc, char* argv[]) {
BOOST_TEST(argc >= 1);
const auto self_binary = boost::filesystem::path(argv[0]);
const auto corrupted_binary = self_binary.parent_path() / "corrupted";

boost::filesystem::copy_file(self_binary, corrupted_binary, boost::filesystem::copy_options::overwrite_existing);
{
std::ofstream ofs{corrupted_binary.string(), std::ios::binary};
ofs.seekp(0);
ofs << "bad";
}
try {
boost::dll::library_info lib_info(corrupted_binary.string());
BOOST_TEST(false);
} catch (const std::exception& ) {}

#if BOOST_OS_WINDOWS
boost::filesystem::copy_file(self_binary, corrupted_binary, boost::filesystem::copy_options::overwrite_existing);
{
std::ofstream ofs{corrupted_binary.string(), std::ios::binary};
ofs.seekp(
sizeof(boost::dll::detail::DWORD_)
+ sizeof(boost::dll::detail::IMAGE_FILE_HEADER_)
+ offsetof(boost::dll::detail::IMAGE_OPTIONAL_HEADER_template<boost::dll::detail::ULONGLONG_>, NumberOfRvaAndSizes)
);
const char data[] = "\0\0\0\0\0\0\0\0\0\0\0\0";
ofs.write(data, sizeof(data));
}

try {
boost::dll::library_info lib_info(corrupted_binary.string());
lib_info.sections();
BOOST_TEST(false);
} catch (const std::exception& ) {}
#endif

#if !BOOST_OS_WINDOWS && !BOOST_OS_MACOS && !BOOST_OS_IOS
// Elf
boost::filesystem::copy_file(self_binary, corrupted_binary, boost::filesystem::copy_options::overwrite_existing);
{
std::ofstream ofs{corrupted_binary.string(), std::ios::binary};
ofs.seekp(40); // header->e_shoff
ofs << "\xff\xff\xff\xff";
}

try {
boost::dll::library_info lib_info(corrupted_binary.string());
lib_info.sections();
BOOST_TEST(false);
} catch (const std::exception& ) {}
#endif

return boost::report_errors();
}

0 comments on commit d4c93c5

Please sign in to comment.