From 9fc013b29af595852c1cc53fdb365a06dd5e7d49 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 31 Mar 2009 15:48:59 +1030 Subject: [PATCH] New test and fixes to crcsync. --- ccan/crcsync/crcsync.c | 10 +++- ccan/crcsync/test/run-crash.c | 93 +++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 ccan/crcsync/test/run-crash.c diff --git a/ccan/crcsync/crcsync.c b/ccan/crcsync/crcsync.c index 87f513ea..2301bc10 100644 --- a/ccan/crcsync/crcsync.c +++ b/ccan/crcsync/crcsync.c @@ -192,7 +192,11 @@ size_t crc_read_block(struct crc_context *ctx, long *result, if (ctx->literal_bytes > ctx->block_size) { *result = ctx->literal_bytes - ctx->block_size; ctx->literal_bytes -= *result; - ctx->buffer_start += *result; + /* Advance buffer. */ + if (*result >= buffer_size(ctx)) + ctx->buffer_start = ctx->buffer_end = 0; + else + ctx->buffer_start += *result; } else *result = 0; @@ -206,7 +210,9 @@ size_t crc_read_block(struct crc_context *ctx, long *result, ctx->buffer_end -= ctx->buffer_start; ctx->buffer_start = 0; } - memcpy(ctx->buffer + ctx->buffer_end, buf, len); + + /* Copy len bytes from tail of buffer. */ + memcpy(ctx->buffer + ctx->buffer_end, buf + buflen - len, len); ctx->buffer_end += len; assert(buffer_size(ctx) <= ctx->block_size); } diff --git a/ccan/crcsync/test/run-crash.c b/ccan/crcsync/test/run-crash.c new file mode 100644 index 00000000..c047cce2 --- /dev/null +++ b/ccan/crcsync/test/run-crash.c @@ -0,0 +1,93 @@ +/* This used to crash us on 64-bit; submitted by + Alex Wulms */ +#include "crcsync/crcsync.h" +#include "crcsync/crcsync.c" +#include "tap/tap.h" +#include +#include + +/* FIXME: ccanize. */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +typedef struct { + int block_count; + unsigned int *crcs; +} crc_info_t; + +static void crcblocks(crc_info_t *crc_info, char *data, int datalen, int blocksize) +{ + crc_info->block_count = (datalen+blocksize-1)/blocksize; + crc_info->crcs = malloc(sizeof(unsigned int)*(crc_info->block_count + 1)); + crc_of_blocks(data, datalen, blocksize, 30, crc_info->crcs); +} + +#define BLOCKSIZE 5 + +int main(int argc, char *argv[]) +{ + /* Divided into BLOCKSIZE blocks */ + char *data1 = + "abcde" "fghij" "klmno" "pqrst" "uvwxy" "z ABC" + "DEFGH" "IJKLM" "NOPQR" "STUVW" "XYZ 0" "12345" "6789"; + /* Divided into blocks that match. */ + char *data2 = + /* NO MATCH */ + "acde" + /* MATCH */ + "fghij" "klmno" + /* NO MATCH */ + "pqr-a-very-long-test-that-differs-between-two-invokations-of-the-same-page-st" + /* MATCH */ + "uvwxy" "z ABC" "DEFGH" "IJKLM" "NOPQR" "STUVW" "XYZ 0" "12345" + /* NO MATCH */ + "6789ab"; + + int expected[] = { 4, + -2, -3, + 77, + -5, -6, -7, -8, -9, -10, -11, -12, + 6 }; + crc_info_t crc_info1; + struct crc_context *crcctx; + long result; + size_t ndigested; + size_t offset = 0; + size_t len2 = strlen(data2); + int expected_i = 0; + + plan_tests(ARRAY_SIZE(expected) + 2); + crcblocks(&crc_info1, data1, strlen(data1), BLOCKSIZE); + + crcctx = crc_context_new(BLOCKSIZE, 30, crc_info1.crcs, crc_info1.block_count); + while ( offset < len2) + { + ndigested = crc_read_block(crcctx, &result, data2+offset, len2 - offset); + offset += ndigested; + if (result < 0) + /* Match. */ + ok1(result == expected[expected_i++]); + else { + /* Literal. */ + ok1(result <= expected[expected_i]); + expected[expected_i] -= result; + if (!expected[expected_i]) + expected_i++; + } + } + + while ((result = crc_read_flush(crcctx)) != 0) { + if (result < 0) + /* Match. */ + ok1(result == expected[expected_i++]); + else { + /* Literal. */ + ok1(result <= expected[expected_i]); + expected[expected_i] -= result; + if (!expected[expected_i]) + expected_i++; + } + } + ok1(expected_i == ARRAY_SIZE(expected)); + + return 0; +} -- 2.39.2