diff options
author | Jay Berkenbilt <jberkenbilt@users.noreply.github.com> | 2023-09-02 21:21:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-02 21:21:04 +0200 |
commit | e640dd30be0fbc7ea29adc137f27b3dc2bfc7466 (patch) | |
tree | e3084e82f3e7b70622b37350b90fcf2cb578a395 /libqpdf/QUtil.cc | |
parent | c51bdeb19cee981cc3e6d308ecff4297a7ca29e7 (diff) | |
parent | d7efc661ec4e762cb819ff1fc6c7f022c82d386c (diff) | |
download | qpdf-e640dd30be0fbc7ea29adc137f27b3dc2bfc7466.tar.zst |
Merge pull request #1016 from m-holger/i1010
Change QUtil::read_file_into_string to work with pipes (fixes #1010)
Diffstat (limited to 'libqpdf/QUtil.cc')
-rw-r--r-- | libqpdf/QUtil.cc | 44 |
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 |