From: Nicolas Pitre <nico@cam.org>
To: Junio C Hamano <junkio@cox.net>
Cc: git@vger.kernel.org
Subject: [PATCH] diff-delta: fold two special tests into one plus cleanups
Date: Tue, 21 Feb 2006 20:41:41 -0500 (EST) [thread overview]
Message-ID: <Pine.LNX.4.64.0602212039350.5606@localhost.localdomain> (raw)
Testing for realloc and size limit can be done with only one test per
loop. Make it so and fix a theoretical off-by-one comparison error in
the process.
The output buffer memory allocation is also bounded by max_size when
specified.
Finally make some variable unsigned to allow the handling of files up to
4GB in size instead of 2GB.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
diff-delta.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)
95c1d1f82a8e36ab1e46b8186ecb34f441914961
diff --git a/diff-delta.c b/diff-delta.c
index c2f656a..ac992e2 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -148,16 +148,20 @@ static void delta_cleanup(bdfile_t *bdf)
cha_free(&bdf->cha);
}
+/* provide the size of the copy opcode given the block offset and size */
#define COPYOP_SIZE(o, s) \
(!!(o & 0xff) + !!(o & 0xff00) + !!(o & 0xff0000) + !!(o & 0xff000000) + \
!!(s & 0xff) + !!(s & 0xff00) + 1)
+/* the maximum size for any opcode */
+#define MAX_OP_SIZE COPYOP_SIZE(0xffffffff, 0xffffffff)
+
void *diff_delta(void *from_buf, unsigned long from_size,
void *to_buf, unsigned long to_size,
unsigned long *delta_size,
unsigned long max_size)
{
- int i, outpos, outsize, inscnt, csize, msize, moff;
+ unsigned int i, outpos, outsize, inscnt, csize, msize, moff;
unsigned int fp;
const unsigned char *ref_data, *ref_top, *data, *top, *ptr1, *ptr2;
unsigned char *out, *orig;
@@ -169,6 +173,8 @@ void *diff_delta(void *from_buf, unsigne
outpos = 0;
outsize = 8192;
+ if (max_size && outsize >= max_size)
+ outsize = max_size + MAX_OP_SIZE + 1;
out = malloc(outsize);
if (!out) {
delta_cleanup(&bdf);
@@ -259,17 +265,15 @@ void *diff_delta(void *from_buf, unsigne
*orig = i;
}
- if (max_size && outpos > max_size) {
- free(out);
- delta_cleanup(&bdf);
- return NULL;
- }
-
- /* next time around the largest possible output is 1 + 4 + 3 */
- if (outpos > outsize - 8) {
+ if (outpos >= outsize - MAX_OP_SIZE) {
void *tmp = out;
outsize = outsize * 3 / 2;
- out = realloc(out, outsize);
+ if (max_size && outsize >= max_size)
+ outsize = max_size + MAX_OP_SIZE + 1;
+ if (max_size && outpos > max_size)
+ out = NULL;
+ else
+ out = realloc(out, outsize);
if (!out) {
free(tmp);
delta_cleanup(&bdf);
--
1.2.2.g6643-dirty
reply other threads:[~2006-02-22 1:42 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.64.0602212039350.5606@localhost.localdomain \
--to=nico@cam.org \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).