Commit d7efc661ec4e762cb819ff1fc6c7f022c82d386c

Authored by m-holger
1 parent c1afe9f8

Change QUtil::read_file_into_string to work with pipes (fixes #1010)

Showing 1 changed file with 33 additions and 11 deletions
libqpdf/QUtil.cc
... ... @@ -1178,21 +1178,43 @@ std::string
1178 1178 QUtil::read_file_into_string(FILE* f, std::string_view filename)
1179 1179 {
1180 1180 fseek(f, 0, SEEK_END);
1181   - auto size = QIntC::to_size(QUtil::tell(f));
1182   - fseek(f, 0, SEEK_SET);
1183   - std::string result(size, '\0');
1184   - if (auto read = fread(result.data(), 1, size, f); read != size) {
  1181 + auto o_size = QUtil::tell(f);
  1182 + if (o_size >= 0) {
  1183 + // Seekable file
  1184 + auto size = QIntC::to_size(o_size);
  1185 + fseek(f, 0, SEEK_SET);
  1186 + std::string result(size, '\0');
  1187 + if (auto n_read = fread(result.data(), 1, size, f); n_read != size) {
  1188 + if (ferror(f)) {
  1189 + throw std::runtime_error(
  1190 + std::string("failure reading file ") + std::string(filename) +
  1191 + " into memory: read " + uint_to_string(n_read) + "; wanted " +
  1192 + uint_to_string(size));
  1193 + } else {
  1194 + throw std::runtime_error(
  1195 + std::string("premature eof reading file ") + std::string(filename) +
  1196 + " into memory: read " + uint_to_string(n_read) + "; wanted " +
  1197 + uint_to_string(size));
  1198 + }
  1199 + }
  1200 + return result;
  1201 + } else {
  1202 + // Pipe or other non-seekable file
  1203 + size_t buf_size = 8192;
  1204 + auto n_read = buf_size;
  1205 + std::string buffer(buf_size, '\0');
  1206 + std::string result;
  1207 + while (n_read == buf_size) {
  1208 + n_read = fread(buffer.data(), 1, buf_size, f);
  1209 + buffer.erase(n_read);
  1210 + result.append(buffer);
  1211 + }
1185 1212 if (ferror(f)) {
1186 1213 throw std::runtime_error(
1187   - std::string("failure reading file ") + std::string(filename) +
1188   - " into memory: read " + uint_to_string(read) + "; wanted " + uint_to_string(size));
1189   - } else {
1190   - throw std::runtime_error(
1191   - std::string("premature eof reading file ") + std::string(filename) +
1192   - " into memory: read " + uint_to_string(read) + "; wanted " + uint_to_string(size));
  1214 + std::string("failure reading file ") + std::string(filename) + " into memory");
1193 1215 }
  1216 + return result;
1194 1217 }
1195   - return result;
1196 1218 }
1197 1219  
1198 1220 static bool
... ...