Commit 50408008 authored by Senthil Prabakaran's avatar Senthil Prabakaran Committed by Mouse

Fix JER encoding

parent 4c509a36
......@@ -45,7 +45,6 @@ asn_TYPE_operation_t asn_OP_NativeInteger = {
NativeInteger_encode_jer,
#else
0,
0,
#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
#if !defined(ASN_DISABLE_OER_SUPPORT)
NativeInteger_decode_oer, /* OER decoder */
......
......@@ -42,6 +42,10 @@ xer_type_decoder_f NativeInteger_decode_xer;
xer_type_encoder_f NativeInteger_encode_xer;
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
#if !defined(ASN_DISABLE_JER_SUPPORT)
jer_type_encoder_f NativeInteger_encode_jer;
#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
#if !defined(ASN_DISABLE_OER_SUPPORT)
oer_type_decoder_f NativeInteger_decode_oer;
oer_type_encoder_f NativeInteger_encode_oer;
......
......@@ -6,58 +6,6 @@
#include <asn_internal.h>
#include <OBJECT_IDENTIFIER.h>
static enum jer_pbd_rval
OBJECT_IDENTIFIER__jer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
const void *chunk_buf, size_t chunk_size) {
OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
const char *chunk_end = (const char *)chunk_buf + chunk_size;
const char *endptr;
asn_oid_arc_t s_arcs[10];
asn_oid_arc_t *arcs = s_arcs;
ssize_t num_arcs;
ssize_t ret;
(void)td;
num_arcs = OBJECT_IDENTIFIER_parse_arcs(
(const char *)chunk_buf, chunk_size, arcs,
sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
if(num_arcs < 0) {
/* Expecting more than zero arcs */
return XPBD_BROKEN_ENCODING;
} else if(num_arcs == 0) {
return XPBD_NOT_BODY_IGNORE;
}
(void)chunk_end;
assert(endptr == chunk_end);
if((size_t)num_arcs > sizeof(s_arcs)/sizeof(s_arcs[0])) {
arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(asn_oid_arc_t));
if(!arcs) return XPBD_SYSTEM_FAILURE;
ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
arcs, num_arcs, &endptr);
if(ret != num_arcs)
return XPBD_SYSTEM_FAILURE; /* assert?.. */
}
/*
* Convert arcs into BER representation.
*/
ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, num_arcs);
if(arcs != s_arcs) FREEMEM(arcs);
return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
}
asn_dec_rval_t
OBJECT_IDENTIFIER_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *td, void **sptr,
const char *opt_mname, const void *buf_ptr,
size_t size) {
return jer_decode_primitive(opt_codec_ctx, td,
sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
buf_ptr, size, OBJECT_IDENTIFIER__jer_body_decode);
}
asn_enc_rval_t
OBJECT_IDENTIFIER_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
......
......@@ -30,35 +30,21 @@ OCTET_STRING_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
*/
buf = st->buf;
end = buf + st->size;
if(flags & JER_F_CANONICAL) {
char *scend = scratch + (sizeof(scratch) - 2);
for(; buf < end; buf++) {
if(p >= scend) {
ASN__CALLBACK(scratch, p - scratch);
p = scratch;
}
*p++ = h2c[(*buf >> 4) & 0x0F];
*p++ = h2c[*buf & 0x0F];
}
ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
} else {
for(i = 0; buf < end; buf++, i++) {
if(!(i % 16) && (i || st->size > 16)) {
ASN__CALLBACK(scratch, p-scratch);
p = scratch;
ASN__TEXT_INDENT(1, ilevel);
}
*p++ = h2c[(*buf >> 4) & 0x0F];
*p++ = h2c[*buf & 0x0F];
*p++ = 0x20;
}
if(p - scratch) {
p--; /* Remove the tail space */
ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
if(st->size > 16)
ASN__TEXT_INDENT(1, ilevel-1);
}
for(i = 0; buf < end; buf++, i++) {
if(!(i % 16) && (i || st->size > 16)) {
ASN__CALLBACK(scratch, p-scratch);
p = scratch;
ASN__TEXT_INDENT(1, ilevel);
}
*p++ = h2c[(*buf >> 4) & 0x0F];
*p++ = h2c[*buf & 0x0F];
*p++ = 0x20;
}
if(p - scratch) {
p--; /* Remove the tail space */
ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
if(st->size > 16)
ASN__TEXT_INDENT(1, ilevel-1);
}
ASN__ENCODED_OK(er);
......
/*
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <OPEN_TYPE.h>
#include <constr_CHOICE.h>
asn_dec_rval_t
OPEN_TYPE_jer_get(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *td, void *sptr,
const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
size_t consumed_myself = 0;
asn_type_selector_result_t selected;
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
void *inner_value;
asn_dec_rval_t rv;
int jer_context = 0;
ssize_t ch_size;
pjer_chunk_type_e ch_type;
if(!(elm->flags & ATF_OPEN_TYPE)) {
ASN__DECODE_FAILED;
}
if(!elm->type_selector) {
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
td->name, elm->name, elm->type->name);
ASN__DECODE_FAILED;
}
selected = elm->type_selector(td, sptr);
if(!selected.presence_index) {
ASN__DECODE_FAILED;
}
/* Fetch the pointer to this member */
assert(elm->flags == ATF_OPEN_TYPE);
if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
} else {
memb_ptr = (char *)sptr + elm->memb_offset;
memb_ptr2 = &memb_ptr;
}
if(*memb_ptr2 != NULL) {
/* Make sure we reset the structure first before encoding */
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
!= 0) {
ASN__DECODE_FAILED;
}
}
/*
* Confirm wrapper.
*/
for(;;) {
ch_size = jer_next_token(&jer_context, ptr, size, &ch_type);
if(ch_size < 0) {
ASN__DECODE_FAILED;
} else {
switch(ch_type) {
case PJER_WMORE:
ASN__DECODE_STARVED;
case PJER_COMMENT:
case PJER_TEXT:
ADVANCE(ch_size);
continue;
case PJER_TAG:
break;
}
break;
}
}
/*
* Wrapper value confirmed.
*/
switch(jer_check_tag(ptr, ch_size, elm->name)) {
case XCT_OPENING:
ADVANCE(ch_size);
break;
case XCT_BROKEN:
default:
ASN__DECODE_FAILED;
}
inner_value =
(char *)*memb_ptr2
+ elm->type->elements[selected.presence_index - 1].memb_offset;
rv = selected.type_descriptor->op->jer_decoder(
opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
ADVANCE(rv.consumed);
rv.consumed = 0;
switch(rv.code) {
case RC_OK:
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
selected.presence_index)
== 0) {
break;
} else {
rv.code = RC_FAIL;
}
/* Fall through */
case RC_FAIL:
/* Point to a best position where failure occurred */
rv.consumed = consumed_myself;
/* Fall through */
case RC_WMORE:
/* Wrt. rv.consumed==0:
* In case a genuine RC_WMORE, the whole Open Type decoding
* will have to be restarted.
*/
if(*memb_ptr2) {
if(elm->flags & ATF_POINTER) {
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
*memb_ptr2 = NULL;
} else {
ASN_STRUCT_RESET(*selected.type_descriptor,
inner_value);
}
}
return rv;
}
/*
* Finalize wrapper.
*/
for(;;) {
ch_size = jer_next_token(&jer_context, ptr, size, &ch_type);
if(ch_size < 0) {
ASN__DECODE_FAILED;
} else {
switch(ch_type) {
case PJER_WMORE:
ASN__DECODE_STARVED;
case PJER_COMMENT:
case PJER_TEXT:
ADVANCE(ch_size);
continue;
case PJER_TAG:
break;
}
break;
}
}
/*
* Wrapper value confirmed.
*/
switch(jer_check_tag(ptr, ch_size, elm->name)) {
case XCT_CLOSING:
ADVANCE(ch_size);
break;
case XCT_BROKEN:
default:
ASN__DECODE_FAILED;
}
rv.consumed += consumed_myself;
return rv;
}
......@@ -259,12 +259,10 @@ NativeInteger.h NativeInteger_jer.c
NativeReal.h NativeReal_jer.c
OBJECT_IDENTIFIER.h OBJECT_IDENTIFIER_jer.c
OCTET_STRING.h OCTET_STRING_jer.c
OPEN_TYPE.h OPEN_TYPE_jer.c
REAL.h REAL_jer.c
RELATIVE-OID.h RELATIVE-OID_jer.c
UTCTime.h UTCTime_jer.c
UniversalString.h UniversalString_jer.c
asn_codecs_prim.h
constr_CHOICE.h constr_CHOICE_jer.c
constr_SEQUENCE_OF.h constr_SEQUENCE_OF_jer.c
constr_SEQUENCE.h constr_SEQUENCE_jer.c
......
......@@ -17,7 +17,7 @@ jer_encode(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_enc_rval_t tmper;
const char *mname;
size_t mlen;
int xcan = (jer_flags & JER_F_CANONICAL) ? 1 : 2;
int xcan = 0;
if(!td || !sptr) goto cb_failed;
......@@ -26,7 +26,7 @@ jer_encode(const asn_TYPE_descriptor_t *td, const void *sptr,
ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
tmper = td->op->jer_encoder(td, sptr, 1, jer_flags, cb, app_key);
tmper = td->op->jer_encoder(td, sptr, 1, 0, cb, app_key);
if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded;
......@@ -59,7 +59,7 @@ jer_fprint(FILE *stream, const asn_TYPE_descriptor_t *td, const void *sptr) {
if(!td || !sptr)
return -1;
er = jer_encode(td, sptr, JER_F_BASIC, jer__print2fp, stream);
er = jer_encode(td, sptr, jer__print2fp, stream);
if(er.encoded == -1)
return -1;
......@@ -94,145 +94,4 @@ jer__buffer_append(const void *buffer, size_t size, void *app_key) {
return 0;
}
enum jer_equivalence_e
jer_equivalent(const struct asn_TYPE_descriptor_s *td, const void *struct1,
const void *struct2, FILE *opt_debug_stream) {
struct jer_buffer xb1 = {0, 0, 0};
struct jer_buffer xb2 = {0, 0, 0};
asn_enc_rval_t e1, e2;
asn_dec_rval_t rval;
void *sptr = NULL;
if(!td || !struct1 || !struct2) {
if(opt_debug_stream) {
if(!td) fprintf(opt_debug_stream, "Type descriptor missing\n");
if(!struct1) fprintf(opt_debug_stream, "Structure 1 missing\n");
if(!struct2) fprintf(opt_debug_stream, "Structure 2 missing\n");
}
return XEQ_FAILURE;
}
e1 = jer_encode(td, struct1, JER_F_BASIC, jer__buffer_append, &xb1);
if(e1.encoded == -1) {
if(opt_debug_stream) {
fprintf(stderr, "JER Encoding of %s failed\n", td->name);
}
FREEMEM(xb1.buffer);
return XEQ_ENCODE1_FAILED;
}
e2 = jer_encode(td, struct2, JER_F_BASIC, jer__buffer_append, &xb2);
if(e2.encoded == -1) {
if(opt_debug_stream) {
fprintf(stderr, "JER Encoding of %s failed\n", td->name);
}
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_ENCODE1_FAILED;
}
if(xb1.buffer_size != xb2.buffer_size
|| memcmp(xb1.buffer, xb2.buffer, xb1.buffer_size) != 0) {
if(opt_debug_stream) {
fprintf(opt_debug_stream,
"Structures JER-encoded into different byte streams:\n=== "
"Structure 1 ===\n%s\n=== Structure 2 ===\n%s\n",
xb1.buffer, xb2.buffer);
}
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_DIFFERENT;
} else {
if(opt_debug_stream) {
fprintf(opt_debug_stream,
"Both structures encoded into the same JER byte stream "
"of size %" ASN_PRI_SIZE ":\n%s",
xb1.buffer_size, xb1.buffer);
}
}
// this needs to be changed as jer_decode does not exist
rval = jer_decode(NULL, td, (void **)&sptr, xb1.buffer,
xb1.buffer_size);
switch(rval.code) {
case RC_OK:
break;
case RC_WMORE:
if(opt_debug_stream) {
fprintf(opt_debug_stream,
"Structure %s JER decode unexpectedly requires "
"more data:\n%s\n",
td->name, xb1.buffer);
}
/* Fall through */
case RC_FAIL:
default:
if(opt_debug_stream) {
fprintf(opt_debug_stream,
"Structure %s JER decoding resulted in failure.\n",
td->name);
}
ASN_STRUCT_FREE(*td, sptr);
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_DECODE_FAILED;
}
if(rval.consumed != xb1.buffer_size
&& ((rval.consumed > xb1.buffer_size)
|| jer_whitespace_span(xb1.buffer + rval.consumed,
xb1.buffer_size - rval.consumed)
!= (xb1.buffer_size - rval.consumed))) {
if(opt_debug_stream) {
fprintf(opt_debug_stream,
"Round-trip decode of %s required less bytes (%" ASN_PRI_SIZE ") than "
"encoded (%" ASN_PRI_SIZE ")\n",
td->name, rval.consumed, xb1.buffer_size);
}
ASN_STRUCT_FREE(*td, sptr);
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_ROUND_TRIP_FAILED;
}
/*
* Reuse xb2 to encode newly decoded structure.
*/
FREEMEM(xb2.buffer);
memset(&xb2, 0, sizeof(xb2));
e2 = jer_encode(td, sptr, JER_F_BASIC, jer__buffer_append, &xb2);
if(e2.encoded == -1) {
if(opt_debug_stream) {
fprintf(stderr, "JER Encoding of round-trip decode of %s failed\n",
td->name);
}
ASN_STRUCT_FREE(*td, sptr);
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_ROUND_TRIP_FAILED;
}
ASN_STRUCT_FREE(*td, sptr);
sptr = 0;
if(xb1.buffer_size != xb2.buffer_size
|| memcmp(xb1.buffer, xb2.buffer, xb1.buffer_size) != 0) {
if(opt_debug_stream) {
fprintf(opt_debug_stream,
"JER Encoding of round-trip decode of %s resulted in "
"different byte stream:\n"
"=== Original ===\n%s\n"
"=== Round-tripped ===\n%s\n",
xb1.buffer, xb2.buffer, td->name);
}
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_ROUND_TRIP_FAILED;
}
FREEMEM(xb1.buffer);
FREEMEM(xb2.buffer);
return XEQ_SUCCESS;
}
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