Commit d7efc661ec4e762cb819ff1fc6c7f022c82d386c
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 |