Skip to content

Commit 50934ba

Browse files
brchiuvlm
authored andcommitted
Fix 'Information Object Set XXX contains no objects' when parsing S1AP's ASN.1
The aforementioned error message displayed during processing the following ASN.1 excerpt. S1AP-ELEMENTARY-PROCEDURES S1AP-ELEMENTARY-PROCEDURE ::= { S1AP-ELEMENTARY-PROCEDURES-CLASS-1 | S1AP-ELEMENTARY-PROCEDURES-CLASS-2, ... } S1AP-ELEMENTARY-PROCEDURES-CLASS-1 S1AP-ELEMENTARY-PROCEDURE ::= { handoverPreparation | ... writeReplaceWarning, ..., uERadioCapabilityMatch | .... uEContextResume } S1AP-ELEMENTARY-PROCEDURES-CLASS-2 S1AP-ELEMENTARY-PROCEDURE ::= { handoverNotification | ... privateMessage, ..., downlinkUEAssociatedLPPaTransport | ... mMECPRelocationIndication } Because S1AP-ELEMENTARY-PROCEDURES-CLASS-1 and S1AP-ELEMENTARY-PROCEDURES-CLASS-2 are resolved 'after' S1AP-ELEMENTARY-PROCEDURES, so the ioc tables of them are not available during resolving S1AP-ELEMENTARY-PROCEDURES. So we can not drop the latter's containedSubtype field at first pass of asn1f_resolve_constraints of fix process. We also add second pass of asn1f_resolve_constraints to have a chance to combine ioc tables of S1AP-ELEMENTARY-PROCEDURES-CLASS-1 and S1AP-ELEMENTARY-PROCEDURES-CLASS-2.
1 parent 4e5edcf commit 50934ba

File tree

4 files changed

+59
-1
lines changed

4 files changed

+59
-1
lines changed

libasn1fix/asn1fix.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ asn1f_fix_module__phase_2(arg_t *arg) {
262262
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_defaults);
263263
RET2RVAL(ret, rvalue);
264264

265+
/*
266+
* Resolve references in constraints (the second pass).
267+
*/
268+
ret = asn1f_recurse_expr(arg, asn1f_resolve_constraints);
269+
RET2RVAL(ret, rvalue);
270+
265271
/*
266272
* Check semantic validity of constraints.
267273
*/

libasn1fix/asn1fix_constraint.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ asn1constraint_pullup(arg_t *arg) {
2121
switch(expr->meta_type) {
2222
case AMT_TYPE:
2323
case AMT_TYPEREF:
24+
case AMT_VALUESET:
2425
break;
2526
default:
2627
return 0; /* Nothing to do */
@@ -273,14 +274,14 @@ static int
273274
constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
274275
asn1p_constraint_t *ct_expr;
275276
int ret;
277+
asn1p_expr_t *rtype = (asn1p_expr_t *)0;
276278

277279
DEBUG("(\"%s\")", asn1f_printable_value(ct->containedSubtype));
278280

279281
if(ct->containedSubtype->type == ATV_VALUESET) {
280282
ct_expr = ct->containedSubtype->value.constraint;
281283
DEBUG("Found %s in constraints", "ValueSet");
282284
} else if(get_reference_from(ct)) {
283-
asn1p_expr_t *rtype;
284285
arg_t tmparg;
285286

286287
rtype = asn1f_lookup_symbol(arg, arg->expr->rhs_pspecs,
@@ -299,6 +300,14 @@ constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
299300
ret = asn1constraint_pullup(&tmparg);
300301
if(ret) return ret;
301302

303+
if(rtype->ioc_table) {
304+
if(!arg->expr->ioc_table)
305+
arg->expr->ioc_table = asn1p_ioc_table_new();
306+
asn1p_ioc_table_append(arg->expr->ioc_table, rtype->ioc_table);
307+
asn1p_value_free(ct->containedSubtype);
308+
ct->containedSubtype = NULL;
309+
}
310+
302311
ct_expr = rtype->combined_constraints;
303312
if(!ct_expr) return 0;
304313
} else {
@@ -330,6 +339,14 @@ constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
330339
}
331340

332341
ct->type = ACT_CA_SET;
342+
343+
/* keep constrainedSubtype field for future usage,
344+
if valueset has not been resolved yet. */
345+
if(rtype &&
346+
(rtype->meta_type == AMT_VALUESET) &&
347+
(!rtype->ioc_table))
348+
return 0;
349+
333350
asn1p_value_free(ct->containedSubtype);
334351
ct->containedSubtype = NULL;
335352

libasn1parser/asn1p_class.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ asn1p_ioc_table_add(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
2525
it->row[it->rows++] = row;
2626
}
2727

28+
void
29+
asn1p_ioc_table_append(asn1p_ioc_table_t *it, asn1p_ioc_table_t *src) {
30+
31+
if(!src) return;
32+
33+
for(size_t i = 0; i < src->rows; i++) {
34+
asn1p_ioc_table_add(it, asn1p_ioc_row_clone(src->row[i]));
35+
}
36+
}
37+
2838
void
2939
asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
3040
if(it) {
@@ -93,6 +103,29 @@ asn1p_ioc_row_new(asn1p_expr_t *oclass) {
93103
return row;
94104
}
95105

106+
asn1p_ioc_row_t *
107+
asn1p_ioc_row_clone(asn1p_ioc_row_t *src) {
108+
asn1p_ioc_row_t *row;
109+
110+
row = calloc(1, sizeof *row);
111+
if(!row) return NULL;
112+
113+
row->column = calloc(src->columns, sizeof *src->column);
114+
if(!row->column) {
115+
free(row);
116+
return NULL;
117+
}
118+
row->columns = src->columns;
119+
120+
for(size_t i = 0; i < src->columns; i++) {
121+
row->column[i].field = src->column[i].field;
122+
row->column[i].value = src->column[i].value ? asn1p_expr_clone(src->column[i].value, 0) : 0;
123+
row->column[i].new_ref = 1;
124+
}
125+
126+
return row;
127+
}
128+
96129
void
97130
asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
98131
if(row) {

libasn1parser/asn1p_class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ typedef struct asn1p_ioc_row_s {
1616
} asn1p_ioc_row_t;
1717

1818
asn1p_ioc_row_t *asn1p_ioc_row_new(struct asn1p_expr_s *oclass);
19+
asn1p_ioc_row_t *asn1p_ioc_row_clone(asn1p_ioc_row_t *src);
1920
size_t asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *);
2021
void asn1p_ioc_row_delete(asn1p_ioc_row_t *);
2122

@@ -27,6 +28,7 @@ typedef struct asn1p_ioc_table_s {
2728

2829
asn1p_ioc_table_t *asn1p_ioc_table_new(void);
2930
void asn1p_ioc_table_add(asn1p_ioc_table_t *, asn1p_ioc_row_t *row);
31+
void asn1p_ioc_table_append(asn1p_ioc_table_t *it, asn1p_ioc_table_t *src);
3032
size_t asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *);
3133
void asn1p_ioc_table_free(asn1p_ioc_table_t *);
3234

0 commit comments

Comments
 (0)