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,21 +1178,43 @@ std::string
1178 QUtil::read_file_into_string(FILE* f, std::string_view filename) 1178 QUtil::read_file_into_string(FILE* f, std::string_view filename)
1179 { 1179 {
1180 fseek(f, 0, SEEK_END); 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 if (ferror(f)) { 1212 if (ferror(f)) {
1186 throw std::runtime_error( 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 static bool 1220 static bool