Add QUtil::read_file_into_memory

This code was essentially duplicated between test_driver and
standalone_fuzz_target_runner.
This commit is contained in:
Jay Berkenbilt 2019-06-22 10:12:10 -04:00
parent 658b5bb3be
commit 1bde5c68a3
7 changed files with 67 additions and 76 deletions

View File

@ -1,3 +1,7 @@
2019-06-22 Jay Berkenbilt <ejb@ql.org>
* Add new function QUtil::read_file_into_memory.
2019-06-21 Jay Berkenbilt <ejb@ql.org>
* When supported, qpdf builds with -fvisibility=hidden, which

View File

@ -1,46 +1,18 @@
#include <qpdf/QUtil.hh>
#include <qpdf/PointerHolder.hh>
#include <qpdf/QIntC.hh>
#include <iostream>
#include <string>
extern "C" int LLVMFuzzerTestOneInput(unsigned char const* data, size_t size);
static void read_file_into_memory(
char const* filename,
PointerHolder<unsigned char>& file_buf, size_t& size)
{
FILE* f = QUtil::safe_fopen(filename, "rb");
fseek(f, 0, SEEK_END);
size = QIntC::to_size(QUtil::tell(f));
fseek(f, 0, SEEK_SET);
file_buf = PointerHolder<unsigned char>(true, new unsigned char[size]);
unsigned char* buf_p = file_buf.getPointer();
size_t bytes_read = 0;
size_t len = 0;
while ((len = fread(buf_p + bytes_read, 1, size - bytes_read, f)) > 0)
{
bytes_read += len;
}
if (bytes_read != size)
{
throw std::runtime_error(
std::string("failure reading file ") + filename +
" into memory: read " +
QUtil::uint_to_string(bytes_read) + "; wanted " +
QUtil::uint_to_string(size));
}
fclose(f);
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++)
{
PointerHolder<unsigned char> file_buf;
PointerHolder<char> file_buf;
size_t size = 0;
read_file_into_memory(argv[i], file_buf, size);
LLVMFuzzerTestOneInput(file_buf.getPointer(), size);
QUtil::read_file_into_memory(argv[i], file_buf, size);
LLVMFuzzerTestOneInput(
reinterpret_cast<unsigned char*>(file_buf.getPointer()), size);
std::cout << argv[i] << " successful" << std::endl;
}
return 0;

View File

@ -24,6 +24,7 @@
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
#include <qpdf/PointerHolder.hh>
#include <string>
#include <list>
#include <vector>
@ -304,6 +305,9 @@ namespace QUtil
std::list<std::string> read_lines_from_file(char const* filename);
QPDF_DLL
std::list<std::string> read_lines_from_file(std::istream&);
QPDF_DLL
void read_file_into_memory(
char const* filename, PointerHolder<char>& file_buf, size_t& size);
// This used to be called strcasecmp, but that is a macro on some
// platforms, so we have to give it a name that is not likely to

View File

@ -957,6 +957,45 @@ QUtil::read_lines_from_file(char const* filename)
return lines;
}
void
QUtil::read_file_into_memory(
char const* filename,
PointerHolder<char>& file_buf, size_t& size)
{
FILE* f = safe_fopen(filename, "rb");
fseek(f, 0, SEEK_END);
size = QIntC::to_size(QUtil::tell(f));
fseek(f, 0, SEEK_SET);
file_buf = PointerHolder<char>(true, new char[size]);
char* buf_p = file_buf.getPointer();
size_t bytes_read = 0;
size_t len = 0;
while ((len = fread(buf_p + bytes_read, 1, size - bytes_read, f)) > 0)
{
bytes_read += len;
}
if (bytes_read != size)
{
if (ferror(f))
{
throw std::runtime_error(
std::string("failure reading file ") + filename +
" into memory: read " +
uint_to_string(bytes_read) + "; wanted " +
uint_to_string(size));
}
else
{
throw std::runtime_error(
std::string("premature eof reading file ") + filename +
" into memory: read " +
uint_to_string(bytes_read) + "; wanted " +
uint_to_string(size));
}
}
fclose(f);
}
std::list<std::string>
QUtil::read_lines_from_file(std::istream& in)
{

File diff suppressed because one or more lines are too long

View File

@ -400,7 +400,7 @@ void same_file_test()
assert_same_file("", "qutil.out", false);
}
void read_lines_from_file_test()
void read_from_file_test()
{
std::list<std::string> lines = QUtil::read_lines_from_file("other-file");
for (std::list<std::string>::iterator iter = lines.begin();
@ -408,6 +408,15 @@ void read_lines_from_file_test()
{
std::cout << *iter << std::endl;
}
PointerHolder<char> buf;
size_t size = 0;
QUtil::read_file_into_memory("other-file", buf, size);
std::cout << "read " << size << " bytes" << std::endl;
char const* p = buf.getPointer();
assert(size == 24652);
assert(memcmp(p, "This file is used for qutil testing.", 36) == 0);
assert(p[59] == static_cast<char>(13));
assert(memcmp(p + 24641, "very long.", 10) == 0);
}
void assert_hex_encode(std::string const& input, std::string const& expected)
@ -472,8 +481,8 @@ int main(int argc, char* argv[])
get_whoami_test();
std::cout << "---- file" << std::endl;
same_file_test();
std::cout << "---- lines from file" << std::endl;
read_lines_from_file_test();
std::cout << "---- read from file" << std::endl;
read_from_file_test();
std::cout << "---- hex encode/decode" << std::endl;
hex_encode_decode_test();
}

View File

@ -168,44 +168,6 @@ static void print_rect(std::ostream& out,
<< r.urx << ", " << r.ury << "]";
}
static void read_file_into_memory(
char const* filename,
PointerHolder<char>& file_buf, size_t& size)
{
FILE* f = QUtil::safe_fopen(filename, "rb");
fseek(f, 0, SEEK_END);
size = QIntC::to_size(QUtil::tell(f));
fseek(f, 0, SEEK_SET);
file_buf = PointerHolder<char>(true, new char[size]);
char* buf_p = file_buf.getPointer();
size_t bytes_read = 0;
size_t len = 0;
while ((len = fread(buf_p + bytes_read, 1, size - bytes_read, f)) > 0)
{
bytes_read += len;
}
if (bytes_read != size)
{
if (ferror(f))
{
throw std::runtime_error(
std::string("failure reading file ") + filename +
" into memory: read " +
QUtil::uint_to_string(bytes_read) + "; wanted " +
QUtil::uint_to_string(size));
}
else
{
throw std::logic_error(
std::string("premature eof reading file ") + filename +
" into memory: read " +
QUtil::uint_to_string(bytes_read) + "; wanted " +
QUtil::uint_to_string(size));
}
}
fclose(f);
}
#define assert_compare_numbers(expected, expr) \
compare_numbers(#expr, expected, expr)
@ -277,7 +239,7 @@ void runtest(int n, char const* filename1, char const* arg2)
std::string filename(std::string(filename1) + ".obfuscated");
size_t size = 0;
read_file_into_memory(filename.c_str(), file_buf, size);
QUtil::read_file_into_memory(filename.c_str(), file_buf, size);
char* p = file_buf.getPointer();
for (size_t i = 0; i < size; ++i)
{
@ -308,7 +270,7 @@ void runtest(int n, char const* filename1, char const* arg2)
{
QTC::TC("qpdf", "exercise processMemoryFile");
size_t size = 0;
read_file_into_memory(filename1, file_buf, size);
QUtil::read_file_into_memory(filename1, file_buf, size);
pdf.processMemoryFile(filename1, file_buf.getPointer(), size);
}