From d7efc661ec4e762cb819ff1fc6c7f022c82d386c Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 27 Jul 2023 20:27:10 +0100 Subject: Change QUtil::read_file_into_string to work with pipes (fixes #1010) --- libqpdf/QUtil.cc | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'libqpdf/QUtil.cc') diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 0fb03579..fcba203f 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -1178,21 +1178,43 @@ std::string QUtil::read_file_into_string(FILE* f, std::string_view filename) { fseek(f, 0, SEEK_END); - auto size = QIntC::to_size(QUtil::tell(f)); - fseek(f, 0, SEEK_SET); - std::string result(size, '\0'); - if (auto read = fread(result.data(), 1, size, f); read != size) { + auto o_size = QUtil::tell(f); + if (o_size >= 0) { + // Seekable file + auto size = QIntC::to_size(o_size); + fseek(f, 0, SEEK_SET); + std::string result(size, '\0'); + if (auto n_read = fread(result.data(), 1, size, f); n_read != size) { + if (ferror(f)) { + throw std::runtime_error( + std::string("failure reading file ") + std::string(filename) + + " into memory: read " + uint_to_string(n_read) + "; wanted " + + uint_to_string(size)); + } else { + throw std::runtime_error( + std::string("premature eof reading file ") + std::string(filename) + + " into memory: read " + uint_to_string(n_read) + "; wanted " + + uint_to_string(size)); + } + } + return result; + } else { + // Pipe or other non-seekable file + size_t buf_size = 8192; + auto n_read = buf_size; + std::string buffer(buf_size, '\0'); + std::string result; + while (n_read == buf_size) { + n_read = fread(buffer.data(), 1, buf_size, f); + buffer.erase(n_read); + result.append(buffer); + } if (ferror(f)) { throw std::runtime_error( - std::string("failure reading file ") + std::string(filename) + - " into memory: read " + uint_to_string(read) + "; wanted " + uint_to_string(size)); - } else { - throw std::runtime_error( - std::string("premature eof reading file ") + std::string(filename) + - " into memory: read " + uint_to_string(read) + "; wanted " + uint_to_string(size)); + std::string("failure reading file ") + std::string(filename) + " into memory"); } + return result; } - return result; } static bool -- cgit v1.2.3-54-g00ecf