1 /*
2 * %CopyrightBegin%
3 *
4 * Copyright Ericsson AB 2004-2020. All Rights Reserved.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * %CopyrightEnd%
19 */
20
21 #include <string.h>
22 #include <stdlib.h>
23
24 #include "ei_runner.h"
25
26 /*
27 * Purpose: Tests the ei_format() function.
28 * Author: Kent
29 */
30
31 #define MESSAGE_BACK(SIZE) \
32 message("err = %d, size2 = %d, expected size = %d, long long val = %lld", \
33 err, size1, SIZE, (EI_LONGLONG)p)
34
35 #define ERLANG_ANY (ERLANG_ASCII|ERLANG_LATIN1|ERLANG_UTF8)
36
37 struct my_atom {
38 erlang_char_encoding from;
39 erlang_char_encoding was_check;
40 erlang_char_encoding result_check;
41 };
42
43 /* Allow arrays constants to be part of macro arguments */
44 #define P99(...) __VA_ARGS__
45
46 int ei_decode_my_atom_as(const char *buf, int *index, char *to,
47 struct my_atom *atom);
48 int ei_decode_my_atom(const char *buf, int *index, char *to,
49 struct my_atom *atom);
50 int ei_decode_my_string(const char *buf, int *index, char *to,
51 struct my_atom *atom);
52
53 #define EI_DECODE_2(FUNC,SIZE,TYPE,VAL) \
54 { \
55 TYPE p; \
56 char *buf; \
57 int size1 = 0; \
58 int size2 = 0; \
59 int err; \
60 message("ei_" #FUNC " " #TYPE " should be " #VAL); \
61 buf = read_packet(NULL); \
62 \
63 err = ei_ ## FUNC(buf+1, &size1, NULL); \
64 message("err = %d, size1 = %d, expected size = %d", \
65 err, size1, SIZE); \
66 if (err != 0) { \
67 if (err != -1) { \
68 fail("returned non zero but not -1 if NULL pointer"); \
69 } else { \
70 fail("returned non zero if NULL pointer"); \
71 } \
72 return; \
73 } \
74 \
75 err = ei_ ## FUNC(buf+1, &size2, &p); \
76 MESSAGE_BACK(SIZE); \
77 if (err != 0) { \
78 if (err != -1) { \
79 fail("returned non zero but not -1"); \
80 } else { \
81 fail("returned non zero"); \
82 } \
83 return; \
84 } \
85 if (p != (TYPE)VAL) { \
86 fail("value is not correct"); \
87 return; \
88 } \
89 \
90 if (size1 != size2) { \
91 fail("size with and without pointer differs"); \
92 return; \
93 } \
94 \
95 if (size1 != SIZE) { \
96 fail1("size of encoded data (%d) is incorrect", size1); \
97 return; \
98 } \
99 free_packet(buf); \
100 } \
101
102 #define EI_DECODE_2_FAIL(FUNC,SIZE,TYPE,VAL) \
103 { \
104 TYPE p, saved_p; \
105 char *buf; \
106 int size1 = 0; \
107 int size2 = 0; \
108 int err; \
109 message("ei_" #FUNC " " #TYPE " should fail"); \
110 memset(&p,'\0',sizeof(p)); \
111 saved_p = p; \
112 buf = read_packet(NULL); \
113 \
114 err = ei_ ## FUNC(buf+1, &size1, NULL); \
115 message("err = %d, size1 = %d, expected size = %d", \
116 err, size1, SIZE); \
117 if (err != -1) { \
118 fail("should return -1 if NULL pointer"); \
119 return; \
120 } \
121 \
122 err = ei_ ## FUNC(buf+1, &size2, &p); \
123 message("err = %d, size2 = %d, expected size = %d", \
124 err, size1, SIZE); \
125 if (err != -1) { \
126 fail("should return -1"); \
127 return; \
128 } \
129 if (p != saved_p) { \
130 fail("p argument was modified"); \
131 return; \
132 } \
133 \
134 if (size1 != 0) { \
135 fail("size of encoded data should be 0 if NULL"); \
136 return; \
137 } \
138 \
139 if (size2 != 0) { \
140 fail("size of encoded data should be 0"); \
141 return; \
142 } \
143 free_packet(buf); \
144 } \
145
146 #define dump(arr, num) { \
147 int i; \
148 message("Dumping " #arr ": "); \
149 for (i = 0; i < num; i++) message("%u, ",(unsigned char)arr[i]); \
150 message("\n"); \
151 }
152
153 #define EI_DECODE_STRING_4(FUNC,SIZE,VAL,ATOM) \
154 { \
155 char p[1024]; \
156 char *buf; \
157 unsigned char val[] = VAL; \
158 int size1 = 0; \
159 int size2 = 0; \
160 int err; \
161 struct my_atom atom = ATOM; \
162 message("ei_" #FUNC " should be " #VAL "\n"); \
163 buf = read_packet(NULL); \
164 \
165 err = ei_ ## FUNC(buf+1, &size1, NULL, &atom); \
166 message("err = %d, size = %d, expected size = %d\n",err,size1,SIZE); \
167 if (err != 0) { \
168 if (err != -1) { \
169 fail("returned non zero but not -1 if NULL pointer"); \
170 } else { \
171 fail("returned non zero if NULL pointer"); \
172 } \
173 return; \
174 } \
175 \
176 err = ei_ ## FUNC(buf+1, &size2, p, &atom); \
177 message("err = %d, size = %d, expected size = %d\n",err,size2,SIZE); \
178 if (err != 0) { \
179 if (err != -1) { \
180 fail("returned non zero but not -1"); \
181 } else { \
182 fail("returned non zero"); \
183 } \
184 return; \
185 } \
186 \
187 if (strcmp(p,val) != 0) { \
188 fail("value is not correct"); \
189 return; \
190 } \
191 \
192 if (size1 != size2) { \
193 fail("size with and without pointer differs"); \
194 return; \
195 } \
196 \
197 if (size1 != SIZE) { \
198 fail("size of encoded data is incorrect"); \
199 return; \
200 } \
201 free_packet(buf); \
202 } \
203
204 #define EI_DECODE_STRING(FUNC,SIZE,VAL) \
205 EI_DECODE_STRING_4(FUNC,SIZE,VAL, \
206 P99({ERLANG_ANY,ERLANG_ANY,ERLANG_ANY}))
207
208 #define EI_DECODE_STRING_FAIL(FUNC,ATOM) \
209 { \
210 char p[1024]; \
211 char *buf; \
212 int size1 = 0; \
213 int size2 = 0; \
214 int err; \
215 struct my_atom atom = ATOM;\
216 message("ei_" #FUNC " should fail\n"); \
217 p[0] = 0; \
218 message("p[0] is %d\n",p[0]); \
219 buf = read_packet(NULL); \
220 \
221 err = ei_ ## FUNC(buf+1, &size1, NULL, &atom); \
222 if (err != -1) { \
223 fail("should return -1 if NULL pointer"); \
224 return; \
225 } \
226 \
227 err = ei_ ## FUNC(buf+1, &size2, p, &atom); \
228 if (err != -1) { \
229 fail("should return -1"); \
230 return; \
231 } \
232 if (p[0] != 0) { \
233 message("p[0] argument was modified to %u\n",(unsigned char)p[0]); \
234 } \
235 \
236 if (size1 != 0) { \
237 fail("size of encoded data should be 0 if NULL"); \
238 return; \
239 } \
240 \
241 if (size2 != 0) { \
242 fail("size of encoded data should be 0"); \
243 return; \
244 } \
245 free_packet(buf); \
246 } \
247
248 //#define EI_DECODE_UTF8_STRING(FUNC,SIZE,VAL)
249
decode_double(double VAL)250 static void decode_double(double VAL)
251 {
252 const int SIZE = 9;
253 double p;
254 char *buf;
255 int size1 = 0;
256 int size2 = 0;
257 int err;
258 message("ei_decode_double value should be %lf", VAL);
259 buf = read_packet(NULL);
260
261 {
262 int ix = size1, type = -1, len = -2;
263 if (ei_get_type(buf+1, &ix, &type, &len) != 0
264 || ix != size1 || type != ERL_FLOAT_EXT || len != 0) {
265 fail2("ei_get_type failed for double, type=%d, len=%d", type, len);
266 }
267 }
268
269 err = ei_decode_double(buf+1, &size1, NULL);
270 message("err = %d, size1 = %d, expected size = %d",
271 err, size1, SIZE);
272 if (err != 0) {
273 if (err != -1) {
274 fail("returned non zero but not -1 if NULL pointer");
275 } else {
276 fail("returned non zero if NULL pointer");
277 }
278 return;
279 }
280
281 err = ei_decode_double(buf+1, &size2, &p);
282 MESSAGE_BACK(SIZE);
283 if (err != 0) {
284 if (err != -1) {
285 fail("returned non zero but not -1");
286 } else {
287 fail("returned non zero");
288 }
289 return;
290 }
291 if (p != VAL) {
292 fail("value is not correct");
293 return;
294 }
295
296 if (size1 != size2) {
297 fail("size with and without pointer differs");
298 return;
299 }
300
301 if (size1 != SIZE) {
302 fail1("size of encoded data (%d) is incorrect", size1);
303 return;
304 }
305 free_packet(buf);
306 }
307
decode_bin(int exp_size,const char * val,int exp_len)308 static void decode_bin(int exp_size, const char* val, int exp_len)
309 {
310 char p[1024];
311 char *buf;
312 long len;
313 int size1 = 0;
314 int size2 = 0;
315 int err;
316 message("ei_decode_binary should be %s", val);
317 buf = read_packet(NULL);
318 err = ei_decode_binary(buf+1, &size1, NULL, &len);
319 message("err = %d, size = %d, len = %d, expected size = %d, expected len = %d\n",\
320 err,size1,len, exp_size, exp_len);
321 if (err != 0) {
322 if (err != -1) {
323 fail("returned non zero but not -1 if NULL pointer");
324 } else {
325 fail("returned non zero");
326 }
327 return;
328 }
329
330 if (len != exp_len) {
331 fail("size is not correct");
332 return;
333 }
334
335 err = ei_decode_binary(buf+1, &size2, p, &len);
336 message("err = %d, size = %d, len = %d, expected size = %d, expected len = %d\n",\
337 err,size2,len, exp_size, exp_len);
338 if (err != 0) {
339 if (err != -1) {
340 fail("returned non zero but not -1 if NULL pointer");
341 } else {
342 fail("returned non zero");
343 }
344 return;
345 }
346
347 if (len != exp_len) {
348 fail("size is not correct");
349 return;
350 }
351
352 if (strncmp(p,val,exp_len) != 0) {
353 fail("value is not correct");
354 return;
355 }
356
357 if (size1 != size2) {
358 fail("size with and without pointer differs");
359 return;
360 }
361
362 if (size1 != exp_size) {
363 fail("size of encoded data is incorrect");
364 return;
365 }
366 free_packet(buf);
367 }
368
decode_bits(int exp_size,const char * val,size_t exp_bits)369 static void decode_bits(int exp_size, const char* val, size_t exp_bits)
370 {
371 const char* p;
372 char *buf;
373 size_t bits;
374 int bitoffs;
375 int size1 = 0;
376 int size2 = 0;
377 int err;
378 message("ei_decode_bitstring should be %d bits", (int)exp_bits);
379 buf = read_packet(NULL);
380 err = ei_decode_bitstring(buf+1, &size1, NULL, &bitoffs, &bits);
381 message("err = %d, size = %d, bitoffs = %d, bits = %d, expected size = %d, expected bits = %d\n",\
382 err,size1, bitoffs, (int)bits, exp_size, (int)exp_bits);
383
384 if (err != 0) {
385 if (err != -1) {
386 fail("returned non zero but not -1 if NULL pointer");
387 } else {
388 fail("returned non zero");
389 }
390 return;
391 }
392
393 if (bits != exp_bits) {
394 fail("number of bits is not correct");
395 return;
396 }
397 if (bitoffs != 0) {
398 fail("non zero bit offset");
399 return;
400 }
401
402 err = ei_decode_bitstring(buf+1, &size2, &p, NULL, &bits);
403 message("err = %d, size = %d, len = %d, expected size = %d, expected len = %d\n",\
404 err,size2, (int)bits, exp_size, (int)exp_bits);
405 if (err != 0) {
406 if (err != -1) {
407 fail("returned non zero but not -1 if NULL pointer");
408 } else {
409 fail("returned non zero");
410 }
411 return;
412 }
413
414 if (bits != exp_bits) {
415 fail("bits is not correct");
416 return;
417 }
418
419 if (memcmp(p, val, (exp_bits+7)/8) != 0) {
420 fail("value is not correct");
421 return;
422 }
423
424 if (size1 != size2) {
425 fail("size with and without pointer differs");
426 return;
427 }
428
429 if (size1 != exp_size) {
430 fail2("size of encoded data is incorrect %d != %d", size1, exp_size);
431 return;
432 }
433 free_packet(buf);
434 }
435
436
437 /* ******************************************************************** */
438
TESTCASE(test_ei_decode_long)439 TESTCASE(test_ei_decode_long)
440 {
441 ei_init();
442
443 EI_DECODE_2 (decode_long, 2, long, 0);
444 EI_DECODE_2 (decode_long, 2, long, 255);
445 EI_DECODE_2 (decode_long, 5, long, 256);
446 EI_DECODE_2 (decode_long, 5, long, -1);
447
448 /* Old 28 bit limits for INTEGER_EXT */
449 EI_DECODE_2 (decode_long, 5, long, 0x07ffffff);
450 EI_DECODE_2 (decode_long, 5, long, -0x08000000);
451 EI_DECODE_2 (decode_long, 5, long, 0x08000000);
452 EI_DECODE_2 (decode_long, 5, long, -0x08000001);
453
454 /* New 32 bit limits for INTEGER_EXT */
455 EI_DECODE_2 (decode_long, 5, long, 0x7fffffff);
456 EI_DECODE_2 (decode_long, 5, long, -ll(0x80000000)); /* Strange :-( */
457 if (sizeof(long) > 4) {
458 EI_DECODE_2(decode_long, 7, long, 0x80000000);
459 EI_DECODE_2(decode_long, 7, long, -ll(0x80000001));
460 }
461 else {
462 EI_DECODE_2_FAIL(decode_long, 7, long, 0x80000000);
463 EI_DECODE_2_FAIL(decode_long, 7, long, -ll(0x80000001));
464 }
465
466 EI_DECODE_2_FAIL(decode_long, 7, long, 0x80000000);
467 EI_DECODE_2_FAIL(decode_long, 7, long, 0xffffffff);
468
469 EI_DECODE_2_FAIL(decode_long, 9, long, ll(0x7fffffffffff));
470 EI_DECODE_2_FAIL(decode_long, 9, long, -ll(0x800000000000));
471 EI_DECODE_2_FAIL(decode_long, 9, long, ll(0xffffffffffff));
472 EI_DECODE_2_FAIL(decode_long, 11, long, ll(0x7fffffffffffffff));
473 EI_DECODE_2_FAIL(decode_long, 11, long, -ll(0x8000000000000000));
474 EI_DECODE_2_FAIL(decode_long, 11, long, ll(0xffffffffffffffff));
475
476 EI_DECODE_2_FAIL(decode_long, 1, long, 0); /* Illegal type sent */
477
478 report(1);
479 }
480
481 /* ******************************************************************** */
482
TESTCASE(test_ei_decode_ulong)483 TESTCASE(test_ei_decode_ulong)
484 {
485 ei_init();
486
487 EI_DECODE_2 (decode_ulong, 2, unsigned long, 0);
488 EI_DECODE_2 (decode_ulong, 2, unsigned long, 255);
489 EI_DECODE_2 (decode_ulong, 5, unsigned long, 256);
490 EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -1);
491
492 EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x07ffffff);
493 EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -0x08000000);
494 EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x08000000);
495 EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -0x08000001);
496
497 EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x7fffffff);
498 EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -ll(0x80000000));
499 EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x80000000);
500 EI_DECODE_2_FAIL(decode_ulong, 7, unsigned long, -ll(0x80000001));
501
502 if (sizeof(long) > 4) {
503 EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0x8000000000000000));
504 EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0xffffffffffffffff));
505 } else {
506 if (sizeof(void*) > 4) {
507 /* Windows */
508 EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0x8000000000000000));
509 EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0xffffffffffffffff));
510 } else {
511 EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x80000000);
512 EI_DECODE_2 (decode_ulong, 7, unsigned long, 0xffffffff);
513 }
514 }
515
516 EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, ll(0x7fffffffffff));
517 EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, -ll(0x800000000000));
518 EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, ll(0xffffffffffff));
519 EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0x7fffffffffffffff));
520 EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, -ll(0x8000000000000000));
521 EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0xffffffffffffffff));
522
523 EI_DECODE_2_FAIL(decode_ulong, 1, unsigned long, 0); /* Illegal type */
524
525 report(1);
526 }
527
528 /* ******************************************************************** */
529
530
TESTCASE(test_ei_decode_longlong)531 TESTCASE(test_ei_decode_longlong)
532 {
533 ei_init();
534
535 EI_DECODE_2 (decode_longlong, 2, EI_LONGLONG, 0);
536 EI_DECODE_2 (decode_longlong, 2, EI_LONGLONG, 255);
537 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 256);
538 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -1);
539
540 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x07ffffff);
541 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -0x08000000);
542 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x08000000);
543 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -0x08000001);
544
545 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x7fffffff);
546 EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -ll(0x80000000));
547 EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x80000000);
548 EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, -ll(0x80000001));
549
550 EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0xffffffff);
551
552 EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, ll(0x7fffffffffff));
553 EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, -ll(0x800000000000));
554 EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, ll(0xffffffffffff));
555 EI_DECODE_2 (decode_longlong, 11, EI_LONGLONG, ll(0x7fffffffffffffff));
556 EI_DECODE_2 (decode_longlong, 11, EI_LONGLONG, -ll(0x8000000000000000));
557 EI_DECODE_2_FAIL(decode_longlong, 11, EI_LONGLONG, ll(0xffffffffffffffff));
558
559 EI_DECODE_2_FAIL(decode_longlong, 1, EI_LONGLONG, 0); /* Illegal type */
560 report(1);
561 }
562
563 /* ******************************************************************** */
564
TESTCASE(test_ei_decode_ulonglong)565 TESTCASE(test_ei_decode_ulonglong)
566 {
567 ei_init();
568
569 EI_DECODE_2 (decode_ulonglong, 2, EI_ULONGLONG, 0);
570 EI_DECODE_2 (decode_ulonglong, 2, EI_ULONGLONG, 255);
571 EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 256);
572 EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -1);
573
574 EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x07ffffff);
575 EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -0x08000000);
576 EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x08000000);
577 EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -0x08000001);
578
579 EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x7fffffff);
580 EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -ll(0x80000000));
581 EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x80000000);
582 EI_DECODE_2_FAIL(decode_ulonglong, 7, EI_ULONGLONG, -0x80000001);
583
584 EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0xffffffff);
585
586 EI_DECODE_2 (decode_ulonglong, 9, EI_ULONGLONG, ll(0x7fffffffffff));
587 EI_DECODE_2_FAIL(decode_ulonglong, 9, EI_ULONGLONG, -ll(0x800000000000));
588 EI_DECODE_2 (decode_ulonglong, 9, EI_ULONGLONG, ll(0xffffffffffff));
589 EI_DECODE_2 (decode_ulonglong,11, EI_ULONGLONG, ll(0x7fffffffffffffff));
590 EI_DECODE_2_FAIL(decode_ulonglong,11, EI_ULONGLONG, -ll(0x8000000000000000));
591 EI_DECODE_2 (decode_ulonglong,11, EI_ULONGLONG, ll(0xffffffffffffffff));
592
593 EI_DECODE_2_FAIL(decode_ulonglong, 1, EI_ULONGLONG, 0); /* Illegal type */
594 report(1);
595 }
596
597
598 /* ******************************************************************** */
599
TESTCASE(test_ei_decode_char)600 TESTCASE(test_ei_decode_char)
601 {
602 ei_init();
603
604 EI_DECODE_2(decode_char, 2, char, 0);
605 EI_DECODE_2(decode_char, 2, char, 0x7f);
606 EI_DECODE_2(decode_char, 2, char, 0xff);
607
608 EI_DECODE_2_FAIL(decode_char, 1, char, 0); /* Illegal type */
609
610 report(1);
611 }
612
613 /* ******************************************************************** */
614
TESTCASE(test_ei_decode_nonoptimal)615 TESTCASE(test_ei_decode_nonoptimal)
616 {
617 ei_init();
618
619 EI_DECODE_2(decode_char, 2, char, 42);
620 EI_DECODE_2(decode_char, 5, char, 42);
621 EI_DECODE_2(decode_char, 4, char, 42);
622 EI_DECODE_2(decode_char, 5, char, 42);
623 EI_DECODE_2(decode_char, 7, char, 42);
624 EI_DECODE_2(decode_char, 7, char, 42);
625 EI_DECODE_2(decode_char, 8, char, 42);
626 EI_DECODE_2(decode_char, 9, char, 42);
627 EI_DECODE_2(decode_char, 12, char, 42);
628
629 /* EI_DECODE_2(decode_char, char, -42); */
630 /* EI_DECODE_2(decode_char, char, -42); */
631 /* EI_DECODE_2(decode_char, char, -42); */
632 /* EI_DECODE_2(decode_char, char, -42); */
633 /* EI_DECODE_2(decode_char, char, -42); */
634 /* EI_DECODE_2(decode_char, char, -42); */
635 /* EI_DECODE_2(decode_char, char, -42); */
636 /* EI_DECODE_2(decode_char, char, -42); */
637 /* EI_DECODE_2(decode_char, char, -42); */
638
639 /* ---------------------------------------------------------------- */
640
641 EI_DECODE_2(decode_long, 2, long, 42);
642 EI_DECODE_2(decode_long, 5, long, 42);
643 EI_DECODE_2(decode_long, 4, long, 42);
644 EI_DECODE_2(decode_long, 5, long, 42);
645 EI_DECODE_2(decode_long, 7, long, 42);
646 EI_DECODE_2(decode_long, 7, long, 42);
647 EI_DECODE_2(decode_long, 8, long, 42);
648 EI_DECODE_2(decode_long, 9, long, 42);
649 EI_DECODE_2(decode_long, 12, long, 42);
650
651 /* EI_DECODE_2(decode_long, 2, long, -42); */
652 EI_DECODE_2(decode_long, 5, long, -42);
653 EI_DECODE_2(decode_long, 4, long, -42);
654 EI_DECODE_2(decode_long, 5, long, -42);
655 EI_DECODE_2(decode_long, 7, long, -42);
656 EI_DECODE_2(decode_long, 7, long, -42);
657 EI_DECODE_2(decode_long, 8, long, -42);
658 EI_DECODE_2(decode_long, 9, long, -42);
659 EI_DECODE_2(decode_long, 12, long, -42);
660
661 /* ---------------------------------------------------------------- */
662
663 EI_DECODE_2(decode_ulong, 2, unsigned long, 42);
664 EI_DECODE_2(decode_ulong, 5, unsigned long, 42);
665 EI_DECODE_2(decode_ulong, 4, unsigned long, 42);
666 EI_DECODE_2(decode_ulong, 5, unsigned long, 42);
667 EI_DECODE_2(decode_ulong, 7, unsigned long, 42);
668 EI_DECODE_2(decode_ulong, 7, unsigned long, 42);
669 EI_DECODE_2(decode_ulong, 8, unsigned long, 42);
670 EI_DECODE_2(decode_ulong, 9, unsigned long, 42);
671 EI_DECODE_2(decode_ulong, 12, unsigned long, 42);
672
673 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
674 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
675 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
676 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
677 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
678 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
679 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
680 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
681 /* EI_DECODE_2(decode_ulong, unsigned long, -42); */
682
683 /* ---------------------------------------------------------------- */
684
685 EI_DECODE_2(decode_longlong, 2, EI_LONGLONG, 42);
686 EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, 42);
687 EI_DECODE_2(decode_longlong, 4, EI_LONGLONG, 42);
688 EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, 42);
689 EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, 42);
690 EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, 42);
691 EI_DECODE_2(decode_longlong, 8, EI_LONGLONG, 42);
692 EI_DECODE_2(decode_longlong, 9, EI_LONGLONG, 42);
693 EI_DECODE_2(decode_longlong, 12, EI_LONGLONG, 42);
694
695 /* EI_DECODE_2(decode_longlong, 2, EI_LONGLONG, -42); */
696 EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, -42);
697 EI_DECODE_2(decode_longlong, 4, EI_LONGLONG, -42);
698 EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, -42);
699 EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, -42);
700 EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, -42);
701 EI_DECODE_2(decode_longlong, 8, EI_LONGLONG, -42);
702 EI_DECODE_2(decode_longlong, 9, EI_LONGLONG, -42);
703 EI_DECODE_2(decode_longlong, 12, EI_LONGLONG, -42);
704
705 /* ---------------------------------------------------------------- */
706
707 EI_DECODE_2(decode_ulonglong, 2, EI_ULONGLONG, 42);
708 EI_DECODE_2(decode_ulonglong, 5, EI_ULONGLONG, 42);
709 EI_DECODE_2(decode_ulonglong, 4, EI_ULONGLONG, 42);
710 EI_DECODE_2(decode_ulonglong, 5, EI_ULONGLONG, 42);
711 EI_DECODE_2(decode_ulonglong, 7, EI_ULONGLONG, 42);
712 EI_DECODE_2(decode_ulonglong, 7, EI_ULONGLONG, 42);
713 EI_DECODE_2(decode_ulonglong, 8, EI_ULONGLONG, 42);
714 EI_DECODE_2(decode_ulonglong, 9, EI_ULONGLONG, 42);
715 EI_DECODE_2(decode_ulonglong, 12, EI_ULONGLONG, 42);
716
717 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
718 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
719 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
720 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
721 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
722 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
723 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
724 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
725 /* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
726
727 /* ---------------------------------------------------------------- */
728
729 report(1);
730 }
731
732 /* ******************************************************************** */
733
TESTCASE(test_ei_decode_misc)734 TESTCASE(test_ei_decode_misc)
735 {
736 ei_init();
737
738 /*
739 EI_DECODE_0(decode_version);
740 */
741 decode_double(0.0);
742 decode_double(-1.0);
743 decode_double(1.0);
744
745 EI_DECODE_2(decode_boolean, 8, int, 0);
746 EI_DECODE_2(decode_boolean, 7, int, 1);
747
748 EI_DECODE_STRING(decode_my_atom, 6, "foo");
749 EI_DECODE_STRING(decode_my_atom, 3, "");
750 EI_DECODE_STRING(decode_my_atom, 9, "������");
751
752 EI_DECODE_STRING(decode_my_string, 6, "foo");
753 EI_DECODE_STRING(decode_my_string, 1, "");
754 EI_DECODE_STRING(decode_my_string, 9, "������");
755
756 decode_bin(8, "foo", 3);
757 decode_bin(5, "", 0);
758 decode_bin(11, "������", 6);
759
760 #define LAST_BYTE(V, BITS) ((V) << (8-(BITS)))
761 {
762 unsigned char bits1[] = {1, 2, LAST_BYTE(3,5) };
763 unsigned char bits2[] = {LAST_BYTE(1,1) };
764 decode_bits(9, bits1, 21);
765 decode_bits(7, bits2, 1);
766 }
767
768 /* FIXME check \0 in strings and atoms? */
769 /*
770 EI_ENCODE_1(decode_tuple_header, 0);
771
772 EI_ENCODE_0(decode_empty_list);
773 */
774 report(1);
775 }
776
777 /* ******************************************************************** */
778
TESTCASE(test_ei_decode_utf8_atom)779 TESTCASE(test_ei_decode_utf8_atom)
780 {
781 ei_init();
782
783 EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({229,0}), /* LATIN1 "�" */
784 P99({ERLANG_ANY,ERLANG_LATIN1,ERLANG_LATIN1}));
785 EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({195,164,0}), /* UTF8 "�" */
786 P99({ERLANG_UTF8,ERLANG_LATIN1,ERLANG_UTF8}));
787 EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({246,0}), /* LATIN1 "�" */
788 P99({ERLANG_LATIN1,ERLANG_LATIN1,ERLANG_LATIN1}));
789 EI_DECODE_STRING_FAIL(decode_my_atom_as,
790 P99({ERLANG_ASCII,ERLANG_ANY,ERLANG_ANY}));
791
792 EI_DECODE_STRING_4(decode_my_atom_as, 4, P99({219,158,0}),
793 P99({ERLANG_ANY,ERLANG_UTF8,ERLANG_UTF8}));
794 EI_DECODE_STRING_4(decode_my_atom_as, 6, P99({219,158,219,158,0}),
795 P99({ERLANG_UTF8,ERLANG_UTF8,ERLANG_UTF8}));
796 EI_DECODE_STRING_FAIL(decode_my_atom_as,
797 P99({ERLANG_LATIN1,ERLANG_ANY,ERLANG_ANY}));
798 EI_DECODE_STRING_FAIL(decode_my_atom_as,
799 P99({ERLANG_ASCII,ERLANG_ANY,ERLANG_ANY}));
800
801 EI_DECODE_STRING_4(decode_my_atom_as, 4, "a",
802 P99({ERLANG_ANY,ERLANG_LATIN1,ERLANG_ASCII}));
803 EI_DECODE_STRING_4(decode_my_atom_as, 4, "b",
804 P99({ERLANG_UTF8,ERLANG_LATIN1,ERLANG_ASCII}));
805 EI_DECODE_STRING_4(decode_my_atom_as, 4, "c",
806 P99({ERLANG_LATIN1,ERLANG_LATIN1,ERLANG_ASCII}));
807 EI_DECODE_STRING_4(decode_my_atom_as, 4, "d",
808 P99({ERLANG_ASCII,ERLANG_LATIN1,ERLANG_ASCII}));
809
810 report(1);
811 }
812
813 /* ******************************************************************** */
814
TESTCASE(test_ei_decode_iodata)815 TESTCASE(test_ei_decode_iodata)
816 {
817 char *buf = NULL, *data = NULL;
818 ei_init();
819
820 while (1) {
821 int unexpected_write = 0;
822 int i;
823 int len, index, saved_index, err;
824
825 if (buf)
826 free_packet(buf);
827 buf = read_packet(&len);
828
829 if (len == 4
830 && buf[0] == 'd'
831 && buf[1] == 'o'
832 && buf[2] == 'n'
833 && buf[3] == 'e') {
834 break;
835 }
836
837 index = 0;
838 err = ei_decode_version(buf, &index, NULL);
839 if (err != 0) {
840 free_packet(buf);
841 fail1("ei_decode_version returned %d", err);
842 }
843 saved_index = index;
844 err = ei_decode_iodata(buf, &index, &len, NULL);
845 if (err != 0) {
846 ei_x_buff x;
847 ei_x_new_with_version(&x);
848 ei_x_encode_atom(&x, "decode_size_failed");
849 send_bin_term(&x);
850 ei_x_free(&x);
851 continue;
852 }
853 if (data) {
854 data -= 100;
855 free(data);
856 }
857 data = malloc(len + 200);
858 if (!data) {
859 ei_x_buff x;
860 ei_x_new_with_version(&x);
861 ei_x_encode_atom(&x, "malloc_failed");
862 send_bin_term(&x);
863 ei_x_free(&x);
864 continue;
865 }
866 for (i = 0; i < len + 200; i++)
867 data[i] = 'Y';
868 data += 100;
869 err = ei_decode_iodata(buf, &saved_index, NULL, (unsigned char *) data);
870 if (err != 0) {
871 ei_x_buff x;
872 ei_x_new_with_version(&x);
873 ei_x_encode_atom(&x, "decode_data_failed");
874 send_bin_term(&x);
875 ei_x_free(&x);
876 continue;
877 }
878
879 for (i = -100; i < 0; i++) {
880 if (data[i] != 'Y') {
881 ei_x_buff x;
882 ei_x_new_with_version(&x);
883 ei_x_encode_atom(&x, "unexpected_write_before_data");
884 send_bin_term(&x);
885 ei_x_free(&x);
886 unexpected_write = !0;
887 break;
888 }
889 }
890
891 if (!unexpected_write) {
892 for (i = len; i < len + 100; i++) {
893 if (data[i] != 'Y') {
894 ei_x_buff x;
895 ei_x_new_with_version(&x);
896 ei_x_encode_atom(&x, "unexpected_write_after_data");
897 send_bin_term(&x);
898 ei_x_free(&x);
899 unexpected_write = !0;
900 break;
901 }
902 }
903 }
904
905 if (!unexpected_write)
906 send_buffer(data, len);
907 }
908
909 if (buf)
910 free_packet(buf);
911 if (data) {
912 data -= 100;
913 free(data);
914 }
915 report(1);
916 }
917
918 /* ******************************************************************** */
919
920 /*
921 * Does not belong here move to its own suite...
922 */
TESTCASE(test_ei_cmp_nc)923 TESTCASE(test_ei_cmp_nc)
924 {
925 char *buf = NULL;
926 ei_init();
927
928 while (1) {
929 int len, index, arity;
930 char atom[MAXATOMLEN_UTF8];
931 ei_x_buff x;
932
933 if (buf)
934 free_packet(buf);
935 buf = read_packet(&len);
936
937 if (len == 4
938 && buf[0] == 'd'
939 && buf[1] == 'o'
940 && buf[2] == 'n'
941 && buf[3] == 'e') {
942 break;
943 }
944
945 ei_x_new_with_version(&x);
946 index = 0;
947 if (ei_decode_version(buf, &index, NULL)
948 || ei_decode_tuple_header(buf, &index, &arity)
949 || (arity != 3)
950 || ei_decode_atom(buf, &index, atom)) {
951 ei_x_encode_atom(&x, "decode_tuple_failed");
952 }
953 else if (strcmp(atom, "cmp_pids") == 0) {
954 erlang_pid a, b;
955 if (ei_decode_pid(buf, &index, &a)
956 || ei_decode_pid(buf, &index, &b)) {
957 ei_x_encode_atom(&x, "decode_pids_failed");
958 }
959 else {
960 long res = (long) ei_cmp_pids(&a, &b);
961 ei_x_encode_long(&x, res);
962 }
963 }
964 else if (strcmp(atom, "cmp_ports") == 0) {
965 erlang_port a, b;
966 if (ei_decode_port(buf, &index, &a)
967 || ei_decode_port(buf, &index, &b)) {
968 ei_x_encode_atom(&x, "decode_ports_failed");
969 }
970 else {
971 long res = (long) ei_cmp_ports(&a, &b);
972 ei_x_encode_long(&x, res);
973 }
974 }
975 else if (strcmp(atom, "cmp_refs") == 0) {
976 erlang_ref a, b;
977 if (ei_decode_ref(buf, &index, &a)
978 || ei_decode_ref(buf, &index, &b)) {
979 ei_x_encode_atom(&x, "decode_refs_failed");
980 }
981 else {
982 long res = (long) ei_cmp_refs(&a, &b);
983 ei_x_encode_long(&x, res);
984 }
985 }
986 else {
987 ei_x_encode_atom(&x, "unexpected_operation");
988 }
989
990 send_bin_term(&x);
991 ei_x_free(&x);
992 }
993
994 if (buf)
995 free_packet(buf);
996 report(1);
997 }
998
999 /* ******************************************************************** */
1000
ei_decode_my_atom_as(const char * buf,int * index,char * to,struct my_atom * atom)1001 int ei_decode_my_atom_as(const char *buf, int *index, char *to,
1002 struct my_atom *atom) {
1003 erlang_char_encoding was,result;
1004 int res = ei_decode_atom_as(buf,index,to,1024,atom->from,&was,&result);
1005 if (res != 0)
1006 return res;
1007 if (!(was & atom->was_check)) {
1008 message("Original encoding was %d not %d\n",was,atom->was_check);
1009 return -1;
1010 } else if (!(result & atom->result_check)) {
1011 message("Result encoding was %d not %d\n",result,atom->result_check);
1012 return -1;
1013 }
1014 return res;
1015 }
1016
ei_decode_my_atom(const char * buf,int * index,char * to,struct my_atom * atom)1017 int ei_decode_my_atom(const char *buf, int *index, char *to,
1018 struct my_atom *atom) {
1019 return ei_decode_atom(buf, index, to);
1020 }
1021
ei_decode_my_string(const char * buf,int * index,char * to,struct my_atom * atom)1022 int ei_decode_my_string(const char *buf, int *index, char *to,
1023 struct my_atom *atom) {
1024 return ei_decode_string(buf, index, to);
1025 }
1026