Skip to content

Commit

Permalink
jer: Add JER-specific constraints, fix BIT STRINGs with variable size
Browse files Browse the repository at this point in the history
  • Loading branch information
v0-e authored and mouse07410 committed Jun 20, 2024
1 parent 5fa129c commit 4d360ed
Show file tree
Hide file tree
Showing 137 changed files with 5,503 additions and 364 deletions.
104 changes: 103 additions & 1 deletion libasn1compiler/asn1c_C.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
static int emit_single_member_OER_constraint_value(arg_t *arg, asn1cnst_range_t *range);
static int emit_single_member_OER_constraint_size(arg_t *arg, asn1cnst_range_t *range);
static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, const char *type);
static int emit_single_member_JER_constraint_size(arg_t *arg, asn1cnst_range_t *range);
static int emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_JER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_table(arg_t *arg, asn1p_expr_t *expr,
asn1c_ioc_table_and_objset_t *);
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier);
Expand Down Expand Up @@ -476,7 +478,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc
});
OUT("};\n");

if((roms_count + aoms_count) && (arg->flags & (A1C_GEN_OER | A1C_GEN_UPER | A1C_GEN_APER))) {
if((roms_count + aoms_count) && (arg->flags & (A1C_GEN_OER | A1C_GEN_UPER | A1C_GEN_APER | A1C_GEN_JER))) {
int elm = 0;
int comma = 0;
comp_mode = 0;
Expand Down Expand Up @@ -2164,6 +2166,29 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alpha
return 0;
}

static int
emit_single_member_JER_constraint_size(arg_t *arg, asn1cnst_range_t *range) {
if(!range) {
/* jer_support.h: asn_jer_constraint_s */
OUT("-1");
return 0;
}

if(range->incompatible || range->not_JER_visible) {
OUT("-1");
} else {
if(range->left.type == ARE_VALUE && range->right.type == ARE_VALUE
&& range->left.value == range->right.value
&& range->left.value >= 0) {
OUT("%s", asn1p_itoa(range->left.value));
} else {
OUT("-1");
}
}

return 0;
}

static int
emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
int save_target = arg->target->target;
Expand Down Expand Up @@ -2385,6 +2410,49 @@ emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
return 0;
}

static int
emit_member_JER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
int save_target = arg->target->target;
asn1cnst_range_t *range;
asn1p_expr_type_e etype;

etype = expr_get_type(arg, expr);

if((arg->flags & A1C_GEN_JER)
&& (etype == ASN_BASIC_BIT_STRING)) {
/* Fall through */
} else {
return 0;
}

REDIR(OT_CTDEFS);

OUT("#if !defined(ASN_DISABLE_JER_SUPPORT)\n");
OUT("static asn_jer_constraints_t "
"asn_JER_%s_%s_constr_%d CC_NOTUSED = {\n",
pfx, MKID(expr), expr->_type_unique_index);

INDENT(+1);

/* .size */
range = asn1constraint_compute_JER_range(expr->Identifier, etype,
expr->combined_constraints,
ACT_CT_SIZE, 0, 0, 0);
if(emit_single_member_JER_constraint_size(arg, range)) {
return -1;
}
asn1constraint_range_free(range);

INDENT(-1);

OUT("};\n");
OUT("#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */\n");

REDIR(save_target);

return 0;
}

static int
safe_string(const uint8_t *buf, int size) {
const uint8_t *end = buf + size;
Expand Down Expand Up @@ -2988,6 +3056,21 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
}
OUT(",\n");
OUT_NOINDENT("#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */\n");
OUT_NOINDENT("#if !defined(ASN_DISABLE_JER_SUPPORT)\n");
if(C99_MODE) OUT(".jer_constraints = ");
if(arg->flags & A1C_GEN_JER) {
if(expr->constraints && expr->expr_type == ASN_BASIC_BIT_STRING) {
OUT("&asn_JER_memb_%s_constr_%d",
MKID(expr),
expr->_type_unique_index);
} else {
OUT("0");
}
} else {
OUT("0");
}
OUT(",\n");
OUT_NOINDENT("#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */\n");
if(C99_MODE) OUT(".general_constraints = ");
if(expr->constraints) {
if(arg->flags & A1C_NO_CONSTRAINTS) {
Expand Down Expand Up @@ -3050,6 +3133,9 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
if(emit_member_PER_constraints(arg, expr, "memb"))
return -1;

if(emit_member_JER_constraints(arg, expr, "memb"))
return -1;

REDIR(save_target);

return 0;
Expand All @@ -3074,6 +3160,9 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
if(emit_member_PER_constraints(arg, expr, "type"))
return -1;

if(emit_member_JER_constraints(arg, expr, "type"))
return -1;

if(HIDE_INNER_DEFS)
OUT("static /* Use -fall-defs-global to expose */\n");
OUT("asn_TYPE_descriptor_t asn_DEF_%s", p);
Expand Down Expand Up @@ -3177,6 +3266,19 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
}
OUT(",\n");
OUT_NOINDENT("#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */\n");
OUT_NOINDENT("#if !defined(ASN_DISABLE_JER_SUPPORT)\n");
if(arg->flags & A1C_GEN_JER) {
if(expr->expr_type == ASN_BASIC_BIT_STRING) {
OUT("&asn_JER_type_%s_constr_%d",
expr_id, expr->_type_unique_index);
} else {
OUT("0");
}
} else {
OUT("0");
}
OUT(",\n");
OUT_NOINDENT("#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */\n");
#define FUNCREF(foo) \
do { \
OUT("%s", p); \
Expand Down
53 changes: 46 additions & 7 deletions libasn1fix/asn1fix_crange.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,12 @@ static int _range_merge_in(asn1cnst_range_t *into, asn1cnst_range_t *cr) {

into->not_OER_visible |= cr->not_OER_visible;
into->not_PER_visible |= cr->not_PER_visible;
into->not_JER_visible |= cr->not_JER_visible;
into->extensible |= cr->extensible;
if(into->extensible)
if(into->extensible) {
into->not_OER_visible = 1;
into->not_JER_visible = 1;
}

into->narrowing = _softest_narrowing(into, cr);

Expand Down Expand Up @@ -592,12 +595,15 @@ _range_intersection(asn1cnst_range_t *range, const asn1cnst_range_t *with, int s
if(is_oer) {
assert(range->extensible == 0);
assert(range->not_OER_visible == 0);
assert(range->not_JER_visible == 0);
assert(with->extensible == 0);
assert(with->not_OER_visible == 0);
assert(with->not_JER_visible == 0);
if(range->extensible) {
assert(range->not_OER_visible);
assert(range->not_JER_visible);
}
if(range->extensible || range->not_OER_visible) {
if(range->extensible || range->not_OER_visible || range->not_JER_visible) {
/* X.696 #8.2.4 Completely ignore the extensible constraints */
/* (XXX)(YYY,...) Retain the first one (XXX). */
asn1cnst_range_t *tmp = _range_new();
Expand All @@ -609,16 +615,19 @@ _range_intersection(asn1cnst_range_t *range, const asn1cnst_range_t *with, int s

if(with->extensible) {
assert(with->not_OER_visible);
assert(with->not_JER_visible);
}
if(with->extensible || with->not_OER_visible) {
if(with->extensible || with->not_OER_visible || with->not_JER_visible) {
/* X.696 #8.2.4 Completely ignore the extensible constraints */
return 0;
}
} else {
/* Propagate errors */
range->extensible |= with->extensible;
if(with->extensible)
if(with->extensible) {
range->not_OER_visible = 1;
range->not_JER_visible = 1;
}
range->not_PER_visible |= with->not_PER_visible;
}
range->empty_constraint |= with->empty_constraint;
Expand Down Expand Up @@ -828,6 +837,11 @@ asn1constraint_compute_PER_range(const char *dbg_name, asn1p_expr_type_e expr_ty
return asn1constraint_compute_constraint_range(dbg_name, expr_type, ct, requested_ct_type, minmax, exmet, cpr_flags);
}

asn1cnst_range_t *
asn1constraint_compute_JER_range(const char *dbg_name, asn1p_expr_type_e expr_type, const asn1p_constraint_t *ct, enum asn1p_constraint_type_e requested_ct_type, const asn1cnst_range_t *minmax, int *exmet, enum cpr_flags cpr_flags) {
return asn1constraint_compute_constraint_range(dbg_name, expr_type, ct, requested_ct_type, minmax, exmet, cpr_flags | CPR_strict_JER_visibility);
}

static asn1cnst_range_t *
asn1f_real_range_from_WCOMPS(const char *dbg_name,
const asn1p_constraint_t *ct) {
Expand Down Expand Up @@ -1044,6 +1058,11 @@ asn1constraint_compute_constraint_range(
return range;
}

if(!ct
|| (range->not_JER_visible && (cpr_flags & CPR_strict_JER_visibility))) {
return range;
}

switch(ct->type) {
case ACT_EL_VALUE:
vmin = vmax = ct->value;
Expand All @@ -1059,6 +1078,7 @@ asn1constraint_compute_constraint_range(
if(!*exmet) {
range->extensible = 1;
range->not_OER_visible = 1;
range->not_JER_visible = 1;
} else {
_range_free(range);
errno = ERANGE;
Expand Down Expand Up @@ -1086,8 +1106,10 @@ asn1constraint_compute_constraint_range(
if(errno == ERANGE) {
range->empty_constraint = 1;
range->extensible = 1;
if(range->extensible)
if(range->extensible) {
range->not_OER_visible = 1;
range->not_PER_visible = 1;
}
tmp = range;
} else {
_range_free(range);
Expand All @@ -1106,8 +1128,10 @@ asn1constraint_compute_constraint_range(
if(!tmp) {
if(errno == ERANGE) {
range->extensible = 1;
if(range->extensible)
if(range->extensible) {
range->not_OER_visible = 1;
range->not_JER_visible = 1;
}
continue;
} else {
_range_free(range);
Expand Down Expand Up @@ -1152,8 +1176,17 @@ asn1constraint_compute_constraint_range(
continue;
}

if(tmp->not_JER_visible
&& (cpr_flags & CPR_strict_JER_visibility)) {
/*
* Ignore not JER-visible
*/
_range_free(tmp);
continue;
}

ret = _range_intersection(range, tmp,
ct->type == ACT_CA_SET, cpr_flags & CPR_strict_OER_visibility);
ct->type == ACT_CA_SET, cpr_flags & (CPR_strict_OER_visibility | CPR_strict_JER_visibility));
_range_free(tmp);
if(ret) {
_range_free(range);
Expand All @@ -1180,6 +1213,7 @@ asn1constraint_compute_constraint_range(
if(errno == ERANGE) {
range->extensible = 1;
range->not_OER_visible = 1;
range->not_JER_visible = 1;
continue;
} else {
_range_free(range);
Expand All @@ -1195,6 +1229,7 @@ asn1constraint_compute_constraint_range(
if(tmp) {
tmp->extensible |= range->extensible;
tmp->not_OER_visible |= range->not_OER_visible;
tmp->not_JER_visible |= range->not_JER_visible;
tmp->empty_constraint |= range->empty_constraint;
_range_free(range);
range = tmp;
Expand All @@ -1215,6 +1250,7 @@ asn1constraint_compute_constraint_range(
if(errno == ERANGE) {
range->extensible = 1;
range->not_OER_visible = 1;
range->not_JER_visible = 1;
continue;
} else {
_range_free(range);
Expand All @@ -1235,6 +1271,7 @@ asn1constraint_compute_constraint_range(
*/
range->extensible |= tmp->extensible;
range->not_OER_visible |= tmp->not_OER_visible;
range->not_JER_visible |= tmp->not_JER_visible;
_range_free(tmp);
continue;
}
Expand All @@ -1247,8 +1284,10 @@ asn1constraint_compute_constraint_range(
if(requested_ct_type == ACT_CT_FROM) {
/*
* X.696 permitted alphabet constraints are not OER-visible.
* X.697 permitted alphabet constraints are not JER-visible.
*/
range->not_OER_visible = 1;
range->not_JER_visible = 1;
if(range->extensible) {
/*
* X.691, #9.3.10:
Expand Down
11 changes: 10 additions & 1 deletion libasn1fix/asn1fix_crange.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef struct asn1cnst_range_s {
int incompatible; /* Constraint incompatible with argument */
int not_OER_visible; /* Contains not OER-visible components */
int not_PER_visible; /* Contains not PER-visible components */
int not_JER_visible; /* Contains not JER-visible components */
} asn1cnst_range_t;

/*
Expand All @@ -50,7 +51,8 @@ enum cpr_flags {
CPR_noflags = 0x00,
CPR_strict_OER_visibility = 0x01,
CPR_strict_PER_visibility = 0x02,
CPR_simulate_fbless_SIZE = 0x04,
CPR_strict_JER_visibility = 0x04,
CPR_simulate_fbless_SIZE = 0x08,
};
asn1cnst_range_t *asn1constraint_compute_OER_range(const char *dbg_name,
asn1p_expr_type_e expr_type,
Expand All @@ -66,6 +68,13 @@ asn1cnst_range_t *asn1constraint_compute_PER_range(const char *dbg_name,
const asn1cnst_range_t *minmax,
int *expectation_met,
enum cpr_flags);
asn1cnst_range_t *asn1constraint_compute_JER_range(const char *dbg_name,
asn1p_expr_type_e expr_type,
const asn1p_constraint_t *ct,
enum asn1p_constraint_type_e required_type,
const asn1cnst_range_t *minmax,
int *expectation_met,
enum cpr_flags);
/* Base implementation */
asn1cnst_range_t *asn1constraint_compute_constraint_range(const char *dbg_name,
asn1p_expr_type_e expr_type,
Expand Down
3 changes: 3 additions & 0 deletions skeletons/ANY.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
0,
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
#if !defined(ASN_DISABLE_JER_SUPPORT)
0,
#endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
asn_generic_no_constraint
}, /* No constraints */
0, 0, /* No members */
Expand Down
5 changes: 3 additions & 2 deletions skeletons/ANY_jer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
#include <ANY.h>

asn_enc_rval_t
ANY_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
ANY_encode_jer(const asn_TYPE_descriptor_t *td, const asn_jer_constraints_t *constraints,
const void *sptr, int ilevel,
enum jer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
void *app_key) {
ASN__ENCODE_FAILED;

/* Dump as binary */
return OCTET_STRING_encode_jer(td, sptr, ilevel, flags, cb, app_key);
return OCTET_STRING_encode_jer(td, constraints, sptr, ilevel, flags, cb, app_key);
}
Loading

0 comments on commit 4d360ed

Please sign in to comment.