diff --git a/skeletons/ANY.c b/skeletons/ANY.c index a1c77118..ed529c57 100644 --- a/skeletons/ANY.c +++ b/skeletons/ANY.c @@ -29,16 +29,15 @@ ANY_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { - (void)ilevel; - (void)flags; - (void)cb; - (void)app_key; + if(flags & XER_F_CANONICAL) { + /* + * Canonical XER-encoding of ANY type is not supported. + */ + _ASN_ENCODE_FAILED; + } - /* - * XER-encoding of ANY type is not supported. - */ - - _ASN_ENCODE_FAILED; + /* Dump as binary */ + return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key); } struct _callback_arg { diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c index b6da3aea..c3788d83 100644 --- a/skeletons/BIT_STRING.c +++ b/skeletons/BIT_STRING.c @@ -78,6 +78,7 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, char *p = scratch; char *scend = scratch + (sizeof(scratch) - 10); const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + int xcan = (flags & XER_F_CANONICAL); uint8_t *buf; uint8_t *end; @@ -94,8 +95,7 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, */ for(buf++; buf < end; buf++) { int v = *buf; - int nline = (flags & XER_F_CANONICAL) - ?0:((((buf - st->buf) - 1) % 16) == 0); + int nline = xcan?0:((((buf - st->buf) - 1) % 8) == 0); if(p >= scend || nline) { er.encoded += p - scratch; _ASN_CALLBACK(scratch, p - scratch); @@ -108,7 +108,8 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, } er.encoded += p - scratch; - _ASN_CALLBACK(scratch, p - scratch); + if(!xcan && (((buf - st->buf) - 1) % 8) == 0) + _i_ASN_TEXT_INDENT(1, ilevel); if(buf < end + 1) { int v = *buf; @@ -120,6 +121,9 @@ BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, _ASN_CALLBACK(scratch, p - scratch); } + if(!xcan && ((st->size - 1) % 8) == 0) + _i_ASN_TEXT_INDENT(1, ilevel - 1); + return er; } @@ -149,7 +153,8 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, * Hexadecimal dump. */ for(buf++; buf < end; buf++) { - if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 16)) { + if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 17) + && buf != st->buf+1) { int i; /* Indentation */ if(cb("\n", 1, app_key)) return -1; @@ -162,9 +167,21 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, *p++ = h2c[*buf & 0x0F]; *p++ = 0x20; } - if(p > scratch) p--; /* Eat the tailing space */ - /* Dump the incomplete 16-bytes row */ - return cb(scratch, p - scratch, app_key); + if(p > scratch) { + p--; /* Eat the tailing space */ + + if((st->size > 17)) { + int i; + if(cb("\n", 1, app_key)) return -1; + for(i = 0; i < ilevel; i++) cb(" ", 1, app_key); + } + + /* Dump the incomplete 16-bytes row */ + if(cb(scratch, p - scratch, app_key)) + return -1; + } + + return 0; } diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index 4b7bd66e..8906c6f8 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -34,6 +34,9 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = { 0 /* No specifics */ }; +#undef _CH_PHASE +#undef NEXT_PHASE +#undef PREV_PHASE #define _CH_PHASE(ctx, inc) do { \ if(ctx->phase == 0) \ ctx->step = 0; \ @@ -42,6 +45,7 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = { #define NEXT_PHASE(ctx) _CH_PHASE(ctx, +1) #define PREV_PHASE(ctx) _CH_PHASE(ctx, -1) +#undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ buf_ptr = ((char *)buf_ptr) + num; \ @@ -49,12 +53,14 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = { consumed_myself += num; \ } while(0) +#undef RETURN #define RETURN(_code) do { \ rval.code = _code; \ rval.consumed = consumed_myself;\ return rval; \ } while(0) +#undef APPEND #define APPEND(bufptr, bufsize) do { \ size_t _bs = (bufsize); \ size_t _ns = ctx->step; /* Allocated */ \ @@ -161,8 +167,10 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td, } type_type = (enum type_type_e)(int)td->specifics; /* An ugly hack */ - ASN_DEBUG("Decoding %s as %s (%ld)", - td->name, "OCTET STRING", (long)size); + ASN_DEBUG("Decoding %s as %s (frame %ld)", + td->name, + (type_type == _TT_GENERIC) ? "OCTET STRING" : "OS-SpecialCase", + (long)size); /* * Create the string if does not exist. @@ -188,8 +196,8 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td, RETURN(rval.code); } - ASN_DEBUG("OS length is %d bytes, form %d", - (int)ctx->left, tlv_constr); + ASN_DEBUG("OS length is %d bytes, form %d (consumed %d==0)", + (int)ctx->left, tlv_constr, rval.consumed); if(tlv_constr) { /* @@ -198,18 +206,6 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td, ctx->ptr = _new_stack(); if(ctx->ptr) { (void *)stck = ctx->ptr; -#if 0 - if(ctx->left < 0) { - stck->cur_ptr->want_nulls = -ctx->left; - stck->cur_ptr->left = -1; - } else { - stck->cur_ptr->want_nulls = 0; - stck->cur_ptr->left = ctx->left; - } - ASN_DEBUG("+EXPECT1 left=%d wn=%d", - stck->cur_ptr->left, - stck->cur_ptr->want_nulls); -#endif if(type_type == _TT_BIT_STRING) { /* Number of meaningless tail bits */ APPEND("\0", 1); @@ -555,6 +551,9 @@ OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, *p++ = h2c[(*buf >> 4) & 0x0F]; *p++ = h2c[*buf & 0x0F]; } + + _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */ + er.encoded += p - scratch; } else { for(i = 0; buf < end; buf++, i++) { if(!(i % 16) && (i || st->size > 16)) { @@ -567,12 +566,15 @@ OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr, *p++ = h2c[*buf & 0x0F]; *p++ = 0x20; } - if(i) p--; /* Remove the tail space */ + if(p - scratch) { + p--; /* Remove the tail space */ + _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */ + er.encoded += p - scratch; + if(st->size > 16) + _i_ASN_TEXT_INDENT(1, ilevel-1); + } } - _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */ - er.encoded += p - scratch; - return er; } @@ -629,9 +631,14 @@ OCTET_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, *p++ = h2c[*buf & 0x0F]; *p++ = 0x20; } - if(i) p--; /* Remove the tail space */ - return cb(scratch, p - scratch, app_key); + if(p > scratch) { + p--; /* Remove the tail space */ + if(cb(scratch, p - scratch, app_key)) + return -1; + } + + return 0; } int diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c index cd407283..5ef1bf44 100644 --- a/skeletons/ber_decoder.c +++ b/skeletons/ber_decoder.c @@ -6,13 +6,16 @@ #include #include +#undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ ptr = ((char *)ptr) + num; \ size -= num; \ consumed_myself += num; \ } while(0) +#undef RETURN #define RETURN(_code) do { \ + fprintf(stderr, "-----%d", __LINE__); \ ber_dec_rval_t rval; \ rval.code = _code; \ rval.consumed = consumed_myself; \ @@ -100,6 +103,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, case -1: RETURN(RC_FAIL); case 0: RETURN(RC_WMORE); } + ADVANCE(tag_len + len_len); } else { assert(tagno < td->tags_count); /* At least one loop */ } diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index ac2bbd68..41fbae3f 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -30,6 +30,7 @@ * This macro "eats" the part of the buffer which is definitely "consumed", * i.e. was correctly converted into local representation or rightfully skipped. */ +#undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ ptr = ((char *)ptr) + num; \ @@ -42,6 +43,7 @@ /* * Switch to the next phase of parsing. */ +#undef NEXT_PHASE #define NEXT_PHASE(ctx) do { \ ctx->phase++; \ ctx->step = 0; \ @@ -50,6 +52,7 @@ /* * Return a standardized complex structure. */ +#undef RETURN #define RETURN(_code) do { \ rval.code = _code; \ rval.consumed = consumed_myself;\ @@ -616,9 +619,11 @@ CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, } /* Print member's name and stuff */ - if(cb(elm->name, strlen(elm->name), app_key) - || cb(": ", 2, app_key)) - return -1; + if(0) { + if(cb(elm->name, strlen(elm->name), app_key) + || cb(": ", 2, app_key)) + return -1; + } return elm->type->print_struct(elm->type, memb_ptr, ilevel, cb, app_key); diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index 9057ac03..041f8c2d 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -30,6 +30,7 @@ * This macro "eats" the part of the buffer which is definitely "consumed", * i.e. was correctly converted into local representation or rightfully skipped. */ +#undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ ptr = ((char *)ptr) + num; \ @@ -42,6 +43,8 @@ /* * Switch to the next phase of parsing. */ +#undef NEXT_PHASE +#undef PHASE_OUT #define NEXT_PHASE(ctx) do { \ ctx->phase++; \ ctx->step = 0; \ @@ -51,6 +54,7 @@ /* * Return a standardized complex structure. */ +#undef RETURN #define RETURN(_code) do { \ rval.code = _code; \ rval.consumed = consumed_myself;\ @@ -228,7 +232,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *td, */ tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag); ASN_DEBUG("Current tag in %s SEQUENCE for element %d " - "(%s) is %s encoded in %d bytes, left %ld", + "(%s) is %s encoded in %d bytes, of frame %ld", td->name, edx, elements[edx].name, ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT); switch(tag_len) { diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index 4c0c3b77..93da7828 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -36,6 +36,7 @@ * This macro "eats" the part of the buffer which is definitely "consumed", * i.e. was correctly converted into local representation or rightfully skipped. */ +#undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ ptr = ((char *)ptr) + num; \ @@ -48,6 +49,7 @@ /* * Switch to the next phase of parsing. */ +#undef NEXT_PHASE #define NEXT_PHASE(ctx) do { \ ctx->phase++; \ ctx->step = 0; \ @@ -56,6 +58,7 @@ /* * Return a standardized complex structure. */ +#undef RETURN #define RETURN(_code) do { \ rval.code = _code; \ rval.consumed = consumed_myself;\ diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index 0a8ee281..05567605 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -24,12 +24,13 @@ * if the V processor returns with "want more data" even if the buffer * contains way more data than the V processor have seen. */ -#define SIZE_VIOLATION (ctx->left != -1 && (size_t)ctx->left <= size) +#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size) /* * This macro "eats" the part of the buffer which is definitely "consumed", * i.e. was correctly converted into local representation or rightfully skipped. */ +#undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ ptr = ((char *)ptr) + num; \ @@ -42,6 +43,8 @@ /* * Switch to the next phase of parsing. */ +#undef NEXT_PHASE +#undef PHASE_OUT #define NEXT_PHASE(ctx) do { \ ctx->phase++; \ ctx->step = 0; \ @@ -51,6 +54,7 @@ /* * Return a standardized complex structure. */ +#undef RETURN #define RETURN(_code) do { \ rval.code = _code; \ rval.consumed = consumed_myself;\ diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c index 51f8d1d5..e4581aaa 100644 --- a/skeletons/xer_encoder.c +++ b/skeletons/xer_encoder.c @@ -42,7 +42,19 @@ xer_encode(asn1_TYPE_descriptor_t *td, void *sptr, return er; } -static int _print2fp(const void *buffer, size_t size, void *app_key); +/* + * This is a helper function for xer_fprint, which directs all the incoming data + * into the provided file descriptor. + */ +static int +xer__print2fp(const void *buffer, size_t size, void *app_key) { + FILE *stream = (FILE *)app_key; + + if(fwrite(buffer, 1, size, stream) != size) + return -1; + + return 0; +} int xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) { @@ -52,20 +64,9 @@ xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) { if(!td || !sptr) return -1; - er = xer_encode(td, sptr, XER_F_BASIC, _print2fp, stream); + er = xer_encode(td, sptr, XER_F_BASIC, xer__print2fp, stream); if(er.encoded == -1) return -1; return fflush(stream); } - -static int -_print2fp(const void *buffer, size_t size, void *app_key) { - FILE *stream = (FILE *)app_key; - - if(fwrite(buffer, 1, size, stream) != size) - return -1; - - return 0; -} -