Commit 7ed25980 authored by Lev Walkin's avatar Lev Walkin

added tests

parent eb08cb2f
...@@ -87,7 +87,7 @@ save_object_as(PDU_t *st, enum enctype how) { ...@@ -87,7 +87,7 @@ save_object_as(PDU_t *st, enum enctype how) {
} }
static PDU_t * static PDU_t *
load_object_from(const char *fname, char *fbuf, int size, enum enctype how) { load_object_from(const char *fname, char *fbuf, int size, enum enctype how, int mustfail) {
asn_dec_rval_t rval; asn_dec_rval_t rval;
PDU_t *st = 0; PDU_t *st = 0;
int csize = 1; int csize = 1;
...@@ -109,11 +109,12 @@ load_object_from(const char *fname, char *fbuf, int size, enum enctype how) { ...@@ -109,11 +109,12 @@ load_object_from(const char *fname, char *fbuf, int size, enum enctype how) {
st = 0; st = 0;
do { do {
fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", fprintf(stderr, "Decoding bytes %d..%d (left %d) [%s]\n",
fbuf_offset, fbuf_offset,
fbuf_chunk < fbuf_left fbuf_chunk < fbuf_left
? fbuf_chunk : fbuf_left, ? fbuf_chunk : fbuf_left,
fbuf_left); fbuf_left,
fname);
if(st) { if(st) {
fprintf(stderr, "=== currently ===\n"); fprintf(stderr, "=== currently ===\n");
asn_fprint(stderr, &asn_DEF_PDU, st); asn_fprint(stderr, &asn_DEF_PDU, st);
...@@ -137,6 +138,10 @@ load_object_from(const char *fname, char *fbuf, int size, enum enctype how) { ...@@ -137,6 +138,10 @@ load_object_from(const char *fname, char *fbuf, int size, enum enctype how) {
rval.code = RC_FAIL; rval.code = RC_FAIL;
rval.consumed += 7; rval.consumed += 7;
rval.consumed /= 8; rval.consumed /= 8;
if(mustfail) {
fprintf(stderr, "-> (this was expected failure)\n");
return 0;
}
} else { } else {
rval.consumed = 0; /* Not restartable */ rval.consumed = 0; /* Not restartable */
ASN_STRUCT_FREE(asn_DEF_PDU, st); ASN_STRUCT_FREE(asn_DEF_PDU, st);
...@@ -144,11 +149,20 @@ load_object_from(const char *fname, char *fbuf, int size, enum enctype how) { ...@@ -144,11 +149,20 @@ load_object_from(const char *fname, char *fbuf, int size, enum enctype how) {
fprintf(stderr, "-> PER wants more\n"); fprintf(stderr, "-> PER wants more\n");
} }
} else { } else {
fprintf(stderr, "-> PER ret %d/%d\n", fprintf(stderr, "-> PER ret %d/%d mf=%d\n",
rval.code, rval.consumed); rval.code, rval.consumed, mustfail);
/* uper_decode() returns _bits_ */ /* uper_decode() returns _bits_ */
rval.consumed += 7; rval.consumed += 7;
rval.consumed /= 8; rval.consumed /= 8;
if((mustfail?1:0) == (rval.code == RC_FAIL)) {
if(mustfail) {
fprintf(stderr, "-> (this was expected failure)\n");
return;
}
} else {
fprintf(stderr, "-> (unexpected %s)\n", mustfail ? "success" : "failure");
//rval.code = RC_FAIL;
}
} }
break; break;
} }
...@@ -224,17 +238,33 @@ compare_with_data_out(const char *fname, char *buf, int size) { ...@@ -224,17 +238,33 @@ compare_with_data_out(const char *fname, char *buf, int size) {
fprintf(stderr, "Comparing PER output with [%s]\n", outName); fprintf(stderr, "Comparing PER output with [%s]\n", outName);
if(strstr(outName, "-0-6-P.out")) {
f = fopen(outName, "w");
fbuf[0] = 0x81;
fbuf[1] = 0x40;
fbuf[2] = 0x80;
fbuf[3] = 0x00;
fbuf[4] = 0x00;
fwrite(fbuf, 1, 5, f);
fclose(f);
}
if(getenv("REGENERATE")) { if(getenv("REGENERATE")) {
f = fopen(outName, "w"); f = fopen(outName, "w");
fwrite(buf, 1, size, f); fwrite(buf, 1, size, f);
fclose(f); fclose(f);
} else { } else {
int mustfail = outName[strlen(outName)-5] == 'P';
f = fopen(outName, "r"); f = fopen(outName, "r");
assert(f); assert(f);
rd = fread(fbuf, 1, sizeof(fbuf), f); rd = fread(fbuf, 1, sizeof(fbuf), f);
assert(rd); assert(rd);
fclose(f); fclose(f);
fprintf(stderr, "Trying to decode [%s]\n", outName);
load_object_from(outName, fbuf, rd, AS_PER, mustfail);
if(mustfail) return;
assert(rd == size); assert(rd == size);
assert(memcmp(fbuf, buf, rd) == 0); assert(memcmp(fbuf, buf, rd) == 0);
fprintf(stderr, "XER->PER recoding .in->.out match.\n"); fprintf(stderr, "XER->PER recoding .in->.out match.\n");
...@@ -246,13 +276,13 @@ process_XER_data(const char *fname, char *fbuf, int size) { ...@@ -246,13 +276,13 @@ process_XER_data(const char *fname, char *fbuf, int size) {
PDU_t *st; PDU_t *st;
int ret; int ret;
st = load_object_from(fname, fbuf, size, AS_XER); st = load_object_from(fname, fbuf, size, AS_XER, 0);
if(!st) return; if(!st) return;
/* Save and re-load as PER */ /* Save and re-load as PER */
save_object_as(st, AS_PER); save_object_as(st, AS_PER);
compare_with_data_out(fname, buf, buf_offset); compare_with_data_out(fname, buf, buf_offset);
st = load_object_from("buffer", buf, buf_offset, AS_PER); st = load_object_from("buffer", buf, buf_offset, AS_PER, 0);
assert(st); assert(st);
save_object_as(st, AS_XER); save_object_as(st, AS_XER);
......
...@@ -1071,44 +1071,60 @@ uper_ugot_refill(asn_per_data_t *pd) { ...@@ -1071,44 +1071,60 @@ uper_ugot_refill(asn_per_data_t *pd) {
/* Advance our position to where pd is */ /* Advance our position to where pd is */
consumed = (pd->buffer - oldpd->buffer) << 3; consumed = (pd->buffer - oldpd->buffer) << 3;
ASN_DEBUG("Refilling [consumed: %d bits from %d (%d->%d)] now [%d (%d->%d)]", ASN_DEBUG("REFILLING [consumed: %d bits from %d (%d->%d)] now [%d (%d->%d)] uncl %d",
consumed, consumed,
oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits, oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits,
pd->nbits - pd->nboff, pd->nboff, pd->nbits); pd->nbits - pd->nboff, pd->nboff, pd->nbits, arg->unclaimed);
oldpd->nbits -= consumed; oldpd->nbits -= consumed;
oldpd->buffer = pd->buffer; oldpd->buffer = pd->buffer;
oldpd->nboff = pd->nboff; oldpd->nboff = pd->nboff;
oldpd->nboff = pd->nbits;
if(arg->unclaimed) { if(arg->unclaimed) {
/* Refill the container */ /* Refill the container */
if(per_get_few_bits(oldpd, 0)) if(per_get_few_bits(oldpd, 1))
return -1; return -1;
if(oldpd->nboff == 0) {
assert(0); assert(0);
return -1;
}
pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff - 1;
pd->nbits = oldpd->nbits;
ASN_DEBUG("====================");
return 0;
} }
if(!arg->repeat) { if(!arg->repeat) {
ASN_DEBUG("Want more but refill doesn't have it"); ASN_DEBUG("Want more but refill doesn't have it");
assert(0);
return -1; return -1;
} }
next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
ASN_DEBUG("Open type length %d bytes, old %d (%d->%d)", ASN_DEBUG("Open type LENGTH %d bytes, old %d (%d->%d) repeat %d",
next_chunk_bytes, oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits); next_chunk_bytes, oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits, arg->repeat);
if(next_chunk_bytes < 0) return -1; if(next_chunk_bytes < 0) return -1;
if(next_chunk_bytes == 0 || !arg->repeat) assert(next_chunk_bytes || !arg->repeat);
if(next_chunk_bytes == 0)
pd->refill = 0; /* No more refills, naturally */ pd->refill = 0; /* No more refills, naturally */
pd->buffer = oldpd->buffer; pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff; pd->nboff = oldpd->nboff;
pd->nbits = oldpd->nbits; pd->nbits = oldpd->nbits;
next_chunk_bits = next_chunk_bytes << 3; next_chunk_bits = next_chunk_bytes << 3;
avail = pd->nbits - pd->nboff; avail = pd->nbits - pd->nboff;
ASN_DEBUG("now at %d bits, want %d",
((((int)pd->buffer ) & 0x7) << 3) + pd->nboff,
next_chunk_bits);
ASN_DEBUG("avail = %d", avail);
if(avail >= next_chunk_bits) { if(avail >= next_chunk_bits) {
pd->nbits = pd->nboff + next_chunk_bits; pd->nbits = pd->nboff + next_chunk_bits;
arg->unclaimed = 0; arg->unclaimed = 0;
} else { } else {
arg->unclaimed = next_chunk_bits - avail; arg->unclaimed = next_chunk_bits - avail;
ASN_DEBUG("Parent has %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed);
} }
ASN_DEBUG("now at %d bits",
((((int)pd->buffer ) & 0x7) << 3) + pd->nboff);
return 0; return 0;
} }
...@@ -1131,18 +1147,47 @@ uper_get_open_type(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -1131,18 +1147,47 @@ uper_get_open_type(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
rv = td->uper_decoder(opt_codec_ctx, td, constraints, sptr, pd); rv = td->uper_decoder(opt_codec_ctx, td, constraints, sptr, pd);
ASN_DEBUG("Open type unconsumed unclaimed=%d, repeat=%d, nbdiff=%d (%d->%d, old=%d (%d->%d))",
arg.unclaimed, arg.repeat,
pd->nbits - pd->nboff, pd->nboff, pd->nbits,
arg.oldpd.nbits - arg.oldpd.nboff, arg.oldpd.nboff, arg.oldpd.nbits);
ASN_DEBUG("now at %d bits",
((((int)pd->buffer ) & 0x7) << 3) + pd->nboff);
padding = pd->nbits - pd->nboff;
if(padding > 7) {
ASN_DEBUG("Too large padding in open type %p (%d->%d) %d",
pd->buffer, pd->nboff, pd->nbits, padding);
rv.code = RC_FAIL;
return rv;
}
ASN_DEBUG("nboff = %d, nbits %d, padding = %d, plus %d/%p", pd->nboff, pd->nbits, padding, pd->buffer - arg.oldpd.buffer, arg.oldpd.buffer);
switch(per_get_few_bits(pd, padding)) {
case -1:
ASN_DEBUG("Padding skip failed");
_ASN_DECODE_FAILED;
case 0: break;
default:
ASN_DEBUG("Non-blank padding");
_ASN_DECODE_FAILED;
}
pd->refill = arg.oldpd.refill;
pd->refill_key = arg.oldpd.refill_key;
/* Skip data not consumed by the decoder */ /* Skip data not consumed by the decoder */
while(arg.unclaimed) { while(arg.unclaimed) {
int toget = 24; int toget = 24;
if(arg.unclaimed < toget) { if(arg.unclaimed < toget)
toget = arg.unclaimed; toget = arg.unclaimed;
arg.unclaimed = 0;
} else {
arg.unclaimed -= toget; arg.unclaimed -= toget;
}
switch(per_get_few_bits(pd, toget)) { switch(per_get_few_bits(pd, toget)) {
case -1: _ASN_DECODE_STARVED; case -1:
case 0: continue; ASN_DEBUG("Claim of %d failed", toget);
_ASN_DECODE_STARVED;
case 0:
ASN_DEBUG("Got claim of %d", toget);
continue;
default: default:
/* Padding must be blank */ /* Padding must be blank */
ASN_DEBUG("Non-blank unconsumed padding"); ASN_DEBUG("Non-blank unconsumed padding");
...@@ -1150,25 +1195,15 @@ uper_get_open_type(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -1150,25 +1195,15 @@ uper_get_open_type(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
} }
} }
ASN_DEBUG("now at %d bits",
((((int)pd->buffer ) & 0x7) << 3) + pd->nboff);
if(arg.repeat) { if(arg.repeat) {
ASN_DEBUG("Not consumed the whole thing"); ASN_DEBUG("Not consumed the whole thing");
rv.code = RC_FAIL; rv.code = RC_FAIL;
return rv; return rv;
} }
padding = pd->nbits - pd->nboff;
if(padding > 7) {
ASN_DEBUG("Too large padding in open type %d", padding);
rv.code = RC_FAIL;
return rv;
}
ASN_DEBUG("nboff = %d, nbits %d, padding = %d, plus %d/%p", pd->nboff, pd->nbits, padding, pd->buffer - arg.oldpd.buffer, arg.oldpd.buffer);
pd->nboff += padding;
assert((ssize_t)pd->nboff <= (ssize_t)pd->nbits);
pd->refill = arg.oldpd.refill;
pd->refill_key = arg.oldpd.refill_key;
return rv; return rv;
} }
......
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