Skip to content

Commit a84650e

Browse files
committed
util: Fix ReadBinaryFile reading beyond maxsize
1 parent 25a91a5 commit a84650e

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

src/test/util_tests.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,18 @@
1717
#include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
1818
#include <util/moneystr.h>
1919
#include <util/overflow.h>
20+
#include <util/readwritefile.h>
2021
#include <util/spanparsing.h>
2122
#include <util/strencodings.h>
2223
#include <util/string.h>
2324
#include <util/time.h>
2425
#include <util/vector.h>
2526

2627
#include <array>
27-
#include <optional>
28+
#include <fstream>
2829
#include <limits>
2930
#include <map>
31+
#include <optional>
3032
#include <stdint.h>
3133
#include <string.h>
3234
#include <thread>
@@ -2576,4 +2578,49 @@ BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
25762578
BOOST_CHECK(!ParseByteUnits("1x", noop));
25772579
}
25782580

2581+
BOOST_AUTO_TEST_CASE(util_ReadBinaryFile)
2582+
{
2583+
fs::path tmpfolder = m_args.GetDataDirBase();
2584+
fs::path tmpfile = tmpfolder / "read_binary.dat";
2585+
std::string expected_text;
2586+
for (int i = 0; i < 30; i++) {
2587+
expected_text += "0123456789";
2588+
}
2589+
{
2590+
std::ofstream file{tmpfile};
2591+
file << expected_text;
2592+
}
2593+
{
2594+
// read all contents in file
2595+
auto [valid, text] = ReadBinaryFile(tmpfile);
2596+
BOOST_CHECK(valid);
2597+
BOOST_CHECK_EQUAL(text, expected_text);
2598+
}
2599+
{
2600+
// read half contents in file
2601+
auto [valid, text] = ReadBinaryFile(tmpfile, expected_text.size() / 2);
2602+
BOOST_CHECK(valid);
2603+
BOOST_CHECK_EQUAL(text, expected_text.substr(0, expected_text.size() / 2));
2604+
}
2605+
{
2606+
// read from non-existent file
2607+
fs::path invalid_file = tmpfolder / "invalid_binary.dat";
2608+
auto [valid, text] = ReadBinaryFile(invalid_file);
2609+
BOOST_CHECK(!valid);
2610+
BOOST_CHECK(text.empty());
2611+
}
2612+
}
2613+
2614+
BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
2615+
{
2616+
fs::path tmpfolder = m_args.GetDataDirBase();
2617+
fs::path tmpfile = tmpfolder / "write_binary.dat";
2618+
std::string expected_text = "bitcoin";
2619+
auto valid = WriteBinaryFile(tmpfile, expected_text);
2620+
std::string actual_text;
2621+
std::ifstream file{tmpfile};
2622+
file >> actual_text;
2623+
BOOST_CHECK(valid);
2624+
BOOST_CHECK_EQUAL(actual_text, expected_text);
2625+
}
25792626
BOOST_AUTO_TEST_SUITE_END()

src/util/readwritefile.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ std::pair<bool,std::string> ReadBinaryFile(const fs::path &filename, size_t maxs
1818
std::string retval;
1919
char buffer[128];
2020
do {
21-
const size_t n = fread(buffer, 1, sizeof(buffer), f);
21+
const size_t n = fread(buffer, 1, std::min(sizeof(buffer), maxsize - retval.size()), f);
2222
// Check for reading errors so we don't return any data if we couldn't
2323
// read the entire file (or up to maxsize)
2424
if (ferror(f)) {
2525
fclose(f);
2626
return std::make_pair(false,"");
2727
}
2828
retval.append(buffer, buffer+n);
29-
} while (!feof(f) && retval.size() <= maxsize);
29+
} while (!feof(f) && retval.size() < maxsize);
3030
fclose(f);
3131
return std::make_pair(true,retval);
3232
}

0 commit comments

Comments
 (0)