Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jer: Add JER-specific constraints, fix BIT STRINGs with variable size #192

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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