{"thread":{"id":"3430","subject":"[PATCH] diff-delta: fold two special tests into one plus cleanups","startedAt":"2006-02-22T01:41:41Z","lastAt":"2006-02-22T01:41:41Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"16552","messageId":"Pine.LNX.4.64.0602212039350.5606@localhost.localdomain","threadId":"3430","inReplyTo":null,"subject":"[PATCH] diff-delta: fold two special tests into one plus cleanups","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-02-22T01:41:41Z","receivedAt":"2006-02-22T01:41:41Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"\nTesting for realloc and size limit can be done with only one test per \nloop. Make it so and fix a theoretical off-by-one comparison error in \nthe process.\n\nThe output buffer memory allocation is also bounded by max_size when \nspecified.\n\nFinally make some variable unsigned to allow the handling of files up to \n4GB in size instead of 2GB.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n\n---\n\n diff-delta.c |   24 ++++++++++++++----------\n 1 files changed, 14 insertions(+), 10 deletions(-)\n\n95c1d1f82a8e36ab1e46b8186ecb34f441914961\ndiff --git a/diff-delta.c b/diff-delta.c\nindex c2f656a..ac992e2 100644\n--- a/diff-delta.c\n+++ b/diff-delta.c\n@@ -148,16 +148,20 @@ static void delta_cleanup(bdfile_t *bdf)\n \tcha_free(&bdf->cha);\n }\n \n+/* provide the size of the copy opcode given the block offset and size */\n #define COPYOP_SIZE(o, s) \\\n     (!!(o & 0xff) + !!(o & 0xff00) + !!(o & 0xff0000) + !!(o & 0xff000000) + \\\n      !!(s & 0xff) + !!(s & 0xff00) + 1)\n \n+/* the maximum size for any opcode */\n+#define MAX_OP_SIZE COPYOP_SIZE(0xffffffff, 0xffffffff)\n+\n void *diff_delta(void *from_buf, unsigned long from_size,\n \t\t void *to_buf, unsigned long to_size,\n \t\t unsigned long *delta_size,\n \t\t unsigned long max_size)\n {\n-\tint i, outpos, outsize, inscnt, csize, msize, moff;\n+\tunsigned int i, outpos, outsize, inscnt, csize, msize, moff;\n \tunsigned int fp;\n \tconst unsigned char *ref_data, *ref_top, *data, *top, *ptr1, *ptr2;\n \tunsigned char *out, *orig;\n@@ -169,6 +173,8 @@ void *diff_delta(void *from_buf, unsigne\n \t\n \toutpos = 0;\n \toutsize = 8192;\n+\tif (max_size && outsize >= max_size)\n+\t\toutsize = max_size + MAX_OP_SIZE + 1;\n \tout = malloc(outsize);\n \tif (!out) {\n \t\tdelta_cleanup(&bdf);\n@@ -259,17 +265,15 @@ void *diff_delta(void *from_buf, unsigne\n \t\t\t*orig = i;\n \t\t}\n \n-\t\tif (max_size && outpos > max_size) {\n-\t\t\tfree(out);\n-\t\t\tdelta_cleanup(&bdf);\n-\t\t\treturn NULL;\n-\t\t}\n-\n-\t\t/* next time around the largest possible output is 1 + 4 + 3 */\n-\t\tif (outpos > outsize - 8) {\n+\t\tif (outpos >= outsize - MAX_OP_SIZE) {\n \t\t\tvoid *tmp = out;\n \t\t\toutsize = outsize * 3 / 2;\n-\t\t\tout = realloc(out, outsize);\n+\t\t\tif (max_size && outsize >= max_size)\n+\t\t\t\toutsize = max_size + MAX_OP_SIZE + 1;\n+\t\t\tif (max_size && outpos > max_size)\n+\t\t\t\tout = NULL;\n+\t\t\telse\n+\t\t\t\tout = realloc(out, outsize);\n \t\t\tif (!out) {\n \t\t\t\tfree(tmp);\n \t\t\t\tdelta_cleanup(&bdf);\n-- \n1.2.2.g6643-dirty\n"}]}