mirror of https://gerrit.osmocom.org/asn1c
BIT STRING now stores the number of unused octets in a separate field.
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@498 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
parent
267b7fdcf0
commit
0f1ab76b7f
|
@ -15,6 +15,7 @@
|
|||
* Fixed CHOICE code spin when indefinite length structures appear
|
||||
in the extensions (Severity: medium, Security impact: medium).
|
||||
Reported by <siden@ul-gsm.ru>.
|
||||
* BIT STRING now stores the number of unused octets in a separate field.
|
||||
|
||||
0.9.6: 2004-Sep-29
|
||||
|
||||
|
|
|
@ -105,18 +105,19 @@ check(int is_ok, uint8_t *buf, int size, size_t consumed) {
|
|||
assert(strcmp(t.e->buf, "xyz") == 0);
|
||||
assert(strcmp(t.f->buf, "love_it") == 0);
|
||||
|
||||
assert(t.g->size == 3);
|
||||
assert(t.g->buf[0] == 2);
|
||||
assert(t.g->buf[1] == 147);
|
||||
assert(t.g->buf[2] != 150);
|
||||
assert(t.g->buf[2] == 148);
|
||||
assert(t.g->size == 2);
|
||||
assert(t.g->bits_unused == 2);
|
||||
printf("%d %d\n", t.g->buf[0], t.g->buf[1]);
|
||||
assert(t.g->buf[0] == 147);
|
||||
assert(t.g->buf[1] != 150);
|
||||
assert(t.g->buf[1] == 148);
|
||||
|
||||
printf("%d\n", t.h->buf[3]);
|
||||
assert(t.h->size == 4);
|
||||
assert(t.h->buf[0] == 1);
|
||||
assert(t.h->buf[1] == 140);
|
||||
assert(t.h->buf[2] == 141);
|
||||
assert(t.h->buf[3] == 142);
|
||||
assert(t.h->size == 3);
|
||||
assert(t.h->bits_unused == 1);
|
||||
assert(t.h->buf[0] == 140);
|
||||
assert(t.h->buf[1] == 141);
|
||||
assert(t.h->buf[2] == 142);
|
||||
} else {
|
||||
if(rval.code == RC_OK) {
|
||||
assert(t.a.size != 2
|
||||
|
@ -127,9 +128,9 @@ check(int is_ok, uint8_t *buf, int size, size_t consumed) {
|
|||
|| !t.f
|
||||
|| t.f->size != 7
|
||||
|| !t.g
|
||||
|| t.g->size != 3
|
||||
|| t.g->size != 2
|
||||
|| !t.h
|
||||
|| t.h->size != 4
|
||||
|| t.h->size != 3
|
||||
);
|
||||
}
|
||||
fprintf(stderr, "%d %d\n", (int)rval.consumed, (int)consumed);
|
||||
|
|
|
@ -256,8 +256,6 @@ ASN_MODULE_HEADERS= \
|
|||
|
||||
ASN_MODULE_HEADERS+=ANY.h
|
||||
ASN_MODULE_SOURCES+=ANY.c
|
||||
ASN_MODULE_HEADERS+=BIT_STRING.h
|
||||
ASN_MODULE_SOURCES+=BIT_STRING.c
|
||||
ASN_MODULE_HEADERS+=BMPString.h
|
||||
ASN_MODULE_SOURCES+=BMPString.c
|
||||
ASN_MODULE_HEADERS+=BOOLEAN.h
|
||||
|
@ -305,6 +303,8 @@ ASN_MODULE_HEADERS+=asn_internal.h
|
|||
ASN_MODULE_HEADERS+=asn_types.h
|
||||
ASN_MODULE_HEADERS+=OCTET_STRING.h
|
||||
ASN_MODULE_SOURCES+=OCTET_STRING.c
|
||||
ASN_MODULE_HEADERS+=BIT_STRING.h
|
||||
ASN_MODULE_SOURCES+=BIT_STRING.c
|
||||
ASN_MODULE_HEADERS+=ber_decoder.h
|
||||
ASN_MODULE_SOURCES+=ber_decoder.c
|
||||
ASN_MODULE_SOURCES+=ber_codec_prim.c
|
||||
|
|
|
@ -448,8 +448,8 @@ maintainer-clean-generic:
|
|||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-rm -f asn1p_l.c
|
||||
-rm -f asn1p_y.c
|
||||
-rm -f asn1p_y.h
|
||||
-rm -f asn1p_y.c
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
|
||||
sizeof(ANY_t),
|
||||
offsetof(ANY_t, _asn_ctx),
|
||||
2 /* Special indicator that this is an ANY type */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_ANY = {
|
||||
"ANY",
|
||||
OCTET_STRING_free,
|
||||
|
@ -19,7 +24,7 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
|
|||
0, /* Use generic outmost tag fetcher */
|
||||
0, 0, 0, 0,
|
||||
0, 0, /* No members */
|
||||
(void *)2 /* Special indicator that this is an ANY type */
|
||||
&asn_DEF_ANY_specs,
|
||||
};
|
||||
|
||||
|
||||
|
@ -94,7 +99,7 @@ ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
|
|||
|
||||
if(ANY_fromType(&tmp, td, sptr)) return 0;
|
||||
|
||||
st = (ANY_t *)MALLOC(sizeof(*st));
|
||||
st = (ANY_t *)CALLOC(1, sizeof(ANY_t *));
|
||||
if(st) {
|
||||
*st = tmp;
|
||||
return st;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#ifndef ASN_TYPE_ANY_H
|
||||
#define ASN_TYPE_ANY_H
|
||||
|
||||
#include <OCTET_STRING.h> /* Implemented via OCTET SRING type */
|
||||
#include <OCTET_STRING.h> /* Implemented via OCTET STRING type */
|
||||
|
||||
typedef struct ANY {
|
||||
uint8_t *buf; /* BER-encoded ANY contents */
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
|
||||
};
|
||||
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_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
||||
"BIT STRING",
|
||||
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
|
||||
|
@ -29,7 +34,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
|||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
|
||||
0, 0, /* No members */
|
||||
(void *)1 /* Special indicator that this is a BIT STRING */
|
||||
&asn_DEF_BIT_STRING_specs
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -41,16 +46,9 @@ 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) {
|
||||
if(st->size == 1 && st->buf[0] != 0) {
|
||||
_ASN_ERRLOG(app_errlog, app_key,
|
||||
"%s: invalid padding byte (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if(st->size == 1 && st->bits_unused) {
|
||||
_ASN_ERRLOG(app_errlog, app_key,
|
||||
"%s: no padding byte (%s:%d)",
|
||||
"%s: invalid padding byte (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
@ -93,9 +91,9 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
/*
|
||||
* Binary dump
|
||||
*/
|
||||
for(buf++; buf < end; buf++) {
|
||||
for(; buf < end; buf++) {
|
||||
int v = *buf;
|
||||
int nline = xcan?0:((((buf - st->buf) - 1) % 8) == 0);
|
||||
int nline = xcan?0:(((buf - st->buf) % 8) == 0);
|
||||
if(p >= scend || nline) {
|
||||
er.encoded += p - scratch;
|
||||
_ASN_CALLBACK(scratch, p - scratch);
|
||||
|
@ -107,7 +105,7 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
p += 8;
|
||||
}
|
||||
|
||||
if(!xcan && (((buf - st->buf) - 1) % 8) == 0)
|
||||
if(!xcan && ((buf - st->buf) % 8) == 0)
|
||||
_i_ASN_TEXT_INDENT(1, ilevel);
|
||||
er.encoded += p - scratch;
|
||||
_ASN_CALLBACK(scratch, p - scratch);
|
||||
|
@ -115,9 +113,9 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
|
||||
if(buf == end) {
|
||||
int v = *buf;
|
||||
int mbit = st->buf[0]; /* bits to skip from the right */
|
||||
int ubits = st->bits_unused;
|
||||
int i;
|
||||
for(i = 7; i >= mbit; i--)
|
||||
for(i = 7; i >= ubits; i--)
|
||||
*p++ = (v & (1 << i)) ? 0x31 : 0x30;
|
||||
er.encoded += p - scratch;
|
||||
_ASN_CALLBACK(scratch, p - scratch);
|
||||
|
@ -156,9 +154,9 @@ BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
/*
|
||||
* Hexadecimal dump.
|
||||
*/
|
||||
for(buf++; buf < end; buf++) {
|
||||
if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 17)
|
||||
&& buf != st->buf+1) {
|
||||
for(; buf < end; buf++) {
|
||||
if((buf - st->buf) % 16 == 0 && (st->size > 16)
|
||||
&& buf != st->buf) {
|
||||
_i_INDENT(1);
|
||||
/* Dump the string */
|
||||
if(cb(scratch, p - scratch, app_key) < 0) return -1;
|
||||
|
@ -172,7 +170,7 @@ BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
if(p > scratch) {
|
||||
p--; /* Eat the tailing space */
|
||||
|
||||
if((st->size > 17)) {
|
||||
if((st->size > 16)) {
|
||||
_i_INDENT(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,16 @@
|
|||
#ifndef _BIT_STRING_H_
|
||||
#define _BIT_STRING_H_
|
||||
|
||||
#include <OCTET_STRING.h>
|
||||
#include <OCTET_STRING.h> /* Some help from OCTET STRING */
|
||||
|
||||
typedef OCTET_STRING_t BIT_STRING_t; /* Implemented via OCTET STRING */
|
||||
typedef struct BIT_STRING_s {
|
||||
uint8_t *buf; /* BIT STRING body */
|
||||
int size; /* Size of the above buffer */
|
||||
|
||||
int bits_unused;/* Unused trailing bits in the last octet (0..7) */
|
||||
|
||||
asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
|
||||
} BIT_STRING_t;
|
||||
|
||||
extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OCTET_STRING.h>
|
||||
#include <BIT_STRING.h> /* for .bits_unused member */
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -13,6 +14,11 @@
|
|||
static ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
|
||||
};
|
||||
static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
|
||||
sizeof(OCTET_STRING_t),
|
||||
offsetof(OCTET_STRING_t, _asn_ctx),
|
||||
0
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
|
||||
"OCTET STRING",
|
||||
OCTET_STRING_free,
|
||||
|
@ -30,7 +36,7 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
|
|||
sizeof(asn_DEF_OCTET_STRING_tags)
|
||||
/ sizeof(asn_DEF_OCTET_STRING_tags[0]),
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
&asn_DEF_OCTET_STRING_specs
|
||||
};
|
||||
|
||||
#undef _CH_PHASE
|
||||
|
@ -148,12 +154,7 @@ OS__add_stack_el(struct _stack *st) {
|
|||
|
||||
static struct _stack *
|
||||
_new_stack() {
|
||||
struct _stack *st;
|
||||
(void *)st = CALLOC(1, sizeof(struct _stack));
|
||||
if(st == NULL)
|
||||
return NULL;
|
||||
|
||||
return st;
|
||||
return (struct _stack *)CALLOC(1, sizeof(struct _stack));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -163,31 +164,34 @@ ber_dec_rval_t
|
|||
OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||
asn_TYPE_descriptor_t *td,
|
||||
void **os_structure, void *buf_ptr, size_t size, int tag_mode) {
|
||||
OCTET_STRING_t *st = (OCTET_STRING_t *)*os_structure;
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? td->specifics : &asn_DEF_OCTET_STRING_specs;
|
||||
BIT_STRING_t *st = (BIT_STRING_t *)*os_structure;
|
||||
ber_dec_rval_t rval;
|
||||
asn_struct_ctx_t *ctx;
|
||||
ssize_t consumed_myself = 0;
|
||||
struct _stack *stck; /* A stack structure */
|
||||
struct _stack *stck; /* Expectations stack structure */
|
||||
struct _stack_el *sel = 0; /* Stack element */
|
||||
int tlv_constr;
|
||||
OS_type_e type_type = (OS_type_e)(int)td->specifics;
|
||||
OS_type_e type_variant = (OS_type_e)specs->subvariant;
|
||||
|
||||
ASN_DEBUG("Decoding %s as %s (frame %ld)",
|
||||
td->name,
|
||||
(type_type == _TT_GENERIC) ? "OCTET STRING" : "OS-SpecialCase",
|
||||
(type_variant == _TT_GENERIC) ?
|
||||
"OCTET STRING" : "OS-SpecialCase",
|
||||
(long)size);
|
||||
|
||||
/*
|
||||
* Create the string if does not exist.
|
||||
*/
|
||||
if(st == NULL) {
|
||||
(void *)st = *os_structure = CALLOC(1, sizeof(*st));
|
||||
(void *)st = *os_structure = CALLOC(1, specs->struct_size);
|
||||
if(st == NULL)
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
/* Restore parsing context */
|
||||
ctx = &st->_asn_ctx;
|
||||
ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
||||
|
||||
switch(ctx->phase) {
|
||||
case 0:
|
||||
|
@ -207,10 +211,6 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
ctx->ptr = _new_stack();
|
||||
if(ctx->ptr) {
|
||||
(void *)stck = ctx->ptr;
|
||||
if(type_type == _TT_BIT_STRING) {
|
||||
/* Number of meaningless tail bits */
|
||||
APPEND("\0", 1);
|
||||
}
|
||||
} else {
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
* Jump into stackless primitive decoding.
|
||||
*/
|
||||
_CH_PHASE(ctx, 3);
|
||||
if(type_type == _TT_ANY && tag_mode != 1)
|
||||
if(type_variant == _TT_ANY && tag_mode != 1)
|
||||
APPEND(buf_ptr, rval.consumed);
|
||||
ADVANCE(rval.consumed);
|
||||
goto phase3;
|
||||
|
@ -296,7 +296,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
|
||||
ASN_DEBUG("Eat EOC; wn=%d--", sel->want_nulls);
|
||||
|
||||
if(type_type == _TT_ANY
|
||||
if(type_variant == _TT_ANY
|
||||
&& (tag_mode != 1 || sel->cont_level))
|
||||
APPEND("\0\0", 2);
|
||||
|
||||
|
@ -320,7 +320,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
* Set up expected tags,
|
||||
* depending on ASN.1 type being decoded.
|
||||
*/
|
||||
switch(type_type) {
|
||||
switch(type_variant) {
|
||||
case _TT_BIT_STRING:
|
||||
/* X.690: 8.6.4.1, NOTE 2 */
|
||||
/* Fall through */
|
||||
|
@ -384,7 +384,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
} else {
|
||||
sel->left = tlv_len;
|
||||
}
|
||||
if(type_type == _TT_ANY
|
||||
if(type_variant == _TT_ANY
|
||||
&& (tag_mode != 1 || sel->cont_level))
|
||||
APPEND(buf_ptr, tlvl);
|
||||
sel->got += tlvl;
|
||||
|
@ -417,16 +417,11 @@ 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_type == _TT_BIT_STRING
|
||||
if(type_variant == _TT_BIT_STRING
|
||||
&& sel->bits_chopped == 0) {
|
||||
/*
|
||||
* Finalize the previous chunk:
|
||||
* strip down unused bits.
|
||||
*/
|
||||
st->buf[st->size-1] &= 0xff << st->buf[0];
|
||||
|
||||
/* Put the unused-bits-octet away */
|
||||
st->bits_unused = *(uint8_t *)buf_ptr;
|
||||
APPEND(((char *)buf_ptr+1), (len - 1));
|
||||
st->buf[0] = *(uint8_t *)buf_ptr;
|
||||
sel->bits_chopped = 1;
|
||||
} else {
|
||||
APPEND(buf_ptr, len);
|
||||
|
@ -451,12 +446,27 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
/*
|
||||
* Primitive form, no stack required.
|
||||
*/
|
||||
assert(ctx->left >= 0);
|
||||
|
||||
if(size < (size_t)ctx->left) {
|
||||
if(!size) RETURN(RC_WMORE);
|
||||
if(type_variant == _TT_BIT_STRING && ctx->step == 0) {
|
||||
st->bits_unused = *(uint8_t *)buf_ptr;
|
||||
ctx->left--;
|
||||
ADVANCE(1);
|
||||
}
|
||||
APPEND(buf_ptr, size);
|
||||
assert(ctx->step);
|
||||
ctx->left -= size;
|
||||
ADVANCE(size);
|
||||
RETURN(RC_WMORE);
|
||||
} else {
|
||||
if(type_variant == _TT_BIT_STRING
|
||||
&& ctx->step == 0 && ctx->left) {
|
||||
st->bits_unused = *(uint8_t *)buf_ptr;
|
||||
ctx->left--;
|
||||
ADVANCE(1);
|
||||
}
|
||||
APPEND(buf_ptr, ctx->left);
|
||||
ADVANCE(ctx->left);
|
||||
ctx->left = 0;
|
||||
|
@ -478,14 +488,15 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
/*
|
||||
* BIT STRING-specific processing.
|
||||
*/
|
||||
if(type_type == _TT_BIT_STRING && st->size >= 2) {
|
||||
if(type_variant == _TT_BIT_STRING && st->size) {
|
||||
/* Finalize BIT STRING: zero out unused bits. */
|
||||
st->buf[st->size-1] &= 0xff << st->buf[0];
|
||||
st->buf[st->size-1] &= 0xff << st->bits_unused;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Took %d bytes to encode %s: [%s]:%d",
|
||||
consumed_myself, td->name,
|
||||
(type_type == _TT_GENERIC) ? (char *)st->buf : "", st->size);
|
||||
(type_variant == _TT_GENERIC) ? (char *)st->buf : "<data>",
|
||||
st->size);
|
||||
|
||||
|
||||
RETURN(RC_OK);
|
||||
|
@ -495,79 +506,65 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
* Encode OCTET STRING type using DER.
|
||||
*/
|
||||
asn_enc_rval_t
|
||||
OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
|
||||
OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
||||
int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_enc_rval_t erval;
|
||||
OCTET_STRING_t *st = (OCTET_STRING_t *)ptr;
|
||||
int add_byte = 0;
|
||||
OS_type_e type_type = (OS_type_e)(int)td->specifics;
|
||||
asn_enc_rval_t er;
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? 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;
|
||||
int fix_last_byte = 0;
|
||||
|
||||
ASN_DEBUG("%s %s as OCTET STRING",
|
||||
cb?"Estimating":"Encoding", td->name);
|
||||
|
||||
/*
|
||||
* Canonicalize BIT STRING.
|
||||
* Write tags.
|
||||
*/
|
||||
if(type_type == _TT_BIT_STRING) {
|
||||
switch(st->size) {
|
||||
case 0: add_byte = 1; break;
|
||||
case 1: st->buf[0] = 0; break;
|
||||
default:
|
||||
/* Finalize BIT STRING: zero out unused bits. */
|
||||
st->buf[st->size-1] &= 0xff << st->buf[0];
|
||||
if(type_variant != _TT_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);
|
||||
if(er.encoded == -1) {
|
||||
er.failed_type = td;
|
||||
er.structure_ptr = sptr;
|
||||
return er;
|
||||
}
|
||||
} else {
|
||||
/* Disallow: [<tag>] IMPLICIT ANY */
|
||||
assert(type_variant != _TT_ANY || tag_mode != -1);
|
||||
er.encoded = 0;
|
||||
}
|
||||
|
||||
if(!cb) {
|
||||
er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
|
||||
return er;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write tags.
|
||||
* Prepare to deal with the last octet of BIT STRING.
|
||||
*/
|
||||
if(type_type != _TT_ANY || tag_mode == 1) {
|
||||
erval.encoded = der_write_tags(td, st->size + add_byte,
|
||||
tag_mode, type_type == _TT_ANY, tag, cb, app_key);
|
||||
if(erval.encoded == -1) {
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
} else {
|
||||
/* Disallow: [...] IMPLICIT ANY */
|
||||
assert(type_type != _TT_ANY || tag_mode != -1);
|
||||
erval.encoded = 0;
|
||||
if(type_variant == _TT_BIT_STRING) {
|
||||
uint8_t b = st->bits_unused & 0x07;
|
||||
if(b && st->size) fix_last_byte = 1;
|
||||
_ASN_CALLBACK(&b, 1);
|
||||
er.encoded++;
|
||||
}
|
||||
|
||||
if(cb) {
|
||||
uint8_t zero;
|
||||
uint8_t *buf;
|
||||
int size;
|
||||
/* Invoke callback for the main part of the buffer */
|
||||
_ASN_CALLBACK(st->buf, st->size - fix_last_byte);
|
||||
|
||||
/* BIT STRING-aware handling */
|
||||
if(add_byte) {
|
||||
zero = 0;
|
||||
buf = &zero;
|
||||
size = 1;
|
||||
} else if(st->buf) {
|
||||
buf = st->buf;
|
||||
size = st->size;
|
||||
} else {
|
||||
assert(st->size == 0);
|
||||
buf = 0; /* Not used */
|
||||
size = 0;
|
||||
}
|
||||
|
||||
if(size) {
|
||||
if(cb(buf, size, app_key) < 0) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
}
|
||||
/* The last octet should be stripped off the unused bits */
|
||||
if(fix_last_byte) {
|
||||
uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused);
|
||||
_ASN_CALLBACK(&b, 1);
|
||||
}
|
||||
|
||||
erval.encoded += st->size + add_byte;
|
||||
|
||||
return erval;
|
||||
er.encoded += st->size;
|
||||
return er;
|
||||
cb_failed:
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
|
@ -790,7 +787,11 @@ OCTET_STRING_print_ascii(asn_TYPE_descriptor_t *td, const void *sptr,
|
|||
void
|
||||
OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
|
||||
struct _stack *stck = (struct _stack *)st->_asn_ctx.ptr;
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? td->specifics : &asn_DEF_OCTET_STRING_specs;
|
||||
asn_struct_ctx_t *ctx = (asn_struct_ctx_t *)
|
||||
((char *)st + specs->ctx_offset);
|
||||
struct _stack *stck = ctx->ptr;
|
||||
|
||||
if(!td || !st)
|
||||
return;
|
||||
|
@ -860,10 +861,12 @@ OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
|
|||
}
|
||||
|
||||
OCTET_STRING_t *
|
||||
OCTET_STRING_new_fromBuf(const char *str, int len) {
|
||||
OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) {
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? td->specifics : &asn_DEF_OCTET_STRING_specs;
|
||||
OCTET_STRING_t *st;
|
||||
|
||||
(void *)st = CALLOC(1, sizeof(*st));
|
||||
st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
|
||||
if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
|
||||
free(st);
|
||||
st = NULL;
|
||||
|
|
|
@ -24,9 +24,9 @@ der_type_encoder_f OCTET_STRING_encode_der;
|
|||
xer_type_encoder_f OCTET_STRING_encode_xer;
|
||||
xer_type_encoder_f OCTET_STRING_encode_xer_ascii;
|
||||
|
||||
/***********************************
|
||||
* Some handy conversion routines. *
|
||||
***********************************/
|
||||
/******************************
|
||||
* Handy conversion routines. *
|
||||
******************************/
|
||||
|
||||
/*
|
||||
* This function clears the previous value of the OCTET STRING (if any)
|
||||
|
@ -39,14 +39,29 @@ xer_type_encoder_f OCTET_STRING_encode_xer_ascii;
|
|||
*/
|
||||
int OCTET_STRING_fromBuf(OCTET_STRING_t *s, const char *str, int size);
|
||||
|
||||
/* Handy conversion from the C string into the OCTET STRING. */
|
||||
#define OCTET_STRING_fromString(s, str) OCTET_STRING_fromBuf(s, str, -1);
|
||||
|
||||
/*
|
||||
* Allocate and fill the new OCTET STRING and return a pointer to the newly
|
||||
* allocated object. NULL is permitted in str: the function will just allocate
|
||||
* empty OCTET STRING.
|
||||
*/
|
||||
OCTET_STRING_t *OCTET_STRING_new_fromBuf(const char *str, int size);
|
||||
OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
|
||||
const char *str, int size);
|
||||
|
||||
/* Handy conversion from the C string into the OCTET STRING. */
|
||||
#define OCTET_STRING_fromString(s, str) OCTET_STRING_fromBuf(s, str, -1);
|
||||
/****************************
|
||||
* Internally useful stuff. *
|
||||
****************************/
|
||||
|
||||
typedef struct asn_OCTET_STRING_specifics_s {
|
||||
/*
|
||||
* Target structure description.
|
||||
*/
|
||||
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 */
|
||||
} asn_OCTET_STRING_specifics_t;
|
||||
|
||||
#endif /* _OCTET_STRING_H_ */
|
||||
|
|
|
@ -133,14 +133,14 @@ typedef struct asn_TYPE_descriptor_s {
|
|||
int (*xer_decoder);/* PLACEHOLDER */ /* Free-form XER decoder */
|
||||
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
|
||||
|
||||
/*
|
||||
* Functions used internally. Should not be used by applications.
|
||||
*/
|
||||
asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
|
||||
/***********************************************************************
|
||||
* Internally useful members. Not to be used by applications directly. *
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
* Tags that are expected to occur.
|
||||
*/
|
||||
asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
|
||||
ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
|
||||
int tags_count; /* Number of tags which are expected */
|
||||
ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#
|
||||
|
||||
ANY.h ANY.c
|
||||
BIT_STRING.h BIT_STRING.c
|
||||
BMPString.h BMPString.c
|
||||
BOOLEAN.h BOOLEAN.c
|
||||
ENUMERATED.h ENUMERATED.c INTEGER.h
|
||||
|
@ -47,6 +46,7 @@ asn_application.h
|
|||
asn_internal.h
|
||||
asn_types.h
|
||||
OCTET_STRING.h OCTET_STRING.c # This one is used too widely
|
||||
BIT_STRING.h BIT_STRING.c # This one is necessary for the above one
|
||||
ber_decoder.h ber_decoder.c
|
||||
ber_codec_prim.c ber_codec_prim.h
|
||||
ber_tlv_length.h ber_tlv_length.c
|
||||
|
|
|
@ -40,7 +40,7 @@ check(int size) {
|
|||
ber_dec_rval_t rval;
|
||||
int i;
|
||||
|
||||
os = OCTET_STRING_new_fromBuf(0, size);
|
||||
os = OCTET_STRING_new_fromBuf(&asn_DEF_OCTET_STRING, 0, size);
|
||||
assert(os);
|
||||
assert(os->size == 0);
|
||||
|
||||
|
@ -69,9 +69,9 @@ check(int size) {
|
|||
}
|
||||
|
||||
if(0) {
|
||||
printf("new(%d):", size);
|
||||
fprintf(stderr, "new(%d):", size);
|
||||
for(i = 0; i < (buf_off<10?buf_off:10); i++)
|
||||
printf(" %02x", buf[i]);
|
||||
fprintf(stderr, " %02x", buf[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ main() {
|
|||
int i;
|
||||
|
||||
for(i = 0; i < 66000; i++) {
|
||||
if(i == 4500) i = 64000;
|
||||
if(i == 4500) i = 64000; /* Jump */
|
||||
check(i);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue