Commit a85b37d3 authored by Lev Walkin's avatar Lev Walkin

new model

parent bb7a7451
/*
* 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 #undef NDEBUG
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -13,7 +19,6 @@ ...@@ -13,7 +19,6 @@
enum expectation { enum expectation {
EXP_OK, /* Encoding/decoding must succeed */ EXP_OK, /* Encoding/decoding must succeed */
EXP_BROKEN, /* Decoding must fail */ EXP_BROKEN, /* Decoding must fail */
EXP_RECLESS, /* Reconstruction is allowed to yield less data */
EXP_DIFFERENT, /* Reconstruction will yield different encoding */ EXP_DIFFERENT, /* Reconstruction will yield different encoding */
}; };
...@@ -36,36 +41,55 @@ _buf_writer(const void *buffer, size_t size, void *app_key) { ...@@ -36,36 +41,55 @@ _buf_writer(const void *buffer, size_t size, void *app_key) {
return 0; return 0;
} }
static int enum der_or_xer {
save_object(PDU_t *st) { AS_DER,
AS_XER,
};
static void
save_object_as(PDU_t *st, enum der_or_xer how) {
asn_enc_rval_t rval; /* Return value */ asn_enc_rval_t rval; /* Return value */
buf_offset = 0; buf_offset = 0;
rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, _buf_writer, 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) { if (rval.encoded == -1) {
fprintf(stderr, fprintf(stderr,
"Cannot encode %s: %s\n", "Cannot encode %s: %s\n",
rval.failed_type->name, strerror(errno)); rval.failed_type->name, strerror(errno));
assert(rval.encoded != -1); assert(rval.encoded != -1);
return -1; /* JIC */ return;
} }
fprintf(stderr, "=== re-encoded ===\n");
fwrite(buf, 1, buf_offset, stderr);
fprintf(stderr, "=== end ===\n");
fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
return 0;
} }
static PDU_t * static PDU_t *
load_object(enum expectation expectation, char *fbuf, int size) { load_object_from(enum expectation expectation, char *fbuf, int size, enum der_or_xer how) {
asn_dec_rval_t rval; asn_dec_rval_t rval;
asn_dec_rval_t (*zer_decode)(struct asn_codec_ctx_s *,
asn_TYPE_descriptor_t *, void **, void *, size_t);
PDU_t *st = 0; PDU_t *st = 0;
int csize; int csize;
if(how == AS_DER)
zer_decode = ber_decode;
else
zer_decode = xer_decode;
fprintf(stderr, "LOADING OBJECT OF SIZE %d\n", size); fprintf(stderr, "LOADING OBJECT OF SIZE %d\n", size);
/* Perform multiple iterations with multiple chunks sizes */ /* Perform multiple iterations with multiple chunks sizes */
...@@ -80,7 +104,7 @@ load_object(enum expectation expectation, char *fbuf, int size) { ...@@ -80,7 +104,7 @@ load_object(enum expectation expectation, char *fbuf, int size) {
do { do {
fprintf(stderr, "Decoding from %d with %d (left %d)\n", fprintf(stderr, "Decoding from %d with %d (left %d)\n",
fbuf_offset, fbuf_chunk, fbuf_left); fbuf_offset, fbuf_chunk, fbuf_left);
rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, rval = zer_decode(0, &asn_DEF_PDU, (void **)&st,
fbuf + fbuf_offset, fbuf + fbuf_offset,
fbuf_chunk < fbuf_left fbuf_chunk < fbuf_left
? fbuf_chunk : fbuf_left); ? fbuf_chunk : fbuf_left);
...@@ -94,6 +118,9 @@ load_object(enum expectation expectation, char *fbuf, int size) { ...@@ -94,6 +118,9 @@ load_object(enum expectation expectation, char *fbuf, int size) {
if(expectation != EXP_BROKEN) { if(expectation != EXP_BROKEN) {
assert(rval.code == RC_OK); assert(rval.code == RC_OK);
if(how == AS_DER) {
assert(fbuf_offset == size);
} else {
assert(fbuf_offset - size < 2 assert(fbuf_offset - size < 2
|| (fbuf_offset + 1 /* "\n" */ == size || (fbuf_offset + 1 /* "\n" */ == size
&& fbuf[size - 1] == '\n') && fbuf[size - 1] == '\n')
...@@ -101,6 +128,7 @@ load_object(enum expectation expectation, char *fbuf, int size) { ...@@ -101,6 +128,7 @@ load_object(enum expectation expectation, char *fbuf, int size) {
&& fbuf[size - 2] == '\r' && fbuf[size - 2] == '\r'
&& fbuf[size - 1] == '\n') && fbuf[size - 1] == '\n')
); );
}
} else { } else {
assert(rval.code != RC_OK); assert(rval.code != RC_OK);
fprintf(stderr, "Failed, but this was expected\n"); fprintf(stderr, "Failed, but this was expected\n");
...@@ -113,32 +141,67 @@ load_object(enum expectation expectation, char *fbuf, int size) { ...@@ -113,32 +141,67 @@ load_object(enum expectation expectation, char *fbuf, int size) {
return 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 static void
process_data(enum expectation expectation, char *fbuf, int size) { process_XER_data(enum expectation expectation, char *fbuf, int size) {
PDU_t *st; PDU_t *st;
int ret; int ret;
st = load_object(expectation, fbuf, size); st = load_object_from(expectation, fbuf, size, AS_XER);
if(!st) return; if(!st) return;
ret = save_object(st); /* Save and re-load as DER */
assert(buf_offset < sizeof(buf)); save_object_as(st, AS_DER);
assert(ret == 0); 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) { 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: case EXP_DIFFERENT:
assert(buf_offset > 0 && buf_offset < size); assert(!xer_encoding_equal(fbuf, size, buf, buf_offset));
break; break;
case EXP_BROKEN: case EXP_BROKEN:
assert(buf_offset == size); assert(!xer_encoding_equal(fbuf, size, buf, buf_offset));
assert(memcmp(buf, fbuf, buf_offset) == 0);
break; break;
case EXP_OK: case EXP_OK:
assert(xer_encoding_equal(fbuf, size, buf, buf_offset));
break; break;
} }
...@@ -165,8 +228,6 @@ process(const char *fname) { ...@@ -165,8 +228,6 @@ process(const char *fname) {
expectation = EXP_BROKEN; break; expectation = EXP_BROKEN; break;
case 'D': /* Reconstructing should yield different data */ case 'D': /* Reconstructing should yield different data */
expectation = EXP_DIFFERENT; break; expectation = EXP_DIFFERENT; break;
case 'L': /* Extensions are present */
expectation = EXP_RECLESS; break;
default: default:
expectation = EXP_OK; break; expectation = EXP_OK; break;
} }
...@@ -185,7 +246,7 @@ process(const char *fname) { ...@@ -185,7 +246,7 @@ process(const char *fname) {
assert(rd < sizeof(fbuf)); /* expect small files */ assert(rd < sizeof(fbuf)); /* expect small files */
process_data(expectation, fbuf, rd); process_XER_data(expectation, fbuf, rd);
return 1; return 1;
} }
...@@ -197,14 +258,17 @@ main() { ...@@ -197,14 +258,17 @@ main() {
int processed_files = 0; int processed_files = 0;
char *str; char *str;
dir = opendir("../data-70");
assert(dir);
/* Process a specific test file */ /* Process a specific test file */
str = getenv("DATA_70_FILE"); str = getenv("DATA_70_FILE");
if(str && strncmp(str, "data-70-", 8) == 0) if(str && strncmp(str, "data-70-", 8) == 0)
process(str); process(str);
dir = opendir("../data-70");
assert(dir);
/*
* Process each file in that directory.
*/
while((dent = readdir(dir))) { while((dent = readdir(dir))) {
if(strncmp(dent->d_name, "data-70-", 8) == 0) if(strncmp(dent->d_name, "data-70-", 8) == 0)
if(process(dent->d_name)) if(process(dent->d_name))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment