diff options
Diffstat (limited to 'asn1c/tests/check-31.-fwide-types.c')
-rw-r--r-- | asn1c/tests/check-31.-fwide-types.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/asn1c/tests/check-31.-fwide-types.c b/asn1c/tests/check-31.-fwide-types.c new file mode 100644 index 00000000..53ccf5ab --- /dev/null +++ b/asn1c/tests/check-31.-fwide-types.c @@ -0,0 +1,217 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Forest.h> + +uint8_t buf1[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 128, /* L, indefinite */ + + 32 | 16, /* [UNIVERSAL 16], constructed */ + 6, /* L */ + + /* height INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 100, + /* width INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 80, + + 32 | 16, /* [UNIVERSAL 16], constructed */ + 6, /* L */ + + /* height INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 110, + /* width INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 82, + + 0, /* End of forest */ + 0 +}; + +uint8_t buf1_reconstr[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 16, /* L */ + + 32 | 16, /* [UNIVERSAL 16], constructed */ + 6, /* L */ + + /* height INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 100, + /* width INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 80, + + 32 | 16, /* [UNIVERSAL 16], constructed */ + 6, /* L */ + + /* height INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 110, + /* width INTEGER */ + 2, /* [UNIVERSAL 2] */ + 1, /* L */ + 82 + +}; + +int buf_pos; +static int bytes_compare(const void *bufferp, size_t size, void *key) { + const uint8_t *buffer = bufferp; + assert(buf_pos + size <= sizeof(buf1_reconstr)); + + (void)key; /* Unused argument */ + + fprintf(stderr, " writing %d (%d)\n", (int)size, buf_pos + (int)size); + + for(; size; buf_pos++, size--, buffer++) { + if(buf1_reconstr[buf_pos] != *buffer) { + fprintf(stderr, + "Byte %d is different: %d != %d (%x != %x)\n", + buf_pos, + *buffer, buf1_reconstr[buf_pos], + *buffer, buf1_reconstr[buf_pos] + ); + assert(buf1_reconstr[buf_pos] == *buffer); + } + } + + return 0; +} + +static void +check(int is_ok, uint8_t *buf, int size, size_t consumed) { + Forest_t t, *tp; + asn_dec_rval_t rval; + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "Buf %p\n", buf); + rval = ber_decode(0, &asn_DEF_Forest, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %d\n", + (int)rval.code, (int)rval.consumed); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + + assert(t.list.count == 2); + assert(t.list.array[0]->height.size == 1); + assert(t.list.array[0]->width.size == 1); + assert(t.list.array[1]->height.size == 1); + assert(t.list.array[1]->width.size == 1); + } else { + if(rval.code == RC_OK) { + assert(t.list.count != 2 + || t.list.array[0]->height.size != 1 + || t.list.array[0]->width.size != 1 + || t.list.array[1]->height.size != 1 + || t.list.array[1]->width.size != 1 + ); + } + assert(rval.consumed <= consumed); + return; + } + + /* + * Try to re-create the buffer. + */ + buf_pos = 0; + der_encode(&asn_DEF_Forest, &t, + bytes_compare, buf1_reconstr); + assert(buf_pos == sizeof(buf1_reconstr)); + + asn_fprint(stderr, &asn_DEF_Forest, &t); + xer_fprint(stderr, &asn_DEF_Forest, &t); + + asn_DEF_Forest.free_struct(&asn_DEF_Forest, &t, 1); +} + +static char xer_buf[512]; +static int xer_off; + +static int +xer_cb(const void *buffer, size_t size, void *key) { + (void)key; + assert(xer_off + size < sizeof(xer_buf)); + memcpy(xer_buf + xer_off, buffer, size); + xer_off += size; + return 0; +} + +static void +check_xer(uint8_t *buf, uint8_t size, char *xer_sample) { + Forest_t *tp = 0; + asn_dec_rval_t rval; + asn_enc_rval_t er; + int xer_sample_len = strlen(xer_sample); + + rval = ber_decode(0, &asn_DEF_Forest, (void **)&tp, buf, size); + assert(rval.code == RC_OK); + assert(rval.consumed == size); + assert(tp); + + xer_off = 0; + er = xer_encode(&asn_DEF_Forest, tp, XER_F_CANONICAL, xer_cb, 0); + assert(er.encoded == xer_off); + assert(xer_off); + xer_buf[xer_off] = 0; + printf("[%s] vs [%s]\n", xer_buf, xer_sample); + assert(xer_off == xer_sample_len); + assert(memcmp(xer_buf, xer_sample, xer_off) == 0); +} + + +static void +try_corrupt(uint8_t *buf, int size) { + uint8_t *tmp; + int i; + + fprintf(stderr, "\nCorrupting...\n"); + + tmp = alloca(size); + + for(i = 0; i < 1000; i++) { + int loc; + memcpy(tmp, buf, size); + + /* Corrupt random _non-value_ location. */ + do { loc = random() % size; } while(tmp[loc] >= 70); + do { tmp[loc] = buf[loc] ^ random(); } while( + (tmp[loc] == buf[loc]) + || (buf[loc] == 0 && tmp[loc] == 0x80)); + + fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n", + i, loc, buf[loc], tmp[loc]); + + check(0, tmp, size, size); + } +} + +int +main(int ac, char **av) { + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + check(1, buf1, sizeof(buf1), sizeof(buf1)); + check_xer(buf1, sizeof(buf1), "<Forest><Tree><height>100</height><width>80</width></Tree><Tree><height>110</height><width>82</width></Tree></Forest>"); + try_corrupt(buf1, sizeof(buf1)); + check(1, buf1, sizeof(buf1) + 20, sizeof(buf1)); + + return 0; +} |