summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorm-holger <m-holger@kubitscheck.org>2023-07-27 21:27:10 +0200
committerm-holger <m-holger@kubitscheck.org>2023-08-07 13:40:34 +0200
commitd7efc661ec4e762cb819ff1fc6c7f022c82d386c (patch)
tree74714a9f3f5045b14daae9027943670cdcedd91a
parentc1afe9f83bee238cce3cd68619d22c21bd7541a7 (diff)
downloadqpdf-d7efc661ec4e762cb819ff1fc6c7f022c82d386c.tar.zst
Change QUtil::read_file_into_string to work with pipes (fixes #1010)
-rw-r--r--libqpdf/QUtil.cc44
1 files changed, 33 insertions, 11 deletions
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