blob: 38c3580fa2a32164e6b6779e3f181511aa534b4b [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#undef NDEBUG
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <string.h>
6#include <assert.h>
7
8#include <T.h>
9
10uint8_t buf1[] = {
11 32 | 16, /* [UNIVERSAL 16], constructed */
12 128, /* L */
13 /* a INTEGER */
14 2, /* [UNIVERSAL 2] */
15 2, /* L */
16 150,
17 70,
Lev Walkin188ed2c2004-09-13 08:31:01 +000018 /* b [2] IMPLICIT BOOLEAN */
Lev Walkinf15320b2004-06-03 03:38:44 +000019 128 | 2, /* [2] */
20 1, /* L */
21 0xff,
22 /* c NULL */
23 5, /* [UNIVERSAL 5] */
24 0, /* L */
25 /* d ENUMERATED */
26 10, /* [UNIVERSAL 10] */
27 1, /* L */
28 222,
Lev Walkin188ed2c2004-09-13 08:31:01 +000029 /* e OCTET STRING */
Lev Walkinf15320b2004-06-03 03:38:44 +000030 4, /* [UNIVERSAL 4] */
31 3, /* L */
32 'x',
33 'y',
34 'z',
Lev Walkin188ed2c2004-09-13 08:31:01 +000035 /*
36 * X.690 specifies that inner structures must be tagged by
37 * stripping off the outer tag for each subsequent level.
38 */
39 /* f [5] IMPLICIT VisibleString */
40 128 | 32 | 5, /* [5], constructed */
Lev Walkinf15320b2004-06-03 03:38:44 +000041 128, /* L indefinite */
Lev Walkin188ed2c2004-09-13 08:31:01 +000042 26, /* [UNIVERSAL 26] (VisibleString), primitive */
Lev Walkinf15320b2004-06-03 03:38:44 +000043 2,
44 'l',
45 'o',
Lev Walkin188ed2c2004-09-13 08:31:01 +000046 32 | 26, /* [UNIVERSAL 26], recursively constructed */
Lev Walkinf15320b2004-06-03 03:38:44 +000047 128,
Lev Walkin188ed2c2004-09-13 08:31:01 +000048 4, /* [UNIVERSAL 4] (OCTET STRING), primitive */
Lev Walkinf15320b2004-06-03 03:38:44 +000049 1,
50 'v',
Lev Walkin188ed2c2004-09-13 08:31:01 +000051 4, /* [UNIVERSAL 4], primitive */
Lev Walkinf15320b2004-06-03 03:38:44 +000052 2,
53 'e',
54 '_',
55 0,
56 0,
Lev Walkin188ed2c2004-09-13 08:31:01 +000057 26, /* [UNIVERSAL 26], primitive */
Lev Walkinf15320b2004-06-03 03:38:44 +000058 2,
59 'i',
60 't',
61 0,
62 0,
63 /* g BIT STRING */
64 3, /* [UNIVERSAL 3], primitive */
65 3, /* L */
66 2, /* Skip 2 bits */
67 147,
68 150, /* => 148 */
Lev Walkin188ed2c2004-09-13 08:31:01 +000069 /* h [7] BIT STRING */
70 128 | 32 | 7, /* [7], constructed */
Lev Walkinf15320b2004-06-03 03:38:44 +000071 128, /* L indefinite */
72 3, /* [UNIVERSAL 3], primitive */
73 3, /* L */
74 0, /* Skip 0 bits */
75 140,
76 141,
77 3, /* [UNIVERSAL 3], primitive */
78 2, /* L */
79 1, /* Skip 1 bit */
80 143, /* => 142 */
Lev Walkin188ed2c2004-09-13 08:31:01 +000081 0, /* End of h */
Lev Walkinf15320b2004-06-03 03:38:44 +000082 0,
83 0, /* End of the whole structure */
84 0,
85 /* Three bytes of planned leftover */
86 111, 222, 223
87};
88
89static void
Lev Walkind9bd7752004-06-05 08:17:50 +000090check(int is_ok, uint8_t *buf, int size, size_t consumed) {
Lev Walkinf15320b2004-06-03 03:38:44 +000091 T_t t, *tp;
Lev Walkin90bf7ae2004-10-20 15:46:56 +000092 asn_dec_rval_t rval;
Lev Walkinf15320b2004-06-03 03:38:44 +000093
94 tp = memset(&t, 0, sizeof(t));
95
96 fprintf(stderr, "Buf %p (%d)\n", buf, (int)size);
Lev Walkinc7400c52004-09-29 13:14:36 +000097 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
Lev Walkinf15320b2004-06-03 03:38:44 +000098 fprintf(stderr, "Returned code %d, consumed %d, expected %d\n",
99 (int)rval.code, (int)rval.consumed, (int)consumed);
100
101 if(is_ok) {
102 assert(rval.code == RC_OK);
103 assert(rval.consumed == consumed);
104
Lev Walkin59b176e2005-11-26 11:25:14 +0000105 assert(strcmp((char *)t.e->buf, "xyz") == 0);
106 assert(strcmp((char *)t.f->buf, "love_it") == 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000107
Lev Walkinbbd93252004-10-12 05:57:23 +0000108 assert(t.g->size == 2);
109 assert(t.g->bits_unused == 2);
Lev Walkine7727d52005-02-25 12:16:59 +0000110 fprintf(stderr, "%d %d\n", t.g->buf[0], t.g->buf[1]);
Lev Walkinbbd93252004-10-12 05:57:23 +0000111 assert(t.g->buf[0] == 147);
112 assert(t.g->buf[1] != 150);
113 assert(t.g->buf[1] == 148);
Lev Walkinf15320b2004-06-03 03:38:44 +0000114
Lev Walkinbbd93252004-10-12 05:57:23 +0000115 assert(t.h->size == 3);
116 assert(t.h->bits_unused == 1);
117 assert(t.h->buf[0] == 140);
118 assert(t.h->buf[1] == 141);
119 assert(t.h->buf[2] == 142);
Lev Walkinf15320b2004-06-03 03:38:44 +0000120 } else {
121 if(rval.code == RC_OK) {
122 assert(t.a.size != 2
123 || !t.d
124 || t.d->size != 1
125 || !t.e
126 || t.e->size != 3
127 || !t.f
128 || t.f->size != 7
129 || !t.g
Lev Walkinbbd93252004-10-12 05:57:23 +0000130 || t.g->size != 2
Lev Walkinf15320b2004-06-03 03:38:44 +0000131 || !t.h
Lev Walkinbbd93252004-10-12 05:57:23 +0000132 || t.h->size != 3
Lev Walkinf15320b2004-06-03 03:38:44 +0000133 );
134 }
135 fprintf(stderr, "%d %d\n", (int)rval.consumed, (int)consumed);
136 assert(rval.consumed <= consumed);
137 }
138
Lev Walkinc7400c52004-09-29 13:14:36 +0000139 asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000140}
141
142static void
143try_corrupt(uint8_t *buf, int size, int allow_consume) {
144 uint8_t *tmp;
145 int i;
146
147 fprintf(stderr, "\nCorrupting...\n");
148
149 tmp = alloca(size);
150
151 for(i = 0; i < 1000; i++) {
152 int loc;
153 memcpy(tmp, buf, size);
154
155 /* Corrupt random _non-value_ location. */
156 do { loc = random() % size; } while(
157 loc == 44 /* bit skips */
158 || loc == 51 /* bit skips */
159 || loc == 56 /* bit skips */
160 || tmp[loc] >= 70);
161 do { tmp[loc] = buf[loc] ^ random(); } while(
162 (tmp[loc] == buf[loc])
163 || (buf[loc] == 0 && tmp[loc] == 0x80));
164
165 fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
166 i, loc, buf[loc], tmp[loc]);
167
168 check(0, tmp, size, allow_consume);
169 }
170}
171
172static void
Lev Walkind9bd7752004-06-05 08:17:50 +0000173partial_read(uint8_t *buf, size_t size) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000174 T_t t, *tp;
Lev Walkin90bf7ae2004-10-20 15:46:56 +0000175 asn_dec_rval_t rval;
Lev Walkind9bd7752004-06-05 08:17:50 +0000176 size_t i1, i2;
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000177 uint8_t *tbuf1 = alloca(size);
178 uint8_t *tbuf2 = alloca(size);
179 uint8_t *tbuf3 = alloca(size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000180
181 fprintf(stderr, "\nPartial read sequence...\n");
182
183 /*
184 * Divide the space (size) into three blocks in various combinations:
185 * |<----->i1<----->i2<----->|
186 * ^ buf ^ buf+size
187 * Try to read block by block.
188 */
189 for(i1 = 0; i1 < size; i1++) {
190 for(i2 = i1; i2 < size; i2++) {
191 uint8_t *chunk1 = buf;
Lev Walkind9bd7752004-06-05 08:17:50 +0000192 size_t size1 = i1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000193 uint8_t *chunk2 = buf + size1;
Lev Walkind9bd7752004-06-05 08:17:50 +0000194 size_t size2 = i2 - i1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000195 uint8_t *chunk3 = buf + size1 + size2;
Lev Walkind9bd7752004-06-05 08:17:50 +0000196 size_t size3 = size - size1 - size2;
Lev Walkinf15320b2004-06-03 03:38:44 +0000197
198 fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000199 (int)size, (int)size1, (int)size2, (int)size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000200
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000201 memset(tbuf1, 0, size);
202 memset(tbuf2, 0, size);
203 memset(tbuf3, 0, size);
204 memcpy(tbuf1, chunk1, size1);
205 memcpy(tbuf2, chunk2, size2);
206 memcpy(tbuf3, chunk3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000207
208 tp = memset(&t, 0, sizeof(t));
209
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000210 fprintf(stderr, "=> Chunk 1 (%d):\n", (int)size1);
Lev Walkinc7400c52004-09-29 13:14:36 +0000211 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000212 tbuf1, size1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000213 assert(rval.code == RC_WMORE);
214 assert(rval.consumed <= size1);
215 if(rval.consumed < size1) {
216 int leftover = size1 - rval.consumed;
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000217 memcpy(tbuf2, tbuf1 + rval.consumed, leftover);
218 memcpy(tbuf2 + leftover, chunk2, size2);
Lev Walkinf15320b2004-06-03 03:38:44 +0000219 size2 += leftover;
220 }
221
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000222 fprintf(stderr, "=> Chunk 2 (%d):\n", (int)size2);
Lev Walkinc7400c52004-09-29 13:14:36 +0000223 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000224 tbuf2, size2);
Lev Walkinf15320b2004-06-03 03:38:44 +0000225 assert(rval.code == RC_WMORE);
226 assert(rval.consumed <= size2);
227 if(rval.consumed < size2) {
228 int leftover = size2 - rval.consumed;
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000229 memcpy(tbuf3, tbuf2 + rval.consumed, leftover);
230 memcpy(tbuf3 + leftover, chunk3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000231 size3 += leftover;
232 }
233
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000234 fprintf(stderr, "=> Chunk 3 (%d):\n", (int)size3);
Lev Walkinc7400c52004-09-29 13:14:36 +0000235 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000236 tbuf3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000237 assert(rval.code == RC_OK);
238 assert(rval.consumed == size3);
239
Lev Walkinc7400c52004-09-29 13:14:36 +0000240 asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000241 }
242 }
243}
244
245int
246main(int ac, char **av) {
247
Lev Walkind9bd7752004-06-05 08:17:50 +0000248 (void)ac; /* Unused argument */
249 (void)av; /* Unused argument */
250
Lev Walkinf15320b2004-06-03 03:38:44 +0000251 /* Check that the full buffer may be decoded normally */
252 check(1, buf1, sizeof(buf1), sizeof(buf1) - 3);
253
254 /* Check that some types of buffer corruptions will lead to failure */
255 try_corrupt(buf1, sizeof(buf1) - 3, sizeof(buf1) - 3);
256
257 /* Split the buffer in parts and check decoder restartability */
258 partial_read(buf1, sizeof(buf1) - 3);
259
260 return 0;
261}