blob: 3658e7cea6064d431104e5201edd9f13006e2d18 [file] [log] [blame]
Lev Walkined3a4ae2017-07-07 10:09:51 -07001#include <stdio.h>
2#include <assert.h>
3
Lev Walkine4d8c922017-07-10 20:29:33 -07004#include <asn_codecs.h>
Lev Walkined3a4ae2017-07-07 10:09:51 -07005#include <INTEGER.h>
Lev Walkined3a4ae2017-07-07 10:09:51 -07006
Lev Walkine4d8c922017-07-10 20:29:33 -07007#define CHECK_DECODE(code, a, b, c, d, e, f) check_decode(__LINE__, code, a, b, c, d, e, f)
Lev Walkincc9b3ae2017-07-14 08:57:02 +04008#define CHECK_ROUNDTRIP(a, b, c) check_roundtrip(__LINE__, a, b, c);
9#define CHECK_ENCODE_OK(a, b, c) check_encode(__LINE__, 0, a, b, c)
10#define CHECK_ENCODE_BAD(a, b, c) check_encode(__LINE__, 1, a, b, c);
Lev Walkin54f34512017-07-10 05:27:46 -070011
Lev Walkine4d8c922017-07-10 20:29:33 -070012static const intmax_t NoBound = -4200024;
13
Lev Walkincc9b3ae2017-07-14 08:57:02 +040014static asn_oer_constraints_t *
15setup_constraints(int lineno, const char *process, intmax_t lower_bound,
16 intmax_t upper_bound) {
17 static struct asn_oer_constraints_s empty_constraints;
Lev Walkine4d8c922017-07-10 20:29:33 -070018 struct asn_oer_constraints_s *constraints = &empty_constraints;
19 struct asn_oer_constraint_s *ct_value = &constraints->value;
Lev Walkin54f34512017-07-10 05:27:46 -070020
Lev Walkincc9b3ae2017-07-14 08:57:02 +040021 memset(&empty_constraints, 0, sizeof(empty_constraints));
22
Lev Walkine4d8c922017-07-10 20:29:33 -070023 /* Setup integer constraints as requested */
24 if(lower_bound == NoBound && upper_bound == NoBound) {
Lev Walkincc9b3ae2017-07-14 08:57:02 +040025 fprintf(stderr, "%d: OER %s without constraints\n", lineno,
26 process);
Lev Walkine4d8c922017-07-10 20:29:33 -070027 constraints = NULL;
28 } else {
29 if(lower_bound != NoBound) {
30 ct_value->flags |= AOC_HAS_LOWER_BOUND;
31 ct_value->lower_bound = lower_bound;
32 }
33 if(upper_bound != NoBound) {
34 ct_value->flags |= AOC_HAS_UPPER_BOUND;
35 ct_value->upper_bound = upper_bound;
36 }
Lev Walkincc9b3ae2017-07-14 08:57:02 +040037 if(lower_bound != NoBound && upper_bound != NoBound) {
38 fprintf(stderr,
39 "%d: OER %s constraints %" PRIdMAX
40 "..%" PRIdMAX "\n",
41 lineno, process, lower_bound, upper_bound);
42 } else if(lower_bound != NoBound) {
43 fprintf(stderr,
44 "%d: OER %s constraints %" PRIdMAX
45 "..MAX\n",
46 lineno, process, lower_bound);
47 } else if(upper_bound != NoBound) {
48 fprintf(stderr,
49 "%d: OER %s constraints MIN..%" PRIdMAX "\n",
50 lineno, process, upper_bound);
51 }
Lev Walkine4d8c922017-07-10 20:29:33 -070052 }
53
Lev Walkincc9b3ae2017-07-14 08:57:02 +040054 return constraints;
55}
56
57static void
58check_decode(int lineno, enum asn_dec_rval_code_e code, intmax_t control, const char *buf, size_t size, const char *dummy, intmax_t lower_bound, intmax_t upper_bound) {
59 static char *code_s[] = { "RC_OK", "RC_WMORE", "RC_FAIL", "<error>" };
60
61 fprintf(stderr, "\n%d: OER decode (control %" PRIdMAX ")\n", lineno, control);
62
63 INTEGER_t *st = NULL;
64 asn_dec_rval_t ret;
65 asn_oer_constraints_t *constraints =
66 setup_constraints(lineno, "decoding", lower_bound, upper_bound);
67
68 fprintf(stderr, "%d: buf[%zu]={%d, %d, ...}\n", lineno, size,
69 ((const uint8_t *)buf)[0],
70 ((const uint8_t *)buf)[1]);
71
Lev Walkine4d8c922017-07-10 20:29:33 -070072 (void)dummy;
73
74 ret = asn_DEF_INTEGER.oer_decoder(0, &asn_DEF_INTEGER, constraints,
75 (void **)&st, buf, size);
Lev Walkin54f34512017-07-10 05:27:46 -070076 if(ret.code != RC_OK) {
77 /* Basic OER decode does not work */
78 fprintf(stderr, "%d: Failed oer_decode(ctl=%" PRIdMAX ", size=%zu)\n",
79 lineno, control, size);
Lev Walkine4d8c922017-07-10 20:29:33 -070080 if(ret.code == code) {
81 fprintf(stderr, " (That was expected)\n");
82 return;
83 } else {
84 fprintf(
85 stderr, " Unexpected return code %s (%d) expected %s\n",
86 code_s[(unsigned)ret.code <= RC_FAIL ? RC_FAIL : (RC_FAIL + 1)],
87 (int)ret.code, code_s[code]);
88 assert(ret.code == code);
89 }
Lev Walkin54f34512017-07-10 05:27:46 -070090 } else {
91 intmax_t outcome;
92 if(asn_INTEGER2imax(st, &outcome) != 0) {
93 /* Result of decode is structurally incorrect */
Lev Walkine4d8c922017-07-10 20:29:33 -070094 fprintf(stderr,
95 "%d: Failed to convert INTEGER 2 imax; structurally "
96 "incorrect INTEGER\n",
Lev Walkin54f34512017-07-10 05:27:46 -070097 lineno);
98 assert(!"Unreachable");
99 } else if(outcome != control) {
100 /* Decoded value is wrong */
101 fprintf(stderr,
102 "%d: Decode result %" PRIdMAX " is not expected %" PRIdMAX
103 "\n",
104 lineno, outcome, control);
105 assert(outcome == control);
106 }
107 }
108
109 fprintf(stderr, "%d: Decode result %" PRIdMAX "\n", lineno, control);
Lev Walkined3a4ae2017-07-07 10:09:51 -0700110}
111
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400112static void
113dump_data(int lineno, const uint8_t *buf, size_t size) {
114 const uint8_t *p = buf;
115 const uint8_t *end = buf + size;
116
117 fprintf(stderr, "%d: Encoded: [", lineno);
118
119 for(; p < end; p++) {
120 fprintf(stderr, "\\x%02x", *(const unsigned char *)p);
121 }
122 fprintf(stderr, "] (%zu bytes)\n", size);
123}
Lev Walkin486fd5c2017-07-10 22:08:14 -0700124
125static void
126check_roundtrip(int lineno, intmax_t value, intmax_t lower_bound, intmax_t upper_bound) {
127 uint8_t tmpbuf[32];
128 size_t tmpbuf_size;
129
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400130 fprintf(stderr, "\n%d: OER round-trip value %" PRIdMAX "\n", lineno, value);
131
Lev Walkin486fd5c2017-07-10 22:08:14 -0700132 INTEGER_t *stOut = (INTEGER_t *)calloc(1, sizeof(*stOut));
133 INTEGER_t *stIn = NULL;
134 asn_enc_rval_t er;
135 asn_dec_rval_t ret;
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400136 asn_oer_constraints_t *constraints =
137 setup_constraints(lineno, "encoding", lower_bound, upper_bound);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700138
139 if(asn_imax2INTEGER(stOut, value) == -1) {
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400140 assert(!"Unreachable imax2INTEGER failure");
141 } else {
142 assert(stOut->buf != NULL);
143 assert(stOut->size != 0);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700144 }
145
146 er = oer_encode_to_buffer(&asn_DEF_INTEGER, constraints, stOut, tmpbuf,
147 sizeof(tmpbuf));
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400148 if(er.encoded == -1) {
149 fprintf(stderr, "%d: OER encode failed for %s\n", lineno,
Lev Walkin486fd5c2017-07-10 22:08:14 -0700150 er.failed_type ? er.failed_type->name : "<none>");
151 assert(er.encoded != -1);
152 }
153 tmpbuf_size = er.encoded;
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400154 ASN_STRUCT_FREE(asn_DEF_INTEGER, stOut);
155
156 dump_data(lineno, tmpbuf, tmpbuf_size);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700157
158 ret = asn_DEF_INTEGER.oer_decoder(0, &asn_DEF_INTEGER, constraints,
159 (void **)&stIn, tmpbuf, tmpbuf_size);
160 if(ret.code != RC_OK) {
161 /* Basic OER decode does not work */
162 fprintf(stderr, "%d: Failed oer_decode(value=%" PRIdMAX ", size=%zu)\n",
163 lineno, value, tmpbuf_size);
164 assert(ret.code == 0);
165 } else {
166 intmax_t outcome;
167 if(asn_INTEGER2imax(stIn, &outcome) != 0) {
168 /* Result of decode is structurally incorrect */
169 fprintf(stderr,
170 "%d: Failed to convert INTEGER 2 imax; structurally "
171 "incorrect INTEGER\n",
172 lineno);
173 assert(!"Unreachable");
174 } else if(outcome != value) {
175 /* Decoded value is wrong */
176 fprintf(stderr,
177 "%d: Decode result %" PRIdMAX " is not expected %" PRIdMAX
178 "\n",
179 lineno, outcome, value);
180 assert(outcome == value);
181 }
182 }
183
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400184 ASN_STRUCT_FREE(asn_DEF_INTEGER, stIn);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700185 fprintf(stderr, "%d: Decode result %" PRIdMAX "\n", lineno, value);
186}
187
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400188static void
189check_encode(int lineno, int bad, intmax_t value, intmax_t lower_bound, intmax_t upper_bound) {
190 uint8_t tmpbuf[32];
191
192 fprintf(stderr, "\n%d: OER encode value %" PRIdMAX "\n", lineno, value);
193
194 INTEGER_t *stOut = (INTEGER_t *)calloc(1, sizeof(*stOut));
195 asn_enc_rval_t er;
196 asn_oer_constraints_t *constraints =
197 setup_constraints(lineno, "encoding", lower_bound, upper_bound);
198
199 if(asn_imax2INTEGER(stOut, value) == -1) {
200 assert(!"Unreachable imax2INTEGER failure");
201 } else {
202 assert(stOut->buf != NULL);
203 assert(stOut->size != 0);
204 }
205
206 er = oer_encode_to_buffer(&asn_DEF_INTEGER, constraints, stOut, tmpbuf,
207 sizeof(tmpbuf));
208 if(er.encoded == -1) {
209 fprintf(stderr, "%d: OER encode failed for %s%s\n", lineno,
210 er.failed_type ? er.failed_type->name : "<none>",
211 bad ? " (expected)" : "");
212 if(!bad) {
213 assert(er.encoded != -1);
214 }
215 } else {
216 dump_data(lineno, tmpbuf, er.encoded);
217 if(bad) {
218 assert(er.encoded == -1);
219 }
220 }
221 ASN_STRUCT_FREE(asn_DEF_INTEGER, stOut);
222}
223
Lev Walkined3a4ae2017-07-07 10:09:51 -0700224int
225main() {
Lev Walkine4d8c922017-07-10 20:29:33 -0700226 CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", NoBound, NoBound);
227 CHECK_DECODE(RC_FAIL, 0, "\x00", 1, "bounds=", NoBound, NoBound);
228 CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 0, 0);
229 CHECK_DECODE(RC_WMORE, 0, "", 0, "bounds=", 0, 1);
230 CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", 0, 1);
231 CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", -1, 1);
232
233 CHECK_DECODE(RC_OK, 0, "\x00", 1, "bounds=", -1, 1);
234 CHECK_DECODE(RC_OK, 1, "\x01", 1, "bounds=", -1, 1);
235 CHECK_DECODE(RC_OK, -1, "\xff", 1, "bounds=", -1, 1);
236 CHECK_DECODE(RC_OK, -1, "\xff", 1, "bounds=", -1, 1);
237 CHECK_DECODE(RC_OK, 127, "\x7f", 1, "bounds=", 0, 127);
238 CHECK_DECODE(RC_OK, 255, "\xff", 1, "bounds=", 0, 127);
239 CHECK_DECODE(RC_OK, 255, "\xff", 1, "bounds=", 0, 255);
240 CHECK_DECODE(RC_WMORE, 0, "\xff", 1, "bounds=", 0, 256);
241 CHECK_DECODE(RC_OK, 65535, "\xff\xff", 2, "bounds=", 0, 256);
242
243 CHECK_DECODE(RC_OK, 0, "\x01\x00", 2, "bounds=", NoBound, 1);
244 CHECK_DECODE(RC_OK, 1, "\x01\x01", 2, "bounds=", NoBound, 1);
245 CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", NoBound, 1);
246 CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", NoBound, 1);
247 CHECK_DECODE(RC_OK, -1, "\x1\xff", 2, "bounds=", NoBound, 255);
248 CHECK_DECODE(RC_WMORE, -1, "\x02\x00\xff", 2, "bounds=", NoBound, 200);
249 CHECK_DECODE(RC_OK, 255, "\x02\x00\xff", 3, "bounds=", NoBound, 200);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700250
251 CHECK_ROUNDTRIP(0, NoBound, NoBound);
252 CHECK_ROUNDTRIP(1, NoBound, NoBound);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400253 CHECK_ROUNDTRIP(-1, NoBound, NoBound);
254 CHECK_ROUNDTRIP(-65000, NoBound, NoBound);
255 CHECK_ROUNDTRIP(65000, NoBound, NoBound);
256 CHECK_ROUNDTRIP(65535, NoBound, NoBound);
257 CHECK_ROUNDTRIP(-65535, NoBound, NoBound);
258 CHECK_ROUNDTRIP(-65536, NoBound, NoBound);
259 CHECK_ROUNDTRIP(65536, NoBound, NoBound);
260 CHECK_ROUNDTRIP(0, -128, 127);
Lev Walkin486fd5c2017-07-10 22:08:14 -0700261 CHECK_ROUNDTRIP(1, -128, 127);
Lev Walkincc9b3ae2017-07-14 08:57:02 +0400262 CHECK_ROUNDTRIP(-1, -128, 127);
263 CHECK_ROUNDTRIP(-127, -128, 127);
264 CHECK_ROUNDTRIP(-128, -128, 127);
265 CHECK_ROUNDTRIP(127, -128, 127);
266 CHECK_ROUNDTRIP(1, 32000, 32000); /* Sic! */
267 CHECK_ROUNDTRIP(32000, 0, 32000); /* Sic! */
268 CHECK_ROUNDTRIP(32000, -32000, 32000); /* Sic! */
269 CHECK_ROUNDTRIP(1, 65000, 65000); /* Sic! */
270 CHECK_ROUNDTRIP(65535, 0, 65000); /* Sic! */
271 CHECK_ROUNDTRIP(65535, -65000, 65000); /* Sic! */
272
273 CHECK_ENCODE_OK(0, 0, 255);
274 CHECK_ENCODE_OK(255, 0, 255);
275 CHECK_ENCODE_BAD(256, 0, 255);
276 CHECK_ENCODE_OK(0, -128, 127);
277 CHECK_ENCODE_OK(127, -128, 127);
278 CHECK_ENCODE_OK(-128, -128, 127);
279 CHECK_ENCODE_BAD(-129, -128, 127);
280 CHECK_ENCODE_BAD(128, -128, 127);
281 CHECK_ENCODE_OK(-4900000000, -5000000000, 5000000000);
282 CHECK_ENCODE_OK(4900000000, -5000000000, 5000000000);
283 CHECK_ENCODE_OK(-2000000000, -4000000000, 0);
284 CHECK_ENCODE_OK(-4000000000, -4000000000, 0);
285 CHECK_ENCODE_BAD(-4900000000, 0, 4000000000);
286 CHECK_ENCODE_BAD(-1, 0, 4000000000);
287 CHECK_ENCODE_BAD(4900000000, 0, 4000000000);
288 CHECK_ENCODE_OK(4100000000, 0, 4000000000); /* Sic! */
289
290 for(size_t i = 0; i < 7 ; i++) {
291 intmax_t value = (intmax_t)1 << i;
292 CHECK_ROUNDTRIP(value, 0, 255);
293 value = -value;
294 CHECK_ROUNDTRIP(value, -128, 127);
295 }
296
297 for(size_t i = 0; i < 16 ; i++) {
298 intmax_t value = (intmax_t)1 << i;
299 CHECK_ROUNDTRIP(value, 0, 65535);
300 value = -value;
301 CHECK_ROUNDTRIP(value, -32768, 32767);
302 }
303
304 for(size_t i = 0; i < 32 ; i++) {
305 intmax_t value = (intmax_t)1 << i;
306 CHECK_ROUNDTRIP(value, 0, 4294967296UL);
307 value = -value;
308 CHECK_ROUNDTRIP(value, -2147483648L, 2147483647L);
309 }
310
311 for(size_t i = 0; i < 8 * sizeof(intmax_t) ; i++) {
312 intmax_t value = (intmax_t)1 << i;
313 CHECK_ROUNDTRIP(value, NoBound, NoBound);
314 value = -value;
315 CHECK_ROUNDTRIP(value, NoBound, NoBound);
316 }
Lev Walkin486fd5c2017-07-10 22:08:14 -0700317
Lev Walkined3a4ae2017-07-07 10:09:51 -0700318}