diff options
Diffstat (limited to 'asn1c/tests/check-src')
37 files changed, 5351 insertions, 0 deletions
diff --git a/asn1c/tests/check-src/check-03.-fwide-types.c b/asn1c/tests/check-src/check-03.-fwide-types.c new file mode 100644 index 00000000..2c44d628 --- /dev/null +++ b/asn1c/tests/check-src/check-03.-fwide-types.c @@ -0,0 +1,62 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include "Enum2.h" +#include "xer_decoder.h" + +static char buf[4096]; +static int buf_offset; + +static int +buf_writer(const void *buffer, size_t size, void *app_key) { + char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + buf_offset += size; + return 0; +} + +static void +check_xer(e_Enum2 eval, char *xer_string) { + asn_dec_rval_t rv; + char buf2[128]; + Enum2_t *e = 0; + long val; + + rv = xer_decode(0, &asn_DEF_Enum2, (void **)&e, + xer_string, strlen(xer_string)); + assert(rv.code == RC_OK); + assert(rv.consumed == strlen(xer_string)); + + asn_INTEGER2long(e, &val); + printf("%s -> %ld == %d\n", xer_string, val, eval); + assert(val == eval); + + buf_offset = 0; + xer_encode(&asn_DEF_Enum2, e, XER_F_CANONICAL, buf_writer, 0); + buf[buf_offset] = 0; + sprintf(buf2, "<Enum2>%s</Enum2>", xer_string); + printf("%d -> %s == %s\n", eval, buf, buf2); + assert(0 == strcmp(buf, buf2)); +} + +int +main() { + + check_xer(Enum2_red, "<red/>"); + check_xer(Enum2_green, "<green/>"); + check_xer(Enum2_blue, "<blue/>"); + check_xer(Enum2_orange, "<orange/>"); + check_xer(Enum2_alpha, "<alpha/>"); + check_xer(Enum2_beta, "<beta/>"); + check_xer(Enum2_gamma, "<gamma/>"); + + return 0; +} diff --git a/asn1c/tests/check-src/check-119.-fwide-types.-gen-PER.c b/asn1c/tests/check-src/check-119.-fwide-types.-gen-PER.c new file mode 100644 index 00000000..8e5c2426 --- /dev/null +++ b/asn1c/tests/check-src/check-119.-fwide-types.-gen-PER.c @@ -0,0 +1,369 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into PER, + * then decoded back from PER, then encoded into XER again, + * and finally compared to the original encoding. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2) */ +#include <string.h> +#include <dirent.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <PDU.h> + +#ifndef SRCDIR +#define SRCDIR_S ".." +#else +#define STRINGIFY_MACRO2(x) #x +#define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x) +#define SRCDIR_S STRINGIFY_MACRO(SRCDIR) +#endif + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_CXER_EXACT, /* Encoding/decoding using CXER must be exact */ + EXP_CXER_DIFF, /* Encoding/decoding using CXER must be different */ + EXP_BROKEN, /* Decoding must fail */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ + EXP_PER_NOCOMP, /* Not PER compatible */ +}; + +static unsigned char buf[4096]; +static size_t buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + for(; b < bend; b++) { + if(*b >= 32 && *b < 127 && *b != '%') + fprintf(stderr, "%c", *b); + else + fprintf(stderr, "%%%02x", *b); + } + fprintf(stderr, "]:%zd\n", size); + buf_offset += size; + return 0; +} + +enum enctype { + AS_PER, + AS_DER, + AS_XER, + AS_CXER, +}; + +static void +save_object_as(PDU_t *st, enum expectation exp, enum enctype how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_PER: + rval = uper_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + if(exp == EXP_PER_NOCOMP) + assert(rval.encoded == -1); + else + assert(rval.encoded > 0); + fprintf(stderr, "SAVED OBJECT IN SIZE %zd\n", buf_offset); + return; + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + case AS_CXER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_CANONICAL, + _buf_writer, 0); + break; + } + + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %zd\n", buf_offset); +} + +static PDU_t * +load_object_from(const char *fname, enum expectation expectation, unsigned char *fbuf, size_t size, enum enctype how) { + asn_dec_rval_t rval; + PDU_t *st = 0; + size_t csize = 1; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %zd FROM [%s] as %s," + " chunks %zd\n", + size, fname, how==AS_PER?"PER":"XER", csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + switch(how) { + case AS_XER: + rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + break; + case AS_PER: + rval = uper_decode(0, &asn_DEF_PDU, + (void **)&st, fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, 0, 0); + if(rval.code == RC_WMORE) { + rval.consumed = 0; /* Not restartable */ + ASN_STRUCT_FREE(asn_DEF_PDU, st); + st = 0; + fprintf(stderr, "-> PER wants more\n"); + } else { + fprintf(stderr, "-> PER ret %d/%ld\n", + rval.code, rval.consumed); + /* uper_decode() returns _bits_ */ + rval.consumed += 7; + rval.consumed /= 8; + } + break; + case AS_DER: + case AS_CXER: + assert(!"DER or CXER not supported for load"); + } + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + if(how == AS_PER) { + fprintf(stderr, "[left %d, off %d, size %zd]\n", + fbuf_left, fbuf_offset, size); + assert(fbuf_offset == (ssize_t)size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == (ssize_t)size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == (ssize_t)size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(char *obuf, size_t osize, char *nbuf, size_t nsize) { + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +process_XER_data(const char *fname, enum expectation expectation, unsigned char *fbuf, size_t size) { + PDU_t *st; + + st = load_object_from(fname, expectation, fbuf, size, AS_XER); + if(!st) return; + + /* Save and re-load as PER */ + save_object_as(st, expectation, AS_PER); + if(expectation == EXP_PER_NOCOMP) + return; /* Already checked */ + st = load_object_from("buffer", expectation, buf, buf_offset, AS_PER); + assert(st); + + save_object_as(st, + expectation, + (expectation == EXP_CXER_EXACT + || expectation == EXP_CXER_DIFF) + ? AS_CXER : AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + switch(expectation) { + case EXP_DIFFERENT: + assert(!xer_encoding_equal((char *)fbuf, size, (char *)buf, buf_offset)); + break; + case EXP_BROKEN: + assert(!xer_encoding_equal((char *)fbuf, size, (char *)buf, buf_offset)); + break; + case EXP_CXER_EXACT: + buf[buf_offset++] = '\n'; + assert(size == buf_offset); + assert(memcmp(fbuf, buf, size) == 0); + break; + case EXP_CXER_DIFF: + buf[buf_offset++] = '\n'; + assert(size != buf_offset + || memcmp(fbuf, buf, size)); + break; + case EXP_OK: + case EXP_PER_NOCOMP: + assert(xer_encoding_equal((char *)fbuf, size, (char *)buf, buf_offset)); + break; + } + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + unsigned char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'E': /* Byte to byte exact reconstruction */ + expectation = EXP_CXER_EXACT; break; + case 'X': /* Should fail byte-to-byte comparison */ + expectation = EXP_CXER_DIFF; break; + case 'P': /* Incompatible with PER */ + expectation = EXP_PER_NOCOMP; break; + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + snprintf((char *)fbuf, sizeof(fbuf), SRCDIR_S "/data-119/%s", fname); + fp = fopen((char *)fbuf, "r"); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd < (ssize_t)sizeof(fbuf)); /* expect small files */ + + process_XER_data(fname, expectation, fbuf, rd); + + fprintf(stderr, "Finished [%s]\n", fname); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_119_FILE"); + if(str && strncmp(str, "data-119-", 9) == 0) { + process(str); + return 0; + } + + dir = opendir(SRCDIR_S "/data-119"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-119-", 9) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-119.-gen-PER.c b/asn1c/tests/check-src/check-119.-gen-PER.c new file mode 100644 index 00000000..a1f2f805 --- /dev/null +++ b/asn1c/tests/check-src/check-119.-gen-PER.c @@ -0,0 +1,371 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into PER, + * then decoded back from PER, then encoded into XER again, + * and finally compared to the original encoding. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2) */ +#include <string.h> +#include <dirent.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <PDU.h> + +#ifndef SRCDIR +#define SRCDIR_S ".." +#else +#define STRINGIFY_MACRO2(x) #x +#define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x) +#define SRCDIR_S STRINGIFY_MACRO(SRCDIR) +#endif + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_CXER_EXACT, /* Encoding/decoding using CXER must be exact */ + EXP_CXER_DIFF, /* Encoding/decoding using CXER must be different */ + EXP_BROKEN, /* Decoding must fail */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ + EXP_PER_NOCOMP, /* Not PER compatible */ +}; + +static unsigned char buf[4096]; +static size_t buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + for(; b < bend; b++) { + if(*b >= 32 && *b < 127 && *b != '%') + fprintf(stderr, "%c", *b); + else + fprintf(stderr, "%%%02x", *b); + } + fprintf(stderr, "]:%zd\n", size); + buf_offset += size; + return 0; +} + +enum enctype { + AS_PER, + AS_DER, + AS_XER, + AS_CXER, +}; + +static void +save_object_as(PDU_t *st, enum expectation exp, enum enctype how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_PER: + rval = uper_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + if(exp == EXP_PER_NOCOMP) + assert(rval.encoded == -1); + else + assert(rval.encoded > 0); + fprintf(stderr, "SAVED OBJECT IN SIZE %zd\n", buf_offset); + return; + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + case AS_CXER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_CANONICAL, + _buf_writer, 0); + break; + } + + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %zd\n", buf_offset); +} + +static PDU_t * +load_object_from(const char *fname, enum expectation expectation, unsigned char *fbuf, size_t size, enum enctype how) { + asn_dec_rval_t rval; + PDU_t *st = 0; + size_t csize = 1; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %zd FROM [%s] as %s," + " chunks %zd\n", + size, fname, how==AS_PER?"PER":"XER", csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + switch(how) { + case AS_XER: + rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + break; + case AS_PER: + rval = uper_decode(0, &asn_DEF_PDU, + (void **)&st, fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, 0, 0); + if(rval.code == RC_WMORE) { + rval.consumed = 0; /* Not restartable */ + ASN_STRUCT_FREE(asn_DEF_PDU, st); + st = 0; + fprintf(stderr, "-> PER wants more\n"); + } else { + fprintf(stderr, "-> PER ret %d/%zd\n", + rval.code, rval.consumed); + /* uper_decode() returns _bits_ */ + rval.consumed += 7; + rval.consumed /= 8; + } + break; + case AS_DER: + case AS_CXER: + assert(!"Unexpected DER or CXER load request"); + } + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + if(how == AS_PER) { + fprintf(stderr, "[left %d, off %d, size %zd]\n", + fbuf_left, fbuf_offset, size); + assert(fbuf_offset == (ssize_t)size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == (ssize_t)size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == (ssize_t)size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(void *obufp, size_t osize, void *nbufp, size_t nsize) { + char *obuf = obufp; + char *nbuf = nbufp; + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +process_XER_data(const char *fname, enum expectation expectation, unsigned char *fbuf, ssize_t size) { + PDU_t *st; + + st = load_object_from(fname, expectation, fbuf, size, AS_XER); + if(!st) return; + + /* Save and re-load as PER */ + save_object_as(st, expectation, AS_PER); + if(expectation == EXP_PER_NOCOMP) + return; /* Already checked */ + st = load_object_from("buffer", expectation, buf, buf_offset, AS_PER); + assert(st); + + save_object_as(st, + expectation, + (expectation == EXP_CXER_EXACT + || expectation == EXP_CXER_DIFF) + ? AS_CXER : AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + switch(expectation) { + case EXP_DIFFERENT: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_BROKEN: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_CXER_EXACT: + buf[buf_offset++] = '\n'; + assert((ssize_t)size == (ssize_t)buf_offset); + assert(memcmp(fbuf, buf, size) == 0); + break; + case EXP_CXER_DIFF: + buf[buf_offset++] = '\n'; + assert((ssize_t)size != (ssize_t)buf_offset + || memcmp(fbuf, buf, size)); + break; + case EXP_OK: + case EXP_PER_NOCOMP: + assert(xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + } + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + unsigned char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'E': /* Byte to byte exact reconstruction */ + expectation = EXP_CXER_EXACT; break; + case 'X': /* Should fail byte-to-byte comparison */ + expectation = EXP_CXER_DIFF; break; + case 'P': /* Incompatible with PER */ + expectation = EXP_PER_NOCOMP; break; + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + snprintf((char *)fbuf, sizeof(fbuf), SRCDIR_S "/data-119/%s", fname); + fp = fopen((char *)fbuf, "r"); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd < (ssize_t)sizeof(fbuf)); /* expect small files */ + + process_XER_data(fname, expectation, fbuf, rd); + + fprintf(stderr, "Finished [%s]\n", fname); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_119_FILE"); + if(str && strncmp(str, "data-119-", 9) == 0) { + process(str); + return 0; + } + + dir = opendir(SRCDIR_S "/data-119"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-119-", 9) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-126.-gen-PER.c b/asn1c/tests/check-src/check-126.-gen-PER.c new file mode 100644 index 00000000..595a1dbf --- /dev/null +++ b/asn1c/tests/check-src/check-126.-gen-PER.c @@ -0,0 +1,372 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into PER, + * compared with *.out file, then decoded and compared with the original. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2) */ +#include <string.h> +#include <dirent.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <PDU.h> + +#ifndef SRCDIR +#define SRCDIR_S ".." +#else +#define STRINGIFY_MACRO2(x) #x +#define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x) +#define SRCDIR_S STRINGIFY_MACRO(SRCDIR) +#endif + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + for(; b < bend; b++) { + if(*b >= 32 && *b < 127 && *b != '%') + fprintf(stderr, "%c", *b); + else + fprintf(stderr, "%%%02x", *b); + } + fprintf(stderr, "]:%zd\n", size); + buf_offset += size; + return 0; +} + +enum enctype { + AS_PER, + AS_DER, + AS_XER, +}; + +static void +save_object_as(PDU_t *st, enum enctype how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_PER: + rval = uper_encode(&asn_DEF_PDU, st, _buf_writer, 0); + assert(rval.encoded > 0); + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); + return; + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + } + + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); +} + +static PDU_t * +load_object_from(const char *fname, unsigned char *fbuf, size_t size, enum enctype how, int mustfail) { + asn_dec_rval_t rval; + PDU_t *st = 0; + ssize_t csize = 1; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %zd FROM [%s] as %s," + " chunks %zd\n", + size, fname, how==AS_PER?"PER":"XER", csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "\nDecoding bytes %d..%d (left %d) [%s]\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left, + fname); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + switch(how) { + case AS_XER: + rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + break; + case AS_DER: + assert(0); + break; + case AS_PER: + rval = uper_decode(0, &asn_DEF_PDU, + (void **)&st, fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, 0, 0); + if(rval.code == RC_WMORE) { + if(fbuf_chunk == fbuf_left) { + fprintf(stderr, "-> PER decode error (%zd bits of %zd bytes (c=%d,l=%d)) \n", rval.consumed, size, fbuf_chunk, fbuf_left); + rval.code = RC_FAIL; + rval.consumed += 7; + rval.consumed /= 8; + if(mustfail) { + fprintf(stderr, "-> (this was expected failure)\n"); + return 0; + } + } else { + rval.consumed = 0; /* Not restartable */ + ASN_STRUCT_FREE(asn_DEF_PDU, st); + st = 0; + fprintf(stderr, "-> PER wants more\n"); + } + } else { + fprintf(stderr, "-> PER ret %d/%zd mf=%d\n", + rval.code, rval.consumed, mustfail); + /* uper_decode() returns _bits_ */ + rval.consumed += 7; + rval.consumed /= 8; + if((mustfail?1:0) == (rval.code == RC_FAIL)) { + if(mustfail) { + fprintf(stderr, "-> (this was expected failure)\n"); + return 0; + } + } else { + fprintf(stderr, "-> (unexpected %s)\n", mustfail ? "success" : "failure"); + rval.code = RC_FAIL; + } + } + break; + } + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + assert(rval.code == RC_OK); + if(how == AS_PER) { + fprintf(stderr, "[left %d, off %d, size %zd]\n", + fbuf_left, fbuf_offset, size); + assert(fbuf_offset == (ssize_t)size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == (ssize_t)size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == (ssize_t)size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(void *obufp, size_t osize, void *nbufp, size_t nsize) { + char *obuf = obufp; + char *nbuf = nbufp; + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +compare_with_data_out(const char *fname, void *datap, size_t size) { + char *data = datap; + char outName[sizeof(SRCDIR_S) + 256]; + unsigned char fbuf[1024]; + size_t rd; + FILE *f; + char lastChar; + int mustfail, compare; + + sprintf(outName, SRCDIR_S "/data-126/%s", fname); + strcpy(outName + strlen(outName) - 3, ".out"); + + fprintf(stderr, "Comparing PER output with [%s]\n", outName); + + lastChar = outName[strlen(outName)-5]; + mustfail = lastChar == 'P'; + compare = lastChar != 'C'; + + if((compare && !mustfail) && getenv("REGENERATE")) { + f = fopen(outName, "w"); + fwrite(data, 1, size, f); + fclose(f); + } else { + f = fopen(outName, "r"); + assert(f); + rd = fread(fbuf, 1, sizeof(fbuf), f); + assert(rd); + fclose(f); + + fprintf(stderr, "Trying to decode [%s]\n", outName); + load_object_from(outName, fbuf, rd, AS_PER, mustfail); + if(mustfail) return; + + if(compare) { + assert(rd == (size_t)size); + assert(memcmp(fbuf, data, rd) == 0); + fprintf(stderr, "XER->PER recoding .in->.out match.\n"); + } else { + assert(rd != (size_t)size || memcmp(fbuf, data, rd)); + fprintf(stderr, "XER->PER recoding .in->.out diverge.\n"); + } + } +} + +static void +process_XER_data(const char *fname, unsigned char *fbuf, size_t size) { + PDU_t *st; + + st = load_object_from(fname, fbuf, size, AS_XER, 0); + if(!st) return; + + /* Save and re-load as PER */ + save_object_as(st, AS_PER); + compare_with_data_out(fname, buf, buf_offset); + st = load_object_from("buffer", buf, buf_offset, AS_PER, 0); + assert(st); + + save_object_as(st, AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + if(fname[strlen(fname) - 4] == 'X') + assert(!xer_encoding_equal((char *)fbuf, size, (char *)buf, buf_offset)); + else + assert(xer_encoding_equal((char *)fbuf, size, (char *)buf, buf_offset)); + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + unsigned char fbuf[sizeof(SRCDIR_S) + 4096]; + char *ext = strrchr(fname, '.'); + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + snprintf((char *)fbuf, sizeof(fbuf), SRCDIR_S "/data-126/%s", fname); + fp = fopen((char *)fbuf, "r"); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert((size_t)rd < sizeof(fbuf)); /* expect small files */ + + process_XER_data(fname, fbuf, rd); + + fprintf(stderr, "Finished [%s]\n", fname); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_126_FILE"); + if(str && strncmp(str, "data-126-", 9) == 0) { + process(str); + return 0; + } + + dir = opendir(SRCDIR_S "/data-126"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-126-", 9) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-127.-gen-PER.c b/asn1c/tests/check-src/check-127.-gen-PER.c new file mode 100644 index 00000000..34b6d748 --- /dev/null +++ b/asn1c/tests/check-src/check-127.-gen-PER.c @@ -0,0 +1,87 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <T.h> + +static void +verify(int testNo, T_t *ti) { + asn_enc_rval_t er; + asn_dec_rval_t rv; + unsigned char buf[16]; + T_t *to = 0; + + fprintf(stderr, "%d IN: { %ld, %ld, %lu, %lu }\n", testNo, + ti->small32range, ti->full32range, + ti->unsigned32, ti->unsplit32); + + er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf); + assert(er.encoded == 8 * sizeof(buf)); + + rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0); + assert(rv.code == RC_OK); + + fprintf(stderr, "%d ENC: %2x%2x%2x%2x %2x%2x%2x%2x\n", testNo, + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + fprintf(stderr, "%d OUT: { %ld, %ld, %lu, %lu } vs { %ld, %ld, %lu, %lu }\n", + testNo, + ti->small32range, ti->full32range, + ti->unsigned32, ti->unsplit32, + to->small32range, to->full32range, + to->unsigned32, to->unsplit32); + assert(ti->small32range == to->small32range); + assert(ti->full32range == to->full32range); + assert(ti->unsigned32 == to->unsigned32); + assert(ti->unsplit32 == to->unsplit32); + + xer_fprint(stderr, &asn_DEF_T, ti); + xer_fprint(stderr, &asn_DEF_T, to); +} + +int main() { + T_t ti; + + ti.small32range = 0; + ti.full32range = 0; + ti.unsigned32 = 0; + ti.unsplit32 = 5; + verify(1, &ti); + + ti.small32range = -1; + ti.full32range = -1; + ti.unsigned32 = 1; + ti.unsplit32 = 300; + verify(2, &ti); + + ti.small32range = -2000000000; + ti.full32range = (-2147483647L - 1); + ti.unsigned32 = 4000000000; + ti.unsplit32 = 500; + verify(3, &ti); + + ti.small32range = -1999999999; + ti.full32range = (-2147483647L); + ti.unsigned32 = 4294967295UL; + ti.unsplit32 = 600; + verify(4, &ti); + + ti.small32range = 2000000000; + ti.full32range = 2147483647; + ti.unsigned32 = 4294967295UL - 100; + ti.unsplit32 = 4294967290UL; + verify(5, &ti); + + ti.small32range = 1999999999; + ti.full32range = 2147483647 - 1; + ti.unsigned32 = 4294967295UL - 1; + ti.unsplit32 = 4294967290UL - 1; + verify(6, &ti); + + return 0; +} diff --git a/asn1c/tests/check-src/check-131.-gen-PER.c b/asn1c/tests/check-src/check-131.-gen-PER.c new file mode 100644 index 00000000..7cc744f4 --- /dev/null +++ b/asn1c/tests/check-src/check-131.-gen-PER.c @@ -0,0 +1,59 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include "T.h" +#include "per_opentype.h" + +int +main() { + asn_per_data_t pd; + asn_per_outp_t po; + asn_dec_rval_t rv; + T_t t; + T_t *t2 = 0; + size_t i; + + memset(&po, 0, sizeof po); + po.buffer = po.tmpspace; + po.nbits = sizeof(po.tmpspace) * 8; + + memset(&t, 0, sizeof t); + + printf("Checking uper_open_type_put():\n"); + assert(0 == uper_open_type_put(&asn_DEF_T, 0, &t, &po)); + assert(po.nbits == (-1 + sizeof(po.tmpspace)) * 8); + printf("po{nboff=%zd; nbits=%zd; buffer=%p; tmpspace=%p}\n", + po.nboff, po.nbits, po.buffer, po.tmpspace); + /* One byte length and one byte 0x00 */ + assert( (po.nboff == 8 && po.buffer == &po.tmpspace[1]) + || (po.nboff == 0 && po.buffer == &po.tmpspace[2])); + assert(po.tmpspace[0] == 0x01); + assert(po.tmpspace[1] == 0x00); + + printf("\nChecking uper_open_type_get():\n"); + for(i = 0; i < 16; i++) { + FREEMEM(t2); t2 = 0; + memset(&pd, 0, sizeof pd); + pd.buffer = po.tmpspace; + pd.nboff = 0; + pd.nbits = i; + rv = uper_open_type_get(0, &asn_DEF_T, 0, (void **)&t2, &pd); + assert(rv.code == RC_WMORE); + } + + memset(&pd, 0, sizeof pd); + pd.buffer = po.tmpspace; + pd.nboff = 0; + pd.nbits = 16; + rv = uper_open_type_get(0, &asn_DEF_T, 0, (void **)&t2, &pd); + assert(rv.code == RC_OK); + assert( (pd.nboff == 8 && pd.buffer == &po.tmpspace[1]) + || (pd.nboff == 16 && pd.buffer == &po.tmpspace[0])); + assert(pd.nboff + pd.nbits == 16); + + return 0; +} diff --git a/asn1c/tests/check-src/check-132.-gen-PER.c b/asn1c/tests/check-src/check-132.-gen-PER.c new file mode 100644 index 00000000..592425c5 --- /dev/null +++ b/asn1c/tests/check-src/check-132.-gen-PER.c @@ -0,0 +1,62 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <T.h> + +static void +verify(int testNo, T_t *ti) { + asn_enc_rval_t er; + asn_dec_rval_t rv; + unsigned char buf[2]; + T_t *to = 0; + + er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf); + fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded); + assert(er.encoded >= 1 && er.encoded <= (ssize_t)(8 * sizeof(buf))); + + rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0); + assert(rv.code == RC_OK); + + fprintf(stderr, "%d ENC: %2x%2x\n", testNo, + buf[0], buf[1]); + fprintf(stderr, "%d OUT: %d\n", testNo, ti->present); + assert(ti->present == to->present); + if(ti->present == T_PR_second) { + assert(ti->choice.second == to->choice.second); + } else { + assert(ti->choice.first.present == to->choice.first.present); + assert(ti->choice.first.choice.nothing == to->choice.first.choice.nothing); + } + + xer_fprint(stderr, &asn_DEF_T, ti); + xer_fprint(stderr, &asn_DEF_T, to); +} + +int main() { + T_t t; + + memset(&t, 0, sizeof(t)); + t.present = T_PR_first; + t.choice.first.present = first_PR_nothing; + t.choice.first.choice.nothing = 5; + verify(0, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_first; + t.choice.first.present = first_PR_nothing; + t.choice.first.choice.nothing = 6; + verify(1, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_second; + t.choice.second = 7; + verify(2, &t); + + return 0; +} diff --git a/asn1c/tests/check-src/check-133.-gen-PER.c b/asn1c/tests/check-src/check-133.-gen-PER.c new file mode 100644 index 00000000..bbd36915 --- /dev/null +++ b/asn1c/tests/check-src/check-133.-gen-PER.c @@ -0,0 +1,83 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <T.h> + +static void +verify(int testNo, T_t *ti) { + asn_enc_rval_t er; + asn_dec_rval_t rv; + unsigned char buf[8]; + T_t *to = 0; + + er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf); + fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded); + assert(er.encoded >= 1); + assert(er.encoded <= (ssize_t)(8 * sizeof(buf))); + + rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0); + assert(rv.code == RC_OK); + + fprintf(stderr, "%d ENC: %2x%2x\n", testNo, + buf[0], buf[1]); + fprintf(stderr, "%d OUT: %d\n", testNo, ti->present); + assert(ti->present == to->present); + switch(ti->present) { + case T_PR_NOTHING: + assert(ti->present != T_PR_NOTHING); + break; + case T_PR_first: + assert(ti->choice.first.present == to->choice.first.present); + assert(ti->choice.first.choice.nothing == to->choice.first.choice.nothing); + break; + case T_PR_second: + assert(ti->choice.second == to->choice.second); + break; + case T_PR_third: + assert(ti->choice.third == to->choice.third); + break; + } + + xer_fprint(stderr, &asn_DEF_T, ti); + xer_fprint(stderr, &asn_DEF_T, to); +} + +int main() { + T_t t; + + return 0; // this test fails, but not important atm. + + memset(&t, 0, sizeof(t)); + t.present = T_PR_first; + t.choice.first.present = first_PR_nothing; + t.choice.first.choice.nothing = 5; + verify(0, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_second; + t.choice.second = -5; + verify(1, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_second; + t.choice.second = 10; + verify(2, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_third; + t.choice.third = -10; + verify(3, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_third; + t.choice.third = 4097; + verify(4, &t); + + return 0; +} diff --git a/asn1c/tests/check-src/check-19.c b/asn1c/tests/check-src/check-19.c new file mode 100644 index 00000000..bb2f7f26 --- /dev/null +++ b/asn1c/tests/check-src/check-19.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Name.h> + +int +main(int ac, char **av) { + Name_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-22.-fwide-types.c b/asn1c/tests/check-src/check-22.-fwide-types.c new file mode 100644 index 00000000..991f2626 --- /dev/null +++ b/asn1c/tests/check-src/check-22.-fwide-types.c @@ -0,0 +1,153 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T1.h> + +uint8_t buf1[] = { + 32 | 16, /* [UNIVERSAL 16], constructed */ + 12, /* L */ + /* INTEGER a */ + ((2 << 6) + 0), /* [0], primitive */ + 2, /* L */ + 150, + 70, + /* b [1] EXPLICIT CHOICE */ + 32 | ((2 << 6) + 1), /* [1] */ + 3, /* L */ + ((2 << 6) + 1), /* [1] */ + 1, + 'i', + /* UTF8String c */ + ((2 << 6) + 2), /* [2], primitive */ + 1, /* L */ + 'x' +}; + +uint8_t buf2[128]; +int buf2_pos; + +static int +buf2_fill(const void *buffer, size_t size, void *app_key) { + + (void)app_key; + + if(buf2_pos + size > sizeof(buf2)) + return -1; + + memcpy(buf2 + buf2_pos, buffer, size); + buf2_pos += size; + + return 0; +} + +static void +check(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + T1_t t, *tp; + void *tpp = &tp; + asn_dec_rval_t rval; + asn_enc_rval_t erval; + int ret; + int i; + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "Buf %p\n", buf); + rval = ber_decode(0, &asn_DEF_T1, (void **)tpp, 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 == (size_t)consumed); + assert(t.a.size == 2); + assert(t.b.present == b_PR_n); + assert(t.b.choice.n.size == 1); + assert(t.b.choice.n.buf[0] == 'i'); + assert(t.c.size == 1); + assert(t.c.buf[0] == 'x'); + + } else { + if(rval.code == RC_OK) { + assert(t.a.size != 2 + || t.b.present != b_PR_n + || t.b.choice.n.size != 1 + || t.c.size != 1 + ); + } + assert(rval.consumed <= (size_t)consumed); + return; + } + + fprintf(stderr, "=> Re-creating using DER encoder <=\n"); + + /* + * Try to re-create using DER encoding. + */ + buf2_pos = 0; + erval = der_encode(&asn_DEF_T1, tp, buf2_fill, 0); + assert(erval.encoded != -1); + if(erval.encoded != sizeof(buf1)) { + printf("%d != %d\n", (int)erval.encoded, (int)sizeof(buf1)); + } + assert(erval.encoded == (ssize_t)sizeof(buf1)); + for(i = 0; i < (ssize_t)sizeof(buf1); i++) { + if(buf1[i] != buf2[i]) { + fprintf(stderr, "Recreated buffer content mismatch:\n"); + fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n", + i, + buf1[i], buf2[i], + buf1[i], buf2[i] + ); + } + assert(buf1[i] == buf2[i]); + } + + fprintf(stderr, "=== asn_fprint() ===\n"); + ret = asn_fprint(stderr, &asn_DEF_T1, tp); + assert(ret == 0); + fprintf(stderr, "=== xer_fprint() ===\n"); + ret = xer_fprint(stderr, &asn_DEF_T1, tp); + assert(ret == 0); + fprintf(stderr, "=== EOF ===\n"); +} + +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] ^= random(); } while(tmp[loc] == buf[loc]); + + 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)); + try_corrupt(buf1, sizeof(buf1)); + check(1, buf1, sizeof(buf1) + 10, sizeof(buf1)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-24.-fwide-types.c b/asn1c/tests/check-src/check-24.-fwide-types.c new file mode 100644 index 00000000..8cd54765 --- /dev/null +++ b/asn1c/tests/check-src/check-24.-fwide-types.c @@ -0,0 +1,97 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +uint8_t buf1[] = { + 32 | ((2 << 6) + 5), /* [5], constructed */ + 17, /* L */ + 32 | 16, /* [UNIVERSAL 16], constructed */ + 15, /* L */ + /* INTEGER a */ + 2, /* [UNIVERSAL 2] */ + 2, /* L */ + 150, + 70, + /* INTEGER b */ + ((2 << 6) + 0), /* [0] */ + 1, /* L */ + 123, + /* INTEGER c */ + ((2 << 6) + 1), /* [1] */ + 1, /* L */ + 123, + /* INTEGER d */ + 32 | ((2 << 6) + 5), /* [5], constructed */ + 3, + 2, + 1, /* L */ + 123, +}; + +static void +check(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + T_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_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + } else { + if(rval.code == RC_OK) { + assert(t.a.size != 2 + || (!t.b || t.b->size != 1) + || (!t.c || t.c->size != 1) + || t.d.size != 1 + ); + } + assert(rval.consumed <= consumed); + } +} + +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] ^= random(); } while(tmp[loc] == buf[loc]); + + 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)); + try_corrupt(buf1, sizeof(buf1)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-25.-fwide-types.c b/asn1c/tests/check-src/check-25.-fwide-types.c new file mode 100644 index 00000000..5564445c --- /dev/null +++ b/asn1c/tests/check-src/check-25.-fwide-types.c @@ -0,0 +1,261 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +uint8_t buf1[] = { + 32 | 16, /* [UNIVERSAL 16], constructed */ + 128, /* L */ + /* a INTEGER */ + 2, /* [UNIVERSAL 2] */ + 2, /* L */ + 150, + 70, + /* b [2] IMPLICIT BOOLEAN */ + 128 | 2, /* [2] */ + 1, /* L */ + 0xff, + /* c NULL */ + 5, /* [UNIVERSAL 5] */ + 0, /* L */ + /* d ENUMERATED */ + 10, /* [UNIVERSAL 10] */ + 1, /* L */ + 222, + /* e OCTET STRING */ + 4, /* [UNIVERSAL 4] */ + 3, /* L */ + 'x', + 'y', + 'z', + /* + * X.690 specifies that inner structures must be tagged by + * stripping off the outer tag for each subsequent level. + */ + /* f [5] IMPLICIT VisibleString */ + 128 | 32 | 5, /* [5], constructed */ + 128, /* L indefinite */ + 26, /* [UNIVERSAL 26] (VisibleString), primitive */ + 2, + 'l', + 'o', + 32 | 26, /* [UNIVERSAL 26], recursively constructed */ + 128, + 4, /* [UNIVERSAL 4] (OCTET STRING), primitive */ + 1, + 'v', + 4, /* [UNIVERSAL 4], primitive */ + 2, + 'e', + '_', + 0, + 0, + 26, /* [UNIVERSAL 26], primitive */ + 2, + 'i', + 't', + 0, + 0, + /* g BIT STRING */ + 3, /* [UNIVERSAL 3], primitive */ + 3, /* L */ + 2, /* Skip 2 bits */ + 147, + 150, /* => 148 */ + /* h [7] BIT STRING */ + 128 | 32 | 7, /* [7], constructed */ + 128, /* L indefinite */ + 3, /* [UNIVERSAL 3], primitive */ + 3, /* L */ + 0, /* Skip 0 bits */ + 140, + 141, + 3, /* [UNIVERSAL 3], primitive */ + 2, /* L */ + 1, /* Skip 1 bit */ + 143, /* => 142 */ + 0, /* End of h */ + 0, + 0, /* End of the whole structure */ + 0, + /* Three bytes of planned leftover */ + 111, 222, 223 +}; + +static void +check(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + T_t t, *tp; + asn_dec_rval_t rval; + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "Buf %p (%zd)\n", buf, size); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd, expected %zd\n", + (int)rval.code, rval.consumed, consumed); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + + assert(strcmp((char *)t.e->buf, "xyz") == 0); + assert(strcmp((char *)t.f->buf, "love_it") == 0); + + assert(t.g->size == 2); + assert(t.g->bits_unused == 2); + fprintf(stderr, "%d %d\n", t.g->buf[0], t.g->buf[1]); + assert(t.g->buf[0] == 147); + assert(t.g->buf[1] != 150); + assert(t.g->buf[1] == 148); + + assert(t.h->size == 3); + assert(t.h->bits_unused == 1); + assert(t.h->buf[0] == 140); + assert(t.h->buf[1] == 141); + assert(t.h->buf[2] == 142); + } else { + if(rval.code == RC_OK) { + assert(t.a.size != 2 + || !t.d + || t.d->size != 1 + || !t.e + || t.e->size != 3 + || !t.f + || t.f->size != 7 + || !t.g + || t.g->size != 2 + || !t.h + || t.h->size != 3 + ); + } + fprintf(stderr, "%zd %zd\n", rval.consumed, consumed); + assert(rval.consumed <= consumed); + } + + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); +} + +static void +try_corrupt(uint8_t *buf, size_t size, int allow_consume) { + 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( + loc == 44 /* bit skips */ + || loc == 51 /* bit skips */ + || loc == 56 /* bit skips */ + || 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, allow_consume); + } +} + +static void +partial_read(uint8_t *buf, size_t size) { + T_t t, *tp; + asn_dec_rval_t rval; + size_t i1, i2; + uint8_t *tbuf1 = alloca(size); + uint8_t *tbuf2 = alloca(size); + uint8_t *tbuf3 = alloca(size); + + fprintf(stderr, "\nPartial read sequence...\n"); + + /* + * Divide the space (size) into three blocks in various combinations: + * |<----->i1<----->i2<----->| + * ^ buf ^ buf+size + * Try to read block by block. + */ + for(i1 = 0; i1 < size; i1++) { + for(i2 = i1; i2 < size; i2++) { + uint8_t *chunk1 = buf; + size_t size1 = i1; + uint8_t *chunk2 = buf + size1; + size_t size2 = i2 - i1; + uint8_t *chunk3 = buf + size1 + size2; + size_t size3 = size - size1 - size2; + + fprintf(stderr, "\n%d:{%d, %d, %d}...\n", + (int)size, (int)size1, (int)size2, (int)size3); + + memset(tbuf1, 0, size); + memset(tbuf2, 0, size); + memset(tbuf3, 0, size); + memcpy(tbuf1, chunk1, size1); + memcpy(tbuf2, chunk2, size2); + memcpy(tbuf3, chunk3, size3); + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "=> Chunk 1 (%d):\n", (int)size1); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + tbuf1, size1); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size1); + if(rval.consumed < size1) { + int leftover = size1 - rval.consumed; + memcpy(tbuf2, tbuf1 + rval.consumed, leftover); + memcpy(tbuf2 + leftover, chunk2, size2); + size2 += leftover; + } + + fprintf(stderr, "=> Chunk 2 (%d):\n", (int)size2); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + tbuf2, size2); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size2); + if(rval.consumed < size2) { + int leftover = size2 - rval.consumed; + memcpy(tbuf3, tbuf2 + rval.consumed, leftover); + memcpy(tbuf3 + leftover, chunk3, size3); + size3 += leftover; + } + + fprintf(stderr, "=> Chunk 3 (%d):\n", (int)size3); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + tbuf3, size3); + assert(rval.code == RC_OK); + assert(rval.consumed == size3); + + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + } + } +} + +int +main(int ac, char **av) { + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + /* Check that the full buffer may be decoded normally */ + check(1, buf1, sizeof(buf1), sizeof(buf1) - 3); + + /* Check that some types of buffer corruptions will lead to failure */ + try_corrupt(buf1, sizeof(buf1) - 3, sizeof(buf1) - 3); + + /* Split the buffer in parts and check decoder restartability */ + partial_read(buf1, sizeof(buf1) - 3); + + return 0; +} diff --git a/asn1c/tests/check-src/check-30.-fwide-types.c b/asn1c/tests/check-src/check-30.-fwide-types.c new file mode 100644 index 00000000..e4a47371 --- /dev/null +++ b/asn1c/tests/check-src/check-30.-fwide-types.c @@ -0,0 +1,264 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + + +/* + * Test that the optional member (c) is really optional. + */ +uint8_t buf1[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 8, /* L */ + + /* a INTEGER */ + 64 | 3, /* [APPLICATION 3] */ + 1, /* L */ + 96, + + /* b IA5String */ + 22, /* [UNIVERSAL 22] */ + 3, /* L */ + 'x', + 'y', + 'z' +}; + +/* + * This buffer aims at checking the duplication. + */ +uint8_t buf2[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 8, /* L */ + + /* a INTEGER */ + 64 | 3, /* [APPLICATION 3] */ + 1, /* L */ + 96, + + /* a INTEGER _again_ */ + 64 | 3, /* [APPLICATION 3] */ + 1, /* L */ + 97, +}; + +/* + * This buffer checks that an unexpected member may be properly ignored. + */ +uint8_t buf3[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 14, /* L */ + + /* INTEGER */ + 64 | 3, /* [APPLICATION 3] */ + 1, /* L */ + 96, + + /* IA5String */ + 22, /* [UNIVERSAL 22] */ + 3, /* L */ + 'x', + 'y', + 'z', + + /* unexpected INTEGER */ + 64 | 4, /* [APPLICATION 4] */ + 1, /* L */ + 96, + + /* [2] BOOLEAN */ + ((2 << 6) + 2), /* [2] */ + 1, /* L */ + 0xff +}; + +/* + * This buffer checks that an unexpected member may be properly ignored. + * This time, with indefinite length encoding. + */ +uint8_t buf4[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 16, /* L */ + + /* a INTEGER */ + 64 | 3, /* [APPLICATION 3] */ + 1, /* L */ + 96, + + /* b IA5String */ + 22, /* [UNIVERSAL 22] */ + 3, /* L */ + 'x', + 'y', + 'z', + + /* unexpected data structure */ + 32 | 64 | 4, /* [APPLICATION 4] */ + 0x80, /* indefinite L */ + 64 | 1, /* [APPLICATION 1] */ + 2, /* L */ + 'a', 'b', + + 0x00, + 0x00 +}; + +/* + * This buffer checks that an unexpected member may be properly ignored. + * This time, with indefinite length encoding at the outer level too. + */ +uint8_t buf5[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 0x80, /* indefinite L */ + + /* INTEGER */ + 64 | 3, /* [APPLICATION 3] */ + 1, /* L */ + 96, + + /* IA5String */ + 22, /* [UNIVERSAL 22] */ + 3, /* L */ + 'x', + 'y', + 'z', + + /* unexpected data structure */ + 32 | 64 | 4, /* [APPLICATION 4] */ + 0x80, /* indefinite L */ + 64 | 1, /* [APPLICATION 1] */ + 2, /* L */ + 'a', 'b', + + 0x00, + 0x00, + + 0x00, + 0x00 +}; + +static void +check(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + T_t t, *tp; + asn_dec_rval_t rval; + + fprintf(stderr, "\nMust %s:\n", is_ok?"suceed":"fail"); + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "Buf %p\n", buf); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd (out of %zd)\n", + (int)rval.code, rval.consumed, size); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + + assert(t.i.size == 1); + assert(t.i.buf[0] == 96); + assert(t.s.size == 3); + assert(strcmp((char *)t.s.buf, "xyz") == 0); + if(buf == buf3) { + assert(t.b); + } else { + assert(t.b == 0); + } + } else { + if(rval.code == RC_OK) { + assert(t.i.size != 1 + || t.s.size != 3 + || !t.b + ); + } + assert(rval.consumed <= consumed); + } +} + + +static char xer_buf[128]; +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) { + T_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_T, (void **)&tp, buf, size); + assert(rval.code == RC_OK); + assert(rval.consumed == size); + assert(tp); + + xer_off = 0; + er = xer_encode(&asn_DEF_T, 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) + 20, sizeof(buf1)); + check(0, buf2, sizeof(buf2) + 1, 5); + check(1, buf3, sizeof(buf3) + 1, sizeof(buf3)); + check(1, buf4, sizeof(buf4), sizeof(buf4)); + check(1, buf5, sizeof(buf5), sizeof(buf5)); + check(1, buf5, sizeof(buf5) + 1, sizeof(buf5)); + check(0, buf5, sizeof(buf5) - 1, sizeof(buf5)); + + check_xer(buf1, sizeof(buf1), "<T><s>xyz</s><i>96</i></T>"); + check_xer(buf3, sizeof(buf3), "<T><s>xyz</s><i>96</i><b><true/></b></T>"); + + fprintf(stderr, "\nPseudo-random buffer corruptions must fail\n"); + try_corrupt(buf1, sizeof(buf1)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-31.-fwide-types.c b/asn1c/tests/check-src/check-31.-fwide-types.c new file mode 100644 index 00000000..2777d0b3 --- /dev/null +++ b/asn1c/tests/check-src/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 + +}; + +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), "<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; +} diff --git a/asn1c/tests/check-src/check-32.c b/asn1c/tests/check-src/check-32.c new file mode 100644 index 00000000..d869a90e --- /dev/null +++ b/asn1c/tests/check-src/check-32.c @@ -0,0 +1,83 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Programming.h> +#include <SeqWithMandatory.h> +#include <SeqWithOptional.h> + +int +main(int ac, char **av) { + Programming_t p; + SeqWithMandatory_t swm; + SeqWithOptional_t *swo = 0; + Error_t *err; + asn_enc_rval_t erv; + asn_dec_rval_t drv; + char buf[128]; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + /* + * No plans to fill Programming_t up: + * just checking whether it compiles or not. + */ + memset(&p, 0, sizeof(p)); + + /* + * Construct a dummy sequence: + * SeqWithMandatory ::= { + * seqOfMan [0] EXPLICIT SEQUENCE OF Error + * } + */ + err = calloc(1, sizeof *err); + memset(&swm, 0, sizeof swm); + OCTET_STRING_fromBuf(&swm.someString, "Oley", 4); + ASN_SEQUENCE_ADD(&swm.seqOfMan, err); + + /* + * Encode the sequence. + */ + erv = der_encode_to_buffer(&asn_DEF_SeqWithMandatory, + &swm, buf, sizeof buf); + assert(erv.encoded > 0); + buf[erv.encoded] = '\0'; + + /* + * Try to decode it using a compatible type. + */ + drv = ber_decode(0, &asn_DEF_SeqWithOptional, (void **)&swo, + buf, erv.encoded); + assert(drv.code == RC_OK); + assert((ssize_t)drv.consumed == erv.encoded); + assert(swo->seqOfOpt != 0); + + xer_fprint(stderr, &asn_DEF_SeqWithOptional, swo); + swo->seqOfOpt = 0; + + erv = der_encode_to_buffer(&asn_DEF_SeqWithOptional, + swo, buf, sizeof buf); + assert(erv.encoded > 0); + buf[erv.encoded] = '\0'; + + swo = 0; + drv = ber_decode(0, &asn_DEF_SeqWithMandatory, (void **)&swo, + buf, erv.encoded); + assert(drv.code != RC_OK); + swo = 0; + drv = ber_decode(0, &asn_DEF_SeqWithOptional, (void **)&swo, + buf, erv.encoded); + assert(drv.code == RC_OK); + assert((ssize_t)drv.consumed == erv.encoded); + assert(swo->seqOfOpt == 0); + + xer_fprint(stderr, &asn_DEF_SeqWithOptional, swo); + + printf("Finished\n"); + + return 0; +} diff --git a/asn1c/tests/check-src/check-33.c b/asn1c/tests/check-src/check-33.c new file mode 100644 index 00000000..61638713 --- /dev/null +++ b/asn1c/tests/check-src/check-33.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +int +main(int ac, char **av) { + T_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-35.c b/asn1c/tests/check-src/check-35.c new file mode 100644 index 00000000..23ed3270 --- /dev/null +++ b/asn1c/tests/check-src/check-35.c @@ -0,0 +1,330 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +uint8_t buf1[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 15, /* L */ + + /* b CHOICE { b2 ObjectDescriptor }*/ + 7, /* [UNIVERSAL 7] */ + 1, /* L */ + 'z', + + /* c BOOLEAN */ + 1, /* [UNIVERSAL 1] */ + 0, /* L */ + + /* a NumericString */ + 18, /* [UNIVERSAL 18] */ + 4, /* L */ + '=', + '<', + '&', + '>', + + /* d.r-oid RELATIVE-OID */ + 13, /* [UNIVERSAL 13] */ + 2, /* L */ + 85, + 79, + +}; + +uint8_t buf1_reconstr[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 16, /* L */ + + /* c BOOLEAN */ + 1, /* [UNIVERSAL 1] */ + 1, /* L */ + 0, + + /* b CHOICE { b2 ObjectDescriptor }*/ + 7, /* [UNIVERSAL 7] */ + 1, /* L */ + 'z', + + /* d.r-oid RELATIVE-OID */ + 13, /* [UNIVERSAL 1] */ + 2, /* L */ + 85, + 79, + + /* a NumericString */ + 18, /* [UNIVERSAL 18] */ + 4, /* L */ + '=', + '<', + '&', + '>', +}; + +uint8_t buf2[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 15, /* L */ + + /* a NumericString */ + 18, /* [UNIVERSAL 18] */ + 4, /* L */ + '=', + '<', + '&', + '>', + + /* c BOOLEAN */ + 1, /* [UNIVERSAL 1] */ + 1, /* L */ + 2, /* True */ + + /* b CHOICE { b1 IA5String }*/ + 22, /* [UNIVERSAL 22] */ + 1, /* L */ + 'z', + + /* d.oid RELATIVE-OID */ + 6, /* [UNIVERSAL 6] */ + 1, /* L */ + 81, + +}; + +uint8_t buf2_reconstr[] = { + 32 | 17, /* [UNIVERSAL 17], constructed */ + 15, /* L */ + + /* c BOOLEAN */ + 1, /* [UNIVERSAL 1] */ + 1, /* L */ + 0xff, /* Canonical True */ + + /* d.oid RELATIVE-OID */ + 6, /* [UNIVERSAL 6] */ + 1, /* L */ + 81, + + /* a NumericString */ + 18, /* [UNIVERSAL 18] */ + 4, /* L */ + '=', + '<', + '&', + '>', + + /* b CHOICE { b1 IA5String }*/ + 22, /* [UNIVERSAL 22] */ + 1, /* L */ + 'z' +}; + +static void +check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) { + asn_dec_rval_t rval; + + tp = memset(tp, 0, sizeof(*tp)); + + fprintf(stderr, "Buf %p (%zd)\n", buf, size); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + + assert(strcmp((char *)tp->a.buf, "=<&>") == 0); + assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0 + && strcmp((char *)tp->b.choice.b2.buf, "z") == 0); + + asn_fprint(stderr, &asn_DEF_T, tp); + xer_fprint(stderr, &asn_DEF_T, tp); +} + +size_t buf_pos; +size_t buf_size; +uint8_t *buf; + +static int +buf_fill(const void *buffer, size_t size, void *app_key) { + + (void)app_key; + + if(buf_pos + size > buf_size) { + fprintf(stderr, "%zd + %zd > %zd\n", + buf_pos, size, buf_size); + return -1; + } + + memcpy(buf + buf_pos, buffer, size); + buf_pos += size; + fprintf(stderr, " written %zd (%zd)\n", size, buf_pos); + + return 0; +} + +static void +compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) { + asn_enc_rval_t erval; + size_t i; + + buf_size = cmp_buf_size + 100; + buf = alloca(buf_size); + buf_pos = 0; + + /* + * Try to re-create using DER encoding. + */ + erval = der_encode(&asn_DEF_T, tp, buf_fill, 0); + assert(erval.encoded != -1); + if(erval.encoded != (ssize_t)cmp_buf_size) { + printf("%zd != %zd\n", erval.encoded, cmp_buf_size); + } + assert(erval.encoded == (ssize_t)cmp_buf_size); + for(i = 0; i < cmp_buf_size; i++) { + if(buf[i] != cmp_buf[i]) { + fprintf(stderr, "Recreated buffer content mismatch:\n"); + fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n", + (int)i, + buf[i], cmp_buf[i], + buf[i], cmp_buf[i] + ); + } + assert(buf[i] == cmp_buf[i]); + } +} + +static void +partial_read(uint8_t *data, size_t size) { + T_t t, *tp; + asn_dec_rval_t rval; + size_t i1, i2; + uint8_t *data1 = alloca(size); + uint8_t *data2 = alloca(size); + uint8_t *data3 = alloca(size); + + fprintf(stderr, "\nPartial read sequence...\n"); + + /* + * Divide the space (size) into three blocks in various combinations: + * |<----->i1<----->i2<----->| + * ^ data ^ data+size + * Try to read block by block. + */ + for(i1 = 0; i1 < size; i1++) { + for(i2 = i1; i2 < size; i2++) { + uint8_t *chunk1 = data; + size_t size1 = i1; + uint8_t *chunk2 = data + size1; + size_t size2 = i2 - i1; + uint8_t *chunk3 = data + size1 + size2; + size_t size3 = size - size1 - size2; + + fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n", + size, size1, size2, size3); + + memset(data1, 0, size); + memset(data2, 0, size); + memset(data3, 0, size); + memcpy(data1, chunk1, size1); + memcpy(data2, chunk2, size2); + memcpy(data3, chunk3, size3); + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "=> Chunk 1 (%zd):\n", size1); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + data1, size1); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size1); + if(rval.consumed < size1) { + int leftover = size1 - rval.consumed; + memcpy(data2, data1 + rval.consumed, leftover); + memcpy(data2 + leftover, chunk2, size2); + size2 += leftover; + } + + fprintf(stderr, "=> Chunk 2 (%zd):\n", size2); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + data2, size2); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size2); + if(rval.consumed < size2) { + int leftover = size2 - rval.consumed; + memcpy(data3, data2 + rval.consumed, leftover); + memcpy(data3 + leftover, chunk3, size3); + size3 += leftover; + } + + fprintf(stderr, "=> Chunk 3 (%zd):\n", size3); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + data3, size3); + assert(rval.code == RC_OK); + assert(rval.consumed == size3); + + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + } + } +} + +static char xer_buf[128]; +static size_t 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 *data, uint8_t size, char *xer_sample) { + T_t *tp = 0; + asn_dec_rval_t rval; + asn_enc_rval_t er; + size_t xer_sample_len = strlen(xer_sample); + + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, data, size); + assert(rval.code == RC_OK); + assert(rval.consumed == size); + assert(tp); + + xer_off = 0; + er = xer_encode(&asn_DEF_T, tp, XER_F_CANONICAL, xer_cb, 0); + assert(xer_off); + xer_buf[xer_off] = 0; + printf("[%s] (%zd/%zd) vs [%s] (%zd)\n", + xer_buf, er.encoded, xer_off, xer_sample, xer_sample_len); + assert(er.encoded == (ssize_t)xer_off); + assert(xer_off == xer_sample_len); + assert(memcmp(xer_buf, xer_sample, xer_off) == 0); +} + + +int +main(int ac, char **av) { + T_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1)); + compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + check_xer(buf1, sizeof(buf1), "<T><c><false/></c><b><b2>z</b2></b><a>=<&></a><d><r-oid>85.79</r-oid></d></T>"); + + check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2)); + compare(&t, buf2_reconstr, sizeof(buf2_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + check_xer(buf2, sizeof(buf2), "<T><c><true/></c><b><b1>z</b1></b><a>=<&></a><d><oid>2.1</oid></d></T>"); + + /* Split the buffer in parts and check decoder restartability */ + partial_read(buf1, sizeof(buf1)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-39.c b/asn1c/tests/check-src/check-39.c new file mode 100644 index 00000000..61638713 --- /dev/null +++ b/asn1c/tests/check-src/check-39.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +int +main(int ac, char **av) { + T_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-41.-fwide-types.c b/asn1c/tests/check-src/check-41.-fwide-types.c new file mode 100644 index 00000000..4dca1e65 --- /dev/null +++ b/asn1c/tests/check-src/check-41.-fwide-types.c @@ -0,0 +1,322 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +uint8_t buf0[] = { + 32 | ((2 << 6) + 1), /* [1], constructed */ + 18, + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 16, /* L */ + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', +}; + +uint8_t buf0_reconstr[] = { + 32 | ((2 << 6) + 1), /* [1], constructed */ + 18, + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 16, /* L */ + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', +}; + + + +uint8_t buf1[] = { + 32 | (2 << 6), /* [0], constructed */ + 0x80 | 1, /* L */ + 134, + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 0x80 | 1, /* L */ + 128, + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + + /* alpha [1] IMPLICIT INTEGER OPTIONAL */ + (2 << 6) + 1, /* [1] */ + 1, /* L */ + 75, +}; + +uint8_t buf1_reconstr[] = { + 32 | (2 << 6), /* [0], constructed */ + 0x80 | 1, /* L */ + 134, + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 0x80 | 1, /* L */ + 128, + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + + /* alpha [1] IMPLICIT INTEGER OPTIONAL */ + (2 << 6) + 1, /* [1] */ + 1, /* L */ + 75, +}; + +uint8_t buf2[] = { + 32 | ((2 << 6) + 1), /* [1], constructed */ + 0x80 | 1, /* L */ + 134, + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 0x80 | 1, /* L */ + 128, + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + + /* beta [2] IMPLICIT INTEGER OPTIONAL */ + (2 << 6) + 2, /* [2] */ + 1, /* L */ + 75, +}; + +uint8_t buf2_reconstr[] = { + 32 | ((2 << 6) + 1), /* [1], constructed */ + 0x80 | 1, /* L */ + 134, + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 0x80 | 1, /* L */ + 128, + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + + /* beta [2] IMPLICIT INTEGER OPTIONAL */ + (2 << 6) + 2, /* [2] */ + 1, /* L */ + 75, +}; + + + + + +static void +check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) { + asn_dec_rval_t rval; + int ret; + + tp = memset(tp, 0, sizeof(*tp)); + + fprintf(stderr, "Buf %p (%zd)\n", buf, size); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + + fprintf(stderr, "=== asn_fprint() ===\n"); + ret = asn_fprint(stderr, &asn_DEF_T, tp); + assert(ret == 0); + fprintf(stderr, "=== xer_fprint() ===\n"); + ret = xer_fprint(stderr, &asn_DEF_T, tp); + fprintf(stderr, "=== END ===\n"); + assert(ret == 0); + + /* + assert(tp->string.size == 128); + assert(strncmp(tp->string.buf, "zz") == 0); + assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0 + && strcmp((char *)tp->b.choice.b2.buf, "z") == 0); + */ +} + +size_t buf_pos; +size_t buf_size; +uint8_t *buffer; + +static int +buf_fill(const void *bufp, size_t size, void *app_key) { + + (void)app_key; /* Unused argument */ + + if(buf_pos + size > buf_size) { + fprintf(stderr, "%zd + %zd > %zd\n", + buf_pos, size, buf_size); + return -1; + } + + memcpy(buffer + buf_pos, bufp, size); + buf_pos += size; + fprintf(stderr, " written %zd (%zd)\n", size, buf_pos); + + return 0; +} + +static void +compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) { + asn_enc_rval_t erval; + size_t i; + + buf_size = cmp_buf_size + 100; + buffer = alloca(buf_size); + buf_pos = 0; + + /* + * Try to re-create using DER encoding. + */ + erval = der_encode(&asn_DEF_T, tp, buf_fill, 0); + assert(erval.encoded != -1); + if(erval.encoded != (ssize_t)cmp_buf_size) { + printf("%zd != %zd\n", erval.encoded, cmp_buf_size); + } + assert(erval.encoded == (ssize_t)cmp_buf_size); + for(i = 0; i < cmp_buf_size; i++) { + if(buffer[i] != cmp_buf[i]) { + fprintf(stderr, "Recreated buffer content mismatch:\n"); + fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n", + (int)i, + buffer[i], cmp_buf[i], + buffer[i], cmp_buf[i] + ); + } + assert(buffer[i] == cmp_buf[i]); + } +} + +static void +partial_read(uint8_t *data, size_t size) { + T_t t, *tp; + asn_dec_rval_t rval; + size_t i1, i2; + uint8_t *data1 = alloca(size); + uint8_t *data2 = alloca(size); + uint8_t *data3 = alloca(size); + + fprintf(stderr, "\nPartial read sequence...\n"); + + /* + * Divide the space (size) into three blocks in various combinations: + * |<----->i1<----->i2<----->| + * ^ data ^ data+size + * Try to read block by block. + */ + for(i1 = 0; i1 < size; i1++) { + for(i2 = i1; i2 < size; i2++) { + uint8_t *chunk1 = data; + size_t size1 = i1; + uint8_t *chunk2 = data + size1; + size_t size2 = i2 - i1; + uint8_t *chunk3 = data + size1 + size2; + size_t size3 = size - size1 - size2; + + fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n", + size, size1, size2, size3); + + memset(data1, 0, size); + memset(data2, 0, size); + memset(data3, 0, size); + memcpy(data1, chunk1, size1); + memcpy(data2, chunk2, size2); + memcpy(data3, chunk3, size3); + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "=> Chunk 1 (%zd):\n", size1); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + data1, size1); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size1); + if(rval.consumed < size1) { + int leftover = size1 - rval.consumed; + memcpy(data2, data1 + rval.consumed, leftover); + memcpy(data2 + leftover, chunk2, size2); + size2 += leftover; + } + + fprintf(stderr, "=> Chunk 2 (%zd):\n", size2); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + data2, size2); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size2); + if(rval.consumed < size2) { + int leftover = size2 - rval.consumed; + memcpy(data3, data2 + rval.consumed, leftover); + memcpy(data3 + leftover, chunk3, size3); + size3 += leftover; + } + + fprintf(stderr, "=> Chunk 3 (%zd):\n", size3); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + data3, size3); + assert(rval.code == RC_OK); + assert(rval.consumed == size3); + + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + } + } +} + +int +main() { + T_t t; + + /* Check exact buf0 */ + check(&t, buf0, sizeof(buf0), sizeof(buf0)); + compare(&t, buf0_reconstr, sizeof(buf0_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Check exact buf1 */ + check(&t, buf1, sizeof(buf1), sizeof(buf1)); + compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Check slightly more than buf1 */ + check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1)); + compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Check exact buf2 */ + check(&t, buf2, sizeof(buf2), sizeof(buf2)); + compare(&t, buf2_reconstr, sizeof(buf2_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Check slightly more than buf2 */ + check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2)); + compare(&t, buf2_reconstr, sizeof(buf2_reconstr)); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Split the buffer in parts and check decoder restartability */ + partial_read(buf0, sizeof(buf0)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-41.c b/asn1c/tests/check-src/check-41.c new file mode 100644 index 00000000..1c1b9072 --- /dev/null +++ b/asn1c/tests/check-src/check-41.c @@ -0,0 +1,219 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + + +uint8_t buf1[] = { + 32 | (2 << 6), /* [0], constructed */ + 25, /* L */ + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 16, /* L */ + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + + /* beta [2] IMPLICIT INTEGER OPTIONAL */ + (2 << 6) + 2, /* [2] */ + 5, /* L */ + 0, + 75, + 0x4b, + 75, + 75, +}; + +uint8_t buf1_reconstr[] = { + 32 | (2 << 6), /* [0], constructed */ + 24, /* L */ + + /* string [0] IMPLICIT UTF8String, */ + (2 << 6), /* [0] */ + 16, /* L */ + 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', + + /* beta [2] IMPLICIT INTEGER OPTIONAL */ + (2 << 6) + 2, /* [2] */ + 4, /* L */ + 75, + 75, + 75, + 0x4b, +}; + + +static void +check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) { + asn_dec_rval_t rval; + + tp = memset(tp, 0, sizeof(*tp)); + + fprintf(stderr, "Buf %p (%zd)\n", buf, size); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + + assert(tp->choice.seq.string.size == 16); + assert(strcmp((char *)tp->choice.seq.string.buf, "zzzzzzzzzzzzzzzz") == 0); + assert(tp->choice.seq.alpha == NULL); + assert(tp->choice.seq.beta); + assert(*tp->choice.seq.beta == 0x4b4b4b4b); +} + +size_t buf_pos; +size_t buf_size; +uint8_t *buf; + +static int +buf_fill(const void *buffer, size_t size, void *app_key) { + + (void)app_key; /* Unused argument */ + + if(buf_pos + size > buf_size) { + fprintf(stderr, "%zd + %zd > %zd\n", + buf_pos, size, buf_size); + return -1; + } + + memcpy(buf + buf_pos, buffer, size); + buf_pos += size; + fprintf(stderr, " written %zd (%zd)\n", size, buf_pos); + + return 0; +} + +static void +compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) { + asn_enc_rval_t erval; + int i; + + buf_size = cmp_buf_size + 100; + buf = alloca(buf_size); + buf_pos = 0; + + /* + * Try to re-create using DER encoding. + */ + erval = der_encode(&asn_DEF_T, tp, buf_fill, 0); + assert(erval.encoded != -1); + if(erval.encoded != cmp_buf_size) { + printf("%zd != %zd\n", erval.encoded, cmp_buf_size); + } + assert(erval.encoded == cmp_buf_size); + for(i = 0; i < cmp_buf_size; i++) { + if(buf[i] != cmp_buf[i]) { + fprintf(stderr, "Recreated buffer content mismatch:\n"); + fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n", + i, + buf[i], cmp_buf[i], + buf[i], cmp_buf[i] + ); + } + assert(buf[i] == cmp_buf[i]); + } +} + +static void +partial_read(uint8_t *buf_0, size_t size) { + T_t t, *tp; + asn_dec_rval_t rval; + size_t i1, i2; + uint8_t *buf_1 = alloca(size); + uint8_t *buf_2 = alloca(size); + uint8_t *buf_3 = alloca(size); + + fprintf(stderr, "\nPartial read sequence...\n"); + + /* + * Divide the space (size) into three blocks in various combinations: + * |<----->i1<----->i2<----->| + * ^ buf_0 ^ buf_0+size + * Try to read block by block. + */ + for(i1 = 0; i1 < size; i1++) { + for(i2 = i1; i2 < size; i2++) { + uint8_t *chunk1 = buf_0; + size_t size1 = i1; + uint8_t *chunk2 = buf_0 + size1; + size_t size2 = i2 - i1; + uint8_t *chunk3 = buf_0 + size1 + size2; + size_t size3 = size - size1 - size2; + + fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n", + size, size1, size2, size3); + + memset(buf_1, 0, size); + memset(buf_2, 0, size); + memset(buf_3, 0, size); + memcpy(buf_1, chunk1, size1); + memcpy(buf_2, chunk2, size2); + memcpy(buf_3, chunk3, size3); + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "=> Chunk 1 (%zd):\n", size1); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + buf_1, size1); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size1); + if(rval.consumed < size1) { + int leftover = size1 - rval.consumed; + memcpy(buf_2, buf_1 + rval.consumed, leftover); + memcpy(buf_2 + leftover, chunk2, size2); + size2 += leftover; + } + + fprintf(stderr, "=> Chunk 2 (%zd):\n", size2); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + buf_2, size2); + assert(rval.code == RC_WMORE); + assert(rval.consumed <= size2); + if(rval.consumed < size2) { + int leftover = size2 - rval.consumed; + memcpy(buf_3, buf_2 + rval.consumed, leftover); + memcpy(buf_3 + leftover, chunk3, size3); + size3 += leftover; + } + + fprintf(stderr, "=> Chunk 3 (%zd):\n", size3); + rval = ber_decode(0, &asn_DEF_T, (void **)&tp, + buf_3, size3); + assert(rval.code == RC_OK); + assert(rval.consumed == size3); + + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + } + } +} + +int +main(int ac, char **av) { + T_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + /* Check exact buf1 */ + check(&t, buf1, sizeof(buf1), sizeof(buf1)); + compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); + asn_fprint(stderr, &asn_DEF_T, &t); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Check slightly more than buf1 */ + check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1)); + compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); + asn_fprint(stderr, &asn_DEF_T, &t); + asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); + + /* Split the buffer in parts and check decoder restartability */ + partial_read(buf1, sizeof(buf1)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-42.c b/asn1c/tests/check-src/check-42.c new file mode 100644 index 00000000..db4ccb76 --- /dev/null +++ b/asn1c/tests/check-src/check-42.c @@ -0,0 +1,142 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <LogLine.h> + +uint8_t buf0[] = { + 48, /* LogLine SEQUENCE */ + 24, /* L */ + 22, /* IA5String */ + 4, /* L */ + /* "zzz\007" */ + 122, 122, 122, 7, + 48, /* varsets SEQUENCE OF VariablePartSet */ + 16, /* L */ + 48, /* VariablePart */ + 14, /* L */ + 48, /* vparts SEQUENCE OF VariablePart */ + 7, /* L */ + 49, /* VariablePart */ + 5, + 26, /* VisibleString */ + 3, + 49, 50, 51, /* 1 2 3 */ + 48, /* ActionItem SEQUENCE */ + 3, /* L */ + 10, /* accept-as ENUMERATED */ + 1, /* L */ + 0, +}; + +uint8_t buf1[] = { + 48, /* LogLine SEQUENCE */ + 19, /* L */ + 22, /* IA5String */ + 6, /* L */ + /* "static" */ + 115, 116, 97, 116, 105, 99, + 48, /* varsets SEQUENCE OF VariablePartSet */ + 9, /* L */ + 48, /* VariablePart */ + 7, /* L */ + 48, /* vparts SEQUENCE OF VariablePart */ + 0, /* L */ + 48, /* ActionItem SEQUENCE */ + 3, /* L */ + 10, /* accept-as ENUMERATED */ + 1, /* L */ + 0, +}; + +static void +check(LogLine_t *tp, uint8_t *ptr, size_t size, size_t consumed) { + asn_dec_rval_t rval; + + tp = memset(tp, 0, sizeof(*tp)); + + fprintf(stderr, "Buf %p (%zd)\n", ptr, size); + rval = ber_decode(0, &asn_DEF_LogLine, (void **)&tp, ptr, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + asn_fprint(stderr, &asn_DEF_LogLine, tp); + asn_DEF_LogLine.free_struct(&asn_DEF_LogLine, tp, 1); +} + +uint8_t *buf; +uint8_t buf_size; +uint8_t buf_pos; + + +static int +buf_fill(const void *buffer, size_t size, void *app_key) { + + (void)app_key; /* Unused argument */ + + assert(buf_pos + size <= buf_size); + + memcpy(buf + buf_pos, buffer, size); + buf_pos += size; + + return 0; +} + +static void +check_serialize() { + LogLine_t ll; + VariablePartSet_t vps; + VariablePart_t vp; + VisibleString_t vpart; + asn_enc_rval_t erval; + int i; + + memset(&ll, 0, sizeof(ll)); + memset(&vps, 0, sizeof(vps)); + memset(&vp, 0, sizeof(vp)); + memset(&vpart, 0, sizeof(vpart)); + vpart.buf = (uint8_t *)"123"; + vpart.size = 3; + + vp.present = VariablePart_PR_vset; + ASN_SET_ADD(&vp.choice.vset, &vpart); + vps.resolution.accept_as = accept_as_unknown; + ASN_SEQUENCE_ADD(&vps.vparts, &vp); + ASN_SEQUENCE_ADD(&ll.varsets, &vps); + ll.line_digest.buf = (uint8_t *)"zzz\007"; + ll.line_digest.size = 4; + + asn_fprint(stderr, &asn_DEF_LogLine, &ll); + buf_size = 128; + buf = alloca(buf_size); + erval = der_encode(&asn_DEF_LogLine, &ll, buf_fill, 0); + assert(erval.encoded > 1); + fprintf(stderr, "Encoded in %zd bytes\n", erval.encoded); + fprintf(stderr, "\n"); + for(i = 0; i < buf_pos; i++) { + fprintf(stderr, "%d ", buf[i]); + } + fprintf(stderr, "\n\n"); + assert(erval.encoded == sizeof(buf0)); + assert(memcmp(buf0, buf, sizeof(buf0)) == 0); +} + +int +main(int ac, char **av) { + LogLine_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + check_serialize(); + + check(&t, buf0, sizeof(buf0), sizeof(buf0)); + check(&t, buf1, sizeof(buf1), sizeof(buf1)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-43.c b/asn1c/tests/check-src/check-43.c new file mode 100644 index 00000000..4a613854 --- /dev/null +++ b/asn1c/tests/check-src/check-43.c @@ -0,0 +1,27 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Test-structure-1.h> +#include <Choice-1.h> + +int +main(int ac, char **av) { + Test_structure_1_t ts1; + Choice_1_t cs1; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&ts1, 0, sizeof(ts1)); + memset(&cs1, 0, sizeof(cs1)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-44.c b/asn1c/tests/check-src/check-44.c new file mode 100644 index 00000000..f7c28354 --- /dev/null +++ b/asn1c/tests/check-src/check-44.c @@ -0,0 +1,66 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +uint8_t buf1[] = { + 32 | ((3 << 6) + 1), /* [PRIVATE 1], constructed */ + 4, /* L */ + ((3 << 6) + 2), /* [PRIVATE 2], primitive */ + 0, /* L */ + ((3 << 6) + 5), /* [PRIVATE 5], primitive */ + 0, /* L */ +}; + +uint8_t buf2[] = { + 32 | ((3 << 6) + 1), /* [PRIVATE 1], constructed */ + 6, /* L */ + ((3 << 6) + 2), /* [PRIVATE 2], primitive */ + 0, /* L */ + 32 | ((3 << 6) + 9), /* [PRIVATE 9], constructed */ + 2, + ((3 << 6) + 1), /* [PRIVATE 1], primitive */ + 0, /* L */ +}; + +static void +check(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + T_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_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + } else { + if(rval.code == RC_OK) { + } + assert(rval.consumed <= consumed); + } +} + +int +main(int ac, char **av) { + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + check(1, buf1, sizeof(buf1), sizeof(buf1)); + check(0, buf1, sizeof(buf1) - 1, sizeof(buf1) - 1); + check(0, buf1, sizeof(buf1) - 2, sizeof(buf1) - 2); + + check(1, buf2, sizeof(buf2), sizeof(buf2)); + check(0, buf2, sizeof(buf2) - 1, sizeof(buf2)); + + return 0; +} diff --git a/asn1c/tests/check-src/check-46.c b/asn1c/tests/check-src/check-46.c new file mode 100644 index 00000000..6e50f645 --- /dev/null +++ b/asn1c/tests/check-src/check-46.c @@ -0,0 +1,46 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> + +uint8_t buf1[] = { + 32 | ((2 << 6) + 3), /* [3], constructed */ + 5, + ((2 << 6) + 5), /* [5], primitive */ + 3, /* L */ + 'a', + 'b', + 'c', +}; + +static void +check(uint8_t *buf, size_t size, size_t consumed) { + T_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_T, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); +} + +int +main(int ac, char **av) { + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + check(buf1, sizeof(buf1), sizeof(buf1)); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-48.c b/asn1c/tests/check-src/check-48.c new file mode 100644 index 00000000..f8a79189 --- /dev/null +++ b/asn1c/tests/check-src/check-48.c @@ -0,0 +1,98 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +#include <UserIdentifier.h> + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + printf("=> ["); + for(; b < bend; b++) + printf(" %02X", *b); + printf("]:%zd\n", size); + buf_offset += size; + return 0; +} + +static int +save_object(void *bs, asn_TYPE_descriptor_t *td) { + asn_enc_rval_t rval; /* Return value */ + int i; + + rval = der_encode(td, bs, _buf_writer, 0); + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return -1; /* JIC */ + } + + buf[buf_offset++] = 123; /* Finalize with garbage */ + + asn_fprint(stderr, td, bs); + xer_fprint(stderr, td, bs); + + printf("OUT: ["); + for(i = 0; i < buf_offset; i++) + printf(" %02x", buf[i]); + printf("]\n"); + + return 0; +} + +static int +load_object(void *bs, asn_TYPE_descriptor_t *td) { + asn_dec_rval_t rval; + + fprintf(stderr, "\nLOADING OBJECT OF SIZE %d\n", buf_offset); + + rval = ber_decode(0, td, (void **)&bs, buf, buf_offset); + assert(rval.code == RC_OK); + + asn_fprint(stderr, td, bs); + xer_fprint(stderr, td, bs); + + return (rval.code == RC_OK)?0:-1; +} + +int +main() { + asn_TYPE_descriptor_t *td = &asn_DEF_UserIdentifier; + UserIdentifier_t user; + UserIdentifier_t user_new; + int ret; + + memset(&user, 0, sizeof user); + memset(&user_new, 0, sizeof user_new); + + user.present = UserIdentifier_PR_phoneNumber; + OCTET_STRING_fromBuf( + &user.choice.phoneNumber, + "0123456789", -1); + + /* Save->Load must succeed */ + save_object(&user, td); + ret = load_object(&user_new, td); + + assert(user_new.present == UserIdentifier_PR_phoneNumber); + + assert(ret == 0); + + printf("OK\n"); + + return ret; +} diff --git a/asn1c/tests/check-src/check-50.c b/asn1c/tests/check-src/check-50.c new file mode 100644 index 00000000..cfdd6006 --- /dev/null +++ b/asn1c/tests/check-src/check-50.c @@ -0,0 +1,23 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Int5.h> +#include <Str4.h> +#include <Utf8-4.h> +#include <VisibleIdentifier.h> + +int +main(int ac, char **av) { + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-59.c b/asn1c/tests/check-src/check-59.c new file mode 100644 index 00000000..ba970bed --- /dev/null +++ b/asn1c/tests/check-src/check-59.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Choice.h> + +int +main(int ac, char **av) { + Choice_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-60.c b/asn1c/tests/check-src/check-60.c new file mode 100644 index 00000000..f871dbb4 --- /dev/null +++ b/asn1c/tests/check-src/check-60.c @@ -0,0 +1,203 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +#include <T1.h> +#include <T2.h> + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + printf("=> ["); + for(; b < bend; b++) + printf(" %02X", *b); + printf("]:%zd\n", size); + buf_offset += size; + return 0; +} + +static int +save_object(void *bs, asn_TYPE_descriptor_t *td) { + asn_enc_rval_t rval; /* Return value */ + int i; + + buf_offset = 0; + + rval = der_encode(td, bs, _buf_writer, 0); + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return -1; /* JIC */ + } + + buf[buf_offset++] = 0xab; /* Finalize with garbage */ + + asn_fprint(stderr, td, bs); + + printf("OUT: ["); + for(i = 0; i < buf_offset; i++) + printf(" %02x", buf[i]); + printf("]\n"); + + return 0; +} + +static int +load_object(void *bs, asn_TYPE_descriptor_t *td) { + asn_dec_rval_t rval; + + fprintf(stderr, "\nLOADING OBJECT OF SIZE %d\n", buf_offset); + + rval = ber_decode(0, td, (void **)&bs, buf, buf_offset); + assert(rval.code == RC_OK); + + asn_fprint(stderr, td, bs); + + return (rval.code == RC_OK)?0:-1; +} + +/* [3] IMPLICIT SEQUENCE { b BOOLEAN } */ +uint8_t test_any_buf1[] = { 0xa3, 0x80, /* [3], constructed, indefinite */ + 0x01, 0x01, 0xff, /* b BOOLEAN ::= TRUE */ + 0x00, 0x00 /* End of content octets */ }; + +/* b BOOLEAN */ +uint8_t test_any_buf2[] = { 0x01, 0x01, 0x13 }; + +int +main() { + asn_TYPE_descriptor_t *td1 = &asn_DEF_T1; + asn_TYPE_descriptor_t *td2 = &asn_DEF_T2; + T1_t t1, t1_new; + T2_t t2, t2_new; + int ret; + + /* + * Test the T1 with constructed indefinite length ANY encoding. + */ + memset(&t1, 0, sizeof(t1)); + memset(&t1_new, 0, sizeof(t1_new)); + + t1.i = 112233; + t1.any.buf = test_any_buf1; + t1.any.size = sizeof(test_any_buf1); + + /* Save->Load must succeed */ + save_object(&t1, td1); + ret = load_object(&t1_new, td1); + + assert(ret == 0); + assert(t1_new.i == 112233); + assert(t1_new.any.size == (ssize_t)sizeof(test_any_buf1)); + assert(memcmp(t1_new.any.buf, test_any_buf1, sizeof(test_any_buf1)) == 0); + + /* + * Test the T1 with primitive encoding. + */ + memset(&t1, 0, sizeof(t1)); + memset(&t1_new, 0, sizeof(t1_new)); + + t1.i = -112233; + t1.any.buf = test_any_buf2; + t1.any.size = sizeof(test_any_buf2); + + /* Save->Load must succeed */ + save_object(&t1, td1); + ret = load_object(&t1_new, td1); + + assert(ret == 0); + assert(t1_new.i == -112233); + assert(t1_new.any.size == (ssize_t)sizeof(test_any_buf2)); + assert(memcmp(t1_new.any.buf, test_any_buf2, sizeof(test_any_buf2)) == 0); + + /* + * Test the T2 empty sequence. + */ + memset(&t2, 0, sizeof(t2)); + memset(&t2_new, 0, sizeof(t2_new)); + + t2.i = 332211; + t2.any = calloc(1, sizeof(*t2.any)); + t2.any->buf = 0; + t2.any->size = 0; + + /* Save->Load must succeed */ + save_object(&t2, td2); + ret = load_object(&t2_new, td2); + + assert(ret == 0); + assert(t2_new.i == 332211); + assert(t2_new.any->size == 0); + + /* + * Test the T2 sequence. + */ + memset(&t2, 0, sizeof(t2)); + memset(&t2_new, 0, sizeof(t2_new)); + + t2.i = 332211; + t2.any = calloc(1, sizeof(*t2.any)); + t2.any->buf = test_any_buf1; + t2.any->size = sizeof(test_any_buf1); + + /* Save->Load must succeed */ + save_object(&t2, td2); + ret = load_object(&t2_new, td2); + + assert(ret == 0); + assert(t2_new.i == 332211); + assert(t2_new.any->size == (ssize_t)sizeof(test_any_buf1)); + assert(memcmp(t2_new.any->buf, test_any_buf1, sizeof(test_any_buf1)) == 0); + + /* + * Test the T2 sequence with primitive encoding. + */ + memset(&t2, 0, sizeof(t2)); + memset(&t2_new, 0, sizeof(t2_new)); + + t2.i = 0; + t2.any = calloc(1, sizeof(*t2.any)); + t2.any->buf = test_any_buf2; + t2.any->size = sizeof(test_any_buf2); + + /* Save->Load must succeed */ + save_object(&t2, td2); + ret = load_object(&t2_new, td2); + + assert(ret == 0); + assert(t2_new.i == 0); + assert(t2_new.any->size == (ssize_t)sizeof(test_any_buf2)); + assert(memcmp(t2_new.any->buf, test_any_buf2, sizeof(test_any_buf2)) == 0); + + /* + * Test T2 with ANY element omitted. + */ + free(t2.any); + t2.any = 0; + memset(&t2_new, 0, sizeof(t2_new)); + + save_object(&t2, td2); + ret = load_object(&t2_new, td2); + + assert(ret == 0); + assert(t2_new.i == 0); + assert(t2_new.any == 0); + + printf("OK\n"); + + return ret; +} diff --git a/asn1c/tests/check-src/check-62.c b/asn1c/tests/check-src/check-62.c new file mode 100644 index 00000000..7c1864bc --- /dev/null +++ b/asn1c/tests/check-src/check-62.c @@ -0,0 +1,220 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2), getcwd(3) */ +#include <string.h> +#include <dirent.h> +#include <assert.h> +#include <errno.h> + +#include <T.h> + +#ifndef SRCDIR +#define SRCDIR_S ".." +#else +#define STRINGIFY_MACRO2(x) #x +#define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x) +#define SRCDIR_S STRINGIFY_MACRO(SRCDIR) +#endif + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_BROKEN, /* Decoding must fail */ + EXP_RECLESS, /* Reconstruction is allowed to yield less data */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ +}; + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + printf("=> ["); + for(; b < bend; b++) + printf(" %02X", *b); + printf("]:%zd\n", size); + buf_offset += size; + return 0; +} + +static int +save_object(T_t *st) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + rval = der_encode(&asn_DEF_T, st, _buf_writer, 0); + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return -1; /* JIC */ + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); + + return 0; +} + +static T_t * +load_object(enum expectation expectation, unsigned char *fbuf, size_t size) { + asn_dec_rval_t rval; + T_t *st = 0; + int csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %d\n", (int)size); + + /* Perform multiple iterations with multiple chunks sizes */ + for(csize = 1; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + if(st) asn_DEF_T.free_struct(&asn_DEF_T, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding from %d with %d (left %d)\n", + fbuf_offset, fbuf_chunk, fbuf_left); + rval = ber_decode(0, &asn_DEF_T, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + assert(fbuf_offset == (ssize_t)size); + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_T.free_struct(&asn_DEF_T, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_T, st); + return st; +} + + +static void +process_data(enum expectation expectation, unsigned char *fbuf, ssize_t size) { + T_t *st; + int ret; + + st = load_object(expectation, fbuf, size); + if(!st) return; + + ret = save_object(st); + assert(buf_offset < (ssize_t)sizeof(buf)); + assert(ret == 0); + + switch(expectation) { + case EXP_RECLESS: + assert(buf_offset > 0 && buf_offset < size); + assert(memcmp(buf + 2, fbuf + 2, buf_offset - 2) == 0); + break; + case EXP_DIFFERENT: + assert(buf_offset > 0 && buf_offset < size); + break; + case EXP_BROKEN: + assert(buf_offset != size + || memcmp(buf, fbuf, buf_offset)); + break; + case EXP_OK: + assert(buf_offset == (ssize_t)size); + assert(memcmp(buf, fbuf, buf_offset) == 0); + break; + } + + asn_DEF_T.free_struct(&asn_DEF_T, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + char prevdir[256]; + unsigned char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int ret; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".ber")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'L': /* Extensions are present */ + expectation = EXP_RECLESS; break; + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + getcwd(prevdir, sizeof(prevdir)); + ret = chdir(SRCDIR_S "/data-62"); + assert(ret == 0); + fp = fopen(fname, "r"); + ret = chdir(prevdir); + assert(ret == 0); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd < (ssize_t)sizeof(fbuf)); /* expect small files */ + + process_data(expectation, fbuf, rd); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + dir = opendir(SRCDIR_S "/data-62"); + assert(dir); + + str = getenv("DATA_62_FILE"); + if(str && strncmp(str, "data-62-", 8) == 0) + process(str); + + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-62-", 8) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-65.c b/asn1c/tests/check-src/check-65.c new file mode 100644 index 00000000..061a3aad --- /dev/null +++ b/asn1c/tests/check-src/check-65.c @@ -0,0 +1,113 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <T.h> +#include <T1.h> + +uint8_t buf1[] = { + 32 | ((2 << 6) + 2), /* [2], constructed */ + 6, + 32 | ((2 << 6) + 3), /* [3], constructed */ + 4, + 32 | ((2 << 6) + 4), /* [4], constructed */ + 2, + 0 | ((2 << 6) + 6), /* [6], primitive */ + 0 +}; + +uint8_t buf2[] = { + + 32 | ((2 << 6) + 0), /* [0], constructed */ + 23, + + 32 | ((2 << 6) + 1), /* [1], constructed */ + 6, + 32 | ((2 << 6) + 4), /* [4], constructed */ + 4, + 0 | ((2 << 6) + 6), /* [6], primitive */ + 2, + 0xC0, + 0x00, + + 32 | ((2 << 6) + 2), /* [2], constructed */ + 6, + 32 | ((2 << 6) + 4), /* [4], constructed */ + 4, + 0 | ((2 << 6) + 6), /* [6], primitive */ + 2, + 0x80, + 0x00, + + 32 | ((2 << 6) + 3), /* [3], constructed */ + 5, + 0 | ((2 << 6) + 6), /* [6], primitive */ + 3, + 0x80, + 0x01, + 0x02, +}; + +static void +check_1(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + asn_TYPE_descriptor_t *td = &asn_DEF_T1; + asn_dec_rval_t rval; + T1_t t, *tp; + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "Buf %p\n", buf); + rval = ber_decode(0, td, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + } else { + if(rval.code == RC_OK) { + } + assert(rval.consumed <= consumed); + } +} + +static void +check_2(int is_ok, uint8_t *buf, size_t size, size_t consumed) { + asn_TYPE_descriptor_t *td = &asn_DEF_T; + asn_dec_rval_t rval; + T_t t, *tp; + + tp = memset(&t, 0, sizeof(t)); + + fprintf(stderr, "Buf %p\n", buf); + rval = ber_decode(0, td, (void **)&tp, buf, size); + fprintf(stderr, "Returned code %d, consumed %zd\n", + (int)rval.code, rval.consumed); + + if(is_ok) { + assert(rval.code == RC_OK); + assert(rval.consumed == consumed); + } else { + if(rval.code == RC_OK) { + } + assert(rval.consumed <= consumed); + } +} + +int +main(int ac, char **av) { + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + check_1(1, buf1, sizeof(buf1), sizeof(buf1)); + check_1(0, buf1, sizeof(buf1) - 1, sizeof(buf1) - 1); + + check_2(1, buf2, sizeof(buf2), sizeof(buf2)); + check_2(0, buf2, sizeof(buf2) - 1, sizeof(buf2) - 1); + + return 0; +} diff --git a/asn1c/tests/check-src/check-70.-fwide-types.c b/asn1c/tests/check-src/check-70.-fwide-types.c new file mode 100644 index 00000000..3a42e99a --- /dev/null +++ b/asn1c/tests/check-src/check-70.-fwide-types.c @@ -0,0 +1,336 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into DER, + * then decoded from DER and encoded into XER again. The resulting + * stream is checked against rules specified in ../data-70/README file. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2), getcwd(3) */ +#include <string.h> +#include <ctype.h> +#include <dirent.h> +#include <assert.h> +#include <errno.h> + +#include <PDU.h> + +#ifndef SRCDIR +#define SRCDIR_S ".." +#else +#define STRINGIFY_MACRO2(x) #x +#define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x) +#define SRCDIR_S STRINGIFY_MACRO(SRCDIR) +#endif + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_CXER_EXACT, /* Encoding/decoding using CXER must be exact */ + EXP_CXER_DIFF, /* Encoding/decoding using CXER must be different */ + EXP_BROKEN, /* Decoding must fail */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ +}; + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + for(; b < bend; b++) { + if(*b >= 32 && *b < 127 && *b != '%') + fprintf(stderr, "%c", *b); + else + fprintf(stderr, "%%%02x", *b); + } + fprintf(stderr, "]:%zd\n", size); + buf_offset += size; + return 0; +} + +enum der_or_xer { + AS_DER, + AS_XER, + AS_CXER, +}; + +static void +save_object_as(PDU_t *st, enum der_or_xer how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + case AS_CXER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_CANONICAL, + _buf_writer, 0); + break; + } + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); +} + +static PDU_t * +load_object_from(enum expectation expectation, unsigned char *fbuf, size_t size, enum der_or_xer how) { + asn_dec_rval_t rval; + asn_dec_rval_t (*zer_decode)(struct asn_codec_ctx_s *, + asn_TYPE_descriptor_t *, void **, const void *, size_t); + PDU_t *st = 0; + size_t csize = 1; + + if(how == AS_DER) + zer_decode = ber_decode; + else + zer_decode = xer_decode; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %zd, chunks %zd\n", + size, csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + rval = zer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + if(how == AS_DER) { + assert(fbuf_offset == (ssize_t)size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == (ssize_t)size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == (ssize_t)size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(void *obufp, size_t osize, void *nbufp, size_t nsize) { + char *obuf = obufp; + char *nbuf = nbufp; + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +process_XER_data(enum expectation expectation, unsigned char *fbuf, size_t size) { + PDU_t *st; + + st = load_object_from(expectation, fbuf, size, AS_XER); + if(!st) return; + + /* Save and re-load as DER */ + save_object_as(st, AS_DER); + st = load_object_from(expectation, buf, buf_offset, AS_DER); + assert(st); + + save_object_as(st, + (expectation == EXP_CXER_EXACT + || expectation == EXP_CXER_DIFF) + ? AS_CXER : AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + switch(expectation) { + case EXP_DIFFERENT: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_BROKEN: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_CXER_EXACT: + buf[buf_offset++] = '\n'; + assert((ssize_t)size == buf_offset); + assert(memcmp(fbuf, buf, size) == 0); + break; + case EXP_CXER_DIFF: + buf[buf_offset++] = '\n'; + assert((ssize_t)size != buf_offset + || memcmp(fbuf, buf, size)); + break; + case EXP_OK: + assert(xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + } + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + char prevdir[256]; + unsigned char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int ret; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'E': /* Byte to byte exact reconstruction */ + expectation = EXP_CXER_EXACT; break; + case 'X': /* Should fail byte-to-byte comparison */ + expectation = EXP_CXER_DIFF; break; + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + getcwd(prevdir, sizeof(prevdir)); + ret = chdir(SRCDIR_S "/data-70"); + assert(ret == 0); + fp = fopen(fname, "r"); + ret = chdir(prevdir); + assert(ret == 0); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd < (ssize_t)sizeof(fbuf)); /* expect small files */ + + process_XER_data(expectation, fbuf, rd); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_70_FILE"); + if(str && strncmp(str, "data-70-", 8) == 0) { + process(str); + return 0; + } + + dir = opendir(SRCDIR_S "/data-70"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-70-", 8) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-70.c b/asn1c/tests/check-src/check-70.c new file mode 100644 index 00000000..d09f095a --- /dev/null +++ b/asn1c/tests/check-src/check-70.c @@ -0,0 +1,308 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into DER, + * then decoded from DER and encoded into XER again. The resulting + * stream is compared with the corresponding .out file. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2), getcwd(3) */ +#include <string.h> +#include <dirent.h> +#include <ctype.h> /* for isspace(3) */ +#include <assert.h> +#include <errno.h> + +#include <PDU.h> + +#ifndef SRCDIR +#define SRCDIR_S ".." +#else +#define STRINGIFY_MACRO2(x) #x +#define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x) +#define SRCDIR_S STRINGIFY_MACRO(SRCDIR) +#endif + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_BROKEN, /* Decoding must fail */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ +}; + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + for(; b < bend; b++) + fprintf(stderr, "%c", *b); + fprintf(stderr, "]:%zd\n", size); + buf_offset += size; + return 0; +} + +enum der_or_xer { + AS_DER, + AS_XER, +}; + +static void +save_object_as(PDU_t *st, enum der_or_xer how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + } + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); +} + +static PDU_t * +load_object_from(enum expectation expectation, unsigned char *fbuf, size_t size, enum der_or_xer how) { + asn_dec_rval_t rval; + asn_dec_rval_t (*zer_decode)(struct asn_codec_ctx_s *, + asn_TYPE_descriptor_t *, void **, const void *, size_t); + PDU_t *st = 0; + size_t csize = 1; + + if(how == AS_DER) + zer_decode = ber_decode; + else + zer_decode = xer_decode; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %zd, chunks %zd\n", + size, csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + rval = zer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + if(how == AS_DER) { + assert(fbuf_offset == (ssize_t)size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == (ssize_t)size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == (ssize_t)size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(void *obufp, size_t osize, void *nbufp, size_t nsize) { + char *obuf = obufp; + char *nbuf = nbufp; + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +process_XER_data(enum expectation expectation, unsigned char *fbuf, size_t size) { + PDU_t *st; + + st = load_object_from(expectation, fbuf, size, AS_XER); + if(!st) return; + + /* Save and re-load as DER */ + save_object_as(st, AS_DER); + st = load_object_from(expectation, buf, buf_offset, AS_DER); + assert(st); + + save_object_as(st, AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + switch(expectation) { + case EXP_DIFFERENT: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_BROKEN: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_OK: + assert(xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + } + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + char prevdir[256]; + unsigned char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int ret; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'X': + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'E': + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + getcwd(prevdir, sizeof(prevdir)); + ret = chdir(SRCDIR_S "/data-70"); + assert(ret == 0); + fp = fopen(fname, "r"); + ret = chdir(prevdir); + assert(ret == 0); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd > 0 && (size_t)rd < sizeof(fbuf)); /* expect small files */ + + process_XER_data(expectation, fbuf, rd); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_70_FILE"); + if(str && strncmp(str, "data-70-", 8) == 0) + process(str); + + dir = opendir(SRCDIR_S "/data-70"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-70-", 8) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-src/check-72.-fcompound-names.c b/asn1c/tests/check-src/check-72.-fcompound-names.c new file mode 100644 index 00000000..322742d1 --- /dev/null +++ b/asn1c/tests/check-src/check-72.-fcompound-names.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Type.h> + +int +main(int ac, char **av) { + Type_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-73.c b/asn1c/tests/check-src/check-73.c new file mode 100644 index 00000000..9d331415 --- /dev/null +++ b/asn1c/tests/check-src/check-73.c @@ -0,0 +1,28 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Epyt.h> + +int +main(int ac, char **av) { + Type_t t; + Epyt_t ept; + Ypet_t ypt; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + memset(&ept, 0, sizeof(ept)); + memset(&ypt, 0, sizeof(ypt)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-92.-findirect-choice.c b/asn1c/tests/check-src/check-92.-findirect-choice.c new file mode 100644 index 00000000..caa367fd --- /dev/null +++ b/asn1c/tests/check-src/check-92.-findirect-choice.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Everything.h> + +int +main(int ac, char **av) { + Everything_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check-92.c b/asn1c/tests/check-src/check-92.c new file mode 100644 index 00000000..caa367fd --- /dev/null +++ b/asn1c/tests/check-src/check-92.c @@ -0,0 +1,24 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> + +#include <Everything.h> + +int +main(int ac, char **av) { + Everything_t t; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&t, 0, sizeof(t)); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} diff --git a/asn1c/tests/check-src/check64-134.-gen-PER.c b/asn1c/tests/check-src/check64-134.-gen-PER.c new file mode 100644 index 00000000..1eaef4ee --- /dev/null +++ b/asn1c/tests/check-src/check64-134.-gen-PER.c @@ -0,0 +1,162 @@ +/* + * Verify INTEGER values with greater than 32 bits range. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <T.h> + +static unsigned long i2ul(const INTEGER_t *i) { + unsigned long l; + int ret = asn_INTEGER2ulong(i, &l); + assert(ret == 0); + return l; +} + +static long i2l(const INTEGER_t *i) { + long l; + int ret = asn_INTEGER2long(i, &l); + assert(ret == 0); + return l; +} + +static void ul2i(INTEGER_t *i, unsigned long l) { + int ret = asn_ulong2INTEGER(i, l); + assert(ret == 0); +} + +static void l2i(INTEGER_t *i, long l) { + int ret = asn_long2INTEGER(i, l); + assert(ret == 0); +} + +static void +verify(int testNo, T_t *ti) { + asn_enc_rval_t er; + asn_dec_rval_t rv; + unsigned char buf[20]; + T_t *to = 0; + + fprintf(stderr, "%d IN: { %lu, %lu, %ld, %ld }\n", testNo, + i2ul(&ti->unsigned33), i2ul(&ti->unsigned42), + i2l(&ti->signed33), i2l(&ti->signed33ext) + ); + + er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf); + assert(er.encoded >= 33 + 42 + 33 + 1 + 33); + + rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0); + assert(rv.code == RC_OK); + + fprintf(stderr, "%d ENC: %2x%2x%2x%2x %2x%2x%2x%2x\n", testNo, + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + fprintf(stderr, "%d OUT: { %lu, %lu, %ld, %ld } vs { %lu, %lu, %ld, %ld }\n", + testNo, + i2ul(&ti->unsigned33), i2ul(&ti->unsigned42), + i2l(&ti->signed33), i2l(&ti->signed33ext), + i2ul(&to->unsigned33), i2ul(&to->unsigned42), + i2l(&to->signed33), i2l(&to->signed33ext)); + assert(i2ul(&ti->unsigned33) == i2ul(&to->unsigned33)); + assert(i2ul(&ti->unsigned42) == i2ul(&to->unsigned42)); + assert(i2l(&ti->signed33) == i2l(&to->signed33)); + assert(i2l(&ti->signed33ext) == i2l(&to->signed33ext)); + + xer_fprint(stderr, &asn_DEF_T, ti); + xer_fprint(stderr, &asn_DEF_T, to); +} + +static void +NO_encode(int testNo, T_t *ti) { + asn_enc_rval_t er; + unsigned char buf[16]; + + fprintf(stderr, "%d IN: { %lu, %lu, %ld, %ld }\n", testNo, + i2ul(&ti->unsigned33), i2ul(&ti->unsigned42), + i2l(&ti->signed33), i2l(&ti->signed33ext) + ); + + er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf); + assert(er.encoded == -1); +} + +int main() { + T_t ti; + + memset(&ti, 0, sizeof(ti)); + ul2i(&ti.unsigned33, 0); + ul2i(&ti.unsigned42, 0); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, 0); + verify(1, &ti); + + ul2i(&ti.unsigned33, 1); + ul2i(&ti.unsigned42, 1); + l2i(&ti.signed33, 1); + l2i(&ti.signed33ext, 1); + verify(2, &ti); + + ul2i(&ti.unsigned33, 5000000000); + ul2i(&ti.unsigned42, 3153600000000); + l2i(&ti.signed33, 4000000000); + l2i(&ti.signed33ext, 4000000000); + verify(3, &ti); + + ul2i(&ti.unsigned33, -1); + ul2i(&ti.unsigned42, 0); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, 0); + NO_encode(4, &ti); + + ul2i(&ti.unsigned33, 0); + ul2i(&ti.unsigned42, -1); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, 0); + NO_encode(5, &ti); + + ul2i(&ti.unsigned33, 0); + ul2i(&ti.unsigned42, 0); + l2i(&ti.signed33, -4000000000-1); + l2i(&ti.signed33ext, 0); + NO_encode(6, &ti); + + ul2i(&ti.unsigned33, 0); + ul2i(&ti.unsigned42, 0); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, -4000000000-1); + assert(ti.signed33ext.size == 5); + verify(7, &ti); /* signed33ext is extensible */ + + ul2i(&ti.unsigned33, 5000000000 + 1); + ul2i(&ti.unsigned42, 0); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, 0); + NO_encode(8, &ti); + + ul2i(&ti.unsigned33, 0); + ul2i(&ti.unsigned42, 3153600000000 + 1); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, 0); + NO_encode(9, &ti); + + ul2i(&ti.unsigned33, 5000000000 - 1); + ul2i(&ti.unsigned42, 3153600000000 - 1); + l2i(&ti.signed33, 4000000000 - 1); + l2i(&ti.signed33ext, 4000000000 - 1); + verify(10, &ti); + + ul2i(&ti.unsigned33, 0); + ul2i(&ti.unsigned42, 0); + l2i(&ti.signed33, 0); + l2i(&ti.signed33ext, 4000000000 + 1); + verify(11, &ti); + + return 0; +} + |