Commit 8945e0ea authored by Lev Walkin's avatar Lev Walkin

extended tags support

parent 71a8aaf5
#include "asn1fix_internal.h" #include "asn1fix_internal.h"
#define AFT_IMAGINARY_ANY 1 /* _fetch_tag() flag */ #define AFT_MAGIC_ANY 1 /* _fetch_tag() flag */
static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v); static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);
static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b); static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
...@@ -375,7 +375,7 @@ _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) { ...@@ -375,7 +375,7 @@ _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
*/ */
save_tag = v->tag; /* Save existing tag */ save_tag = v->tag; /* Save existing tag */
memset(&v->tag, 0, sizeof(v->tag)); /* Remove it temporarily */ memset(&v->tag, 0, sizeof(v->tag)); /* Remove it temporarily */
ret = asn1f_fetch_tag(arg->asn, arg->mod, v, &tag, 0); ret = asn1f_fetch_outmost_tag(arg->asn, arg->mod, v, &tag, 0);
v->tag = save_tag; /* Restore the tag back */ v->tag = save_tag; /* Restore the tag back */
if(ret == 0) return 0; /* If found tag, it's okay */ if(ret == 0) return 0; /* If found tag, it's okay */
...@@ -403,8 +403,8 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) { ...@@ -403,8 +403,8 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
int ra, rb; int ra, rb;
int ret; int ret;
ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta, AFT_IMAGINARY_ANY); ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a, &ta, AFT_MAGIC_ANY);
rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb, AFT_IMAGINARY_ANY); rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b, &tb, AFT_MAGIC_ANY);
/* /*
* If both tags are explicitly or implicitly given, use them. * If both tags are explicitly or implicitly given, use them.
......
#include "asn1fix_internal.h" #include "asn1fix_internal.h"
int #define ADD_TAG(skip, newtag) do { \
asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int flags) { void *__p; \
int ret; if(skip) { skip--; break; } \
__p = realloc((*tags), \
sizeof(struct asn1p_type_tag_s) * (count + 1)); \
if(!__p) return -1; \
*tags = __p; \
(*tags)[count++] = newtag; \
if((flags & AFT_FETCH_OUTMOST)) return count; \
if(newtag.tag_mode == TM_IMPLICIT) skip++; \
} while(0)
if(expr->tag.tag_class != TC_NOCLASS) { static int
*tag = expr->tag; asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int skip, enum asn1f_aft_flags_e flags) {
return 0; asn1p_expr_t *expr = arg->expr;
}
/* If this type is tagged, add this tag first */
if(expr->tag.tag_class != TC_NOCLASS)
ADD_TAG(skip, expr->tag);
/* REMOVE ME */
if(expr->expr_type == A1TC_EXTENSIBLE) { if(expr->expr_type == A1TC_EXTENSIBLE) {
memset(tag, 0, sizeof(*tag)); struct asn1p_type_tag_s tt;
tag->tag_class = -1; memset(&tt, 0, sizeof(tt));
return 0; tt.tag_class = -1;
ADD_TAG(skip, tt);
return count;
} }
if(expr->meta_type == AMT_TYPE) { if(expr->meta_type == AMT_TYPE) {
memset(tag, 0, sizeof(*tag)); struct asn1p_type_tag_s tt;
tag->tag_class = TC_UNIVERSAL; memset(&tt, 0, sizeof(tt));
tag->tag_value = expr_type2uclass_value[expr->expr_type]; tt.tag_class = TC_UNIVERSAL;
if(flags && expr->expr_type == ASN_TYPE_ANY) { tt.tag_value = expr_type2uclass_value[expr->expr_type];
assert(tag->tag_value == 0); if(tt.tag_value == 0) {
tag->tag_value = -1; if(expr->expr_type == ASN_TYPE_ANY
return 0; && (flags & AFT_IMAGINARY_ANY))
tt.tag_value = -1;
else
return -1;
} }
return (tag->tag_value == 0) ? -1 : 0; ADD_TAG(skip, tt);
return count;
} }
if(expr->meta_type == AMT_TYPEREF) { if(expr->meta_type == AMT_TYPEREF) {
arg_t arg; expr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
expr = asn1f_lookup_symbol(&arg, expr->module, expr->reference);
if(expr == NULL) return -1; if(expr == NULL) return -1;
if(expr->_mark & TM_RECURSION) if(expr->_mark & TM_RECURSION)
return -1; return -1;
arg->expr = expr;
expr->_mark |= TM_RECURSION; expr->_mark |= TM_RECURSION;
ret = asn1f_fetch_tag(asn, expr->module, expr, tag, count = asn1f_fetch_tags_impl(arg, tags, count, skip, flags);
flags);
expr->_mark &= ~TM_RECURSION; expr->_mark &= ~TM_RECURSION;
return ret; return count;
} }
return -1; return -1;
} }
int
asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int _aft_imaginary_any) {
struct asn1p_type_tag_s *tags;
enum asn1f_aft_flags_e flags;
int count;
flags = AFT_FETCH_OUTMOST;
flags |= AFT_IMAGINARY_ANY * _aft_imaginary_any;
count = asn1f_fetch_tags(asn, mod, expr, &tags, flags);
if(count <= 0) return count;
*tag = tags[0];
free(tags);
return 0;
}
int
asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s **tags_r, enum asn1f_aft_flags_e flags) {
arg_t arg;
struct asn1p_type_tag_s *tags = 0;
int count;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = mod;
arg.expr = expr;
count = asn1f_fetch_tags_impl(&arg, &tags, 0, 0, flags);
if(count <= 0 && tags) {
free(tags);
tags = 0;
}
*tags_r = tags;
return count;
}
#ifndef _ASN1FIX_TAGS_H_ #ifndef _ASN1FIX_TAGS_H_
#define _ASN1FIX_TAGS_H_ #define _ASN1FIX_TAGS_H_
int asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int special_ANY_handling); enum asn1f_aft_flags_e {
AFT_IMAGINARY_ANY = 0x01, /* Treat ANY tag as [IMAGINARY ANY] */
AFT_FETCH_OUTMOST = 0x02, /* Fetch only outmost tag */
};
/*
* Allocate and return an array of tags for the given type.
* Type1 ::= [2] EXPLICIT Type2
* Type2 ::= [3] IMPLICIT Type3
* Type3 ::= [4] EXPLICIT SEQUENCE { ... }
* Will return [2][3][UNIVERSAL 16] for the Type1.
*/
int asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr,
struct asn1p_type_tag_s **tags, enum asn1f_aft_flags_e flags);
/*
* Fetch the outmost tag of the given type.
* Type1 ::= Type2
* Type2 ::= [2] Type3
* Type3 ::= SEQUENCE { ... }
* Will yield [2] for Type1.
*/
int asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int _aft_imaginary_any);
#endif /* _ASN1FIX_TAGS_H_ */ #endif /* _ASN1FIX_TAGS_H_ */
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