From e32fd66bb95adfa0e8cb0e060aa84465ebe2c5a5 Mon Sep 17 00:00:00 2001 From: Josh Klontz Date: Tue, 8 Jul 2014 09:51:47 -0400 Subject: [PATCH] made br_iterate_utemplates_file more robust --- openbr/universal_template.cpp | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/openbr/universal_template.cpp b/openbr/universal_template.cpp index 84ad7ca..15ad775 100644 --- a/openbr/universal_template.cpp +++ b/openbr/universal_template.cpp @@ -58,18 +58,44 @@ static void callAndFree(br_utemplate_callback callback, br_utemplate t, br_callb void br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_callback_context context, bool parallel) { QFutureSynchronizer futures; - while (!feof(file)) { + while (true) { br_utemplate t = (br_utemplate) malloc(sizeof(br_universal_template)); - if (fread(t, sizeof(br_universal_template), 1, file) > 0) { - t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->size); - if (fread(t+1, 1, t->size, file) != t->size) - qFatal("Unexepected EOF when reading universal template data."); - if (parallel) futures.addFuture(QtConcurrent::run(callAndFree, callback, t, context)); - else callAndFree(callback, t, context); - } else { - free(t); + int bytesRemaining = sizeof(br_universal_template); + while (bytesRemaining > 0) { + bytesRemaining -= fread(reinterpret_cast(t) + sizeof(br_universal_template) - bytesRemaining, 1, bytesRemaining, file); + + if (feof(file)) { + if (bytesRemaining == sizeof(br_universal_template)) { + free(t); + return; + } else { + qFatal("Unexpected end of file when reading template metadata."); + } + } + + if (ferror(file)) { + perror(NULL); + qFatal("Error while reading template metadata."); + } } + + t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->size); + bytesRemaining = t->size; + while (bytesRemaining > 0) { + bytesRemaining -= fread(&t->data[t->size - bytesRemaining], 1, bytesRemaining, file); + + if (feof(file)) + qFatal("Unexpected end of file when reading template data."); + + if (ferror(file)) { + perror(NULL); + qFatal("Error while reading template data."); + } + } + + if (parallel) futures.addFuture(QtConcurrent::run(callAndFree, callback, t, context)); + else callAndFree(callback, t, context); } futures.waitForFinished(); } -- libgit2 0.21.4