fail gracefully on large inputs
authorHelmut Grohne <helmut@subdivi.de>
Sun, 24 Mar 2013 15:16:43 +0000 (16:16 +0100)
committerHelmut Grohne <helmut@subdivi.de>
Sun, 24 Mar 2013 15:16:43 +0000 (16:16 +0100)
fuzzy.c

diff --git a/fuzzy.c b/fuzzy.c
index d359b30..88af850 100644 (file)
--- a/fuzzy.c
+++ b/fuzzy.c
@@ -187,16 +187,18 @@ static int ssdeep_engine_step(struct ssdeep_context *self, unsigned char c) {
                         * automatically false for all further bs. I.e. if
                         * h === -1 (mod 2*bs) then h === -1 (mod bs). */
                        break;
-               /* We don't need bs until next iteration. Update now, so we
-                * don't forget about it. */
-               bs *= 2;
                /* We have hit a reset point. We now emit hashes which are
                 * based on all characters in the piece of the message between
                 * the last reset point and this one */
-               if(unlikely(0 == bh->dlen)) /* Can only happen 30 times. */
+               if(unlikely(0 == bh->dlen && bs < UINT32_MAX / 2)) {
+                       /* Can only happen 30 times. */
                        /* First step for this blocksize. Clone next. */
                        if(blockhash_fork(bh) < 0)
                                return -1;
+               }
+               /* We don't need bs until next iteration. Update now, so we
+                * don't forget about it. */
+               bs *= 2;
                if(bh->dlen < SPAMSUM_LENGTH - 1) {
                        /* We can have a problem with the tail overflowing. The
                         * easiest way to cope with this is to only reset the
@@ -241,7 +243,9 @@ static int ssdeep_digest(const struct ssdeep_context *self,
        /* Initial blocksize guess. */
        while((size_t)bs * SPAMSUM_LENGTH < self->total_size) {
                bs *= 2;
-               assert(bh->next != NULL);
+               if(bh->next == NULL)
+                       /* The input exceeds data types. */
+                       return -1;
                bh = bh->next;
        }
        /* Adapt blocksize guess to actual digest length. */