#undef NDEBUG #include #include #include #include #include #include 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 }; size_t 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 %zd (%zd)\n", size, buf_pos + size); for(; size; buf_pos++, size--, buffer++) { if(buf1_reconstr[buf_pos] != *buffer) { fprintf(stderr, "Byte %zd 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, size_t 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 == (ssize_t)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, size_t 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), "1008011082"); try_corrupt(buf1, sizeof(buf1)); check(1, buf1, sizeof(buf1) + 20, sizeof(buf1)); return 0; }