summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2026-02-20 05:17:32 +0100
committerGravatar Nikias Bassen2026-02-20 05:17:32 +0100
commit3bdee70a9c1490ea011c6fb65193b2c7e242d26d (patch)
tree90389bf6f8542bac2f2a4fffa1f5b31d099ee364
parente3d5bbdf1f213caafedf185251fba02558d30b98 (diff)
downloadlibplist-3bdee70a9c1490ea011c6fb65193b2c7e242d26d.tar.gz
libplist-3bdee70a9c1490ea011c6fb65193b2c7e242d26d.tar.bz2
plistutil: Read STDIN in chunks instead of 1 byte at a time
-rw-r--r--tools/plistutil.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/tools/plistutil.c b/tools/plistutil.c
index 6e697cf..bdf195e 100644
--- a/tools/plistutil.c
+++ b/tools/plistutil.c
@@ -246,45 +246,49 @@ int main(int argc, char *argv[])
246 return 1; 246 return 1;
247 } 247 }
248 plist_entire[read_size] = '\0'; 248 plist_entire[read_size] = '\0';
249 char ch; 249 char buf[4096];
250 while(read(STDIN_FILENO, &ch, 1) > 0) 250 ssize_t n;
251 { 251
252 if (read_size >= read_capacity) { 252 while (1) {
253 char *old = plist_entire; 253 n = read(STDIN_FILENO, buf, sizeof(buf));
254 read_capacity += 4096; 254 if (n > 0) {
255 plist_entire = realloc(plist_entire, sizeof(char) * read_capacity); 255 size_t needed = read_size + (size_t)n + 1;
256 if (plist_entire == NULL) 256 if (needed > read_capacity) {
257 { 257 size_t newcap = read_capacity ? read_capacity : 4096;
258 fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n"); 258 while (newcap < needed) {
259 free(old); 259 newcap *= 2;
260 free(options); 260 }
261 return 1; 261
262 char *tmp = realloc(plist_entire, newcap);
263 if (!tmp) {
264 fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n");
265 free(plist_entire);
266 free(options);
267 return 1;
268 }
269 plist_entire = tmp;
270 read_capacity = newcap;
262 } 271 }
272
273 memcpy(plist_entire + read_size, buf, (size_t)n);
274 read_size += (size_t)n;
275 continue;
263 } 276 }
264 plist_entire[read_size] = ch; 277
265 read_size++; 278 if (n == 0) { // EOF
266 } 279 break;
267 if (read_size >= read_capacity) {
268 char *old = plist_entire;
269 plist_entire = realloc(plist_entire, sizeof(char) * (read_capacity+1));
270 if (plist_entire == NULL)
271 {
272 fprintf(stderr, "ERROR: Failed to reallocate stdin buffer\n");
273 free(old);
274 free(options);
275 return 1;
276 } 280 }
277 }
278 plist_entire[read_size] = '\0';
279 281
280 // Not positive we need this, but it doesnt seem to hurt lol 282 // n < 0: error
281 if(ferror(stdin)) 283 if (errno == EINTR)
282 { 284 continue;
283 fprintf(stderr, "ERROR: reading from stdin.\n"); 285
286 fprintf(stderr, "ERROR: Failed to read from stdin\n");
284 free(plist_entire); 287 free(plist_entire);
285 free(options); 288 free(options);
286 return 1; 289 return 1;
287 } 290 }
291 plist_entire[read_size] = '\0';
288 } 292 }
289 else 293 else
290 { 294 {