aboutsummaryrefslogtreecommitdiffstats
path: root/asn1c/tests/check-src
diff options
context:
space:
mode:
Diffstat (limited to 'asn1c/tests/check-src')
-rw-r--r--asn1c/tests/check-src/check-03.-fwide-types.c62
-rw-r--r--asn1c/tests/check-src/check-119.-fwide-types.-gen-PER.c369
-rw-r--r--asn1c/tests/check-src/check-119.-gen-PER.c371
-rw-r--r--asn1c/tests/check-src/check-126.-gen-PER.c372
-rw-r--r--asn1c/tests/check-src/check-127.-gen-PER.c87
-rw-r--r--asn1c/tests/check-src/check-131.-gen-PER.c59
-rw-r--r--asn1c/tests/check-src/check-132.-gen-PER.c62
-rw-r--r--asn1c/tests/check-src/check-133.-gen-PER.c83
-rw-r--r--asn1c/tests/check-src/check-19.c24
-rw-r--r--asn1c/tests/check-src/check-22.-fwide-types.c153
-rw-r--r--asn1c/tests/check-src/check-24.-fwide-types.c97
-rw-r--r--asn1c/tests/check-src/check-25.-fwide-types.c261
-rw-r--r--asn1c/tests/check-src/check-30.-fwide-types.c264
-rw-r--r--asn1c/tests/check-src/check-31.-fwide-types.c217
-rw-r--r--asn1c/tests/check-src/check-32.c83
-rw-r--r--asn1c/tests/check-src/check-33.c24
-rw-r--r--asn1c/tests/check-src/check-35.c330
-rw-r--r--asn1c/tests/check-src/check-39.c24
-rw-r--r--asn1c/tests/check-src/check-41.-fwide-types.c322
-rw-r--r--asn1c/tests/check-src/check-41.c219
-rw-r--r--asn1c/tests/check-src/check-42.c142
-rw-r--r--asn1c/tests/check-src/check-43.c27
-rw-r--r--asn1c/tests/check-src/check-44.c66
-rw-r--r--asn1c/tests/check-src/check-46.c46
-rw-r--r--asn1c/tests/check-src/check-48.c98
-rw-r--r--asn1c/tests/check-src/check-50.c23
-rw-r--r--asn1c/tests/check-src/check-59.c24
-rw-r--r--asn1c/tests/check-src/check-60.c203
-rw-r--r--asn1c/tests/check-src/check-62.c220
-rw-r--r--asn1c/tests/check-src/check-65.c113
-rw-r--r--asn1c/tests/check-src/check-70.-fwide-types.c336
-rw-r--r--asn1c/tests/check-src/check-70.c308
-rw-r--r--asn1c/tests/check-src/check-72.-fcompound-names.c24
-rw-r--r--asn1c/tests/check-src/check-73.c28
-rw-r--r--asn1c/tests/check-src/check-92.-findirect-choice.c24
-rw-r--r--asn1c/tests/check-src/check-92.c24
-rw-r--r--asn1c/tests/check-src/check64-134.-gen-PER.c162
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>=&lt;&amp;&gt;</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>=&lt;&amp;&gt;</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;
+}
+