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