fix output for ugly corner case master
authorHelmut Grohne <helmut@subdivi.de>
Tue, 9 Sep 2014 17:42:22 +0000 (19:42 +0200)
committerHelmut Grohne <helmut@subdivi.de>
Tue, 9 Sep 2014 17:42:22 +0000 (19:42 +0200)
When the roll_sum of the last piece happens to be 0, the original
algorithm picks one byte of the digest behind the end. In the original
algorithm, it is initially set to zero and updated unconditionally even
when the length is not increased. Copy that behaviour.

fuzzy.c

diff --git a/fuzzy.c b/fuzzy.c
index f1dcdcf..2e6fa8d 100644 (file)
--- a/fuzzy.c
+++ b/fuzzy.c
@@ -119,6 +119,7 @@ struct fuzzy_state {
        self->bhend = 1;
        self->bh[0].h = HASH_INIT;
        self->bh[0].halfh = HASH_INIT;
+       self->bh[0].digest[0] = '\0';
        self->bh[0].dlen = 0;
        self->total_size = 0;
        roll_init(&self->roll);
@@ -134,6 +135,7 @@ static void fuzzy_try_fork_blockhash(struct fuzzy_state *self) {
        nbh = obh + 1;
        nbh->h = obh->h;
        nbh->halfh = obh->halfh;
+       nbh->digest[0] = '\0';
        nbh->dlen = 0;
        ++self->bhend;
 }
@@ -188,6 +190,8 @@ static void fuzzy_engine_step(struct fuzzy_state *self, unsigned char c) {
                        /* First step for this blocksize. Clone next. */
                        fuzzy_try_fork_blockhash(self);
                }
+               self->bh[i].digest[self->bh[i].dlen] =
+                       b64[self->bh[i].h % 64];
                if(self->bh[i].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
@@ -195,8 +199,7 @@ static void fuzzy_engine_step(struct fuzzy_state *self, unsigned char c) {
                         * our signature. This has the effect of combining the
                         * last few pieces of the message into a single piece
                         * */
-                       self->bh[i].digest[self->bh[i].dlen++] =
-                               b64[self->bh[i].h % 64];
+                       self->bh[i].digest[++(self->bh[i].dlen)] = '\0';
                        self->bh[i].h = HASH_INIT;
                        if(self->bh[i].dlen < SPAMSUM_LENGTH / 2)
                                self->bh[i].halfh = HASH_INIT;
@@ -283,6 +286,16 @@ int fuzzy_digest(const struct fuzzy_state *self, /*@out@*/ char *result,
                        ++result;
                        --remain;
                }
+       } else if(self->bh[bi].digest[i] != '\0') {
+               assert(remain > 0);
+               *result = self->bh[bi].digest[i];
+               if((flags & FUZZY_FLAG_ELIMSEQ) == 0 || i < 3 ||
+                               *result != result[-1] ||
+                               *result != result[-2] ||
+                               *result != result[-3]) {
+                       ++result;
+                       --remain;
+               }
        }
        assert(remain > 0);
        *result++ = ':';