mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Regenerate asn1 code
Regenerate the code with asn1c 0.9.27, this allows us to pick up a few fixes for problems identified by coverity as well as other general bugfixes. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
@@ -15,7 +15,7 @@ static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
|
||||
static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
|
||||
sizeof(BIT_STRING_t),
|
||||
offsetof(BIT_STRING_t, _asn_ctx),
|
||||
1, /* Special indicator that this is a BIT STRING type */
|
||||
ASN_OSUBV_BIT
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
||||
"BIT STRING",
|
||||
@@ -50,14 +50,15 @@ BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
|
||||
if(st && st->buf) {
|
||||
if(st->size == 1 && st->bits_unused) {
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
if((st->size == 0 && st->bits_unused)
|
||||
|| st->bits_unused < 0 || st->bits_unused > 7) {
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: invalid padding byte (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: value not given (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "GKCurrentKeys.h"
|
||||
|
||||
static asn_TYPE_member_t asn_MBR_GKCurrentKeys_1[] = {
|
||||
@@ -24,7 +22,7 @@ static ber_tlv_tag_t asn_DEF_GKCurrentKeys_tags_1[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
|
||||
};
|
||||
static asn_TYPE_tag2member_t asn_MAP_GKCurrentKeys_tag2el_1[] = {
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 } /* serviceIdentity at 19 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 } /* serviceIdentity */
|
||||
};
|
||||
static asn_SEQUENCE_specifics_t asn_SPC_GKCurrentKeys_specs_1 = {
|
||||
sizeof(struct GKCurrentKeys),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -35,3 +35,4 @@ extern asn_TYPE_descriptor_t asn_DEF_GKCurrentKeys;
|
||||
#endif
|
||||
|
||||
#endif /* _GKCurrentKeys_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "GKNewKeys.h"
|
||||
|
||||
static asn_TYPE_member_t asn_MBR_enctypes_3[] = {
|
||||
@@ -66,7 +64,7 @@ static asn_TYPE_member_t asn_MBR_GKNewKeys_1[] = {
|
||||
},
|
||||
{ ATF_NOFLAGS, 0, offsetof(struct GKNewKeys, enctypes),
|
||||
(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
|
||||
+1, /* EXPLICIT tag at current level */
|
||||
0,
|
||||
&asn_DEF_enctypes_3,
|
||||
0, /* Defer constraints checking to the member type */
|
||||
0, /* PER is not compiled, use -gen-PER */
|
||||
@@ -87,9 +85,9 @@ static ber_tlv_tag_t asn_DEF_GKNewKeys_tags_1[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
|
||||
};
|
||||
static asn_TYPE_tag2member_t asn_MAP_GKNewKeys_tag2el_1[] = {
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* serviceIdentity at 13 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* enctypes at 14 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* password at 15 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* serviceIdentity */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* enctypes */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* password */
|
||||
};
|
||||
static asn_SEQUENCE_specifics_t asn_SPC_GKNewKeys_specs_1 = {
|
||||
sizeof(struct GKNewKeys),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -45,3 +45,4 @@ extern asn_TYPE_descriptor_t asn_DEF_GKNewKeys;
|
||||
#endif
|
||||
|
||||
#endif /* _GKNewKeys_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "GKReply.h"
|
||||
|
||||
static asn_TYPE_member_t asn_MBR_keys_3[] = {
|
||||
@@ -77,8 +75,8 @@ static ber_tlv_tag_t asn_DEF_GKReply_tags_1[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
|
||||
};
|
||||
static asn_TYPE_tag2member_t asn_MAP_GKReply_tag2el_1[] = {
|
||||
{ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* newkvno at 23 */
|
||||
{ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 } /* keys at 25 */
|
||||
{ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* newkvno */
|
||||
{ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 } /* keys */
|
||||
};
|
||||
static asn_SEQUENCE_specifics_t asn_SPC_GKReply_specs_1 = {
|
||||
sizeof(struct GKReply),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -49,3 +49,4 @@ extern asn_TYPE_descriptor_t asn_DEF_GKReply;
|
||||
#include "KrbKey.h"
|
||||
|
||||
#endif /* _GKReply_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "GetKeytabControl.h"
|
||||
|
||||
static asn_TYPE_member_t asn_MBR_GetKeytabControl_1[] = {
|
||||
@@ -39,9 +37,9 @@ static asn_TYPE_member_t asn_MBR_GetKeytabControl_1[] = {
|
||||
},
|
||||
};
|
||||
static asn_TYPE_tag2member_t asn_MAP_GetKeytabControl_tag2el_1[] = {
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* newkeys at 7 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* curkeys at 8 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* reply at 10 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* newkeys */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* curkeys */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* reply */
|
||||
};
|
||||
static asn_CHOICE_specifics_t asn_SPC_GetKeytabControl_specs_1 = {
|
||||
sizeof(struct GetKeytabControl),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -50,3 +50,4 @@ extern asn_TYPE_descriptor_t asn_DEF_GetKeytabControl;
|
||||
#endif
|
||||
|
||||
#endif /* _GetKeytabControl_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003-2014 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
@@ -24,8 +24,13 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
|
||||
INTEGER_encode_der,
|
||||
INTEGER_decode_xer,
|
||||
INTEGER_encode_xer,
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
#else
|
||||
INTEGER_decode_uper, /* Unaligned PER decoder */
|
||||
INTEGER_encode_uper, /* Unaligned PER encoder */
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_INTEGER_tags,
|
||||
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
|
||||
@@ -106,47 +111,30 @@ INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_by
|
||||
char scratch[32]; /* Enough for 64-bit integer */
|
||||
uint8_t *buf = st->buf;
|
||||
uint8_t *buf_end = st->buf + st->size;
|
||||
signed long accum;
|
||||
signed long value;
|
||||
ssize_t wrote = 0;
|
||||
char *p;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Advance buf pointer until the start of the value's body.
|
||||
* This will make us able to process large integers using simple case,
|
||||
* when the actual value is small
|
||||
* (0x0000000000abcdef would yield a fine 0x00abcdef)
|
||||
*/
|
||||
/* Skip the insignificant leading bytes */
|
||||
for(; buf < buf_end-1; buf++) {
|
||||
switch(*buf) {
|
||||
case 0x00: if((buf[1] & 0x80) == 0) continue; break;
|
||||
case 0xff: if((buf[1] & 0x80) != 0) continue; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(specs && specs->field_unsigned)
|
||||
ret = asn_INTEGER2ulong(st, (unsigned long *)&value);
|
||||
else
|
||||
ret = asn_INTEGER2long(st, &value);
|
||||
|
||||
/* Simple case: the integer size is small */
|
||||
if((size_t)(buf_end - buf) <= sizeof(accum)) {
|
||||
if(ret == 0) {
|
||||
const asn_INTEGER_enum_map_t *el;
|
||||
size_t scrsize;
|
||||
char *scr;
|
||||
|
||||
if(buf == buf_end) {
|
||||
accum = 0;
|
||||
} else {
|
||||
accum = (*buf & 0x80) ? -1 : 0;
|
||||
for(; buf < buf_end; buf++)
|
||||
accum = (accum << 8) | *buf;
|
||||
}
|
||||
|
||||
el = INTEGER_map_value2enum(specs, accum);
|
||||
el = (value >= 0 || !specs || !specs->field_unsigned)
|
||||
? INTEGER_map_value2enum(specs, value) : 0;
|
||||
if(el) {
|
||||
scrsize = el->enum_len + 32;
|
||||
scr = (char *)alloca(scrsize);
|
||||
if(plainOrXER == 0)
|
||||
ret = snprintf(scr, scrsize,
|
||||
"%ld (%s)", accum, el->enum_name);
|
||||
"%ld (%s)", value, el->enum_name);
|
||||
else
|
||||
ret = snprintf(scr, scrsize,
|
||||
"<%s/>", el->enum_name);
|
||||
@@ -158,7 +146,9 @@ INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_by
|
||||
} else {
|
||||
scrsize = sizeof(scratch);
|
||||
scr = scratch;
|
||||
ret = snprintf(scr, scrsize, "%ld", accum);
|
||||
ret = snprintf(scr, scrsize,
|
||||
(specs && specs->field_unsigned)
|
||||
?"%lu":"%ld", value);
|
||||
}
|
||||
assert(ret > 0 && (size_t)ret < scrsize);
|
||||
return (cb(scr, ret, app_key) < 0) ? -1 : ret;
|
||||
@@ -317,57 +307,71 @@ INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
|
||||
static enum xer_pbd_rval
|
||||
INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
|
||||
INTEGER_t *st = (INTEGER_t *)sptr;
|
||||
long sign = 1;
|
||||
long value;
|
||||
long dec_value;
|
||||
long hex_value = 0;
|
||||
const char *lp;
|
||||
const char *lstart = (const char *)chunk_buf;
|
||||
const char *lstop = lstart + chunk_size;
|
||||
enum {
|
||||
ST_SKIPSPACE,
|
||||
ST_LEADSPACE,
|
||||
ST_SKIPSPHEX,
|
||||
ST_WAITDIGITS,
|
||||
ST_DIGITS,
|
||||
ST_DIGITS_TRAILSPACE,
|
||||
ST_HEXDIGIT1,
|
||||
ST_HEXDIGIT2,
|
||||
ST_HEXDIGITS_TRAILSPACE,
|
||||
ST_HEXCOLON,
|
||||
ST_EXTRASTUFF
|
||||
} state = ST_SKIPSPACE;
|
||||
ST_END_ENUM,
|
||||
ST_UNEXPECTED
|
||||
} state = ST_LEADSPACE;
|
||||
const char *dec_value_start = 0; /* INVARIANT: always !0 in ST_DIGITS */
|
||||
const char *dec_value_end = 0;
|
||||
|
||||
if(chunk_size)
|
||||
ASN_DEBUG("INTEGER body %d 0x%2x..0x%2x",
|
||||
chunk_size, *lstart, lstop[-1]);
|
||||
ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
|
||||
(long)chunk_size, *lstart, lstop[-1]);
|
||||
|
||||
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
|
||||
return XPBD_SYSTEM_FAILURE;
|
||||
|
||||
/*
|
||||
* We may have received a tag here. It will be processed inline.
|
||||
* Use strtoul()-like code and serialize the result.
|
||||
*/
|
||||
for(value = 0, lp = lstart; lp < lstop; lp++) {
|
||||
for(lp = lstart; lp < lstop; lp++) {
|
||||
int lv = *lp;
|
||||
switch(lv) {
|
||||
case 0x09: case 0x0a: case 0x0d: case 0x20:
|
||||
switch(state) {
|
||||
case ST_SKIPSPACE:
|
||||
case ST_LEADSPACE:
|
||||
case ST_DIGITS_TRAILSPACE:
|
||||
case ST_HEXDIGITS_TRAILSPACE:
|
||||
case ST_SKIPSPHEX:
|
||||
continue;
|
||||
case ST_HEXCOLON:
|
||||
if(xer_is_whitespace(lp, lstop - lp)) {
|
||||
lp = lstop - 1;
|
||||
case ST_DIGITS:
|
||||
dec_value_end = lp;
|
||||
state = ST_DIGITS_TRAILSPACE;
|
||||
continue;
|
||||
case ST_HEXCOLON:
|
||||
state = ST_HEXDIGITS_TRAILSPACE;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2d: /* '-' */
|
||||
if(state == ST_SKIPSPACE) {
|
||||
sign = -1;
|
||||
if(state == ST_LEADSPACE) {
|
||||
dec_value = 0;
|
||||
dec_value_start = lp;
|
||||
state = ST_WAITDIGITS;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 0x2b: /* '+' */
|
||||
if(state == ST_SKIPSPACE) {
|
||||
if(state == ST_LEADSPACE) {
|
||||
dec_value = 0;
|
||||
dec_value_start = lp;
|
||||
state = ST_WAITDIGITS;
|
||||
continue;
|
||||
}
|
||||
@@ -375,48 +379,32 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
|
||||
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
|
||||
switch(state) {
|
||||
case ST_DIGITS: break;
|
||||
case ST_DIGITS: continue;
|
||||
case ST_SKIPSPHEX: /* Fall through */
|
||||
case ST_HEXDIGIT1:
|
||||
value = (lv - 0x30) << 4;
|
||||
hex_value = (lv - 0x30) << 4;
|
||||
state = ST_HEXDIGIT2;
|
||||
continue;
|
||||
case ST_HEXDIGIT2:
|
||||
value += (lv - 0x30);
|
||||
hex_value += (lv - 0x30);
|
||||
state = ST_HEXCOLON;
|
||||
st->buf[st->size++] = value;
|
||||
st->buf[st->size++] = (uint8_t)hex_value;
|
||||
continue;
|
||||
case ST_HEXCOLON:
|
||||
return XPBD_BROKEN_ENCODING;
|
||||
default:
|
||||
case ST_LEADSPACE:
|
||||
dec_value = 0;
|
||||
dec_value_start = lp;
|
||||
/* FALL THROUGH */
|
||||
case ST_WAITDIGITS:
|
||||
state = ST_DIGITS;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
long new_value = value * 10;
|
||||
|
||||
if(new_value / 10 != value)
|
||||
/* Overflow */
|
||||
return XPBD_DECODER_LIMIT;
|
||||
|
||||
value = new_value + (lv - 0x30);
|
||||
/* Check for two's complement overflow */
|
||||
if(value < 0) {
|
||||
/* Check whether it is a LONG_MIN */
|
||||
if(sign == -1
|
||||
&& (unsigned long)value
|
||||
== ~((unsigned long)-1 >> 1)) {
|
||||
sign = 1;
|
||||
} else {
|
||||
/* Overflow */
|
||||
return XPBD_DECODER_LIMIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case 0x3c: /* '<' */
|
||||
if(state == ST_SKIPSPACE) {
|
||||
break;
|
||||
case 0x3c: /* '<', start of XML encoded enumeration */
|
||||
if(state == ST_LEADSPACE) {
|
||||
const asn_INTEGER_enum_map_t *el;
|
||||
el = INTEGER_map_enum2value(
|
||||
(asn_INTEGER_specifics_t *)
|
||||
@@ -424,8 +412,8 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||
if(el) {
|
||||
ASN_DEBUG("Found \"%s\" => %ld",
|
||||
el->enum_name, el->nat_value);
|
||||
state = ST_DIGITS;
|
||||
value = el->nat_value;
|
||||
dec_value = el->nat_value;
|
||||
state = ST_END_ENUM;
|
||||
lp = lstop - 1;
|
||||
continue;
|
||||
}
|
||||
@@ -443,13 +431,12 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||
* places as a decimal value.
|
||||
* Switch decoding mode. */
|
||||
ASN_DEBUG("INTEGER re-evaluate as hex form");
|
||||
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
|
||||
return XPBD_SYSTEM_FAILURE;
|
||||
state = ST_SKIPSPHEX;
|
||||
dec_value_start = 0;
|
||||
lp = lstart - 1;
|
||||
continue;
|
||||
} else {
|
||||
ASN_DEBUG("state %d at %d", state, lp - lstart);
|
||||
ASN_DEBUG("state %d at %ld", state, (long)(lp - lstart));
|
||||
break;
|
||||
}
|
||||
/* [A-Fa-f] */
|
||||
@@ -457,24 +444,23 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||
case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
|
||||
switch(state) {
|
||||
case ST_SKIPSPHEX:
|
||||
case ST_SKIPSPACE: /* Fall through */
|
||||
case ST_LEADSPACE: /* Fall through */
|
||||
case ST_HEXDIGIT1:
|
||||
value = lv - ((lv < 0x61) ? 0x41 : 0x61);
|
||||
value += 10;
|
||||
value <<= 4;
|
||||
hex_value = lv - ((lv < 0x61) ? 0x41 : 0x61);
|
||||
hex_value += 10;
|
||||
hex_value <<= 4;
|
||||
state = ST_HEXDIGIT2;
|
||||
continue;
|
||||
case ST_HEXDIGIT2:
|
||||
value += lv - ((lv < 0x61) ? 0x41 : 0x61);
|
||||
value += 10;
|
||||
st->buf[st->size++] = value;
|
||||
hex_value += lv - ((lv < 0x61) ? 0x41 : 0x61);
|
||||
hex_value += 10;
|
||||
st->buf[st->size++] = (uint8_t)hex_value;
|
||||
state = ST_HEXCOLON;
|
||||
continue;
|
||||
case ST_DIGITS:
|
||||
ASN_DEBUG("INTEGER re-evaluate as hex form");
|
||||
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
|
||||
return XPBD_SYSTEM_FAILURE;
|
||||
state = ST_SKIPSPHEX;
|
||||
dec_value_start = 0;
|
||||
lp = lstart - 1;
|
||||
continue;
|
||||
default:
|
||||
@@ -484,39 +470,54 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||
}
|
||||
|
||||
/* Found extra non-numeric stuff */
|
||||
ASN_DEBUG("Found non-numeric 0x%2x at %d",
|
||||
lv, lp - lstart);
|
||||
state = ST_EXTRASTUFF;
|
||||
ASN_DEBUG("INTEGER :: Found non-numeric 0x%2x at %ld",
|
||||
lv, (long)(lp - lstart));
|
||||
state = ST_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
case ST_END_ENUM:
|
||||
/* Got a complete and valid enumeration encoded as a tag. */
|
||||
break;
|
||||
case ST_DIGITS:
|
||||
/* Everything is cool */
|
||||
dec_value_end = lstop;
|
||||
/* FALL THROUGH */
|
||||
case ST_DIGITS_TRAILSPACE:
|
||||
/* The last symbol encountered was a digit. */
|
||||
switch(asn_strtol_lim(dec_value_start, &dec_value_end, &dec_value)) {
|
||||
case ASN_STRTOL_OK:
|
||||
break;
|
||||
case ASN_STRTOL_ERROR_RANGE:
|
||||
return XPBD_DECODER_LIMIT;
|
||||
case ASN_STRTOL_ERROR_INVAL:
|
||||
case ASN_STRTOL_EXPECT_MORE:
|
||||
case ASN_STRTOL_EXTRA_DATA:
|
||||
return XPBD_BROKEN_ENCODING;
|
||||
}
|
||||
break;
|
||||
case ST_HEXCOLON:
|
||||
case ST_HEXDIGITS_TRAILSPACE:
|
||||
st->buf[st->size] = 0; /* Just in case termination */
|
||||
return XPBD_BODY_CONSUMED;
|
||||
case ST_HEXDIGIT1:
|
||||
case ST_HEXDIGIT2:
|
||||
case ST_SKIPSPHEX:
|
||||
return XPBD_BROKEN_ENCODING;
|
||||
default:
|
||||
if(xer_is_whitespace(lp, lstop - lp)) {
|
||||
if(state != ST_EXTRASTUFF)
|
||||
case ST_LEADSPACE:
|
||||
/* Content not found */
|
||||
return XPBD_NOT_BODY_IGNORE;
|
||||
break;
|
||||
} else {
|
||||
ASN_DEBUG("INTEGER: No useful digits (state %d)",
|
||||
state);
|
||||
case ST_WAITDIGITS:
|
||||
case ST_UNEXPECTED:
|
||||
ASN_DEBUG("INTEGER: No useful digits (state %d)", state);
|
||||
return XPBD_BROKEN_ENCODING; /* No digits */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
value *= sign; /* Change sign, if needed */
|
||||
|
||||
if(asn_long2INTEGER(st, value))
|
||||
/*
|
||||
* Convert the result of parsing of enumeration or a straight
|
||||
* decimal value into a BER representation.
|
||||
*/
|
||||
if(asn_long2INTEGER(st, dec_value))
|
||||
return XPBD_SYSTEM_FAILURE;
|
||||
|
||||
return XPBD_BODY_CONSUMED;
|
||||
@@ -551,9 +552,12 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#ifndef ASN_DISABLE_PER_SUPPORT
|
||||
|
||||
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_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
INTEGER_t *st = (INTEGER_t *)*sptr;
|
||||
asn_per_constraint_t *ct;
|
||||
@@ -576,6 +580,8 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
}
|
||||
|
||||
FREEMEM(st->buf);
|
||||
st->buf = 0;
|
||||
st->size = 0;
|
||||
if(ct) {
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
st->buf = (uint8_t *)CALLOC(1, 2);
|
||||
@@ -586,25 +592,38 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
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 */
|
||||
/* X.691-2008/11, #13.2.2, constrained whole number */
|
||||
if(ct && ct->flags != APC_UNCONSTRAINED) {
|
||||
/* #10.5.6 */
|
||||
/* #11.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_STARVED;
|
||||
ASN_DEBUG("Got value %ld + low %ld",
|
||||
value, ct->lower_bound);
|
||||
value += ct->lower_bound;
|
||||
if(asn_long2INTEGER(st, value))
|
||||
if((size_t)ct->range_bits > 8 * sizeof(unsigned long))
|
||||
_ASN_DECODE_FAILED;
|
||||
|
||||
if(specs && specs->field_unsigned) {
|
||||
unsigned long uvalue;
|
||||
if(uper_get_constrained_whole_number(pd,
|
||||
&uvalue, ct->range_bits))
|
||||
_ASN_DECODE_STARVED;
|
||||
ASN_DEBUG("Got value %lu + low %ld",
|
||||
uvalue, ct->lower_bound);
|
||||
uvalue += ct->lower_bound;
|
||||
if(asn_ulong2INTEGER(st, uvalue))
|
||||
_ASN_DECODE_FAILED;
|
||||
} else {
|
||||
unsigned long svalue;
|
||||
if(uper_get_constrained_whole_number(pd,
|
||||
&svalue, ct->range_bits))
|
||||
_ASN_DECODE_STARVED;
|
||||
ASN_DEBUG("Got value %ld + low %ld",
|
||||
svalue, ct->lower_bound);
|
||||
svalue += ct->lower_bound;
|
||||
if(asn_long2INTEGER(st, svalue))
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
} else {
|
||||
@@ -649,6 +668,7 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_enc_rval_t
|
||||
INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er;
|
||||
INTEGER_t *st = (INTEGER_t *)sptr;
|
||||
const uint8_t *buf;
|
||||
@@ -665,6 +685,25 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
|
||||
if(ct) {
|
||||
int inext = 0;
|
||||
if(specs && specs->field_unsigned) {
|
||||
unsigned long uval;
|
||||
if(asn_INTEGER2ulong(st, &uval))
|
||||
_ASN_ENCODE_FAILED;
|
||||
/* Check proper range */
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
if(uval < (unsigned long)ct->lower_bound)
|
||||
inext = 1;
|
||||
} else if(ct->range_bits >= 0) {
|
||||
if(uval < (unsigned long)ct->lower_bound
|
||||
|| uval > (unsigned long)ct->upper_bound)
|
||||
inext = 1;
|
||||
}
|
||||
ASN_DEBUG("Value %lu (%02x/%d) lb %lu ub %lu %s",
|
||||
uval, st->buf[0], st->size,
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
inext ? "ext" : "fix");
|
||||
value = uval;
|
||||
} else {
|
||||
if(asn_INTEGER2long(st, &value))
|
||||
_ASN_ENCODE_FAILED;
|
||||
/* Check proper range */
|
||||
@@ -680,6 +719,7 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
value, st->buf[0], st->size,
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
inext ? "ext" : "fix");
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
@@ -690,13 +730,13 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
}
|
||||
|
||||
|
||||
/* X.691, #12.2.2 */
|
||||
/* X.691-11/2008, #13.2.2, test if constrained whole number */
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
/* #10.5.6 */
|
||||
ASN_DEBUG("Encoding integer with range %d bits",
|
||||
ct->range_bits);
|
||||
if(per_put_few_bits(po, value - ct->lower_bound,
|
||||
ct->range_bits))
|
||||
/* #11.5.6 -> #11.3 */
|
||||
ASN_DEBUG("Encoding integer %ld (%lu) with range %d bits",
|
||||
value, value - ct->lower_bound, ct->range_bits);
|
||||
unsigned long v = value - ct->lower_bound;
|
||||
if(uper_put_constrained_whole_number_u(po, v, ct->range_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
@@ -719,6 +759,8 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
|
||||
int
|
||||
asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
|
||||
uint8_t *b, *end;
|
||||
@@ -779,6 +821,63 @@ asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) {
|
||||
uint8_t *b, *end;
|
||||
unsigned long l;
|
||||
size_t size;
|
||||
|
||||
if(!iptr || !iptr->buf || !lptr) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
b = iptr->buf;
|
||||
size = iptr->size;
|
||||
end = b + size;
|
||||
|
||||
/* If all extra leading bytes are zeroes, ignore them */
|
||||
for(; size > sizeof(unsigned long); b++, size--) {
|
||||
if(*b) {
|
||||
/* Value won't fit unsigned long */
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Conversion engine */
|
||||
for(l = 0; b < end; b++)
|
||||
l = (l << 8) | *b;
|
||||
|
||||
*lptr = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) {
|
||||
uint8_t *buf;
|
||||
uint8_t *end;
|
||||
uint8_t *b;
|
||||
int shr;
|
||||
|
||||
if(value <= LONG_MAX)
|
||||
return asn_long2INTEGER(st, value);
|
||||
|
||||
buf = (uint8_t *)MALLOC(1 + sizeof(value));
|
||||
if(!buf) return -1;
|
||||
|
||||
end = buf + (sizeof(value) + 1);
|
||||
buf[0] = 0;
|
||||
for(b = buf + 1, shr = (sizeof(long)-1)*8; b < end; shr -= 8, b++)
|
||||
*b = (uint8_t)(value >> shr);
|
||||
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->buf = buf;
|
||||
st->size = 1 + sizeof(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asn_long2INTEGER(INTEGER_t *st, long value) {
|
||||
uint8_t *buf, *bp;
|
||||
@@ -833,3 +932,92 @@ asn_long2INTEGER(INTEGER_t *st, long value) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is going to be DEPRECATED soon.
|
||||
*/
|
||||
enum asn_strtol_result_e
|
||||
asn_strtol(const char *str, const char *end, long *lp) {
|
||||
const char *endp = end;
|
||||
|
||||
switch(asn_strtol_lim(str, &endp, lp)) {
|
||||
case ASN_STRTOL_ERROR_RANGE:
|
||||
return ASN_STRTOL_ERROR_RANGE;
|
||||
case ASN_STRTOL_ERROR_INVAL:
|
||||
return ASN_STRTOL_ERROR_INVAL;
|
||||
case ASN_STRTOL_EXPECT_MORE:
|
||||
return ASN_STRTOL_ERROR_INVAL; /* Retain old behavior */
|
||||
case ASN_STRTOL_OK:
|
||||
return ASN_STRTOL_OK;
|
||||
case ASN_STRTOL_EXTRA_DATA:
|
||||
return ASN_STRTOL_ERROR_INVAL; /* Retain old behavior */
|
||||
}
|
||||
|
||||
return ASN_STRTOL_ERROR_INVAL; /* Retain old behavior */
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the number in the given string until the given *end position,
|
||||
* returning the position after the last parsed character back using the
|
||||
* same (*end) pointer.
|
||||
* WARNING: This behavior is different from the standard strtol(3).
|
||||
*/
|
||||
enum asn_strtol_result_e
|
||||
asn_strtol_lim(const char *str, const char **end, long *lp) {
|
||||
int sign = 1;
|
||||
long l;
|
||||
|
||||
const long upper_boundary = LONG_MAX / 10;
|
||||
long last_digit_max = LONG_MAX % 10;
|
||||
|
||||
if(str >= *end) return ASN_STRTOL_ERROR_INVAL;
|
||||
|
||||
switch(*str) {
|
||||
case '-':
|
||||
last_digit_max++;
|
||||
sign = -1;
|
||||
case '+':
|
||||
str++;
|
||||
if(str >= *end) {
|
||||
*end = str;
|
||||
return ASN_STRTOL_EXPECT_MORE;
|
||||
}
|
||||
}
|
||||
|
||||
for(l = 0; str < (*end); str++) {
|
||||
switch(*str) {
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
|
||||
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: {
|
||||
int d = *str - '0';
|
||||
if(l < upper_boundary) {
|
||||
l = l * 10 + d;
|
||||
} else if(l == upper_boundary) {
|
||||
if(d <= last_digit_max) {
|
||||
if(sign > 0) {
|
||||
l = l * 10 + d;
|
||||
} else {
|
||||
sign = 1;
|
||||
l = -l * 10 - d;
|
||||
}
|
||||
} else {
|
||||
*end = str;
|
||||
return ASN_STRTOL_ERROR_RANGE;
|
||||
}
|
||||
} else {
|
||||
*end = str;
|
||||
return ASN_STRTOL_ERROR_RANGE;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
*end = str;
|
||||
*lp = sign * l;
|
||||
return ASN_STRTOL_EXTRA_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
*end = str;
|
||||
*lp = sign * l;
|
||||
return ASN_STRTOL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef struct asn_INTEGER_specifics_s {
|
||||
int map_count; /* Elements in either map */
|
||||
int extension; /* This map is extensible */
|
||||
int strict_enumeration; /* Enumeration set is fixed */
|
||||
int field_width; /* Size of native integer */
|
||||
int field_unsigned; /* Signed=0, unsigned=1 */
|
||||
} asn_INTEGER_specifics_t;
|
||||
|
||||
asn_struct_print_f INTEGER_print;
|
||||
@@ -51,7 +53,22 @@ per_type_encoder_f INTEGER_encode_uper;
|
||||
* -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
|
||||
*/
|
||||
int asn_INTEGER2long(const INTEGER_t *i, long *l);
|
||||
int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l);
|
||||
int asn_long2INTEGER(INTEGER_t *i, long l);
|
||||
int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l);
|
||||
|
||||
/* A a reified version of strtol(3) with nicer error reporting. */
|
||||
enum asn_strtol_result_e {
|
||||
ASN_STRTOL_ERROR_RANGE = -3, /* Input outside of numeric range for long type */
|
||||
ASN_STRTOL_ERROR_INVAL = -2, /* Invalid data encountered (e.g., "+-") */
|
||||
ASN_STRTOL_EXPECT_MORE = -1, /* More data expected (e.g. "+") */
|
||||
ASN_STRTOL_OK = 0, /* Conversion succeded, number ends at (*end) */
|
||||
ASN_STRTOL_EXTRA_DATA = 1, /* Conversion succeded, but the string has extra stuff */
|
||||
};
|
||||
enum asn_strtol_result_e asn_strtol_lim(const char *str, const char **end, long *l);
|
||||
|
||||
/* The asn_strtol is going to be DEPRECATED soon */
|
||||
enum asn_strtol_result_e asn_strtol(const char *str, const char *end, long *l);
|
||||
|
||||
/*
|
||||
* Convert the integer value into the corresponding enumeration map entry.
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "Int32.h"
|
||||
|
||||
int
|
||||
@@ -23,7 +21,7 @@ Int32_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
|
||||
value = *(const long *)sptr;
|
||||
|
||||
if((value >= -2147483648 && value <= 2147483647)) {
|
||||
if((value >= (-2147483647L - 1) && value <= 2147483647)) {
|
||||
/* Constraint check succeeded */
|
||||
return 0;
|
||||
} else {
|
||||
@@ -42,6 +40,7 @@ static void
|
||||
Int32_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
|
||||
td->free_struct = asn_DEF_NativeInteger.free_struct;
|
||||
td->print_struct = asn_DEF_NativeInteger.print_struct;
|
||||
td->check_constraints = asn_DEF_NativeInteger.check_constraints;
|
||||
td->ber_decoder = asn_DEF_NativeInteger.ber_decoder;
|
||||
td->der_encoder = asn_DEF_NativeInteger.der_encoder;
|
||||
td->xer_decoder = asn_DEF_NativeInteger.xer_decoder;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -36,3 +36,4 @@ xer_type_encoder_f Int32_encode_xer;
|
||||
#endif
|
||||
|
||||
#endif /* _Int32_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "KrbKey.h"
|
||||
|
||||
static asn_TYPE_member_t asn_MBR_KrbKey_1[] = {
|
||||
@@ -42,9 +40,9 @@ static ber_tlv_tag_t asn_DEF_KrbKey_tags_1[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
|
||||
};
|
||||
static asn_TYPE_tag2member_t asn_MAP_KrbKey_tag2el_1[] = {
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* key at 28 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* salt at 29 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* s2kparams at 30 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* key */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* salt */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* s2kparams */
|
||||
};
|
||||
static asn_SEQUENCE_specifics_t asn_SPC_KrbKey_specs_1 = {
|
||||
sizeof(struct KrbKey),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -44,3 +44,4 @@ extern asn_TYPE_descriptor_t asn_DEF_KrbKey;
|
||||
#include "TypeValuePair.h"
|
||||
|
||||
#endif /* _KrbKey_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -25,6 +25,7 @@ ASN1C_SOURCES = \
|
||||
per_support.c \
|
||||
per_decoder.c \
|
||||
per_encoder.c \
|
||||
per_opentype.c \
|
||||
$(NULL)
|
||||
|
||||
ASN1C_HEADERS =
|
||||
@@ -56,6 +57,7 @@ ASN1C_HEADERS =
|
||||
per_support.h \
|
||||
per_decoder.h \
|
||||
per_encoder.h \
|
||||
per_opentype.h \
|
||||
$(NULL)
|
||||
|
||||
ASN1Cdir = .
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2004, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
/*
|
||||
@@ -177,9 +177,9 @@ NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
inext = 1;
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 0))
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
ct = 0;
|
||||
if(inext) ct = 0;
|
||||
} else if(inext) {
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
@@ -196,7 +196,10 @@ NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
if(uper_put_nsnnwn(po, value - (specs->extension - 1)))
|
||||
ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
|
||||
value, specs->extension, inext,
|
||||
value - (inext ? (specs->extension - 1) : 0));
|
||||
if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
|
||||
@@ -48,6 +48,7 @@ asn_dec_rval_t
|
||||
NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
asn_TYPE_descriptor_t *td,
|
||||
void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) {
|
||||
asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
long *native = (long *)*nint_ptr;
|
||||
asn_dec_rval_t rval;
|
||||
ber_tlv_len_t length;
|
||||
@@ -105,7 +106,9 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
|
||||
tmp.size = length;
|
||||
|
||||
if(asn_INTEGER2long(&tmp, &l)) {
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
|
||||
: asn_INTEGER2long(&tmp, &l)) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
@@ -145,7 +148,7 @@ NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
|
||||
|
||||
/* Prepare a fake INTEGER */
|
||||
for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
|
||||
*p = native;
|
||||
*p = (uint8_t)native;
|
||||
|
||||
tmp.buf = buf;
|
||||
tmp.size = sizeof(buf);
|
||||
@@ -167,6 +170,7 @@ asn_dec_rval_t
|
||||
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_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval;
|
||||
INTEGER_t st;
|
||||
void *st_ptr = (void *)&st;
|
||||
@@ -182,7 +186,9 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
|
||||
opt_mname, buf_ptr, size);
|
||||
if(rval.code == RC_OK) {
|
||||
long l;
|
||||
if(asn_INTEGER2long(&st, &l)) {
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
|
||||
: asn_INTEGER2long(&st, &l)) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
} else {
|
||||
@@ -205,6 +211,7 @@ asn_enc_rval_t
|
||||
NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
int ilevel, enum xer_encoder_flags_e flags,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
char scratch[32]; /* Enough for 64-bit int */
|
||||
asn_enc_rval_t er;
|
||||
const long *native = (const long *)sptr;
|
||||
@@ -214,7 +221,9 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
|
||||
if(!native) _ASN_ENCODE_FAILED;
|
||||
|
||||
er.encoded = snprintf(scratch, sizeof(scratch), "%ld", *native);
|
||||
er.encoded = snprintf(scratch, sizeof(scratch),
|
||||
(specs && specs->field_unsigned)
|
||||
? "%lu" : "%ld", *native);
|
||||
if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
|
||||
|| cb(scratch, er.encoded, app_key) < 0)
|
||||
_ASN_ENCODE_FAILED;
|
||||
@@ -227,6 +236,7 @@ NativeInteger_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;
|
||||
long *native = (long *)*sptr;
|
||||
INTEGER_t tmpint;
|
||||
@@ -244,7 +254,9 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
||||
rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
|
||||
&tmpintptr, pd);
|
||||
if(rval.code == RC_OK) {
|
||||
if(asn_INTEGER2long(&tmpint, native))
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
|
||||
: asn_INTEGER2long(&tmpint, native))
|
||||
rval.code = RC_FAIL;
|
||||
else
|
||||
ASN_DEBUG("NativeInteger %s got value %ld",
|
||||
@@ -258,6 +270,7 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er;
|
||||
long native;
|
||||
INTEGER_t tmpint;
|
||||
@@ -269,7 +282,9 @@ NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
|
||||
|
||||
memset(&tmpint, 0, sizeof(tmpint));
|
||||
if(asn_long2INTEGER(&tmpint, native))
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_ulong2INTEGER(&tmpint, native)
|
||||
: asn_long2INTEGER(&tmpint, native))
|
||||
_ASN_ENCODE_FAILED;
|
||||
er = INTEGER_encode_uper(td, constraints, &tmpint, po);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
@@ -282,6 +297,7 @@ NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
int
|
||||
NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
||||
const long *native = (const long *)sptr;
|
||||
char scratch[32]; /* Enough for 64-bit int */
|
||||
int ret;
|
||||
@@ -290,7 +306,9 @@ NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(native) {
|
||||
ret = snprintf(scratch, sizeof(scratch), "%ld", *native);
|
||||
ret = snprintf(scratch, sizeof(scratch),
|
||||
(specs && specs->field_unsigned)
|
||||
? "%lu" : "%ld", *native);
|
||||
assert(ret > 0 && (size_t)ret < sizeof(scratch));
|
||||
return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
|
||||
@@ -17,10 +17,12 @@ static ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
|
||||
static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
|
||||
sizeof(OCTET_STRING_t),
|
||||
offsetof(OCTET_STRING_t, _asn_ctx),
|
||||
0
|
||||
ASN_OSUBV_STR
|
||||
};
|
||||
static asn_per_constraint_t asn_DEF_OCTET_STRING_constraint = {
|
||||
APC_SEMI_CONSTRAINED, -1, -1, 0, 0
|
||||
static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
|
||||
{ APC_CONSTRAINED, 8, 8, 0, 255 },
|
||||
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
|
||||
0, 0
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
|
||||
"OCTET STRING", /* Canonical name */
|
||||
@@ -102,15 +104,6 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
|
||||
st->size = _es; \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* Internal variant of the OCTET STRING.
|
||||
*/
|
||||
typedef enum OS_type {
|
||||
_TT_GENERIC = 0, /* Just a random OCTET STRING */
|
||||
_TT_BIT_STRING = 1, /* BIT STRING type, a special case */
|
||||
_TT_ANY = 2 /* ANY type, a special case too */
|
||||
} OS_type_e;
|
||||
|
||||
/*
|
||||
* The main reason why ASN.1 is still alive is that too much time and effort
|
||||
* is necessary for learning it more or less adequately, thus creating a gut
|
||||
@@ -185,11 +178,11 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
struct _stack *stck; /* Expectations stack structure */
|
||||
struct _stack_el *sel = 0; /* Stack element */
|
||||
int tlv_constr;
|
||||
OS_type_e type_variant = (OS_type_e)specs->subvariant;
|
||||
enum asn_OS_Subvariant type_variant = specs->subvariant;
|
||||
|
||||
ASN_DEBUG("Decoding %s as %s (frame %ld)",
|
||||
td->name,
|
||||
(type_variant == _TT_GENERIC) ?
|
||||
(type_variant == ASN_OSUBV_STR) ?
|
||||
"OCTET STRING" : "OS-SpecialCase",
|
||||
(long)size);
|
||||
|
||||
@@ -230,7 +223,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
* Jump into stackless primitive decoding.
|
||||
*/
|
||||
_CH_PHASE(ctx, 3);
|
||||
if(type_variant == _TT_ANY && tag_mode != 1)
|
||||
if(type_variant == ASN_OSUBV_ANY && tag_mode != 1)
|
||||
APPEND(buf_ptr, rval.consumed);
|
||||
ADVANCE(rval.consumed);
|
||||
goto phase3;
|
||||
@@ -309,7 +302,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
|
||||
ASN_DEBUG("Eat EOC; wn=%d--", sel->want_nulls);
|
||||
|
||||
if(type_variant == _TT_ANY
|
||||
if(type_variant == ASN_OSUBV_ANY
|
||||
&& (tag_mode != 1 || sel->cont_level))
|
||||
APPEND("\0\0", 2);
|
||||
|
||||
@@ -334,10 +327,10 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
* depending on ASN.1 type being decoded.
|
||||
*/
|
||||
switch(type_variant) {
|
||||
case _TT_BIT_STRING:
|
||||
case ASN_OSUBV_BIT:
|
||||
/* X.690: 8.6.4.1, NOTE 2 */
|
||||
/* Fall through */
|
||||
case _TT_GENERIC:
|
||||
case ASN_OSUBV_STR:
|
||||
default:
|
||||
if(sel) {
|
||||
int level = sel->cont_level;
|
||||
@@ -352,7 +345,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
/* else, Fall through */
|
||||
}
|
||||
/* Fall through */
|
||||
case _TT_ANY:
|
||||
case ASN_OSUBV_ANY:
|
||||
expected_tag = tlv_tag;
|
||||
break;
|
||||
}
|
||||
@@ -397,7 +390,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
} else {
|
||||
sel->left = tlv_len;
|
||||
}
|
||||
if(type_variant == _TT_ANY
|
||||
if(type_variant == ASN_OSUBV_ANY
|
||||
&& (tag_mode != 1 || sel->cont_level))
|
||||
APPEND(buf_ptr, tlvl);
|
||||
sel->got += tlvl;
|
||||
@@ -431,7 +424,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
len = ((ber_tlv_len_t)size < sel->left)
|
||||
? (ber_tlv_len_t)size : sel->left;
|
||||
if(len > 0) {
|
||||
if(type_variant == _TT_BIT_STRING
|
||||
if(type_variant == ASN_OSUBV_BIT
|
||||
&& sel->bits_chopped == 0) {
|
||||
/* Put the unused-bits-octet away */
|
||||
st->bits_unused = *(const uint8_t *)buf_ptr;
|
||||
@@ -464,7 +457,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
|
||||
if(size < (size_t)ctx->left) {
|
||||
if(!size) RETURN(RC_WMORE);
|
||||
if(type_variant == _TT_BIT_STRING && !ctx->context) {
|
||||
if(type_variant == ASN_OSUBV_BIT && !ctx->context) {
|
||||
st->bits_unused = *(const uint8_t *)buf_ptr;
|
||||
ctx->left--;
|
||||
ADVANCE(1);
|
||||
@@ -475,7 +468,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
ADVANCE(size);
|
||||
RETURN(RC_WMORE);
|
||||
} else {
|
||||
if(type_variant == _TT_BIT_STRING
|
||||
if(type_variant == ASN_OSUBV_BIT
|
||||
&& !ctx->context && ctx->left) {
|
||||
st->bits_unused = *(const uint8_t *)buf_ptr;
|
||||
ctx->left--;
|
||||
@@ -502,14 +495,14 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
/*
|
||||
* BIT STRING-specific processing.
|
||||
*/
|
||||
if(type_variant == _TT_BIT_STRING && st->size) {
|
||||
if(type_variant == ASN_OSUBV_BIT && st->size) {
|
||||
/* Finalize BIT STRING: zero out unused bits. */
|
||||
st->buf[st->size-1] &= 0xff << st->bits_unused;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld",
|
||||
(long)consumed_myself, td->name,
|
||||
(type_variant == _TT_GENERIC) ? (char *)st->buf : "<data>",
|
||||
(type_variant == ASN_OSUBV_STR) ? (char *)st->buf : "<data>",
|
||||
(long)st->size);
|
||||
|
||||
|
||||
@@ -528,7 +521,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
? (asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_DEF_OCTET_STRING_specs;
|
||||
BIT_STRING_t *st = (BIT_STRING_t *)sptr;
|
||||
OS_type_e type_variant = (OS_type_e)specs->subvariant;
|
||||
enum asn_OS_Subvariant type_variant = specs->subvariant;
|
||||
int fix_last_byte = 0;
|
||||
|
||||
ASN_DEBUG("%s %s as OCTET STRING",
|
||||
@@ -537,10 +530,11 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
/*
|
||||
* Write tags.
|
||||
*/
|
||||
if(type_variant != _TT_ANY || tag_mode == 1) {
|
||||
if(type_variant != ASN_OSUBV_ANY || tag_mode == 1) {
|
||||
er.encoded = der_write_tags(td,
|
||||
(type_variant == _TT_BIT_STRING) + st->size,
|
||||
tag_mode, type_variant == _TT_ANY, tag, cb, app_key);
|
||||
(type_variant == ASN_OSUBV_BIT) + st->size,
|
||||
tag_mode, type_variant == ASN_OSUBV_ANY, tag,
|
||||
cb, app_key);
|
||||
if(er.encoded == -1) {
|
||||
er.failed_type = td;
|
||||
er.structure_ptr = sptr;
|
||||
@@ -548,19 +542,19 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
}
|
||||
} else {
|
||||
/* Disallow: [<tag>] IMPLICIT ANY */
|
||||
assert(type_variant != _TT_ANY || tag_mode != -1);
|
||||
assert(type_variant != ASN_OSUBV_ANY || tag_mode != -1);
|
||||
er.encoded = 0;
|
||||
}
|
||||
|
||||
if(!cb) {
|
||||
er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
|
||||
er.encoded += (type_variant == ASN_OSUBV_BIT) + st->size;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare to deal with the last octet of BIT STRING.
|
||||
*/
|
||||
if(type_variant == _TT_BIT_STRING) {
|
||||
if(type_variant == ASN_OSUBV_BIT) {
|
||||
uint8_t b = st->bits_unused & 0x07;
|
||||
if(b && st->size) fix_last_byte = 1;
|
||||
_ASN_CALLBACK(&b, 1);
|
||||
@@ -595,7 +589,7 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
uint8_t *end;
|
||||
size_t i;
|
||||
|
||||
if(!st || !st->buf)
|
||||
if(!st || (!st->buf && st->size))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
er.encoded = 0;
|
||||
@@ -751,7 +745,7 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
(void)ilevel; /* Unused argument */
|
||||
(void)flags; /* Unused argument */
|
||||
|
||||
if(!st || !st->buf)
|
||||
if(!st || (!st->buf && st->size))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
buf = st->buf;
|
||||
@@ -1197,6 +1191,135 @@ OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx,
|
||||
OCTET_STRING__convert_entrefs);
|
||||
}
|
||||
|
||||
static int
|
||||
OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf,
|
||||
size_t units, unsigned int bpc, unsigned int unit_bits,
|
||||
long lb, long ub, asn_per_constraints_t *pc) {
|
||||
uint8_t *end = buf + units * bpc;
|
||||
|
||||
ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
|
||||
(int)units, lb, ub, unit_bits);
|
||||
|
||||
/* X.691: 27.5.4 */
|
||||
if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
|
||||
/* Decode without translation */
|
||||
lb = 0;
|
||||
} else if(pc && pc->code2value) {
|
||||
if(unit_bits > 16)
|
||||
return 1; /* FATAL: can't have constrained
|
||||
* UniversalString with more than
|
||||
* 16 million code points */
|
||||
for(; buf < end; buf += bpc) {
|
||||
int value;
|
||||
int code = per_get_few_bits(po, unit_bits);
|
||||
if(code < 0) return -1; /* WMORE */
|
||||
value = pc->code2value(code);
|
||||
if(value < 0) {
|
||||
ASN_DEBUG("Code %d (0x%02x) is"
|
||||
" not in map (%ld..%ld)",
|
||||
code, code, lb, ub);
|
||||
return 1; /* FATAL */
|
||||
}
|
||||
switch(bpc) {
|
||||
case 1: *buf = value; break;
|
||||
case 2: buf[0] = value >> 8; buf[1] = value; break;
|
||||
case 4: buf[0] = value >> 24; buf[1] = value >> 16;
|
||||
buf[2] = value >> 8; buf[3] = value; break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Shortcut the no-op copying to the aligned structure */
|
||||
if(lb == 0 && (unit_bits == 8 * bpc)) {
|
||||
return per_get_many_bits(po, buf, 0, unit_bits * units);
|
||||
}
|
||||
|
||||
for(; buf < end; buf += bpc) {
|
||||
int code = per_get_few_bits(po, unit_bits);
|
||||
int ch = code + lb;
|
||||
if(code < 0) return -1; /* WMORE */
|
||||
if(ch > ub) {
|
||||
ASN_DEBUG("Code %d is out of range (%ld..%ld)",
|
||||
ch, lb, ub);
|
||||
return 1; /* FATAL */
|
||||
}
|
||||
switch(bpc) {
|
||||
case 1: *buf = ch; break;
|
||||
case 2: buf[0] = ch >> 8; buf[1] = ch; break;
|
||||
case 4: buf[0] = ch >> 24; buf[1] = ch >> 16;
|
||||
buf[2] = ch >> 8; buf[3] = ch; break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf,
|
||||
size_t units, unsigned int bpc, unsigned int unit_bits,
|
||||
long lb, long ub, asn_per_constraints_t *pc) {
|
||||
const uint8_t *end = buf + units * bpc;
|
||||
|
||||
ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)",
|
||||
(int)units, lb, ub, unit_bits, bpc);
|
||||
|
||||
/* X.691: 27.5.4 */
|
||||
if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
|
||||
/* Encode as is */
|
||||
lb = 0;
|
||||
} else if(pc && pc->value2code) {
|
||||
for(; buf < end; buf += bpc) {
|
||||
int code;
|
||||
uint32_t value;
|
||||
switch(bpc) {
|
||||
case 1: value = *(const uint8_t *)buf; break;
|
||||
case 2: value = (buf[0] << 8) | buf[1]; break;
|
||||
case 4: value = (buf[0] << 24) | (buf[1] << 16)
|
||||
| (buf[2] << 8) | buf[3]; break;
|
||||
default: return -1;
|
||||
}
|
||||
code = pc->value2code(value);
|
||||
if(code < 0) {
|
||||
ASN_DEBUG("Character %d (0x%02x) is"
|
||||
" not in map (%ld..%ld)",
|
||||
*buf, *buf, lb, ub);
|
||||
return -1;
|
||||
}
|
||||
if(per_put_few_bits(po, code, unit_bits))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shortcut the no-op copying to the aligned structure */
|
||||
if(lb == 0 && (unit_bits == 8 * bpc)) {
|
||||
return per_put_many_bits(po, buf, unit_bits * units);
|
||||
}
|
||||
|
||||
for(ub -= lb; buf < end; buf += bpc) {
|
||||
int ch;
|
||||
uint32_t value;
|
||||
switch(bpc) {
|
||||
case 1: value = *(const uint8_t *)buf; break;
|
||||
case 2: value = (buf[0] << 8) | buf[1]; break;
|
||||
case 4: value = (buf[0] << 24) | (buf[1] << 16)
|
||||
| (buf[2] << 8) | buf[3]; break;
|
||||
default: return -1;
|
||||
}
|
||||
ch = value - lb;
|
||||
if(ch < 0 || ch > ub) {
|
||||
ASN_DEBUG("Character %d (0x%02x)"
|
||||
" is out of range (%ld..%ld)",
|
||||
*buf, *buf, lb, ub + lb);
|
||||
return -1;
|
||||
}
|
||||
if(per_put_few_bits(po, ch, unit_bits))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
||||
asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
|
||||
@@ -1205,18 +1328,62 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_DEF_OCTET_STRING_specs;
|
||||
asn_per_constraint_t *ct = constraints ? &constraints->size
|
||||
: (td->per_constraints
|
||||
? &td->per_constraints->size
|
||||
: &asn_DEF_OCTET_STRING_constraint);
|
||||
asn_per_constraints_t *pc = constraints ? constraints
|
||||
: td->per_constraints;
|
||||
asn_per_constraint_t *cval;
|
||||
asn_per_constraint_t *csiz;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
|
||||
ssize_t consumed_myself = 0;
|
||||
int repeat;
|
||||
int unit_bits = (specs->subvariant != 1) * 7 + 1;
|
||||
enum {
|
||||
OS__BPC_BIT = 0,
|
||||
OS__BPC_CHAR = 1,
|
||||
OS__BPC_U16 = 2,
|
||||
OS__BPC_U32 = 4
|
||||
} bpc; /* Bytes per character */
|
||||
unsigned int unit_bits;
|
||||
unsigned int canonical_unit_bits;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(pc) {
|
||||
cval = &pc->value;
|
||||
csiz = &pc->size;
|
||||
} else {
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
}
|
||||
|
||||
switch(specs->subvariant) {
|
||||
default:
|
||||
case ASN_OSUBV_ANY:
|
||||
ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
|
||||
RETURN(RC_FAIL);
|
||||
case ASN_OSUBV_BIT:
|
||||
canonical_unit_bits = unit_bits = 1;
|
||||
bpc = OS__BPC_BIT;
|
||||
break;
|
||||
case ASN_OSUBV_STR:
|
||||
canonical_unit_bits = unit_bits = 8;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_CHAR;
|
||||
break;
|
||||
case ASN_OSUBV_U16:
|
||||
canonical_unit_bits = unit_bits = 16;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U16;
|
||||
break;
|
||||
case ASN_OSUBV_U32:
|
||||
canonical_unit_bits = unit_bits = 32;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U32;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the string.
|
||||
*/
|
||||
@@ -1225,24 +1392,26 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
||||
if(!st) RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
ASN_DEBUG("PER Decoding %s %ld .. %ld bits %d",
|
||||
ct->flags & APC_EXTENSIBLE ? "extensible" : "fixed",
|
||||
ct->lower_bound, ct->upper_bound, ct->effective_bits);
|
||||
ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
|
||||
csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
|
||||
csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
|
||||
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(csiz->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) RETURN(RC_WMORE);
|
||||
if(inext) ct = &asn_DEF_OCTET_STRING_constraint;
|
||||
consumed_myself = 0;
|
||||
if(inext) {
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
unit_bits = canonical_unit_bits;
|
||||
}
|
||||
}
|
||||
|
||||
if(ct->effective_bits >= 0
|
||||
&& (!st->buf || st->size < ct->upper_bound)) {
|
||||
if(csiz->effective_bits >= 0) {
|
||||
FREEMEM(st->buf);
|
||||
if(unit_bits == 1) {
|
||||
st->size = (ct->upper_bound + 7) >> 3;
|
||||
if(bpc) {
|
||||
st->size = csiz->upper_bound * bpc;
|
||||
} else {
|
||||
st->size = ct->upper_bound;
|
||||
st->size = (csiz->upper_bound + 7) >> 3;
|
||||
}
|
||||
st->buf = (uint8_t *)MALLOC(st->size + 1);
|
||||
if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
|
||||
@@ -1251,46 +1420,70 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
||||
/* X.691, #16.5: zero-length encoding */
|
||||
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
|
||||
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
|
||||
if(ct->effective_bits == 0) {
|
||||
int ret = per_get_many_bits(pd, st->buf, 0,
|
||||
unit_bits * ct->upper_bound);
|
||||
if(csiz->effective_bits == 0) {
|
||||
int ret;
|
||||
if(bpc) {
|
||||
ASN_DEBUG("Encoding OCTET STRING size %ld",
|
||||
csiz->upper_bound);
|
||||
ret = OCTET_STRING_per_get_characters(pd, st->buf,
|
||||
csiz->upper_bound, bpc, unit_bits,
|
||||
cval->lower_bound, cval->upper_bound, pc);
|
||||
if(ret > 0) RETURN(RC_FAIL);
|
||||
} else {
|
||||
ASN_DEBUG("Encoding BIT STRING size %ld",
|
||||
csiz->upper_bound);
|
||||
ret = per_get_many_bits(pd, st->buf, 0,
|
||||
unit_bits * csiz->upper_bound);
|
||||
}
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
consumed_myself += unit_bits * ct->upper_bound;
|
||||
consumed_myself += unit_bits * csiz->upper_bound;
|
||||
st->buf[st->size] = 0;
|
||||
if(unit_bits == 1 && (ct->upper_bound & 0x7))
|
||||
st->bits_unused = 8 - (ct->upper_bound & 0x7);
|
||||
if(bpc == 0) {
|
||||
int ubs = (csiz->upper_bound & 0x7);
|
||||
st->bits_unused = ubs ? 8 - ubs : 0;
|
||||
}
|
||||
RETURN(RC_OK);
|
||||
}
|
||||
|
||||
st->size = 0;
|
||||
do {
|
||||
ssize_t raw_len;
|
||||
ssize_t len_bytes;
|
||||
ssize_t len_bits;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
len_bits = uper_get_length(pd, ct->effective_bits, &repeat);
|
||||
if(len_bits < 0) RETURN(RC_WMORE);
|
||||
len_bits += ct->lower_bound;
|
||||
raw_len = uper_get_length(pd, csiz->effective_bits, &repeat);
|
||||
if(raw_len < 0) RETURN(RC_WMORE);
|
||||
raw_len += csiz->lower_bound;
|
||||
|
||||
ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
|
||||
(long)ct->effective_bits, (long)len_bits,
|
||||
(long)csiz->effective_bits, (long)raw_len,
|
||||
repeat ? "repeat" : "once", td->name);
|
||||
if(unit_bits == 1) {
|
||||
if(bpc) {
|
||||
len_bytes = raw_len * bpc;
|
||||
len_bits = len_bytes * unit_bits;
|
||||
} else {
|
||||
len_bits = raw_len;
|
||||
len_bytes = (len_bits + 7) >> 3;
|
||||
if(len_bits & 0x7)
|
||||
st->bits_unused = 8 - (len_bits & 0x7);
|
||||
/* len_bits be multiple of 16K if repeat is set */
|
||||
} else {
|
||||
len_bytes = len_bits;
|
||||
len_bits = len_bytes << 3;
|
||||
}
|
||||
p = REALLOC(st->buf, st->size + len_bytes + 1);
|
||||
if(!p) RETURN(RC_FAIL);
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
|
||||
if(bpc) {
|
||||
ret = OCTET_STRING_per_get_characters(pd,
|
||||
&st->buf[st->size], raw_len, bpc, unit_bits,
|
||||
cval->lower_bound, cval->upper_bound, pc);
|
||||
if(ret > 0) RETURN(RC_FAIL);
|
||||
} else {
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size],
|
||||
0, len_bits);
|
||||
}
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
st->size += len_bytes;
|
||||
} while(repeat);
|
||||
@@ -1306,41 +1499,87 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_DEF_OCTET_STRING_specs;
|
||||
asn_per_constraint_t *ct = constraints ? &constraints->size
|
||||
: (td->per_constraints
|
||||
? &td->per_constraints->size
|
||||
: &asn_DEF_OCTET_STRING_constraint);
|
||||
asn_per_constraints_t *pc = constraints ? constraints
|
||||
: td->per_constraints;
|
||||
asn_per_constraint_t *cval;
|
||||
asn_per_constraint_t *csiz;
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
int unit_bits = (specs->subvariant != 1) * 7 + 1;
|
||||
asn_enc_rval_t er;
|
||||
int ct_extensible = ct->flags & APC_EXTENSIBLE;
|
||||
asn_enc_rval_t er = { 0, 0, 0 };
|
||||
int inext = 0; /* Lies not within extension root */
|
||||
int sizeinunits = st->size;
|
||||
unsigned int unit_bits;
|
||||
unsigned int canonical_unit_bits;
|
||||
unsigned int sizeinunits;
|
||||
const uint8_t *buf;
|
||||
int ret;
|
||||
enum {
|
||||
OS__BPC_BIT = 0,
|
||||
OS__BPC_CHAR = 1,
|
||||
OS__BPC_U16 = 2,
|
||||
OS__BPC_U32 = 4
|
||||
} bpc; /* Bytes per character */
|
||||
int ct_extensible;
|
||||
|
||||
if(!st || !st->buf)
|
||||
if(!st || (!st->buf && st->size))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
if(unit_bits == 1) {
|
||||
if(pc) {
|
||||
cval = &pc->value;
|
||||
csiz = &pc->size;
|
||||
} else {
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
}
|
||||
ct_extensible = csiz->flags & APC_EXTENSIBLE;
|
||||
|
||||
switch(specs->subvariant) {
|
||||
default:
|
||||
case ASN_OSUBV_ANY:
|
||||
_ASN_ENCODE_FAILED;
|
||||
case ASN_OSUBV_BIT:
|
||||
canonical_unit_bits = unit_bits = 1;
|
||||
bpc = OS__BPC_BIT;
|
||||
sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
|
||||
ASN_DEBUG("BIT STRING of %d bytes, %d bits unused",
|
||||
sizeinunits, st->bits_unused);
|
||||
sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
|
||||
break;
|
||||
case ASN_OSUBV_STR:
|
||||
canonical_unit_bits = unit_bits = 8;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_CHAR;
|
||||
sizeinunits = st->size;
|
||||
break;
|
||||
case ASN_OSUBV_U16:
|
||||
canonical_unit_bits = unit_bits = 16;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U16;
|
||||
sizeinunits = st->size / 2;
|
||||
break;
|
||||
case ASN_OSUBV_U32:
|
||||
canonical_unit_bits = unit_bits = 32;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U32;
|
||||
sizeinunits = st->size / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %s into %d units of %d bits"
|
||||
" (%d..%d, effective %d)%s",
|
||||
" (%ld..%ld, effective %d)%s",
|
||||
td->name, sizeinunits, unit_bits,
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
ct->effective_bits, ct_extensible ? " EXT" : "");
|
||||
csiz->lower_bound, csiz->upper_bound,
|
||||
csiz->effective_bits, ct_extensible ? " EXT" : "");
|
||||
|
||||
/* Figure out wheter size lies within PER visible consrtaint */
|
||||
/* Figure out whether size lies within PER visible constraint */
|
||||
|
||||
if(ct->effective_bits >= 0) {
|
||||
if(sizeinunits < ct->lower_bound
|
||||
|| sizeinunits > ct->upper_bound) {
|
||||
if(csiz->effective_bits >= 0) {
|
||||
if((int)sizeinunits < csiz->lower_bound
|
||||
|| (int)sizeinunits > csiz->upper_bound) {
|
||||
if(ct_extensible) {
|
||||
ct = &asn_DEF_OCTET_STRING_constraint;
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
unit_bits = canonical_unit_bits;
|
||||
inext = 1;
|
||||
} else
|
||||
_ASN_ENCODE_FAILED;
|
||||
@@ -1358,14 +1597,21 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
/* X.691, #16.5: zero-length encoding */
|
||||
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
|
||||
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
|
||||
if(ct->effective_bits >= 0) {
|
||||
if(csiz->effective_bits >= 0) {
|
||||
ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits",
|
||||
st->size, sizeinunits - ct->lower_bound,
|
||||
ct->effective_bits);
|
||||
ret = per_put_few_bits(po, sizeinunits - ct->lower_bound,
|
||||
ct->effective_bits);
|
||||
st->size, sizeinunits - csiz->lower_bound,
|
||||
csiz->effective_bits);
|
||||
ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound,
|
||||
csiz->effective_bits);
|
||||
if(ret) _ASN_ENCODE_FAILED;
|
||||
ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits);
|
||||
if(bpc) {
|
||||
ret = OCTET_STRING_per_put_characters(po, st->buf,
|
||||
sizeinunits, bpc, unit_bits,
|
||||
cval->lower_bound, cval->upper_bound, pc);
|
||||
} else {
|
||||
ret = per_put_many_bits(po, st->buf,
|
||||
sizeinunits * unit_bits);
|
||||
}
|
||||
if(ret) _ASN_ENCODE_FAILED;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
@@ -1383,15 +1629,22 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
ssize_t maySave = uper_put_length(po, sizeinunits);
|
||||
if(maySave < 0) _ASN_ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
|
||||
ASN_DEBUG("Encoding %ld of %ld",
|
||||
(long)maySave, (long)sizeinunits);
|
||||
|
||||
if(bpc) {
|
||||
ret = OCTET_STRING_per_put_characters(po, buf,
|
||||
maySave, bpc, unit_bits,
|
||||
cval->lower_bound, cval->upper_bound, pc);
|
||||
} else {
|
||||
ret = per_put_many_bits(po, buf, maySave * unit_bits);
|
||||
}
|
||||
if(ret) _ASN_ENCODE_FAILED;
|
||||
|
||||
if(unit_bits == 1)
|
||||
buf += maySave >> 3;
|
||||
if(bpc)
|
||||
buf += maySave * bpc;
|
||||
else
|
||||
buf += maySave;
|
||||
buf += maySave >> 3;
|
||||
sizeinunits -= maySave;
|
||||
assert(!(maySave & 0x07) || !sizeinunits);
|
||||
}
|
||||
@@ -1412,7 +1665,8 @@ OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
|
||||
if(!st || !st->buf) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
if(!st || (!st->buf && st->size))
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
/*
|
||||
* Dump the contents of the buffer in hexadecimal.
|
||||
@@ -1448,7 +1702,7 @@ OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(st && st->buf) {
|
||||
if(st && (st->buf || !st->size)) {
|
||||
return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
@@ -1472,6 +1726,7 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||
|
||||
if(st->buf) {
|
||||
FREEMEM(st->buf);
|
||||
st->buf = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,7 +70,13 @@ typedef struct asn_OCTET_STRING_specifics_s {
|
||||
int struct_size; /* Size of the structure */
|
||||
int ctx_offset; /* Offset of the asn_struct_ctx_t member */
|
||||
|
||||
int subvariant; /* {0,1,2} for O-S, BIT STRING or ANY */
|
||||
enum asn_OS_Subvariant {
|
||||
ASN_OSUBV_ANY, /* The open type (ANY) */
|
||||
ASN_OSUBV_BIT, /* BIT STRING */
|
||||
ASN_OSUBV_STR, /* String types, not {BMP,Universal}String */
|
||||
ASN_OSUBV_U16, /* 16-bit character (BMPString) */
|
||||
ASN_OSUBV_U32 /* 32-bit character (UniversalString) */
|
||||
} subvariant;
|
||||
} asn_OCTET_STRING_specifics_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
*/
|
||||
|
||||
#include <asn_internal.h>
|
||||
|
||||
#include "TypeValuePair.h"
|
||||
|
||||
static asn_TYPE_member_t asn_MBR_TypeValuePair_1[] = {
|
||||
@@ -33,8 +31,8 @@ static ber_tlv_tag_t asn_DEF_TypeValuePair_tags_1[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
|
||||
};
|
||||
static asn_TYPE_tag2member_t asn_MAP_TypeValuePair_tag2el_1[] = {
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* type at 34 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* value at 35 */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* type */
|
||||
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* value */
|
||||
};
|
||||
static asn_SEQUENCE_specifics_t asn_SPC_TypeValuePair_specs_1 = {
|
||||
sizeof(struct TypeValuePair),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
|
||||
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
|
||||
* From ASN.1 module "KeytabModule"
|
||||
* found in "ipa.asn1"
|
||||
* `asn1c -fskeletons-copy`
|
||||
@@ -37,3 +37,4 @@ extern asn_TYPE_descriptor_t asn_DEF_TypeValuePair;
|
||||
#endif
|
||||
|
||||
#endif /* _TypeValuePair_H_ */
|
||||
#include <asn_internal.h>
|
||||
|
||||
@@ -62,7 +62,7 @@ typedef struct asn_enc_rval_s {
|
||||
tmp_error.encoded = -1; \
|
||||
tmp_error.failed_type = td; \
|
||||
tmp_error.structure_ptr = sptr; \
|
||||
ASN_DEBUG("Failed to encode element %s", td->name); \
|
||||
ASN_DEBUG("Failed to encode element %s", td ? td->name : ""); \
|
||||
return tmp_error; \
|
||||
} while(0)
|
||||
#define _ASN_ENCODED_OK(rval) do { \
|
||||
@@ -92,7 +92,7 @@ typedef struct asn_dec_rval_s {
|
||||
asn_dec_rval_t tmp_error; \
|
||||
tmp_error.code = RC_FAIL; \
|
||||
tmp_error.consumed = 0; \
|
||||
ASN_DEBUG("Failed to decode element %s", td->name); \
|
||||
ASN_DEBUG("Failed to decode element %s", td ? td->name : ""); \
|
||||
return tmp_error; \
|
||||
} while(0)
|
||||
#define _ASN_DECODE_STARVED do { \
|
||||
|
||||
@@ -15,7 +15,7 @@ ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
|
||||
void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
|
||||
ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
|
||||
asn_dec_rval_t rval;
|
||||
ber_tlv_len_t length;
|
||||
ber_tlv_len_t length = 0; // =0 to avoid [incorrect] warning.
|
||||
|
||||
/*
|
||||
* If the structure is not there, allocate it.
|
||||
@@ -143,20 +143,26 @@ struct xdp_arg_s {
|
||||
int want_more;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Since some kinds of primitive values can be encoded using value-specific
|
||||
* tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must
|
||||
* be supplied with such tags to parse them as needed.
|
||||
*/
|
||||
static int
|
||||
xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
|
||||
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
|
||||
enum xer_pbd_rval bret;
|
||||
|
||||
if(arg->decoded_something) {
|
||||
if(xer_is_whitespace(chunk_buf, chunk_size))
|
||||
return 0; /* Skip it. */
|
||||
/*
|
||||
* Decoding was done once already. Prohibit doing it again.
|
||||
* The chunk_buf is guaranteed to start at '<'.
|
||||
*/
|
||||
assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);
|
||||
|
||||
/*
|
||||
* Decoding was performed once already. Prohibit doing it again.
|
||||
*/
|
||||
if(arg->decoded_something)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bret = arg->prim_body_decoder(arg->type_descriptor,
|
||||
arg->struct_key, chunk_buf, chunk_size);
|
||||
@@ -177,13 +183,20 @@ xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size)
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
|
||||
xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
|
||||
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
|
||||
enum xer_pbd_rval bret;
|
||||
size_t lead_wsp_size;
|
||||
|
||||
if(arg->decoded_something) {
|
||||
if(xer_is_whitespace(chunk_buf, chunk_size))
|
||||
if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {
|
||||
/*
|
||||
* Example:
|
||||
* "<INTEGER>123<!--/--> </INTEGER>"
|
||||
* ^- chunk_buf position.
|
||||
*/
|
||||
return chunk_size;
|
||||
}
|
||||
/*
|
||||
* Decoding was done once already. Prohibit doing it again.
|
||||
*/
|
||||
@@ -203,6 +216,10 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m
|
||||
return -1;
|
||||
}
|
||||
|
||||
lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);
|
||||
chunk_buf = (const char *)chunk_buf + lead_wsp_size;
|
||||
chunk_size -= lead_wsp_size;
|
||||
|
||||
bret = arg->prim_body_decoder(arg->type_descriptor,
|
||||
arg->struct_key, chunk_buf, chunk_size);
|
||||
switch(bret) {
|
||||
@@ -215,7 +232,7 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m
|
||||
arg->decoded_something = 1;
|
||||
/* Fall through */
|
||||
case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
|
||||
return chunk_size;
|
||||
return lead_wsp_size + chunk_size;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -253,7 +270,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
|
||||
|
||||
rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
|
||||
xml_tag, buf_ptr, size,
|
||||
xer_decode__unexpected_tag, xer_decode__body);
|
||||
xer_decode__unexpected_tag, xer_decode__primitive_body);
|
||||
switch(rc.code) {
|
||||
case RC_OK:
|
||||
if(!s_arg.decoded_something) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003, 2004, 2005, 2007 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Environment version might be used to avoid running with the old library */
|
||||
#define ASN1C_ENVIRONMENT_VERSION 920 /* Compile-time version */
|
||||
#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */
|
||||
int get_asn1c_environment_version(void); /* Run-time version */
|
||||
|
||||
#define CALLOC(nmemb, size) calloc(nmemb, size)
|
||||
@@ -28,6 +28,9 @@ int get_asn1c_environment_version(void); /* Run-time version */
|
||||
#define REALLOC(oldptr, size) realloc(oldptr, size)
|
||||
#define FREEMEM(ptr) free(ptr)
|
||||
|
||||
#define asn_debug_indent 0
|
||||
#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)
|
||||
|
||||
/*
|
||||
* A macro for debugging the ASN.1 internals.
|
||||
* You may enable or override it.
|
||||
@@ -35,7 +38,18 @@ int get_asn1c_environment_version(void); /* Run-time version */
|
||||
#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
|
||||
#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
|
||||
#ifdef __GNUC__
|
||||
#ifdef ASN_THREAD_SAFE
|
||||
/* Thread safety requires sacrifice in output indentation:
|
||||
* Retain empty definition of ASN_DEBUG_INDENT_ADD. */
|
||||
#else /* !ASN_THREAD_SAFE */
|
||||
#undef ASN_DEBUG_INDENT_ADD
|
||||
#undef asn_debug_indent
|
||||
int asn_debug_indent;
|
||||
#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
|
||||
#endif /* ASN_THREAD_SAFE */
|
||||
#define ASN_DEBUG(fmt, args...) do { \
|
||||
int adi = asn_debug_indent; \
|
||||
while(adi--) fprintf(stderr, " "); \
|
||||
fprintf(stderr, fmt, ##args); \
|
||||
fprintf(stderr, " (%s:%d)\n", \
|
||||
__FILE__, __LINE__); \
|
||||
@@ -70,6 +84,7 @@ static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
|
||||
int __nl = ((nl) != 0); \
|
||||
int __i; \
|
||||
if(__nl) _ASN_CALLBACK("\n", 1); \
|
||||
if(__level < 0) __level = 0; \
|
||||
for(__i = 0; __i < __level; __i++) \
|
||||
_ASN_CALLBACK(" ", 4); \
|
||||
er.encoded += __nl + 4 * __level; \
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2004, 2007 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
/*
|
||||
@@ -16,20 +17,27 @@
|
||||
#include <stdlib.h> /* For *alloc(3) */
|
||||
#include <string.h> /* For memcpy(3) */
|
||||
#include <sys/types.h> /* For size_t */
|
||||
#include <limits.h> /* For LONG_MAX */
|
||||
#include <stdarg.h> /* For va_start */
|
||||
#include <stddef.h> /* for offsetof and ptrdiff_t */
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
|
||||
/* To avoid linking with ws2_32.lib, here's the definition of ntohl() */
|
||||
#define sys_ntohl(l) ((((l) << 24) & 0xff000000) \
|
||||
| (((l) << 8) & 0xff0000) \
|
||||
| (((l) >> 8) & 0xff00) \
|
||||
| ((l >> 24) & 0xff))
|
||||
|
||||
#ifdef _MSC_VER /* MSVS.Net */
|
||||
#ifndef __cplusplus
|
||||
#define inline __inline
|
||||
#endif
|
||||
#ifndef ASSUMESTDTYPES /* Standard types have been defined elsewhere */
|
||||
#define ssize_t SSIZE_T
|
||||
typedef char int8_t;
|
||||
typedef short int16_t;
|
||||
@@ -37,6 +45,7 @@ typedef int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#endif /* ASSUMESTDTYPES */
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <float.h>
|
||||
@@ -44,9 +53,11 @@ typedef unsigned int uint32_t;
|
||||
#define finite _finite
|
||||
#define copysign _copysign
|
||||
#define ilogb _logb
|
||||
#else /* !_MSC_VER */
|
||||
#include <stdint.h>
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#else /* !WIN32 */
|
||||
#else /* !_WIN32 */
|
||||
|
||||
#if defined(__vxworks)
|
||||
#include <types/vxTypes.h>
|
||||
@@ -74,19 +85,33 @@ typedef unsigned int uint32_t;
|
||||
#endif /* defined(sun) */
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h> /* for ntohl() */
|
||||
#define sys_ntohl(foo) ntohl(foo)
|
||||
|
||||
#endif /* defined(__vxworks) */
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#ifndef GCC_PRINTFLIKE
|
||||
#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
|
||||
#endif
|
||||
#ifndef GCC_NOTUSED
|
||||
#define GCC_NOTUSED __attribute__((unused))
|
||||
#endif
|
||||
#else
|
||||
#ifndef GCC_PRINTFLIKE
|
||||
#define GCC_PRINTFLIKE(fmt,var) /* nothing */
|
||||
#endif
|
||||
#ifndef GCC_NOTUSED
|
||||
#define GCC_NOTUSED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Figure out if thread safety is requested */
|
||||
#if !defined(ASN_THREAD_SAFE) && (defined(THREAD_SAFE) || defined(_REENTRANT))
|
||||
#define ASN_THREAD_SAFE
|
||||
#endif /* Thread safety */
|
||||
|
||||
#ifndef offsetof /* If not defined by <stddef.h> */
|
||||
#define offsetof(s, m) ((ptrdiff_t)&(((s *)0)->m) - (ptrdiff_t)((s *)0))
|
||||
|
||||
@@ -206,7 +206,7 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
|
||||
*/
|
||||
len_len = ber_fetch_length(tlv_constr,
|
||||
(const char *)ptr + tag_len, size - tag_len, &tlv_len);
|
||||
ASN_DEBUG("Fetchinig len = %ld", (long)len_len);
|
||||
ASN_DEBUG("Fetching len = %ld", (long)len_len);
|
||||
switch(len_len) {
|
||||
case -1: RETURN(RC_FAIL);
|
||||
case 0: RETURN(RC_WMORE);
|
||||
|
||||
@@ -17,6 +17,7 @@ struct asn_codec_ctx_s; /* Forward declaration */
|
||||
/*
|
||||
* The BER decoder of any type.
|
||||
* This function may be invoked directly from the application.
|
||||
* The der_encode() function (der_encoder.h) is an opposite to ber_decode().
|
||||
*/
|
||||
asn_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <constr_CHOICE.h>
|
||||
#include <per_opentype.h>
|
||||
|
||||
/*
|
||||
* Number of bytes left for this structure.
|
||||
@@ -482,7 +483,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int present;
|
||||
|
||||
if(!sptr) {
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: value not given (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
@@ -501,7 +502,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
if(!memb_ptr) {
|
||||
if(elm->optional)
|
||||
return 0;
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: mandatory CHOICE element %s absent (%s:%d)",
|
||||
td->name, elm->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
@@ -524,7 +525,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: no CHOICE element given (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
@@ -534,7 +535,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
#undef XER_ADVANCE
|
||||
#define XER_ADVANCE(num_bytes) do { \
|
||||
size_t num = num_bytes; \
|
||||
buf_ptr = ((const char *)buf_ptr) + num;\
|
||||
buf_ptr = (const void *)(((const char *)buf_ptr) + num); \
|
||||
size -= num; \
|
||||
consumed_myself += num; \
|
||||
} while(0)
|
||||
@@ -871,8 +872,6 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
value += specs->ext_start;
|
||||
if(value >= td->elements_count)
|
||||
_ASN_DECODE_FAILED;
|
||||
ASN_DEBUG("NOT IMPLEMENTED YET");
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Adjust if canonical order is different from natural order */
|
||||
@@ -892,11 +891,17 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
}
|
||||
ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
|
||||
elm->per_constraints, memb_ptr2, pd);
|
||||
} else {
|
||||
rv = uper_open_type_get(opt_codec_ctx, elm->type,
|
||||
elm->per_constraints, memb_ptr2, pd);
|
||||
}
|
||||
|
||||
if(rv.code != RC_OK)
|
||||
ASN_DEBUG("Failed to decode %s in %s (CHOICE)",
|
||||
elm->name, td->name);
|
||||
ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d",
|
||||
elm->name, td->name, rv.code);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -908,6 +913,7 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraint_t *ct;
|
||||
void *memb_ptr;
|
||||
int present;
|
||||
int present_enc;
|
||||
|
||||
if(!sptr) _ASN_ENCODE_FAILED;
|
||||
|
||||
@@ -929,15 +935,17 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
else
|
||||
present--;
|
||||
|
||||
/* Adjust if canonical order is different from natural order */
|
||||
if(specs->canonical_order)
|
||||
present = specs->canonical_order[present];
|
||||
|
||||
ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
|
||||
|
||||
/* Adjust if canonical order is different from natural order */
|
||||
if(specs->canonical_order)
|
||||
present_enc = specs->canonical_order[present];
|
||||
else
|
||||
present_enc = present;
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(present < ct->lower_bound
|
||||
|| present > ct->upper_bound) {
|
||||
if(present_enc < ct->lower_bound
|
||||
|| present_enc > ct->upper_bound) {
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, 1, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
@@ -951,18 +959,6 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
if(per_put_few_bits(po, 0, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, present, ct->range_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
} else {
|
||||
if(specs->ext_start == -1)
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(uper_put_nsnnwn(po, present - specs->ext_start))
|
||||
_ASN_ENCODE_FAILED;
|
||||
ASN_DEBUG("NOT IMPLEMENTED YET");
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
elm = &td->elements[present];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
@@ -972,8 +968,24 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, present_enc, ct->range_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
return elm->type->uper_encoder(elm->type, elm->per_constraints,
|
||||
memb_ptr, po);
|
||||
} else {
|
||||
asn_enc_rval_t rval;
|
||||
if(specs->ext_start == -1)
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(uper_put_nsnnwn(po, present_enc - specs->ext_start))
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(uper_open_type_put(elm->type, elm->per_constraints,
|
||||
memb_ptr, po))
|
||||
_ASN_ENCODE_FAILED;
|
||||
rval.encoded = 0;
|
||||
_ASN_ENCODED_OK(rval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <constr_SEQUENCE.h>
|
||||
#include <per_opentype.h>
|
||||
|
||||
/*
|
||||
* Number of bytes left for this structure.
|
||||
@@ -346,7 +347,8 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
* or an extension (...),
|
||||
* or an end of the indefinite-length structure.
|
||||
*/
|
||||
if(!IN_EXTENSION_GROUP(specs, edx)) {
|
||||
if(!IN_EXTENSION_GROUP(specs,
|
||||
edx + elements[edx].optional)) {
|
||||
ASN_DEBUG("Unexpected tag %s (at %d)",
|
||||
ber_tlv_tag_string(tlv_tag), edx);
|
||||
ASN_DEBUG("Expected tag %s (%s)%s",
|
||||
@@ -358,7 +360,10 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
} else {
|
||||
/* Skip this tag */
|
||||
ssize_t skip;
|
||||
edx += elements[edx].optional;
|
||||
|
||||
ASN_DEBUG("Skipping unexpected %s (at %d)",
|
||||
ber_tlv_tag_string(tlv_tag), edx);
|
||||
skip = ber_skip_length(opt_codec_ctx,
|
||||
BER_TLV_CONSTRUCTED(ptr),
|
||||
(const char *)ptr + tag_len,
|
||||
@@ -662,8 +667,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr2 = (void **)((char *)st
|
||||
+ elm->memb_offset);
|
||||
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)st + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
@@ -976,7 +980,7 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int edx;
|
||||
|
||||
if(!sptr) {
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: value not given (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
@@ -994,7 +998,7 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
if(!memb_ptr) {
|
||||
if(elm->optional)
|
||||
continue;
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: mandatory element %s absent (%s:%d)",
|
||||
td->name, elm->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
@@ -1027,7 +1031,7 @@ SEQUENCE_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_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
|
||||
void *st = *sptr; /* Target structure. */
|
||||
int extpresent = 0; /* Extension additions are present */
|
||||
int extpresent; /* Extension additions are present */
|
||||
uint8_t *opres; /* Presence of optional root members */
|
||||
asn_per_data_t opmd;
|
||||
asn_dec_rval_t rv;
|
||||
@@ -1049,9 +1053,12 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
if(specs->ext_before >= 0) {
|
||||
extpresent = per_get_few_bits(pd, 1);
|
||||
if(extpresent < 0) _ASN_DECODE_STARVED;
|
||||
} else {
|
||||
extpresent = 0;
|
||||
}
|
||||
|
||||
/* Prepare a place and read-in the presence bitmap */
|
||||
memset(&opmd, 0, sizeof(opmd));
|
||||
if(specs->roms_count) {
|
||||
opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
|
||||
if(!opres) _ASN_DECODE_FAILED;
|
||||
@@ -1061,24 +1068,24 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
_ASN_DECODE_STARVED;
|
||||
}
|
||||
opmd.buffer = opres;
|
||||
opmd.nboff = 0;
|
||||
opmd.nbits = specs->roms_count;
|
||||
ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
|
||||
td->name, specs->roms_count, *opres);
|
||||
} else {
|
||||
opres = 0;
|
||||
memset(&opmd, 0, sizeof opmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the sequence ROOT elements.
|
||||
*/
|
||||
for(edx = 0; edx < ((specs->ext_before < 0)
|
||||
? td->elements_count : specs->ext_before + 1); edx++) {
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
|
||||
if(IN_EXTENSION_GROUP(specs, edx))
|
||||
continue;
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
||||
@@ -1101,6 +1108,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
FREEMEM(opres);
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
ASN_DEBUG("Filled-in default");
|
||||
}
|
||||
/* The member is just not present */
|
||||
continue;
|
||||
@@ -1120,18 +1128,94 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
}
|
||||
}
|
||||
|
||||
/* Optionality map is not needed anymore */
|
||||
FREEMEM(opres);
|
||||
|
||||
/*
|
||||
* Deal with extensions.
|
||||
*/
|
||||
if(extpresent) {
|
||||
ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name);
|
||||
_ASN_DECODE_FAILED;
|
||||
} else {
|
||||
for(edx = specs->roms_count; edx < specs->roms_count
|
||||
+ specs->aoms_count; edx++) {
|
||||
ssize_t bmlength;
|
||||
uint8_t *epres; /* Presence of extension members */
|
||||
asn_per_data_t epmd;
|
||||
|
||||
bmlength = uper_get_nslength(pd);
|
||||
if(bmlength < 0) _ASN_DECODE_STARVED;
|
||||
|
||||
ASN_DEBUG("Extensions %ld present in %s", (long)bmlength, td->name);
|
||||
|
||||
epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
|
||||
if(!epres) _ASN_DECODE_STARVED;
|
||||
|
||||
/* Get the extensions map */
|
||||
if(per_get_many_bits(pd, epres, 0, bmlength))
|
||||
_ASN_DECODE_STARVED;
|
||||
|
||||
memset(&epmd, 0, sizeof(epmd));
|
||||
epmd.buffer = epres;
|
||||
epmd.nbits = bmlength;
|
||||
ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
|
||||
td->name, (long)bmlength, *epres);
|
||||
|
||||
/* Go over extensions and read them in */
|
||||
for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
int present;
|
||||
|
||||
if(!IN_EXTENSION_GROUP(specs, edx)) {
|
||||
ASN_DEBUG("%d is not extension", edx);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (void *)((char *)st + elm->memb_offset);
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
|
||||
present = per_get_few_bits(&epmd, 1);
|
||||
if(present <= 0) {
|
||||
if(present < 0) break; /* No more extensions */
|
||||
continue;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
|
||||
rv = uper_open_type_get(opt_codec_ctx, elm->type,
|
||||
elm->per_constraints, memb_ptr2, pd);
|
||||
if(rv.code != RC_OK) {
|
||||
FREEMEM(epres);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip over overflow extensions which aren't present
|
||||
* in this system's version of the protocol */
|
||||
for(;;) {
|
||||
ASN_DEBUG("Getting overflow extensions");
|
||||
switch(per_get_few_bits(&epmd, 1)) {
|
||||
case -1: break;
|
||||
case 0: continue;
|
||||
default:
|
||||
if(uper_open_type_skip(opt_codec_ctx, pd)) {
|
||||
FREEMEM(epres);
|
||||
_ASN_DECODE_STARVED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
FREEMEM(epres);
|
||||
}
|
||||
|
||||
/* Fill DEFAULT members in extensions */
|
||||
for(edx = specs->roms_count; edx < specs->roms_count
|
||||
+ specs->aoms_count; edx++) {
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
void **memb_ptr2; /* Pointer to member pointer */
|
||||
|
||||
if(!elm->default_value) continue;
|
||||
|
||||
@@ -1139,31 +1223,81 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)st
|
||||
+ elm->memb_offset);
|
||||
if(*memb_ptr2) continue;
|
||||
} else {
|
||||
memb_ptr = (char *)st + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
continue; /* Extensions are all optionals */
|
||||
}
|
||||
|
||||
/* Set default value */
|
||||
if(elm->default_value(1, memb_ptr2)) {
|
||||
FREEMEM(opres);
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv.consumed = 0;
|
||||
rv.code = RC_OK;
|
||||
FREEMEM(opres);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
asn_per_outp_t *po1, asn_per_outp_t *po2) {
|
||||
asn_SEQUENCE_specifics_t *specs
|
||||
= (asn_SEQUENCE_specifics_t *)td->specifics;
|
||||
int exts_present = 0;
|
||||
int exts_count = 0;
|
||||
int edx;
|
||||
|
||||
if(specs->ext_before < 0)
|
||||
return 0;
|
||||
|
||||
/* Find out which extensions are present */
|
||||
for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
int present;
|
||||
|
||||
if(!IN_EXTENSION_GROUP(specs, edx)) {
|
||||
ASN_DEBUG("%s (@%d) is not extension", elm->type->name, edx);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
present = (*memb_ptr2 != 0);
|
||||
} else {
|
||||
memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
||||
memb_ptr2 = &memb_ptr;
|
||||
present = 1;
|
||||
}
|
||||
|
||||
ASN_DEBUG("checking %s (@%d) present => %d",
|
||||
elm->type->name, edx, present);
|
||||
exts_count++;
|
||||
exts_present += present;
|
||||
|
||||
/* Encode as presence marker */
|
||||
if(po1 && per_put_few_bits(po1, present, 1))
|
||||
return -1;
|
||||
/* Encode as open type field */
|
||||
if(po2 && present && uper_open_type_put(elm->type,
|
||||
elm->per_constraints, *memb_ptr2, po2))
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return exts_present ? exts_count : 0;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_SEQUENCE_specifics_t *specs
|
||||
= (asn_SEQUENCE_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er;
|
||||
int n_extensions;
|
||||
int edx;
|
||||
int i;
|
||||
|
||||
@@ -1175,8 +1309,18 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
er.encoded = 0;
|
||||
|
||||
ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
|
||||
if(specs->ext_before >= 0)
|
||||
_ASN_ENCODE_FAILED; /* We don't encode extensions yet */
|
||||
|
||||
|
||||
/*
|
||||
* X.691#18.1 Whether structure is extensible
|
||||
* and whether to encode extensions
|
||||
*/
|
||||
if(specs->ext_before >= 0) {
|
||||
n_extensions = SEQUENCE_handle_extensions(td, sptr, 0, 0);
|
||||
per_put_few_bits(po, n_extensions ? 1 : 0, 1);
|
||||
} else {
|
||||
n_extensions = 0; /* There are no extensions to encode */
|
||||
}
|
||||
|
||||
/* Encode a presence bitmap */
|
||||
for(i = 0; i < specs->roms_count; i++) {
|
||||
@@ -1212,14 +1356,21 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the sequence ROOT elements.
|
||||
* Encode the sequence ROOT elements.
|
||||
*/
|
||||
for(edx = 0; edx < ((specs->ext_before < 0)
|
||||
? td->elements_count : specs->ext_before + 1); edx++) {
|
||||
ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before);
|
||||
for(edx = 0; edx < ((specs->ext_after < 0)
|
||||
? td->elements_count : specs->ext_before - 1); edx++) {
|
||||
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
|
||||
if(IN_EXTENSION_GROUP(specs, edx))
|
||||
continue;
|
||||
|
||||
ASN_DEBUG("About to encode %s", elm->type->name);
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
@@ -1240,12 +1391,32 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
|
||||
continue;
|
||||
|
||||
ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
|
||||
er = elm->type->uper_encoder(elm->type, elm->per_constraints,
|
||||
*memb_ptr2, po);
|
||||
if(er.encoded == -1)
|
||||
return er;
|
||||
}
|
||||
|
||||
/* No extensions to encode */
|
||||
if(!n_extensions) _ASN_ENCODED_OK(er);
|
||||
|
||||
ASN_DEBUG("Length of %d bit-map", n_extensions);
|
||||
/* #18.8. Write down the presence bit-map length. */
|
||||
if(uper_put_nslength(po, n_extensions))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Bit-map of %d elements", n_extensions);
|
||||
/* #18.7. Encoding the extensions presence bit-map. */
|
||||
/* TODO: act upon NOTE in #18.7 for canonical PER */
|
||||
if(SEQUENCE_handle_extensions(td, sptr, po, 0) != n_extensions)
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Writing %d extensions", n_extensions);
|
||||
/* #18.9. Encode extensions as open type fields. */
|
||||
if(SEQUENCE_handle_extensions(td, sptr, 0, po) != n_extensions)
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,6 +227,8 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
}
|
||||
/* Fall through */
|
||||
case RC_FAIL: /* Fatal error */
|
||||
ASN_STRUCT_FREE(*elm->type, ctx->ptr);
|
||||
ctx->ptr = 0;
|
||||
RETURN(RC_FAIL);
|
||||
} /* switch(rval) */
|
||||
|
||||
@@ -787,8 +789,10 @@ SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
void
|
||||
SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||
if(td && ptr) {
|
||||
asn_SET_OF_specifics_t *specs;
|
||||
asn_TYPE_member_t *elm = td->elements;
|
||||
asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
|
||||
asn_struct_ctx_t *ctx; /* Decoder context */
|
||||
int i;
|
||||
|
||||
/*
|
||||
@@ -804,6 +808,13 @@ SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||
|
||||
asn_set_empty(list); /* Remove (list->array) */
|
||||
|
||||
specs = (asn_SET_OF_specifics_t *)td->specifics;
|
||||
ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset);
|
||||
if(ctx->ptr) {
|
||||
ASN_STRUCT_FREE(*elm->type, ctx->ptr);
|
||||
ctx->ptr = 0;
|
||||
}
|
||||
|
||||
if(!contents_only) {
|
||||
FREEMEM(ptr);
|
||||
}
|
||||
@@ -819,7 +830,7 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int i;
|
||||
|
||||
if(!sptr) {
|
||||
_ASN_CTFAIL(app_key, td,
|
||||
_ASN_CTFAIL(app_key, td, sptr,
|
||||
"%s: value not given (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
@@ -904,7 +915,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
nelems = uper_get_length(pd,
|
||||
ct ? ct->effective_bits : -1, &repeat);
|
||||
ASN_DEBUG("Got to decode %d elements (eff %d)",
|
||||
(int)nelems, (int)ct ? ct->effective_bits : -1);
|
||||
(int)nelems, (int)(ct ? ct->effective_bits : -1));
|
||||
if(nelems < 0) _ASN_DECODE_STARVED;
|
||||
}
|
||||
|
||||
@@ -921,7 +932,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
ASN_DEBUG("Failed to add element into %s",
|
||||
td->name);
|
||||
/* Fall through */
|
||||
rv.code == RC_FAIL;
|
||||
rv.code = RC_FAIL;
|
||||
} else {
|
||||
ASN_DEBUG("Failed decoding %s of %s (SET OF)",
|
||||
elm->type->name, td->name);
|
||||
|
||||
@@ -15,6 +15,7 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* The DER encoder of any type. May be invoked by the application.
|
||||
* The ber_decode() function (ber_decoder.h) is an opposite of der_encode().
|
||||
*/
|
||||
asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
void *struct_ptr, /* Structure to be encoded */
|
||||
|
||||
@@ -2,6 +2,40 @@
|
||||
#include <asn_internal.h>
|
||||
#include <per_decoder.h>
|
||||
|
||||
/*
|
||||
* Decode a "Production of a complete encoding", X.691#10.1.
|
||||
* The complete encoding contains at least one byte, and is an integral
|
||||
* multiple of 8 bytes.
|
||||
*/
|
||||
asn_dec_rval_t
|
||||
uper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) {
|
||||
asn_dec_rval_t rval;
|
||||
|
||||
rval = uper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0);
|
||||
if(rval.consumed) {
|
||||
/*
|
||||
* We've always given 8-aligned data,
|
||||
* so convert bits to integral bytes.
|
||||
*/
|
||||
rval.consumed += 7;
|
||||
rval.consumed >>= 3;
|
||||
} else if(rval.code == RC_OK) {
|
||||
if(size) {
|
||||
if(((const uint8_t *)buffer)[0] == 0) {
|
||||
rval.consumed = 1; /* 1 byte */
|
||||
} else {
|
||||
ASN_DEBUG("Expecting single zeroed byte");
|
||||
rval.code = RC_FAIL;
|
||||
}
|
||||
} else {
|
||||
/* Must contain at least 8 bits. */
|
||||
rval.code = RC_WMORE;
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
|
||||
asn_codec_ctx_t s_codec_ctx;
|
||||
@@ -30,6 +64,7 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
|
||||
}
|
||||
|
||||
/* Fill in the position indicator */
|
||||
memset(&pd, 0, sizeof(pd));
|
||||
pd.buffer = (const uint8_t *)buffer;
|
||||
pd.nboff = skip_bits;
|
||||
pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
|
||||
@@ -46,6 +81,9 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
|
||||
/* Return the number of consumed bits */
|
||||
rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
|
||||
+ pd.nboff - skip_bits;
|
||||
ASN_DEBUG("PER decoding consumed %ld, counted %ld",
|
||||
(long)rval.consumed, (long)pd.moved);
|
||||
assert(rval.consumed == pd.moved);
|
||||
} else {
|
||||
/* PER codec is not a restartable */
|
||||
rval.consumed = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2005, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _PER_DECODER_H_
|
||||
@@ -14,8 +14,20 @@ extern "C" {
|
||||
|
||||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Unaligned PER decoder of a "complete encoding" as per X.691#10.1.
|
||||
* On success, this call always returns (.consumed >= 1), as per X.691#10.1.3.
|
||||
*/
|
||||
asn_dec_rval_t uper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
||||
void **struct_ptr, /* Pointer to a target structure's pointer */
|
||||
const void *buffer, /* Data to be decoded */
|
||||
size_t size /* Size of data buffer */
|
||||
);
|
||||
|
||||
/*
|
||||
* Unaligned PER decoder of any ASN.1 type. May be invoked by the application.
|
||||
* WARNING: This call returns the number of BITS read from the stream. Beware.
|
||||
*/
|
||||
asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
||||
|
||||
@@ -2,41 +2,11 @@
|
||||
#include <asn_internal.h>
|
||||
#include <per_encoder.h>
|
||||
|
||||
/* Flush partially filled buffer */
|
||||
static int _uper_encode_flush_outp(asn_per_outp_t *po);
|
||||
static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key);
|
||||
|
||||
asn_enc_rval_t
|
||||
uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_per_outp_t po;
|
||||
asn_enc_rval_t er;
|
||||
|
||||
/*
|
||||
* Invoke type-specific encoder.
|
||||
*/
|
||||
if(!td || !td->uper_encoder)
|
||||
_ASN_ENCODE_FAILED; /* PER is not compiled in */
|
||||
|
||||
po.buffer = po.tmpspace;
|
||||
po.nboff = 0;
|
||||
po.nbits = 8 * sizeof(po.tmpspace);
|
||||
po.outper = cb;
|
||||
po.op_key = app_key;
|
||||
po.flushed_bytes = 0;
|
||||
|
||||
er = td->uper_encoder(td, 0, sptr, &po);
|
||||
if(er.encoded != -1) {
|
||||
size_t bits_to_flush;
|
||||
|
||||
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
|
||||
|
||||
/* Set number of bits encoded to a firm value */
|
||||
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
|
||||
|
||||
if(_uper_encode_flush_outp(&po))
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
return er;
|
||||
return uper_encode_internal(td, 0, sptr, cb, app_key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -63,20 +33,71 @@ asn_enc_rval_t
|
||||
uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
|
||||
enc_to_buf_arg key;
|
||||
|
||||
/*
|
||||
* Invoke type-specific encoder.
|
||||
*/
|
||||
if(!td || !td->uper_encoder)
|
||||
_ASN_ENCODE_FAILED; /* PER is not compiled in */
|
||||
|
||||
key.buffer = buffer;
|
||||
key.left = buffer_size;
|
||||
|
||||
ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
|
||||
if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
|
||||
|
||||
return uper_encode(td, sptr, encode_to_buffer_cb, &key);
|
||||
return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
|
||||
}
|
||||
|
||||
typedef struct enc_dyn_arg {
|
||||
void *buffer;
|
||||
size_t length;
|
||||
size_t allocated;
|
||||
} enc_dyn_arg;
|
||||
static int
|
||||
encode_dyn_cb(const void *buffer, size_t size, void *key) {
|
||||
enc_dyn_arg *arg = key;
|
||||
if(arg->length + size >= arg->allocated) {
|
||||
void *p;
|
||||
arg->allocated = arg->allocated ? (arg->allocated << 2) : size;
|
||||
p = REALLOC(arg->buffer, arg->allocated);
|
||||
if(!p) {
|
||||
FREEMEM(arg->buffer);
|
||||
memset(arg, 0, sizeof(*arg));
|
||||
return -1;
|
||||
}
|
||||
arg->buffer = p;
|
||||
}
|
||||
memcpy(((char *)arg->buffer) + arg->length, buffer, size);
|
||||
arg->length += size;
|
||||
return 0;
|
||||
}
|
||||
ssize_t
|
||||
uper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r) {
|
||||
asn_enc_rval_t er;
|
||||
enc_dyn_arg key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
er = uper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
|
||||
switch(er.encoded) {
|
||||
case -1:
|
||||
FREEMEM(key.buffer);
|
||||
return -1;
|
||||
case 0:
|
||||
FREEMEM(key.buffer);
|
||||
key.buffer = MALLOC(1);
|
||||
if(key.buffer) {
|
||||
*(char *)key.buffer = '\0';
|
||||
*buffer_r = key.buffer;
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
*buffer_r = key.buffer;
|
||||
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
|
||||
return ((er.encoded + 7) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Internally useful functions.
|
||||
*/
|
||||
|
||||
/* Flush partially filled buffer */
|
||||
static int
|
||||
_uper_encode_flush_outp(asn_per_outp_t *po) {
|
||||
uint8_t *buf;
|
||||
@@ -93,3 +114,38 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
|
||||
|
||||
return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
|
||||
}
|
||||
|
||||
static asn_enc_rval_t
|
||||
uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_per_outp_t po;
|
||||
asn_enc_rval_t er;
|
||||
|
||||
/*
|
||||
* Invoke type-specific encoder.
|
||||
*/
|
||||
if(!td || !td->uper_encoder)
|
||||
_ASN_ENCODE_FAILED; /* PER is not compiled in */
|
||||
|
||||
po.buffer = po.tmpspace;
|
||||
po.nboff = 0;
|
||||
po.nbits = 8 * sizeof(po.tmpspace);
|
||||
po.outper = cb;
|
||||
po.op_key = app_key;
|
||||
po.flushed_bytes = 0;
|
||||
|
||||
er = td->uper_encoder(td, constraints, sptr, &po);
|
||||
if(er.encoded != -1) {
|
||||
size_t bits_to_flush;
|
||||
|
||||
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
|
||||
|
||||
/* Set number of bits encoded to a firm value */
|
||||
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
|
||||
|
||||
if(_uper_encode_flush_outp(&po))
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
return er;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2006, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _PER_ENCODER_H_
|
||||
@@ -16,6 +16,9 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Unaligned PER encoder of any ASN.1 type. May be invoked by the application.
|
||||
* WARNING: This function returns the number of encoded bits in the .encoded
|
||||
* field of the return value. Use the following formula to convert to bytes:
|
||||
* bytes = ((.encoded + 7) / 8)
|
||||
*/
|
||||
asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
void *struct_ptr, /* Structure to be encoded */
|
||||
@@ -23,7 +26,11 @@ asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
void *app_key /* Arbitrary callback argument */
|
||||
);
|
||||
|
||||
/* A variant of uper_encode() which encodes data into the existing buffer */
|
||||
/*
|
||||
* A variant of uper_encode() which encodes data into the existing buffer
|
||||
* WARNING: This function returns the number of encoded bits in the .encoded
|
||||
* field of the return value.
|
||||
*/
|
||||
asn_enc_rval_t uper_encode_to_buffer(
|
||||
struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
void *struct_ptr, /* Structure to be encoded */
|
||||
@@ -31,6 +38,19 @@ asn_enc_rval_t uper_encode_to_buffer(
|
||||
size_t buffer_size /* Initial buffer size (max) */
|
||||
);
|
||||
|
||||
/*
|
||||
* A variant of uper_encode_to_buffer() which allocates buffer itself.
|
||||
* Returns the number of bytes in the buffer or -1 in case of failure.
|
||||
* WARNING: This function produces a "Production of the complete encoding",
|
||||
* with length of at least one octet. Contrast this to precise bit-packing
|
||||
* encoding of uper_encode() and uper_encode_to_buffer().
|
||||
*/
|
||||
ssize_t uper_encode_to_new_buffer(
|
||||
struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
asn_per_constraints_t *constraints,
|
||||
void *struct_ptr, /* Structure to be encoded */
|
||||
void **buffer_r /* Buffer allocated and returned */
|
||||
);
|
||||
|
||||
/*
|
||||
* Type of the generic PER encoder function.
|
||||
|
||||
378
asn1/asn1c/per_opentype.c
Normal file
378
asn1/asn1c/per_opentype.c
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <per_support.h>
|
||||
#include <constr_TYPE.h>
|
||||
#include <per_opentype.h>
|
||||
|
||||
typedef struct uper_ugot_key {
|
||||
asn_per_data_t oldpd; /* Old per data source */
|
||||
size_t unclaimed;
|
||||
size_t ot_moved; /* Number of bits moved by OT processing */
|
||||
int repeat;
|
||||
} uper_ugot_key;
|
||||
|
||||
static int uper_ugot_refill(asn_per_data_t *pd);
|
||||
static int per_skip_bits(asn_per_data_t *pd, int skip_nbits);
|
||||
static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);
|
||||
|
||||
/*
|
||||
* Encode an "open type field".
|
||||
* #10.1, #10.2
|
||||
*/
|
||||
int
|
||||
uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
void *buf;
|
||||
void *bptr;
|
||||
ssize_t size;
|
||||
size_t toGo;
|
||||
|
||||
ASN_DEBUG("Open type put %s ...", td->name);
|
||||
|
||||
size = uper_encode_to_new_buffer(td, constraints, sptr, &buf);
|
||||
if(size <= 0) return -1;
|
||||
|
||||
for(bptr = buf, toGo = size; toGo;) {
|
||||
ssize_t maySave = uper_put_length(po, toGo);
|
||||
ASN_DEBUG("Prepending length %d to %s and allowing to save %d",
|
||||
(int)size, td->name, (int)maySave);
|
||||
if(maySave < 0) break;
|
||||
if(per_put_many_bits(po, bptr, maySave * 8)) break;
|
||||
bptr = (char *)bptr + maySave;
|
||||
toGo -= maySave;
|
||||
}
|
||||
|
||||
FREEMEM(buf);
|
||||
if(toGo) return -1;
|
||||
|
||||
ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
|
||||
td->name, (long)size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static asn_dec_rval_t
|
||||
uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv;
|
||||
ssize_t chunk_bytes;
|
||||
int repeat;
|
||||
uint8_t *buf = 0;
|
||||
size_t bufLen = 0;
|
||||
size_t bufSize = 0;
|
||||
asn_per_data_t spd;
|
||||
size_t padding;
|
||||
|
||||
_ASN_STACK_OVERFLOW_CHECK(ctx);
|
||||
|
||||
ASN_DEBUG("Getting open type %s...", td->name);
|
||||
|
||||
do {
|
||||
chunk_bytes = uper_get_length(pd, -1, &repeat);
|
||||
if(chunk_bytes < 0) {
|
||||
FREEMEM(buf);
|
||||
_ASN_DECODE_STARVED;
|
||||
}
|
||||
if(bufLen + chunk_bytes > bufSize) {
|
||||
void *ptr;
|
||||
bufSize = chunk_bytes + (bufSize << 2);
|
||||
ptr = REALLOC(buf, bufSize);
|
||||
if(!ptr) {
|
||||
FREEMEM(buf);
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
buf = ptr;
|
||||
}
|
||||
if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
|
||||
FREEMEM(buf);
|
||||
_ASN_DECODE_STARVED;
|
||||
}
|
||||
bufLen += chunk_bytes;
|
||||
} while(repeat);
|
||||
|
||||
ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
|
||||
(long)bufLen);
|
||||
|
||||
memset(&spd, 0, sizeof(spd));
|
||||
spd.buffer = buf;
|
||||
spd.nbits = bufLen << 3;
|
||||
|
||||
ASN_DEBUG_INDENT_ADD(+4);
|
||||
rv = td->uper_decoder(ctx, td, constraints, sptr, &spd);
|
||||
ASN_DEBUG_INDENT_ADD(-4);
|
||||
|
||||
if(rv.code == RC_OK) {
|
||||
/* Check padding validity */
|
||||
padding = spd.nbits - spd.nboff;
|
||||
if ((padding < 8 ||
|
||||
/* X.691#10.1.3 */
|
||||
(spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
|
||||
per_get_few_bits(&spd, padding) == 0) {
|
||||
/* Everything is cool */
|
||||
FREEMEM(buf);
|
||||
return rv;
|
||||
}
|
||||
FREEMEM(buf);
|
||||
if(padding >= 8) {
|
||||
ASN_DEBUG("Too large padding %d in open type", (int)padding);
|
||||
_ASN_DECODE_FAILED;
|
||||
} else {
|
||||
ASN_DEBUG("Non-zero padding");
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
} else {
|
||||
FREEMEM(buf);
|
||||
/* rv.code could be RC_WMORE, nonsense in this context */
|
||||
rv.code = RC_FAIL; /* Noone would give us more */
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static asn_dec_rval_t GCC_NOTUSED
|
||||
uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
uper_ugot_key arg;
|
||||
asn_dec_rval_t rv;
|
||||
ssize_t padding;
|
||||
|
||||
_ASN_STACK_OVERFLOW_CHECK(ctx);
|
||||
|
||||
ASN_DEBUG("Getting open type %s from %s", td->name,
|
||||
per_data_string(pd));
|
||||
arg.oldpd = *pd;
|
||||
arg.unclaimed = 0;
|
||||
arg.ot_moved = 0;
|
||||
arg.repeat = 1;
|
||||
pd->refill = uper_ugot_refill;
|
||||
pd->refill_key = &arg;
|
||||
pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */
|
||||
pd->moved = 0; /* This now counts the open type size in bits */
|
||||
|
||||
ASN_DEBUG_INDENT_ADD(+4);
|
||||
rv = td->uper_decoder(ctx, td, constraints, sptr, pd);
|
||||
ASN_DEBUG_INDENT_ADD(-4);
|
||||
|
||||
#define UPDRESTOREPD do { \
|
||||
/* buffer and nboff are valid, preserve them. */ \
|
||||
pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); \
|
||||
pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); \
|
||||
pd->refill = arg.oldpd.refill; \
|
||||
pd->refill_key = arg.oldpd.refill_key; \
|
||||
} while(0)
|
||||
|
||||
if(rv.code != RC_OK) {
|
||||
UPDRESTOREPD;
|
||||
return rv;
|
||||
}
|
||||
|
||||
ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name,
|
||||
per_data_string(pd),
|
||||
per_data_string(&arg.oldpd),
|
||||
(int)arg.unclaimed, (int)arg.repeat);
|
||||
|
||||
padding = pd->moved % 8;
|
||||
if(padding) {
|
||||
int32_t pvalue;
|
||||
if(padding > 7) {
|
||||
ASN_DEBUG("Too large padding %d in open type",
|
||||
(int)padding);
|
||||
rv.code = RC_FAIL;
|
||||
UPDRESTOREPD;
|
||||
return rv;
|
||||
}
|
||||
padding = 8 - padding;
|
||||
ASN_DEBUG("Getting padding of %d bits", (int)padding);
|
||||
pvalue = per_get_few_bits(pd, padding);
|
||||
switch(pvalue) {
|
||||
case -1:
|
||||
ASN_DEBUG("Padding skip failed");
|
||||
UPDRESTOREPD;
|
||||
_ASN_DECODE_STARVED;
|
||||
case 0: break;
|
||||
default:
|
||||
ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",
|
||||
(int)padding, (int)pvalue);
|
||||
UPDRESTOREPD;
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
if(pd->nboff != pd->nbits) {
|
||||
ASN_DEBUG("Open type %s overhead pd%s old%s", td->name,
|
||||
per_data_string(pd), per_data_string(&arg.oldpd));
|
||||
if(1) {
|
||||
UPDRESTOREPD;
|
||||
_ASN_DECODE_FAILED;
|
||||
} else {
|
||||
arg.unclaimed += pd->nbits - pd->nboff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust pd back so it points to original data */
|
||||
UPDRESTOREPD;
|
||||
|
||||
/* Skip data not consumed by the decoder */
|
||||
if(arg.unclaimed) {
|
||||
ASN_DEBUG("Getting unclaimed %d", (int)arg.unclaimed);
|
||||
switch(per_skip_bits(pd, arg.unclaimed)) {
|
||||
case -1:
|
||||
ASN_DEBUG("Claim of %d failed", (int)arg.unclaimed);
|
||||
_ASN_DECODE_STARVED;
|
||||
case 0:
|
||||
ASN_DEBUG("Got claim of %d", (int)arg.unclaimed);
|
||||
break;
|
||||
default:
|
||||
/* Padding must be blank */
|
||||
ASN_DEBUG("Non-blank unconsumed padding");
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
arg.unclaimed = 0;
|
||||
}
|
||||
|
||||
if(arg.repeat) {
|
||||
ASN_DEBUG("Not consumed the whole thing");
|
||||
rv.code = RC_FAIL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
asn_dec_rval_t
|
||||
uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
|
||||
return uper_open_type_get_simple(ctx, td, constraints, sptr, pd);
|
||||
}
|
||||
|
||||
int
|
||||
uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
|
||||
asn_TYPE_descriptor_t s_td;
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
s_td.name = "<unknown extension>";
|
||||
s_td.uper_decoder = uper_sot_suck;
|
||||
|
||||
rv = uper_open_type_get(ctx, &s_td, 0, 0, pd);
|
||||
if(rv.code != RC_OK)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal functions.
|
||||
*/
|
||||
|
||||
static asn_dec_rval_t
|
||||
uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
(void)ctx;
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)sptr;
|
||||
|
||||
while(per_get_few_bits(pd, 24) >= 0);
|
||||
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = pd->moved;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
uper_ugot_refill(asn_per_data_t *pd) {
|
||||
uper_ugot_key *arg = pd->refill_key;
|
||||
ssize_t next_chunk_bytes, next_chunk_bits;
|
||||
ssize_t avail;
|
||||
|
||||
asn_per_data_t *oldpd = &arg->oldpd;
|
||||
|
||||
ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld",
|
||||
(long)pd->moved, (long)oldpd->moved);
|
||||
|
||||
/* Advance our position to where pd is */
|
||||
oldpd->buffer = pd->buffer;
|
||||
oldpd->nboff = pd->nboff;
|
||||
oldpd->nbits -= pd->moved - arg->ot_moved;
|
||||
oldpd->moved += pd->moved - arg->ot_moved;
|
||||
arg->ot_moved = pd->moved;
|
||||
|
||||
if(arg->unclaimed) {
|
||||
/* Refill the container */
|
||||
if(per_get_few_bits(oldpd, 1))
|
||||
return -1;
|
||||
if(oldpd->nboff == 0) {
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
pd->buffer = oldpd->buffer;
|
||||
pd->nboff = oldpd->nboff - 1;
|
||||
pd->nbits = oldpd->nbits;
|
||||
ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)",
|
||||
(long)pd->moved);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!arg->repeat) {
|
||||
ASN_DEBUG("Want more but refill doesn't have it");
|
||||
return -1;
|
||||
}
|
||||
|
||||
next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
|
||||
ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld",
|
||||
(long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat);
|
||||
if(next_chunk_bytes < 0) return -1;
|
||||
if(next_chunk_bytes == 0) {
|
||||
pd->refill = 0; /* No more refills, naturally */
|
||||
assert(!arg->repeat); /* Implementation guarantee */
|
||||
}
|
||||
next_chunk_bits = next_chunk_bytes << 3;
|
||||
avail = oldpd->nbits - oldpd->nboff;
|
||||
if(avail >= next_chunk_bits) {
|
||||
pd->nbits = oldpd->nboff + next_chunk_bits;
|
||||
arg->unclaimed = 0;
|
||||
ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)",
|
||||
(long)next_chunk_bits, (long)oldpd->moved,
|
||||
(long)oldpd->nboff, (long)oldpd->nbits,
|
||||
(long)(oldpd->nbits - oldpd->nboff));
|
||||
} else {
|
||||
pd->nbits = oldpd->nbits;
|
||||
arg->unclaimed = next_chunk_bits - avail;
|
||||
ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld",
|
||||
(long)avail, (long)next_chunk_bits,
|
||||
(long)arg->unclaimed);
|
||||
}
|
||||
pd->buffer = oldpd->buffer;
|
||||
pd->nboff = oldpd->nboff;
|
||||
ASN_DEBUG("Refilled pd%s old%s",
|
||||
per_data_string(pd), per_data_string(oldpd));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
per_skip_bits(asn_per_data_t *pd, int skip_nbits) {
|
||||
int hasNonZeroBits = 0;
|
||||
while(skip_nbits > 0) {
|
||||
int skip;
|
||||
|
||||
/* per_get_few_bits() is more efficient when nbits <= 24 */
|
||||
if(skip_nbits < 24)
|
||||
skip = skip_nbits;
|
||||
else
|
||||
skip = 24;
|
||||
skip_nbits -= skip;
|
||||
|
||||
switch(per_get_few_bits(pd, skip)) {
|
||||
case -1: return -1; /* Starving */
|
||||
case 0: continue; /* Skipped empty space */
|
||||
default: hasNonZeroBits = 1; continue;
|
||||
}
|
||||
}
|
||||
return hasNonZeroBits;
|
||||
}
|
||||
22
asn1/asn1c/per_opentype.h
Normal file
22
asn1/asn1c/per_opentype.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _PER_OPENTYPE_H_
|
||||
#define _PER_OPENTYPE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);
|
||||
|
||||
int uper_open_type_skip(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd);
|
||||
|
||||
int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PER_OPENTYPE_H_ */
|
||||
@@ -1,25 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2005-2014 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_system.h>
|
||||
#include <asn_internal.h>
|
||||
#include <per_support.h>
|
||||
|
||||
char *
|
||||
per_data_string(asn_per_data_t *pd) {
|
||||
static char buf[2][32];
|
||||
static int n;
|
||||
n = (n+1) % 2;
|
||||
snprintf(buf[n], sizeof(buf),
|
||||
"{m=%ld span %+ld[%d..%d] (%d)}",
|
||||
(long)pd->moved,
|
||||
(((long)pd->buffer) & 0xf),
|
||||
(int)pd->nboff, (int)pd->nbits,
|
||||
(int)(pd->nbits - pd->nboff));
|
||||
return buf[n];
|
||||
}
|
||||
|
||||
void
|
||||
per_get_undo(asn_per_data_t *pd, int nbits) {
|
||||
if((ssize_t)pd->nboff < nbits) {
|
||||
assert((ssize_t)pd->nboff < nbits);
|
||||
} else {
|
||||
pd->nboff -= nbits;
|
||||
pd->moved -= nbits;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract a small number of bits (<= 31) from the specified PER data pointer.
|
||||
*/
|
||||
int32_t
|
||||
per_get_few_bits(asn_per_data_t *pd, int nbits) {
|
||||
size_t off; /* Next after last bit offset */
|
||||
ssize_t nleft; /* Number of bits left in this stream */
|
||||
uint32_t accum;
|
||||
const uint8_t *buf;
|
||||
|
||||
if(nbits < 0 || pd->nboff + nbits > pd->nbits)
|
||||
if(nbits < 0)
|
||||
return -1;
|
||||
|
||||
ASN_DEBUG("[PER get %d bits from %p+%d bits]",
|
||||
nbits, pd->buffer, pd->nboff);
|
||||
nleft = pd->nbits - pd->nboff;
|
||||
if(nbits > nleft) {
|
||||
int32_t tailv, vhead;
|
||||
if(!pd->refill || nbits > 31) return -1;
|
||||
/* Accumulate unused bytes before refill */
|
||||
ASN_DEBUG("Obtain the rest %d bits (want %d)",
|
||||
(int)nleft, (int)nbits);
|
||||
tailv = per_get_few_bits(pd, nleft);
|
||||
if(tailv < 0) return -1;
|
||||
/* Refill (replace pd contents with new data) */
|
||||
if(pd->refill(pd))
|
||||
return -1;
|
||||
nbits -= nleft;
|
||||
vhead = per_get_few_bits(pd, nbits);
|
||||
/* Combine the rest of previous pd with the head of new one */
|
||||
tailv = (tailv << nbits) | vhead; /* Could == -1 */
|
||||
return tailv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize position indicator.
|
||||
@@ -29,7 +71,9 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
|
||||
pd->nbits -= (pd->nboff & ~0x07);
|
||||
pd->nboff &= 0x07;
|
||||
}
|
||||
off = (pd->nboff += nbits);
|
||||
pd->moved += nbits;
|
||||
pd->nboff += nbits;
|
||||
off = pd->nboff;
|
||||
buf = pd->buffer;
|
||||
|
||||
/*
|
||||
@@ -47,15 +91,29 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
|
||||
else if(nbits <= 31) {
|
||||
asn_per_data_t tpd = *pd;
|
||||
/* Here are we with our 31-bits limit plus 1..7 bits offset. */
|
||||
tpd.nboff -= nbits;
|
||||
per_get_undo(&tpd, nbits);
|
||||
/* The number of available bits in the stream allow
|
||||
* for the following operations to take place without
|
||||
* invoking the ->refill() function */
|
||||
accum = per_get_few_bits(&tpd, nbits - 24) << 24;
|
||||
accum |= per_get_few_bits(&tpd, 24);
|
||||
} else {
|
||||
pd->nboff -= nbits; /* Oops, revert back */
|
||||
per_get_undo(pd, nbits);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (accum & (((uint32_t)1 << nbits) - 1));
|
||||
accum &= (((uint32_t)1 << nbits) - 1);
|
||||
|
||||
ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]",
|
||||
(int)nbits, (int)nleft,
|
||||
(int)pd->moved,
|
||||
(((long)pd->buffer) & 0xf),
|
||||
(int)pd->nboff, (int)pd->nbits,
|
||||
pd->buffer[0],
|
||||
(int)(pd->nbits - pd->nboff),
|
||||
(int)accum);
|
||||
|
||||
return accum;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -129,6 +187,30 @@ uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
|
||||
return (16384 * value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the normally small length "n".
|
||||
* This procedure used to decode length of extensions bit-maps
|
||||
* for SET and SEQUENCE types.
|
||||
*/
|
||||
ssize_t
|
||||
uper_get_nslength(asn_per_data_t *pd) {
|
||||
ssize_t length;
|
||||
|
||||
ASN_DEBUG("Getting normally small length");
|
||||
|
||||
if(per_get_few_bits(pd, 1) == 0) {
|
||||
length = per_get_few_bits(pd, 6) + 1;
|
||||
if(length <= 0) return -1;
|
||||
ASN_DEBUG("l=%d", (int)length);
|
||||
return length;
|
||||
} else {
|
||||
int repeat;
|
||||
length = uper_get_length(pd, -1, &repeat);
|
||||
if(length >= 0 && !repeat) return length;
|
||||
return -1; /* Error, or do not support >16K extensions */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the normally small non-negative whole number.
|
||||
* X.691, #10.6
|
||||
@@ -156,8 +238,8 @@ uper_get_nsnnwn(asn_per_data_t *pd) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the normally small non-negative whole number.
|
||||
* X.691, #10.6
|
||||
* X.691-11/2008, #11.6
|
||||
* Encoding of a normally small non-negative whole number
|
||||
*/
|
||||
int
|
||||
uper_put_nsnnwn(asn_per_outp_t *po, int n) {
|
||||
@@ -182,6 +264,58 @@ uper_put_nsnnwn(asn_per_outp_t *po, int n) {
|
||||
}
|
||||
|
||||
|
||||
/* X.691-2008/11, #11.5.6 -> #11.3 */
|
||||
int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *out_value, int nbits) {
|
||||
unsigned long lhalf; /* Lower half of the number*/
|
||||
long half;
|
||||
|
||||
if(nbits <= 31) {
|
||||
half = per_get_few_bits(pd, nbits);
|
||||
if(half < 0) return -1;
|
||||
*out_value = half;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((size_t)nbits > 8 * sizeof(*out_value))
|
||||
return -1; /* RANGE */
|
||||
|
||||
half = per_get_few_bits(pd, 31);
|
||||
if(half < 0) return -1;
|
||||
|
||||
if(uper_get_constrained_whole_number(pd, &lhalf, nbits - 31))
|
||||
return -1;
|
||||
|
||||
*out_value = ((unsigned long)half << (nbits - 31)) | lhalf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* X.691-2008/11, #11.5.6 -> #11.3 */
|
||||
int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits) {
|
||||
/*
|
||||
* Assume signed number can be safely coerced into
|
||||
* unsigned of the same range.
|
||||
* The following testing code will likely be optimized out
|
||||
* by compiler if it is true.
|
||||
*/
|
||||
unsigned long uvalue1 = ULONG_MAX;
|
||||
long svalue = uvalue1;
|
||||
unsigned long uvalue2 = svalue;
|
||||
assert(uvalue1 == uvalue2);
|
||||
return uper_put_constrained_whole_number_u(po, v, nbits);
|
||||
}
|
||||
|
||||
int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits) {
|
||||
if(nbits <= 31) {
|
||||
return per_put_few_bits(po, v, nbits);
|
||||
} else {
|
||||
/* Put higher portion first, followed by lower 31-bit */
|
||||
if(uper_put_constrained_whole_number_u(po, v >> 31, nbits - 31))
|
||||
return -1;
|
||||
return per_put_few_bits(po, v, 31);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a small number of bits (<= 31).
|
||||
*/
|
||||
@@ -193,8 +327,8 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
|
||||
|
||||
if(obits <= 0 || obits >= 32) return obits ? -1 : 0;
|
||||
|
||||
ASN_DEBUG("[PER put %d bits to %p+%d bits]",
|
||||
obits, po->buffer, po->nboff);
|
||||
ASN_DEBUG("[PER put %d bits %x to %p+%d bits]",
|
||||
obits, (int)bits, po->buffer, (int)po->nboff);
|
||||
|
||||
/*
|
||||
* Normalize position indicator.
|
||||
@@ -210,7 +344,9 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
|
||||
*/
|
||||
if(po->nboff + obits > po->nbits) {
|
||||
int complete_bytes = (po->buffer - po->tmpspace);
|
||||
if(po->outper(po->buffer, complete_bytes, po->op_key) < 0)
|
||||
ASN_DEBUG("[PER output %ld complete + %ld]",
|
||||
(long)complete_bytes, (long)po->flushed_bytes);
|
||||
if(po->outper(po->tmpspace, complete_bytes, po->op_key) < 0)
|
||||
return -1;
|
||||
if(po->nboff)
|
||||
po->tmpspace[0] = po->buffer[0];
|
||||
@@ -224,41 +360,47 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
|
||||
*/
|
||||
buf = po->buffer;
|
||||
omsk = ~((1 << (8 - po->nboff)) - 1);
|
||||
off = (po->nboff += obits);
|
||||
off = (po->nboff + obits);
|
||||
|
||||
/* Clear data of debris before meaningful bits */
|
||||
bits &= (((uint32_t)1 << obits) - 1);
|
||||
|
||||
ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, bits, bits,
|
||||
po->nboff - obits, off, buf[0], omsk&0xff, buf[0] & omsk);
|
||||
ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits,
|
||||
(int)bits, (int)bits,
|
||||
(int)po->nboff, (int)off,
|
||||
buf[0], (int)(omsk&0xff),
|
||||
(int)(buf[0] & omsk));
|
||||
|
||||
if(off <= 8) /* Completely within 1 byte */
|
||||
po->nboff = off,
|
||||
bits <<= (8 - off),
|
||||
buf[0] = (buf[0] & omsk) | bits;
|
||||
else if(off <= 16)
|
||||
po->nboff = off,
|
||||
bits <<= (16 - off),
|
||||
buf[0] = (buf[0] & omsk) | (bits >> 8),
|
||||
buf[1] = bits;
|
||||
else if(off <= 24)
|
||||
po->nboff = off,
|
||||
bits <<= (24 - off),
|
||||
buf[0] = (buf[0] & omsk) | (bits >> 16),
|
||||
buf[1] = bits >> 8,
|
||||
buf[2] = bits;
|
||||
else if(off <= 31)
|
||||
po->nboff = off,
|
||||
bits <<= (32 - off),
|
||||
buf[0] = (buf[0] & omsk) | (bits >> 24),
|
||||
buf[1] = bits >> 16,
|
||||
buf[2] = bits >> 8,
|
||||
buf[3] = bits;
|
||||
else {
|
||||
ASN_DEBUG("->[PER out split %d]", obits);
|
||||
per_put_few_bits(po, bits >> 8, 24);
|
||||
per_put_few_bits(po, bits >> (obits - 24), 24);
|
||||
per_put_few_bits(po, bits, obits - 24);
|
||||
ASN_DEBUG("<-[PER out split %d]", obits);
|
||||
}
|
||||
|
||||
ASN_DEBUG("[PER out %u/%x => %02x buf+%d]",
|
||||
bits, bits, buf[0], po->buffer - po->tmpspace);
|
||||
ASN_DEBUG("[PER out %u/%x => %02x buf+%ld]",
|
||||
(int)bits, (int)bits, buf[0],
|
||||
(long)(po->buffer - po->tmpspace));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -316,3 +458,26 @@ uper_put_length(asn_per_outp_t *po, size_t length) {
|
||||
? -1 : (ssize_t)(length << 14);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Put the normally small length "n" into the stream.
|
||||
* This procedure used to encode length of extensions bit-maps
|
||||
* for SET and SEQUENCE types.
|
||||
*/
|
||||
int
|
||||
uper_put_nslength(asn_per_outp_t *po, size_t length) {
|
||||
|
||||
if(length <= 64) {
|
||||
/* #10.9.3.4 */
|
||||
if(length == 0) return -1;
|
||||
return per_put_few_bits(po, length-1, 7) ? -1 : 0;
|
||||
} else {
|
||||
if(uper_put_length(po, length) != (ssize_t)length) {
|
||||
/* This might happen in case of >16K extensions */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2005-2014 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _PER_SUPPORT_H_
|
||||
@@ -29,6 +30,8 @@ typedef struct asn_per_constraint_s {
|
||||
typedef struct asn_per_constraints_s {
|
||||
asn_per_constraint_t value;
|
||||
asn_per_constraint_t size;
|
||||
int (*value2code)(unsigned int value);
|
||||
int (*code2value)(unsigned int code);
|
||||
} asn_per_constraints_t;
|
||||
|
||||
/*
|
||||
@@ -38,6 +41,9 @@ typedef struct asn_per_data_s {
|
||||
const uint8_t *buffer; /* Pointer to the octet stream */
|
||||
size_t nboff; /* Bit offset to the meaningful bit */
|
||||
size_t nbits; /* Number of bits in the stream */
|
||||
size_t moved; /* Number of bits moved through this bit stream */
|
||||
int (*refill)(struct asn_per_data_s *);
|
||||
void *refill_key;
|
||||
} asn_per_data_t;
|
||||
|
||||
/*
|
||||
@@ -47,6 +53,9 @@ typedef struct asn_per_data_s {
|
||||
*/
|
||||
int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
|
||||
|
||||
/* Undo the immediately preceeding "get_few_bits" operation */
|
||||
void per_get_undo(asn_per_data_t *per_data, int get_nbits);
|
||||
|
||||
/*
|
||||
* Extract a large number of bits from the specified PER data pointer.
|
||||
* This function returns -1 if the specified number of bits could not be
|
||||
@@ -62,11 +71,22 @@ ssize_t uper_get_length(asn_per_data_t *pd,
|
||||
int effective_bound_bits,
|
||||
int *repeat);
|
||||
|
||||
/*
|
||||
* Get the normally small length "n".
|
||||
*/
|
||||
ssize_t uper_get_nslength(asn_per_data_t *pd);
|
||||
|
||||
/*
|
||||
* Get the normally small non-negative whole number.
|
||||
*/
|
||||
ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
|
||||
|
||||
/* X.691-2008/11, #11.5.6 */
|
||||
int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *v, int nbits);
|
||||
|
||||
/* Non-thread-safe debugging function, don't use it */
|
||||
char *per_data_string(asn_per_data_t *pd);
|
||||
|
||||
/*
|
||||
* This structure supports forming PER output.
|
||||
*/
|
||||
@@ -86,6 +106,10 @@ int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits);
|
||||
/* Output a large number of bits */
|
||||
int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
|
||||
|
||||
/* X.691-2008/11, #11.5 */
|
||||
int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits);
|
||||
int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits);
|
||||
|
||||
/*
|
||||
* Put the length "n" to the Unaligned PER stream.
|
||||
* This function returns the number of units which may be flushed
|
||||
@@ -93,6 +117,12 @@ int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
|
||||
*/
|
||||
ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
|
||||
|
||||
/*
|
||||
* Put the normally small length "n" to the Unaligned PER stream.
|
||||
* Returns 0 or -1.
|
||||
*/
|
||||
int uper_put_nslength(asn_per_outp_t *po, size_t length);
|
||||
|
||||
/*
|
||||
* Put the normally small non-negative whole number.
|
||||
*/
|
||||
|
||||
@@ -109,7 +109,8 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
|
||||
|
||||
if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
|
||||
if(size >= 2)
|
||||
ASN_DEBUG("Broken XML tag: \"%c...%c\"", buf[0], buf[size - 1]);
|
||||
ASN_DEBUG("Broken XML tag: \"%c...%c\"",
|
||||
buf[0], buf[size - 1]);
|
||||
return XCT_BROKEN;
|
||||
}
|
||||
|
||||
@@ -315,8 +316,8 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
xer_is_whitespace(const void *chunk_buf, size_t chunk_size) {
|
||||
size_t
|
||||
xer_whitespace_span(const void *chunk_buf, size_t chunk_size) {
|
||||
const char *p = (const char *)chunk_buf;
|
||||
const char *pend = p + chunk_size;
|
||||
|
||||
@@ -329,12 +330,13 @@ xer_is_whitespace(const void *chunk_buf, size_t chunk_size) {
|
||||
* SPACE (32)
|
||||
*/
|
||||
case 0x09: case 0x0a: case 0x0d: case 0x20:
|
||||
break;
|
||||
continue;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1; /* All whitespace */
|
||||
return (p - (const char *)chunk_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -87,12 +87,11 @@ xer_check_tag_e xer_check_tag(const void *buf_ptr, int size,
|
||||
const char *need_tag);
|
||||
|
||||
/*
|
||||
* Check whether this buffer consists of entirely XER whitespace characters.
|
||||
* Get the number of bytes consisting entirely of XER whitespace characters.
|
||||
* RETURN VALUES:
|
||||
* 1: Whitespace or empty string
|
||||
* 0: Non-whitespace
|
||||
* >=0: Number of whitespace characters in the string.
|
||||
*/
|
||||
int xer_is_whitespace(const void *chunk_buf, size_t chunk_size);
|
||||
size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size);
|
||||
|
||||
/*
|
||||
* Skip the series of anticipated extensions.
|
||||
|
||||
Reference in New Issue
Block a user