diff options
| author | 2026-02-20 05:17:32 +0100 | |
|---|---|---|
| committer | 2026-02-20 05:17:32 +0100 | |
| commit | 3bdee70a9c1490ea011c6fb65193b2c7e242d26d (patch) | |
| tree | 90389bf6f8542bac2f2a4fffa1f5b31d099ee364 | |
| parent | e3d5bbdf1f213caafedf185251fba02558d30b98 (diff) | |
| download | libplist-3bdee70a9c1490ea011c6fb65193b2c7e242d26d.tar.gz libplist-3bdee70a9c1490ea011c6fb65193b2c7e242d26d.tar.bz2 | |
plistutil: Read STDIN in chunks instead of 1 byte at a time
| -rw-r--r-- | tools/plistutil.c | 66 |
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 | { |
