New test and fixes to crcsync.
[ccan] / ccan / crcsync / test / run-crash.c
1 /* This used to crash us on 64-bit; submitted by
2    Alex Wulms <alex.wulms@scarlet.be> */
3 #include "crcsync/crcsync.h"
4 #include "crcsync/crcsync.c"
5 #include "tap/tap.h"
6 #include <stdlib.h>
7 #include <stdbool.h>
8
9 /* FIXME: ccanize. */
10 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
11
12 typedef struct {
13         int block_count;
14         unsigned int *crcs;
15 } crc_info_t;
16
17 static void crcblocks(crc_info_t *crc_info, char *data, int datalen, int blocksize)
18 {
19         crc_info->block_count = (datalen+blocksize-1)/blocksize;
20         crc_info->crcs = malloc(sizeof(unsigned int)*(crc_info->block_count + 1));
21         crc_of_blocks(data, datalen, blocksize, 30, crc_info->crcs);
22 }
23
24 #define BLOCKSIZE 5
25
26 int main(int argc, char *argv[])
27 {
28         /* Divided into BLOCKSIZE blocks */
29         char *data1 =
30                 "abcde" "fghij" "klmno" "pqrst" "uvwxy" "z ABC"
31                 "DEFGH" "IJKLM" "NOPQR" "STUVW" "XYZ 0" "12345" "6789";
32         /* Divided into blocks that match. */
33         char *data2 =
34                 /* NO MATCH */
35                 "acde"
36                 /* MATCH */
37                 "fghij" "klmno" 
38                 /* NO MATCH */
39                 "pqr-a-very-long-test-that-differs-between-two-invokations-of-the-same-page-st"
40                 /* MATCH */
41                 "uvwxy" "z ABC" "DEFGH" "IJKLM" "NOPQR" "STUVW" "XYZ 0" "12345"
42                 /* NO MATCH */
43                 "6789ab";
44
45         int expected[] = { 4,
46                            -2, -3,
47                            77,
48                            -5, -6, -7, -8, -9, -10, -11, -12,
49                            6 };
50         crc_info_t crc_info1;
51         struct crc_context *crcctx;
52         long result;
53         size_t ndigested;
54         size_t offset = 0;
55         size_t len2 = strlen(data2);
56         int expected_i = 0;
57
58         plan_tests(ARRAY_SIZE(expected) + 2);
59         crcblocks(&crc_info1, data1, strlen(data1), BLOCKSIZE);
60
61         crcctx = crc_context_new(BLOCKSIZE, 30, crc_info1.crcs, crc_info1.block_count);
62         while ( offset < len2)
63         {
64                 ndigested = crc_read_block(crcctx, &result, data2+offset, len2 - offset);
65                 offset += ndigested;
66                 if (result < 0)
67                         /* Match. */
68                         ok1(result == expected[expected_i++]);
69                 else {
70                         /* Literal. */
71                         ok1(result <= expected[expected_i]);
72                         expected[expected_i] -= result;
73                         if (!expected[expected_i])
74                                 expected_i++;
75                 }
76         }
77
78         while ((result = crc_read_flush(crcctx)) != 0) {
79                 if (result < 0)
80                         /* Match. */
81                         ok1(result == expected[expected_i++]);
82                 else {
83                         /* Literal. */
84                         ok1(result <= expected[expected_i]);
85                         expected[expected_i] -= result;
86                         if (!expected[expected_i])
87                                 expected_i++;
88                 }
89         }
90         ok1(expected_i == ARRAY_SIZE(expected));
91         
92         return 0;
93 }