upgrade: PER related changes

pespin/master
Lev Walkin 2005-11-26 11:25:14 +00:00
parent 708530582f
commit 59b176ee35
119 changed files with 14519 additions and 2306 deletions

View File

@ -1,9 +1,11 @@
0.9.20: 2005-Nov-07
0.9.20: 2005-Nov-13
* SET OF CHOICE, SEQUENCE OF CHOICE and a certain named S/O types
are represented differently in XER. THIS IS AN ICOMPATIBLE CHANGE.
(Test case 70) (Severity: low; Security impact: low)
* PER implementation has started
* asn1c: Removed -ftypes88 command line option.
0.9.19: 2005-Oct-06

7
TODO
View File

@ -1,7 +1,6 @@
1. MAJOR:
1.1 Support for PER encoding. Requires advanced subtype constraints support,
which is already completed.
1.1 Support for PER encoding. PER decoding is already supported.
1.2 Support for Information Object Classes.
Status: Support for parsing IOCs is mostly present.
@ -12,7 +11,3 @@ which is already completed.
2.1 Support for EXTERNAL, EMBEDDED-PDV and CHARACTER STRING types.
Requires something from 1.2 (Information Object Classes).
3. MINOR:
3.1 Support for DEFAULT encoding and decoding, at least in INTEGER/ENUMERATED types.

View File

@ -4,7 +4,7 @@ asn1c \- ASN.1 Compiler
.SH SYNOPSIS
asn1c [\fB\-E\fR [\fB-F\fR] | \fB\-P\fR | \fB\-R\fR]
[\fB\-S\fR\fIdir\fR] [\fB-X\fR]
[\fB\-W\fR\fIdebug-\fR...] [\fB\-f\fR\fIoption\fR...] [\fB\-p\fR\fIrint-\fR...]
[\fB\-W\fR\fIdebug-\fR...] [\fB\-f\fR\fIoption\fR] [\fB\-gen-\fR\fIoption\fR] [\fB\-print-\fR\fIoption\fR]
\fIinfile\fR...
.SH DESCRIPTION
asn1c compiles the ASN.1 specifications into the set of
@ -25,7 +25,11 @@ and other encoding standards.
.br
\fB\-fall-defs-global \-fbless-SIZE \-fcompound-names \-findirect-choice
.BI "\-fknown-extern-type="<name>
\fB\-fnative-types \-fno-constraints \-fno-include-deps \-funnamed-unions \-fskeletons-copy \-ftypes88\fR
\fB\-fnative-types \-fno-constraints \-fno-include-deps \-funnamed-unions \-fskeletons-copy
.TP
\fICodecs Generation Options\fR
.br
.B \-gen-PER
.TP
\fIOutput Options\fR
.br
@ -117,11 +121,10 @@ Enable unnamed unions in the definitions of target language's structures.
.TP
.B \-fskeletons-copy
Copy support files (skeletons) rather than symlink them.
.SH CODECS GENERATION OPTIONS
.TP
.B \-ftypes88
Pretend to support only ASN.1:1988 embedded types. Certain reserved words,
such as UniversalString and BMPString, become ordinary type references
and may be redefined by the specification.
.B \-gen-PER
Generate Packed Encoding Rules (PER) support code.
.SH OUTPUT OPTIONS
.TP
.B \-print-constraints

View File

@ -62,7 +62,7 @@ main(int ac, char **av) {
/*
* Process command-line options.
*/
while((ch = getopt(ac, av, "EFf:hLPp:RS:vW:X")) != -1)
while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1)
switch(ch) {
case 'E':
print_arg__print_out = 1;
@ -95,13 +95,19 @@ main(int ac, char **av) {
asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
} else if(strcmp(optarg, "skeletons-copy") == 0) {
asn1_compiler_flags |= A1C_SKELETONS_COPY;
} else if(strcmp(optarg, "types88") == 0) {
asn1_parser_flags |= A1P_TYPES_RESTRICT_TO_1988;
} else {
fprintf(stderr, "-f%s: Invalid argument\n", optarg);
exit(EX_USAGE);
}
break;
case 'g':
if(strcmp(optarg, "en-PER") == 0) {
asn1_compiler_flags |= A1C_GEN_PER;
} else {
fprintf(stderr, "-g%s: Invalid argument\n", optarg);
exit(EX_USAGE);
}
break;
case 'h':
usage(av[0]);
case 'P':
@ -109,7 +115,15 @@ main(int ac, char **av) {
asn1_compiler_flags &= ~A1C_NO_C99;
break;
case 'p':
if(strcmp(optarg, "rint-constraints") == 0) {
if(strncmp(optarg, "du=", 3) == 0) {
char *pduname = optarg + 3;
if(strcmp(pduname, "auto")) {
fprintf(stderr, "-pdu=%s: expected -pdu=auto\n",
pduname);
exit(EX_USAGE);
}
asn1_compiler_flags |= A1C_PDU_AUTO;
} else if(strcmp(optarg, "rint-constraints") == 0) {
asn1_printer_flags |= APF_DEBUG_CONSTRAINTS;
} else if(strcmp(optarg, "rint-lines") == 0) {
asn1_printer_flags |= APF_LINE_COMMENTS;
@ -250,7 +264,8 @@ main(int ac, char **av) {
/*
* Make sure the skeleton directory is out there.
*/
if(skeletons_dir == NULL) {
if((asn1_compiler_flags & A1C_OMIT_SUPPORT_CODE) == 0
&& skeletons_dir == NULL) {
struct stat sb;
skeletons_dir = DATADIR;
if((av[-optind][0] == '.' || av[-optind][1] == '/')
@ -326,7 +341,10 @@ usage(const char *av0) {
" -fno-include-deps Do not generate courtesy #includes for dependencies\n"
" -funnamed-unions Enable unnamed unions in structures\n"
" -fskeletons-copy Force copying the support files\n"
" -ftypes88 Pretend to support only ASN.1:1988 embedded types\n"
"\n"
" -gen-PER Generate PER support code\n"
" -pdu=auto Generate PDU table (discover PDUs automatically)\n"
"\n"
" -print-constraints Explain subtype constraints (debug)\n"

View File

@ -102,8 +102,8 @@ check(int is_ok, uint8_t *buf, int size, size_t consumed) {
assert(rval.code == RC_OK);
assert(rval.consumed == consumed);
assert(strcmp(t.e->buf, "xyz") == 0);
assert(strcmp(t.f->buf, "love_it") == 0);
assert(strcmp((char *)t.e->buf, "xyz") == 0);
assert(strcmp((char *)t.f->buf, "love_it") == 0);
assert(t.g->size == 2);
assert(t.g->bits_unused == 2);

View File

@ -36,8 +36,12 @@ _buf_writer(const void *buffer, size_t size, void *app_key) {
b = buf + buf_offset;
bend = b + size;
fprintf(stderr, "=> [");
for(; b < bend; b++)
fprintf(stderr, "%c", *b);
for(; b < bend; b++) {
if(*b >= 32 && *b < 127 && *b != '%')
fprintf(stderr, "%c", *b);
else
fprintf(stderr, "%%02x", *b);
}
fprintf(stderr, "]:%ld\n", (long)size);
buf_offset += size;
return 0;

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#include "asn1c_out.h"
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
#include <asn1fix_export.h> /* other exportable stuff from libasn1fix */
#include <asn1fix_export.h> /* other exportables from libasn1fix */
static int asn1c_emit_constraint_tables(arg_t *arg, int got_size);
static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range);

View File

@ -66,7 +66,12 @@ asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
asn1c_fdeps_t *cur;
char buf[4096];
FILE *f;
int hit_COMMON_FILES = 0;
enum {
SS_DYNAMIC, /* Dynamic list of dependencies */
SS_CODEC_PER, /* Use contents only if -gen-PER */
SS_COMMON_FILES, /* Section for dependencies */
SS_IGNORE /* Ignore contents of this section */
} special_section = SS_DYNAMIC;
(void)arg;
@ -91,17 +96,27 @@ asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
for(p = strtok(buf, " \t\r\n"); p;
p = strtok(NULL, " \t\r\n")) {
asn1c_fdeps_t *d;
/*
* If hit "COMMON-FILES:", treat everything else
* as a huge dependency.
* Special "prefix" section.
*/
if(strcmp(p, "COMMON-FILES:") == 0) {
hit_COMMON_FILES = 1;
if(strchr(p, ':')) {
special_section = SS_IGNORE;
if(strcmp(p, "COMMON-FILES:") == 0) {
special_section = SS_COMMON_FILES;
} else if((arg->flags & A1C_GEN_PER)
&& strcmp(p, "CODEC-PER:") == 0) {
special_section = SS_CODEC_PER;
}
break;
}
if(special_section == SS_IGNORE)
continue;
d = asn1c_new_dep(p);
assert(d);
d->used_somewhere = hit_COMMON_FILES;
d->used_somewhere = special_section;
if(asn1c_dep_add(cur, d) == 1)
cur = d;

View File

@ -11,6 +11,7 @@ static int asn1c_print_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *);
static int asn1c_copy_over(arg_t *arg, char *path);
static int identical_files(const char *fname1, const char *fname2);
static int generate_pdu_collection_file(arg_t *arg);
int
asn1c_save_compiled_output(arg_t *arg, const char *datadir,
@ -18,7 +19,7 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir,
asn1c_fdeps_t *deps = 0;
asn1c_fdeps_t *dlist;
asn1p_module_t *mod;
FILE *mkf;
FILE *mkf; /* Makefile.am.sample */
int i;
deps = asn1c_read_file_dependencies(arg, datadir);
@ -108,6 +109,12 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir,
}
}
if(arg->flags & A1C_PDU_AUTO) {
fprintf(mkf, "ASN_MODULE_SOURCES+=pdu_collection.c\n");
if(generate_pdu_collection_file(arg))
return -1;
}
fprintf(mkf, "\n\n"
"lib_LTLIBRARIES=libsomething.la\n"
"libsomething_la_SOURCES="
@ -438,3 +445,62 @@ asn1c_copy_over(arg_t *arg, char *path) {
return 1;
}
static int
generate_pdu_collection_file(arg_t *arg) {
asn1p_module_t *mod;
FILE *fp;
fp = asn1c_open_file("pdu_collection", ".c", 0);
if(fp == NULL) {
perror("pdu_collection.c");
return -1;
}
fprintf(fp,
"/*\n"
" * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
" */\n\n");
fprintf(fp, "struct asn_TYPE_descriptor_s;\t"
"/* Forward declaration */\n\n");
TQ_FOR(mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(mod->members), next) {
if(arg->expr->_type_referenced
|| !asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb)
continue;
fprintf(fp, "extern struct asn_TYPE_descriptor_s "
"asn_DEF_%s;\n",
asn1c_make_identifier(0, arg->expr->Identifier,
NULL));
}
}
fprintf(fp, "\n\n");
fprintf(fp, "struct asn_TYPE_descriptor_s *asn_pdu_collection[] = {\n");
TQ_FOR(mod, &(arg->asn->modules), mod_next) {
int mod_printed = 0;
TQ_FOR(arg->expr, &(mod->members), next) {
if(arg->expr->_type_referenced
|| !asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb)
continue;
if(!mod_printed++)
fprintf(fp, "\t/* From module %s in %s */\n",
arg->expr->module->ModuleName,
arg->expr->module->source_file_name);
fprintf(fp, "\t&asn_DEF_%s,\t\n",
asn1c_make_identifier(0, arg->expr->Identifier,
NULL));
}
}
fprintf(fp, "\t0\n};\n\n");
fclose(fp);
fprintf(stderr, "Generated pdu_collection.c\n");
return 0;
}

View File

@ -56,6 +56,16 @@ enum asn1c_flags {
* Copy support files rather than symlink them.
*/
A1C_SKELETONS_COPY = 0x0800,
/*
* -gen-PER
* Generate PER support code
*/
A1C_GEN_PER = 0x1000,
/*
* -pdu=auto
* Generate PDU table
*/
A1C_PDU_AUTO = 0x2000
};
/*

View File

@ -1,7 +1,5 @@
#include "asn1fix_internal.h"
#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_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
static int _asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr);
@ -337,6 +335,7 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
case ASN_CONSTR_SEQUENCE:
case ASN_CONSTR_SET:
case ASN_CONSTR_CHOICE:
DEBUG("Checking tags of members of constructed types");
break;
default:
return 0;
@ -353,6 +352,8 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
if(expr->expr_type != ASN_CONSTR_SEQUENCE || v->marker.flags) {
asn1p_expr_t *nv;
for(nv = v; (nv = TQ_NEXT(nv, next));) {
DEBUG("S/C comparing tags %s s. %s",
v->Identifier, nv->Identifier);
if(_asn1f_compare_tags(arg, v, nv))
r_value = -1;
if(expr->expr_type == ASN_CONSTR_SEQUENCE
@ -404,12 +405,15 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
int ra, rb;
int ret;
ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a, &ta, AFT_MAGIC_ANY);
rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b, &tb, AFT_MAGIC_ANY);
ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a,
&ta, AFT_IMAGINARY_ANY);
rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b,
&tb, AFT_IMAGINARY_ANY);
/*
* If both tags are explicitly or implicitly given, use them.
*/
DEBUG("Fetching outmost tags: %d, %d", ra, rb);
if(ra == 0 && rb == 0) {
/*
* Simple case: fetched both tags.

View File

@ -370,6 +370,7 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
return NULL;
}
tc->_type_referenced = 1;
tc->_mark |= TM_RECURSION;
WITH_MODULE(tc->module,
expr = asn1f_find_terminal_thing(arg, tc, what));

View File

@ -18,6 +18,9 @@
if((flags & AFT_FETCH_OUTMOST)) return count; \
} while(0)
/* X.691, #22.2 */
static int asn1f_fetch_minimal_choice_root_tag(arg_t *arg, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags);
static int
asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int skip, enum asn1f_aft_flags_e flags) {
asn1p_expr_t *expr = arg->expr;
@ -44,9 +47,13 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
if(expr->expr_type == ASN_TYPE_ANY
&& (flags & AFT_IMAGINARY_ANY))
tt.tag_value = -1;
else if(expr->expr_type == ASN_CONSTR_CHOICE)
return count ? count : -1;
else
else if(expr->expr_type != ASN_CONSTR_CHOICE)
return -1;
else if(count) return count;
else if((flags & AFT_CANON_CHOICE) == 0)
return -1;
else if(asn1f_fetch_minimal_choice_root_tag(arg,
&tt, flags))
return -1;
}
ADD_TAG(skip, tt);
@ -55,6 +62,7 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
if(expr->meta_type == AMT_TYPEREF) {
asn1p_expr_t *nexpr;
DEBUG("Following the reference %s", expr->Identifier);
nexpr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
if(nexpr == NULL) {
if(errno != EEXIST) /* -fknown-extern-type */
@ -87,18 +95,52 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
return count;
}
DEBUG("No tags discovered for type %d", expr->expr_type);
return -1;
}
static int
asn1f_fetch_minimal_choice_root_tag(arg_t *arg, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags) {
struct asn1p_type_tag_s min_tag;
asn1p_expr_t *v;
memset(&min_tag, 0, sizeof(min_tag));
min_tag.tag_class = TC_PRIVATE + 1;
TQ_FOR(v, &(arg->expr->members), next) {
arg_t tmparg = *arg;
struct asn1p_type_tag_s *tags = 0;
int count;
if(v->expr_type == A1TC_EXTENSIBLE)
break; /* Search only within extension root */
tmparg.expr = v;
count = asn1f_fetch_tags_impl(&tmparg, &tags, 0, 0, flags);
if(count <= 0) continue;
if(tags[0].tag_class < min_tag.tag_class)
min_tag = tags[0];
else if(tags[0].tag_class == min_tag.tag_class
&& tags[0].tag_value < min_tag.tag_value)
min_tag = tags[0];
free(tags);
}
if(min_tag.tag_class == TC_PRIVATE + 1)
return -1;
else
*tag = min_tag;
return 0;
}
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) {
asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags) {
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;
flags |= AFT_FETCH_OUTMOST;
count = asn1f_fetch_tags(asn, mod, expr, &tags, flags);
if(count <= 0) return count;

View File

@ -5,6 +5,7 @@ enum asn1f_aft_flags_e {
AFT_IMAGINARY_ANY = 0x01, /* Treat ANY tag as [IMAGINARY ANY] */
AFT_FETCH_OUTMOST = 0x02, /* Fetch only outmost tag */
AFT_FULL_COLLECT = 0x04, /* Collect all tags */
AFT_CANON_CHOICE = 0x08, /* Fetch the minimal CHOICE root tag */
};
/*
@ -24,6 +25,6 @@ int asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr,
* 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);
int asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e);
#endif /* _ASN1FIX_TAGS_H_ */

View File

@ -21,8 +21,10 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
ANY_encode_xer,
0,
0, /* Use generic outmost tag fetcher */
0, 0, 0, 0,
0, /* No PER visible constraints */
0, 0, /* No members */
&asn_DEF_ANY_specs,
};

View File

@ -27,6 +27,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
OCTET_STRING_decode_xer_binary,
BIT_STRING_encode_xer,
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BIT_STRING_tags,
sizeof(asn_DEF_BIT_STRING_tags)
@ -34,6 +35,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
asn_DEF_BIT_STRING_tags, /* Same as above */
sizeof(asn_DEF_BIT_STRING_tags)
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
&asn_DEF_BIT_STRING_specs
};
@ -124,9 +126,7 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
er.structure_ptr = 0;
er.failed_type = 0;
return er;
_ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}

View File

@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
OCTET_STRING_encode_der,
BMPString_decode_xer, /* Convert from UTF-8 */
BMPString_encode_xer, /* Convert to UTF-8 */
0,
0, /* Use generic outmost tag fetcher */
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
/ sizeof(asn_DEF_BMPString_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@ -156,7 +158,7 @@ BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = BMPString__dump(st, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
return er;
_ASN_ENCODED_OK(er);
}
int

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@ -22,11 +22,13 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
BOOLEAN_encode_der,
BOOLEAN_decode_xer,
BOOLEAN_encode_xer,
BOOLEAN_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BOOLEAN_tags,
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
asn_DEF_BOOLEAN_tags, /* Same as above */
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@ -126,7 +128,7 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
erval.encoded += 1;
return erval;
_ASN_ENCODED_OK(erval);
}
@ -196,7 +198,7 @@ BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = 8;
}
return er;
_ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
@ -234,3 +236,33 @@ BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
}
}
asn_dec_rval_t
BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_dec_rval_t rv;
BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
(void)opt_codec_ctx;
(void)constraints;
if(!st) {
st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
if(!st) _ASN_DECODE_FAILED;
}
/*
* Extract a single bit
*/
switch(per_get_few_bits(pd, 1)) {
case 1: *st = 1; break;
case 0: *st = 0; break;
case -1: default: _ASN_DECODE_FAILED;
}
ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
rv.code = RC_OK;
rv.consumed = 1;
return rv;
}

View File

@ -26,6 +26,7 @@ ber_type_decoder_f BOOLEAN_decode_ber;
der_type_encoder_f BOOLEAN_encode_der;
xer_type_decoder_f BOOLEAN_decode_xer;
xer_type_encoder_f BOOLEAN_encode_xer;
per_type_decoder_f BOOLEAN_decode_uper;
#ifdef __cplusplus
}

View File

@ -1,9 +1,10 @@
/*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <ENUMERATED.h>
#include <NativeEnumerated.h>
#include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
/*
@ -22,12 +23,33 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
INTEGER_encode_der, /* Implemented in terms of INTEGER */
INTEGER_decode_xer, /* This is temporary! */
INTEGER_encode_xer,
ENUMERATED_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_ENUMERATED_tags,
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
asn_DEF_ENUMERATED_tags, /* Same as above */
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
asn_dec_rval_t
ENUMERATED_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_dec_rval_t rval;
ENUMERATED_t *st = (ENUMERATED_t *)*sptr;
long value, *vptr = &value;
if(!st) {
st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st)));
if(!st) _ASN_DECODE_FAILED;
}
rval = NativeEnumerated_decode_uper(opt_codec_ctx, td, constraints,
(void **)&vptr, pd);
if(rval.code == RC_OK)
if(asn_long2INTEGER(st, value))
rval.code = RC_FAIL;
return rval;
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef _ENUMERATED_H_
@ -15,6 +15,8 @@ typedef INTEGER_t ENUMERATED_t; /* Implemented via INTEGER */
extern asn_TYPE_descriptor_t asn_DEF_ENUMERATED;
per_type_decoder_f ENUMERATED_decode_uper;
#ifdef __cplusplus
}
#endif

View File

@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
0,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
/ sizeof(asn_DEF_GeneralString_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};

View File

@ -128,6 +128,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
GeneralizedTime_encode_der,
OCTET_STRING_decode_xer_utf8,
GeneralizedTime_encode_xer,
0,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
@ -135,6 +136,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
/ sizeof(asn_DEF_GeneralizedTime_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};

View File

@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
0,
0, /* Use generic outmost tag fetcher */
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
/ sizeof(asn_DEF_GraphicString_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};

View File

@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
0,
0, /* Use generic outmost tag fetcher */
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
/ sizeof(asn_DEF_IA5String_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};

View File

@ -24,11 +24,13 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
INTEGER_encode_der,
INTEGER_decode_xer,
INTEGER_encode_xer,
INTEGER_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_INTEGER_tags,
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
asn_DEF_INTEGER_tags, /* Same as above */
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@ -430,9 +432,102 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
er.structure_ptr = 0;
er.failed_type = 0;
return er;
_ASN_ENCODED_OK(er);
}
asn_dec_rval_t
INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_dec_rval_t rval = { RC_OK, 0 };
INTEGER_t *st = (INTEGER_t *)*sptr;
asn_per_constraint_t *ct;
int repeat;
(void)opt_codec_ctx;
if(!st) {
st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
if(!st) _ASN_DECODE_FAILED;
}
if(!constraints) constraints = td->per_constraints;
ct = constraints ? &constraints->value : 0;
if(ct && ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
if(inext < 0) _ASN_DECODE_FAILED;
if(inext) ct = 0;
}
FREEMEM(st->buf);
if(ct) {
if(ct->flags & APC_SEMI_CONSTRAINED) {
st->buf = (uint8_t *)CALLOC(1, 2);
if(!st->buf) _ASN_DECODE_FAILED;
st->size = 1;
} else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
size_t size = (ct->range_bits + 7) >> 3;
st->buf = (uint8_t *)MALLOC(1 + size + 1);
if(!st->buf) _ASN_DECODE_FAILED;
st->size = size;
} else {
st->size = 0;
}
} else {
st->size = 0;
}
/* X.691, #12.2.2 */
if(ct && ct->flags != APC_UNCONSTRAINED) {
/* #10.5.6 */
ASN_DEBUG("Integer with range %d bits", ct->range_bits);
if(ct->range_bits >= 0) {
long value = per_get_few_bits(pd, ct->range_bits);
if(value < 0) _ASN_DECODE_FAILED;
ASN_DEBUG("Got value %ld + low %ld",
value, ct->lower_bound);
value += ct->lower_bound;
if(asn_long2INTEGER(st, value))
_ASN_DECODE_FAILED;
return rval;
}
} else {
ASN_DEBUG("Decoding unconstrained integer %s", td->name);
}
/* X.691, #12.2.3, #12.2.4 */
do {
ssize_t len;
void *p;
int ret;
/* Get the PER length */
len = uper_get_length(pd, -1, &repeat);
if(len < 0) _ASN_DECODE_FAILED;
p = REALLOC(st->buf, st->size + len + 1);
if(!p) _ASN_DECODE_FAILED;
st->buf = (uint8_t *)p;
ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
if(ret < 0) _ASN_DECODE_FAILED;
st->size += len;
} while(repeat);
st->buf[st->size] = 0; /* JIC */
/* #12.2.3 */
if(ct && ct->lower_bound) {
/*
* TODO: replace by in-place arithmetics.
*/
long value;
if(asn_INTEGER2long(st, &value))
_ASN_DECODE_FAILED;
if(asn_long2INTEGER(st, value + ct->lower_bound))
_ASN_DECODE_FAILED;
}
return rval;
}
int

View File

@ -28,7 +28,7 @@ typedef struct asn_INTEGER_specifics_s {
asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
unsigned int *enum2value; /* "tag" => N; sorted by tag */
int map_count; /* Elements in either map */
int extensible; /* This map is extensible */
int extension; /* This map is extensible */
int strict_enumeration; /* Enumeration set is fixed */
} asn_INTEGER_specifics_t;
@ -37,6 +37,7 @@ ber_type_decoder_f INTEGER_decode_ber;
der_type_encoder_f INTEGER_encode_der;
xer_type_decoder_f INTEGER_decode_xer;
xer_type_encoder_f INTEGER_encode_xer;
per_type_decoder_f INTEGER_decode_uper;
/***********************************
* Some handy conversion routines. *

View File

@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
0,
0, /* Use generic outmost tag fetcher */
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
/ sizeof(asn_DEF_ISO646String_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@ -23,11 +23,13 @@ asn_TYPE_descriptor_t asn_DEF_NULL = {
NULL_encode_der, /* Special handling of DER encoding */
NULL_decode_xer,
NULL_encode_xer,
NULL_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_NULL_tags,
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
asn_DEF_NULL_tags, /* Same as above */
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@ -44,7 +46,7 @@ NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
erval.structure_ptr = ptr;
}
return erval;
_ASN_ENCODED_OK(erval);
}
asn_enc_rval_t
@ -62,8 +64,7 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
/* XMLNullValue is empty */
er.encoded = 0;
return er;
_ASN_ENCODED_OK(er);
}
@ -101,3 +102,31 @@ NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
}
}
asn_dec_rval_t
NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_dec_rval_t rv;
(void)opt_codec_ctx;
(void)td;
(void)constraints;
(void)pd;
if(!*sptr) {
*sptr = MALLOC(sizeof(NULL_t));
if(*sptr) {
*(NULL_t *)*sptr = 0;
} else {
_ASN_DECODE_FAILED;
}
}
/*
* NULL type does not have content octets.
*/
rv.code = RC_OK;
rv.consumed = 0;
return rv;
}

View File

@ -23,6 +23,7 @@ asn_struct_print_f NULL_print;
der_type_encoder_f NULL_encode_der;
xer_type_decoder_f NULL_decode_xer;
xer_type_encoder_f NULL_encode_xer;
per_type_decoder_f NULL_decode_uper;
#ifdef __cplusplus
}

View File

@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
NativeInteger_encode_der,
NativeInteger_decode_xer,
NativeEnumerated_encode_xer,
NativeEnumerated_decode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeEnumerated_tags,
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
asn_DEF_NativeEnumerated_tags, /* Same as above */
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@ -59,13 +61,65 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
return er;
_ASN_ENCODED_OK(er);
} else {
ASN_DEBUG("ASN.1 forbids dealing with "
"unknown value of ENUMERATED type");
_ASN_ENCODE_FAILED;
}
return er;
}
asn_dec_rval_t
NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
asn_dec_rval_t rval = { RC_OK, 0 };
long *native = (long *)*sptr;
asn_per_constraint_t *ct;
long value;
(void)opt_codec_ctx;
if(constraints) ct = &constraints->value;
else if(td->per_constraints) ct = &td->per_constraints->value;
else _ASN_DECODE_FAILED; /* Mandatory! */
if(!specs) _ASN_DECODE_FAILED;
if(!native) {
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
if(!native) _ASN_DECODE_FAILED;
}
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
if(ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
if(inext < 0) _ASN_DECODE_FAILED;
if(inext) ct = 0;
}
if(ct && ct->range_bits >= 0) {
value = per_get_few_bits(pd, ct->range_bits);
if(value < 0) _ASN_DECODE_FAILED;
if(value >= (specs->extension
? specs->extension - 1 : specs->map_count))
_ASN_DECODE_FAILED;
} else {
if(!specs->extension)
_ASN_DECODE_FAILED;
/*
* X.691, #10.6: normally small non-negative whole number;
*/
value = uper_get_nsnnwn(pd);
if(value < 0) _ASN_DECODE_FAILED;
value += specs->extension - 1;
if(value >= specs->map_count)
_ASN_DECODE_FAILED;
}
*native = specs->value2enum[value].nat_value;
ASN_DEBUG("Decoded %s = %ld", td->name, *native);
return rval;
}

View File

@ -21,6 +21,7 @@ extern "C" {
extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
xer_type_encoder_f NativeEnumerated_encode_xer;
per_type_decoder_f NativeEnumerated_decode_uper;
#ifdef __cplusplus
}

View File

@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
NativeInteger_encode_der,
NativeInteger_decode_xer,
NativeInteger_encode_xer,
NativeInteger_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeInteger_tags,
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
asn_DEF_NativeInteger_tags, /* Same as above */
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@ -108,18 +110,6 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
}
*native = l;
/*
* Note that native integer size might be other than long.
* This expression hopefully will be optimized away
* by compiler.
*/
if(sizeof(*native) != sizeof(long) && ((long)*native != l)) {
*native = 0; /* Safe value */
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
}
rval.code = RC_OK;
@ -176,38 +166,25 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
const void *buf_ptr, size_t size) {
asn_dec_rval_t rval;
INTEGER_t *st = 0;
INTEGER_t st;
void *st_ptr = (void *)&st;
long *native = (long *)*sptr;
if(!native) {
*sptr = CALLOC(1, sizeof(int));
native = (long *)*sptr;
if(!native) {
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
if(!native) _ASN_DECODE_FAILED;
}
rval = INTEGER_decode_xer(opt_codec_ctx, td, (void **)st_ptr,
memset(&st, 0, sizeof(st));
rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
opt_mname, buf_ptr, size);
if(rval.code == RC_OK) {
long l;
if(asn_INTEGER2long(st, &l)) {
if(asn_INTEGER2long(&st, &l)) {
rval.code = RC_FAIL;
rval.consumed = 0;
} else {
*native = l;
/* Native type might be shorter than long */
if(sizeof(*native) != sizeof(long)
&& ((long)*native != l)) {
*native = 0; /* Safe value */
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
}
} else {
/*
@ -217,7 +194,7 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
*/
rval.consumed = 0;
}
asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0);
asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &st, 1);
return rval;
}