update to asn1c aper branch commit 6e00cbce7304a6972e82a12bb5fa82e41fa541be

which is closes to Lev Walkins master 62913d8b8e1eb96d74315ff748475ca818b69752
changes/39/3439/1
Harald Welte 8 years ago
parent f6b9173b02
commit 41b85d5597

@ -1,18 +1,16 @@
diff --git a/include/asn1c/asn_internal.h b/include/asn1c/asn_internal.h
index 67f055a..45b1adb 100644
--- a/include/asn1c/asn_internal.h
+++ b/include/asn1c/asn_internal.h
--- ../asn1c/skeletons/asn_internal.h 2015-08-31 09:29:45.590924282 +0200
+++ include/asn1c/asn_internal.h 2015-08-31 09:26:17.461872713 +0200
@@ -15,6 +15,8 @@
#include <assert.h> /* for assert() macro */
#endif
+#include <osmocore/talloc.h>
+#include <osmocom/core/talloc.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -23,10 +25,12 @@ extern "C" {
#define ASN1C_ENVIRONMENT_VERSION 920 /* Compile-time version */
@@ -23,10 +25,12 @@
#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */
int get_asn1c_environment_version(void); /* Run-time version */
-#define CALLOC(nmemb, size) calloc(nmemb, size)
@ -26,5 +24,5 @@ index 67f055a..45b1adb 100644
+#define REALLOC(oldptr, size) talloc_realloc_size(talloc_asn1_ctx, oldptr, size)
+#define FREEMEM(ptr) talloc_free(ptr)
/*
* A macro for debugging the ASN.1 internals.
#define asn_debug_indent 0
#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)

@ -1,4 +1,4 @@
AC_INIT([libasn1c], [0.9.21],
AC_INIT([libasn1c], [0.9.28],
[openbsc-devel@lists.openbsc.org])
AM_INIT_AUTOMAKE([dist-bzip2])

@ -32,10 +32,13 @@ xer_type_encoder_f ANY_encode_xer;
/* Convert another ASN.1 type into the ANY. This implies DER encoding. */
int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr);
int ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr);
ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr);
ANY_t *ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr);
/* Convert the contents of the ANY type into the specified type. */
int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
int ANY_to_type_aper(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
#define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size))
#define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \

@ -28,6 +28,8 @@ xer_type_decoder_f BOOLEAN_decode_xer;
xer_type_encoder_f BOOLEAN_encode_xer;
per_type_decoder_f BOOLEAN_decode_uper;
per_type_encoder_f BOOLEAN_encode_uper;
per_type_decoder_f BOOLEAN_decode_aper;
per_type_encoder_f BOOLEAN_encode_aper;
#ifdef __cplusplus
}

@ -17,6 +17,8 @@ extern asn_TYPE_descriptor_t asn_DEF_ENUMERATED;
per_type_decoder_f ENUMERATED_decode_uper;
per_type_encoder_f ENUMERATED_encode_uper;
per_type_decoder_f ENUMERATED_decode_aper;
per_type_encoder_f ENUMERATED_encode_aper;
#ifdef __cplusplus
}

@ -18,15 +18,15 @@ extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
/* Map with <tag> to integer value association */
typedef struct asn_INTEGER_enum_map_s {
long nat_value; /* associated native integer value */
int64_t nat_value; /* associated native integer value */
size_t enum_len; /* strlen("tag") */
const char *enum_name; /* "tag" */
} asn_INTEGER_enum_map_t;
/* This type describes an enumeration for INTEGER and ENUMERATED types */
typedef struct asn_INTEGER_specifics_s {
asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
unsigned int *enum2value; /* "tag" => N; sorted by tag */
typedef const struct asn_INTEGER_specifics_s {
const asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
const unsigned int *enum2value; /* "tag" => N; sorted by tag */
int map_count; /* Elements in either map */
int extension; /* This map is extensible */
int strict_enumeration; /* Enumeration set is fixed */
@ -41,6 +41,8 @@ xer_type_decoder_f INTEGER_decode_xer;
xer_type_encoder_f INTEGER_encode_xer;
per_type_decoder_f INTEGER_decode_uper;
per_type_encoder_f INTEGER_encode_uper;
per_type_decoder_f INTEGER_decode_aper;
per_type_encoder_f INTEGER_encode_aper;
/***********************************
* Some handy conversion routines. *
@ -52,11 +54,28 @@ per_type_encoder_f INTEGER_encode_uper;
* -1/ERANGE: Value encoded is out of range for long representation
* -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
*/
int asn_INTEGER2int64(const INTEGER_t *i, int64_t *l);
int asn_INTEGER2uint64(const INTEGER_t *i, uint64_t *l);
int asn_INTEGER2long(const INTEGER_t *i, long *l);
int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l);
int asn_int642INTEGER(INTEGER_t *i, int64_t l);
int asn_uint642INTEGER(INTEGER_t *i, uint64_t 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.
*/

@ -25,6 +25,8 @@ xer_type_decoder_f NULL_decode_xer;
xer_type_encoder_f NULL_encode_xer;
per_type_decoder_f NULL_decode_uper;
per_type_encoder_f NULL_encode_uper;
per_type_decoder_f NULL_decode_aper;
per_type_encoder_f NULL_encode_aper;
#ifdef __cplusplus
}

@ -24,6 +24,8 @@ extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
xer_type_encoder_f NativeEnumerated_encode_xer;
per_type_decoder_f NativeEnumerated_decode_uper;
per_type_encoder_f NativeEnumerated_encode_uper;
per_type_decoder_f NativeEnumerated_decode_aper;
per_type_encoder_f NativeEnumerated_encode_aper;
asn_struct_print_f NativeEnumerated_print;
#ifdef __cplusplus

@ -29,6 +29,8 @@ xer_type_decoder_f NativeInteger_decode_xer;
xer_type_encoder_f NativeInteger_encode_xer;
per_type_decoder_f NativeInteger_decode_uper;
per_type_encoder_f NativeInteger_encode_uper;
per_type_decoder_f NativeInteger_decode_aper;
per_type_encoder_f NativeInteger_encode_aper;
#ifdef __cplusplus
}

@ -27,6 +27,8 @@ xer_type_decoder_f NativeReal_decode_xer;
xer_type_encoder_f NativeReal_encode_xer;
per_type_decoder_f NativeReal_decode_uper;
per_type_encoder_f NativeReal_encode_uper;
per_type_decoder_f NativeReal_decode_aper;
per_type_encoder_f NativeReal_encode_aper;
#ifdef __cplusplus
}

@ -68,7 +68,7 @@ xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
* WARNING: The function always returns the real number of arcs,
* even if there is no sufficient (_arc_slots) provided.
*/
int OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *_oid,
int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid,
void *_arcs, /* e.g., unsigned int arcs[N] */
unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
unsigned int _arc_slots /* e.g., N */);
@ -91,12 +91,12 @@ int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *_oid,
/*
* Print the specified OBJECT IDENTIFIER arc.
*/
int OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen,
int OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen,
int add, /* Arbitrary offset, required to process the first two arcs */
asn_app_consume_bytes_f *cb, void *app_key);
/* Same as above, but returns the number of written digits, instead of 0 */
ssize_t OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
asn_app_consume_bytes_f *cb, void *app_key);
/*
@ -127,7 +127,7 @@ int OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
* Internal functions.
* Used by RELATIVE-OID implementation in particular.
*/
int OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen,
int OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen,
signed int add, void *value, unsigned int value_size);
int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf,
const void *arcval, unsigned int arcval_size, int _prepared_order);

@ -32,6 +32,8 @@ xer_type_encoder_f OCTET_STRING_encode_xer;
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
per_type_decoder_f OCTET_STRING_decode_uper;
per_type_encoder_f OCTET_STRING_encode_uper;
per_type_decoder_f OCTET_STRING_decode_aper;
per_type_encoder_f OCTET_STRING_encode_aper;
/******************************
* Handy conversion routines. *
@ -63,7 +65,7 @@ OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
* Internally useful stuff. *
****************************/
typedef struct asn_OCTET_STRING_specifics_s {
typedef const struct asn_OCTET_STRING_specifics_s {
/*
* Target structure description.
*/

@ -21,6 +21,8 @@ xer_type_decoder_f REAL_decode_xer;
xer_type_encoder_f REAL_encode_xer;
per_type_decoder_f REAL_decode_uper;
per_type_encoder_f REAL_encode_uper;
per_type_decoder_f REAL_decode_aper;
per_type_encoder_f REAL_encode_aper;
/***********************************
* Some handy conversion routines. *

@ -25,7 +25,7 @@ xer_type_encoder_f RELATIVE_OID_encode_xer;
**********************************/
/* See OBJECT_IDENTIFIER_get_arcs() function in OBJECT_IDENTIFIER.h */
int RELATIVE_OID_get_arcs(RELATIVE_OID_t *_roid,
int RELATIVE_OID_get_arcs(const RELATIVE_OID_t *_roid,
void *arcs, unsigned int arc_type_size, unsigned int arc_slots);
/* See OBJECT_IDENTIFIER_set_arcs() function in OBJECT_IDENTIFIER.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 { \

@ -22,7 +22,7 @@ extern "C" {
#endif
/* Environment version might be used to avoid running with the old library */
#define ASN1C_ENVIRONMENT_VERSION 922 /* Compile-time version */
#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */
int get_asn1c_environment_version(void); /* Run-time version */
extern void *talloc_asn1_ctx;
@ -32,6 +32,9 @@ extern void *talloc_asn1_ctx;
#define REALLOC(oldptr, size) talloc_realloc_size(talloc_asn1_ctx, oldptr, size)
#define FREEMEM(ptr) talloc_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.
@ -40,17 +43,25 @@ extern void *talloc_asn1_ctx;
#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
#ifdef __GNUC__
#ifdef ASN_THREAD_SAFE
#define asn_debug_indent 0
/* 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 { \
extern int asn_debug; /* Allow option on execution */
#define ASN_DEBUG(fmt, args...) \
if (asn_debug) { \
do { \
int adi = asn_debug_indent; \
while(adi--) fprintf(stderr, " "); \
fprintf(stderr, fmt, ##args); \
fprintf(stderr, " (%s:%d)\n", \
__FILE__, __LINE__); \
} while(0)
} while(0); \
}
#else /* !__GNUC__ */
void ASN_DEBUG_f(const char *fmt, ...);
#define ASN_DEBUG ASN_DEBUG_f

@ -21,7 +21,7 @@
#include <stdarg.h> /* For va_start */
#include <stddef.h> /* for offsetof and ptrdiff_t */
#ifdef WIN32
#ifdef _WIN32
#include <malloc.h>
#define snprintf _snprintf
@ -29,9 +29,9 @@
/* To avoid linking with ws2_32.lib, here's the definition of ntohl() */
#define sys_ntohl(l) ((((l) << 24) & 0xff000000) \
| (((l) << 16) & 0xff0000) \
| (((l) << 8) & 0xff00) \
| ((l) & 0xff))
| (((l) << 8) & 0xff0000) \
| (((l) >> 8) & 0xff00) \
| ((l >> 24) & 0xff))
#ifdef _MSC_VER /* MSVS.Net */
#ifndef __cplusplus
@ -57,7 +57,7 @@ typedef unsigned int uint32_t;
#include <stdint.h>
#endif /* _MSC_VER */
#else /* !WIN32 */
#else /* !_WIN32 */
#if defined(__vxworks)
#include <types/vxTypes.h>
@ -90,7 +90,7 @@ typedef unsigned int uint32_t;
#endif /* defined(__vxworks) */
#endif /* WIN32 */
#endif /* _WIN32 */
#if __GNUC__ >= 3
#ifndef GCC_PRINTFLIKE

@ -12,7 +12,7 @@
extern "C" {
#endif
typedef struct asn_CHOICE_specifics_s {
typedef const struct asn_CHOICE_specifics_s {
/*
* Target structure description.
*/
@ -24,7 +24,7 @@ typedef struct asn_CHOICE_specifics_s {
/*
* Tags to members mapping table.
*/
asn_TYPE_tag2member_t *tag2el;
const asn_TYPE_tag2member_t *tag2el;
int tag2el_count;
/* Canonical ordering of CHOICE elements, for PER */
@ -48,6 +48,8 @@ xer_type_decoder_f CHOICE_decode_xer;
xer_type_encoder_f CHOICE_encode_xer;
per_type_decoder_f CHOICE_decode_uper;
per_type_encoder_f CHOICE_encode_uper;
per_type_decoder_f CHOICE_decode_aper;
per_type_encoder_f CHOICE_encode_aper;
asn_outmost_tag_f CHOICE_outmost_tag;
#ifdef __cplusplus

@ -11,7 +11,7 @@
extern "C" {
#endif
typedef struct asn_SEQUENCE_specifics_s {
typedef const struct asn_SEQUENCE_specifics_s {
/*
* Target structure description.
*/
@ -21,14 +21,14 @@ typedef struct asn_SEQUENCE_specifics_s {
/*
* Tags to members mapping table (sorted).
*/
asn_TYPE_tag2member_t *tag2el;
const asn_TYPE_tag2member_t *tag2el;
int tag2el_count;
/*
* Optional members of the extensions root (roms) or additions (aoms).
* Meaningful for PER.
*/
int *oms; /* Optional MemberS */
const int *oms; /* Optional MemberS */
int roms_count; /* Root optional members count */
int aoms_count; /* Additions optional members count */
@ -52,6 +52,8 @@ xer_type_decoder_f SEQUENCE_decode_xer;
xer_type_encoder_f SEQUENCE_encode_xer;
per_type_decoder_f SEQUENCE_decode_uper;
per_type_encoder_f SEQUENCE_encode_uper;
per_type_decoder_f SEQUENCE_decode_aper;
per_type_encoder_f SEQUENCE_encode_aper;
#ifdef __cplusplus
}

@ -22,9 +22,11 @@ extern "C" {
#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
#define SEQUENCE_OF_decode_xer SET_OF_decode_xer
#define SEQUENCE_OF_decode_uper SET_OF_decode_uper
#define SEQUENCE_OF_decode_aper SET_OF_decode_aper
der_type_encoder_f SEQUENCE_OF_encode_der;
xer_type_encoder_f SEQUENCE_OF_encode_xer;
per_type_encoder_f SEQUENCE_OF_encode_uper;
per_type_encoder_f SEQUENCE_OF_encode_aper;
#ifdef __cplusplus
}

@ -12,7 +12,7 @@ extern "C" {
#endif
typedef struct asn_SET_specifics_s {
typedef const struct asn_SET_specifics_s {
/*
* Target structure description.
*/
@ -25,21 +25,21 @@ typedef struct asn_SET_specifics_s {
* Sometimes suitable for DER encoding (untagged CHOICE is present);
* if so, tag2el_count will be greater than td->elements_count.
*/
asn_TYPE_tag2member_t *tag2el;
const asn_TYPE_tag2member_t *tag2el;
int tag2el_count;
/*
* Tags to members mapping table, second edition.
* Suitable for CANONICAL-XER encoding.
*/
asn_TYPE_tag2member_t *tag2el_cxer;
const asn_TYPE_tag2member_t *tag2el_cxer;
int tag2el_cxer_count;
/*
* Extensions-related stuff.
*/
int extensible; /* Whether SET is extensible */
unsigned int *_mandatory_elements; /* Bitmask of mandatory ones */
const unsigned int *_mandatory_elements; /* Bitmask of mandatory ones */
} asn_SET_specifics_t;
/*
@ -53,7 +53,9 @@ der_type_encoder_f SET_encode_der;
xer_type_decoder_f SET_decode_xer;
xer_type_encoder_f SET_encode_xer;
per_type_decoder_f SET_decode_uper;
per_type_decoder_f SET_decode_aper;
per_type_encoder_f SET_encode_uper;
per_type_encoder_f SET_encode_aper;
/***********************
* Some handy helpers. *

@ -11,7 +11,7 @@
extern "C" {
#endif
typedef struct asn_SET_OF_specifics_s {
typedef const struct asn_SET_OF_specifics_s {
/*
* Target structure description.
*/
@ -34,6 +34,8 @@ xer_type_decoder_f SET_OF_decode_xer;
xer_type_encoder_f SET_OF_encode_xer;
per_type_decoder_f SET_OF_decode_uper;
per_type_encoder_f SET_OF_encode_uper;
per_type_decoder_f SET_OF_decode_aper;
per_type_encoder_f SET_OF_encode_aper;
#ifdef __cplusplus
}

@ -73,7 +73,7 @@ typedef int (asn_struct_print_f)(
* Do not use it in your application.
*/
typedef ber_tlv_tag_t (asn_outmost_tag_f)(
struct asn_TYPE_descriptor_s *type_descriptor,
const struct asn_TYPE_descriptor_s *type_descriptor,
const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag);
/* The instance of the above function type; used internally. */
asn_outmost_tag_f asn_TYPE_outmost_tag;
@ -83,8 +83,8 @@ asn_outmost_tag_f asn_TYPE_outmost_tag;
* The definitive description of the destination language's structure.
*/
typedef struct asn_TYPE_descriptor_s {
char *name; /* A name of the ASN.1 type. "" in some cases. */
char *xml_tag; /* Name used in XML tag */
const char *name; /* A name of the ASN.1 type. "" in some cases. */
const char *xml_tag; /* Name used in XML tag */
/*
* Generalized functions for dealing with the specific type.
@ -99,6 +99,8 @@ typedef struct asn_TYPE_descriptor_s {
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
per_type_decoder_f *aper_decoder; /* Aligned PER decoder */
per_type_encoder_f *aper_encoder; /* Aligned PER encoder */
/***********************************************************************
* Internally useful members. Not to be used by applications directly. *
@ -108,10 +110,10 @@ typedef struct asn_TYPE_descriptor_s {
* 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 */
int all_tags_count; /* Number of tags */
const ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
int tags_count; /* Number of tags which are expected */
const ber_tlv_tag_t *all_tags; /* Every tag for BER/containment */
int all_tags_count; /* Number of tags */
asn_per_constraints_t *per_constraints; /* PER compiled constraints */
@ -125,7 +127,7 @@ typedef struct asn_TYPE_descriptor_s {
* Additional information describing the type, used by appropriate
* functions above.
*/
void *specifics;
const void *specifics;
} asn_TYPE_descriptor_t;
/*
@ -147,7 +149,7 @@ typedef struct asn_TYPE_member_s {
asn_constr_check_f *memb_constraints; /* Constraints validator */
asn_per_constraints_t *per_constraints; /* PER compiled constraints */
int (*default_value)(int setval, void **sptr); /* DEFAULT <value> */
char *name; /* ASN.1 identifier of the element */
const char *name; /* ASN.1 identifier of the element */
} asn_TYPE_member_t;
/*

@ -38,7 +38,29 @@ asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
int unused_bits /* Number of unused tailing bits, 0..7 */
);
/*
* Aligned 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 aper_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 */
);
/*
* Aligned 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 aper_decode(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 */
int skip_bits, /* Number of unused leading bits, 0..7 */
int unused_bits /* Number of unused tailing bits, 0..7 */
);
/*
* Type of the type-specific PER decoder function.
*/

@ -38,6 +38,12 @@ asn_enc_rval_t uper_encode_to_buffer(
size_t buffer_size /* Initial buffer size (max) */
);
asn_enc_rval_t aper_encode_to_buffer(
struct asn_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
void *buffer, /* Pre-allocated 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.
@ -52,6 +58,11 @@ ssize_t uper_encode_to_new_buffer(
void **buffer_r /* Buffer allocated and returned */
);
ssize_t
aper_encode_to_new_buffer(struct asn_TYPE_descriptor_s *td,
asn_per_constraints_t *constraints,
void *sptr,
void **buffer_r);
/*
* Type of the generic PER encoder function.
*/

@ -15,6 +15,8 @@ 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);
int aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po);
#ifdef __cplusplus
}
#endif

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
* Copyright (c) 2005-2014 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
@ -15,7 +15,7 @@ extern "C" {
/*
* Pre-computed PER constraints.
*/
typedef struct asn_per_constraint_s {
typedef const struct asn_per_constraint_s {
enum asn_per_constraint_flags {
APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */
APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */
@ -24,12 +24,12 @@ typedef struct asn_per_constraint_s {
} flags;
int range_bits; /* Full number of bits in the range */
int effective_bits; /* Effective bits */
long lower_bound; /* "lb" value */
long upper_bound; /* "ub" value */
int64_t lower_bound; /* "lb" value */
int64_t upper_bound; /* "ub" value */
} asn_per_constraint_t;
typedef struct asn_per_constraints_s {
asn_per_constraint_t value;
asn_per_constraint_t size;
typedef const struct asn_per_constraints_s {
struct asn_per_constraint_s value;
struct asn_per_constraint_s size;
int (*value2code)(unsigned int value);
int (*code2value)(unsigned int code);
} asn_per_constraints_t;
@ -39,9 +39,9 @@ typedef struct asn_per_constraints_s {
*/
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 */
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;
@ -71,15 +71,25 @@ ssize_t uper_get_length(asn_per_data_t *pd,
int effective_bound_bits,
int *repeat);
ssize_t aper_get_length(asn_per_data_t *pd,
int range,
int effective_bound_bits,
int *repeat);
/*
* Get the normally small length "n".
*/
ssize_t uper_get_nslength(asn_per_data_t *pd);
ssize_t aper_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);
ssize_t aper_get_nsnnwn(asn_per_data_t *pd, int range);
/* 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);
@ -103,6 +113,14 @@ 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);
/* Align the current bit position to octet bundary */
int aper_put_align(asn_per_outp_t *po);
int32_t aper_get_align(asn_per_data_t *pd);
/*
* Put the length "n" to the Unaligned PER stream.
* This function returns the number of units which may be flushed
@ -110,17 +128,23 @@ 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);
ssize_t aper_put_length(asn_per_outp_t *po, int range, size_t 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);
int aper_put_nslength(asn_per_outp_t *po, size_t length);
/*
* Put the normally small non-negative whole number.
*/
int uper_put_nsnnwn(asn_per_outp_t *po, int n);
int aper_put_nsnnwn(asn_per_outp_t *po, int range, int number);
#ifdef __cplusplus
}
#endif

@ -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.

@ -21,7 +21,10 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
ANY_encode_xer,
0, 0,
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
OCTET_STRING_decode_aper,
OCTET_STRING_encode_aper,
0, /* Use generic outmost tag fetcher */
0, 0, 0, 0,
0, /* No PER visible constraints */
@ -87,6 +90,37 @@ ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
return 0;
}
int
ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
uint8_t *buffer = NULL;
ssize_t erval;
if(!st || !td) {
errno = EINVAL;
return -1;
}
if(!sptr) {
if(st->buf) FREEMEM(st->buf);
st->size = 0;
return 0;
}
erval = aper_encode_to_new_buffer(td, td->per_constraints, sptr, (void**)&buffer);
if(erval == -1) {
if(buffer) FREEMEM(buffer);
return -1;
}
assert((size_t)erval > 0);
if(st->buf) FREEMEM(st->buf);
st->buf = buffer;
st->size = erval;
return 0;
}
ANY_t *
ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
ANY_t tmp;
@ -111,6 +145,30 @@ ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
}
}
ANY_t *
ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
ANY_t tmp;
ANY_t *st;
if(!td || !sptr) {
errno = EINVAL;
return 0;
}
memset(&tmp, 0, sizeof(tmp));
if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
if(st) {
*st = tmp;
return st;
} else {
FREEMEM(tmp.buf);
return 0;
}
}
int
ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
asn_dec_rval_t rval;
@ -138,6 +196,33 @@ ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
}
}
int
ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
asn_dec_rval_t rval;
void *newst = 0;
if(!st || !td || !struct_ptr) {
errno = EINVAL;
return -1;
}
if(st->buf == 0) {
/* Nothing to convert, make it empty. */
*struct_ptr = (void *)0;
return 0;
}
rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
if(rval.code == RC_OK) {
*struct_ptr = newst;
return 0;
} else {
/* Remove possibly partially decoded data. */
ASN_STRUCT_FREE(*td, newst);
return -1;
}
}
static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
struct _callback_arg *arg = (struct _callback_arg *)key;

@ -9,7 +9,7 @@
/*
* BIT STRING basic type description.
*/
static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
static const 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 = {
@ -29,6 +29,8 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
BIT_STRING_encode_xer,
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
OCTET_STRING_decode_aper, /* Aligned PER decoder */
OCTET_STRING_encode_aper, /* Aligned PER encoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BIT_STRING_tags,
sizeof(asn_DEF_BIT_STRING_tags)
@ -140,7 +142,7 @@ cb_failed:
int
BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
static const char *h2c = "0123456789ABCDEF";
const char * const h2c = "0123456789ABCDEF";
char scratch[64];
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
uint8_t *buf;

@ -9,7 +9,7 @@
/*
* BMPString basic type description.
*/
static ber_tlv_tag_t asn_DEF_BMPString_tags[] = {
static const ber_tlv_tag_t asn_DEF_BMPString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (30 << 2)), /* [UNIVERSAL 30] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
@ -35,6 +35,8 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
BMPString_encode_xer, /* Convert to UTF-8 */
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
OCTET_STRING_decode_aper, /* Aligned PER decoder */
OCTET_STRING_encode_aper, /* Aligned PER encoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
@ -143,7 +145,7 @@ BMPString_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
return rc;
} else {
dstwc[wcs_len] = 0; /* nul-terminate */
wcs = (uint32_t *)dstwc;
wcs = (uint32_t *)(void *)dstwc; /* Alignment OK */
}
}

@ -9,7 +9,7 @@
/*
* BOOLEAN basic type description.
*/
static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
static const ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
};
asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
@ -24,6 +24,8 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
BOOLEAN_encode_xer,
BOOLEAN_decode_uper, /* Unaligned PER decoder */
BOOLEAN_encode_uper, /* Unaligned PER encoder */
BOOLEAN_decode_aper, /* Aligned PER decoder */
BOOLEAN_encode_aper, /* Aligned PER encoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BOOLEAN_tags,
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
@ -161,10 +163,7 @@ BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
}
return XPBD_BODY_CONSUMED;
} else {
if(xer_is_whitespace(chunk_buf, chunk_size))
return XPBD_NOT_BODY_IGNORE;
else
return XPBD_BROKEN_ENCODING;
return XPBD_BROKEN_ENCODING;
}
}
@ -267,18 +266,63 @@ BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
return rv;
}
asn_dec_rval_t
BOOLEAN_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_dec_rval_t rv;
BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
(void)opt_codec_ctx;
(void)constraints;
if(!st) {
st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
if(!st) _ASN_DECODE_FAILED;
}
/*
* Extract a single bit
*/
switch(per_get_few_bits(pd, 1)) {
case 1: *st = 1; break;
case 0: *st = 0; break;
case -1: default: _ASN_DECODE_STARVED;
}
ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
rv.code = RC_OK;
rv.consumed = 1;
return rv;
}
asn_enc_rval_t
BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
asn_enc_rval_t er;
asn_enc_rval_t er = { 0, 0, 0 };
(void)constraints;
if(!st) _ASN_ENCODE_FAILED;
per_put_few_bits(po, *st ? 1 : 0, 1);
if(per_put_few_bits(po, *st ? 1 : 0, 1))
_ASN_ENCODE_FAILED;
_ASN_ENCODED_OK(er);
}
asn_enc_rval_t
BOOLEAN_encode_aper(asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
asn_enc_rval_t er;
(void)constraints;
if(!st) _ASN_ENCODE_FAILED;
per_put_few_bits(po, *st ? 1 : 0, 1);
_ASN_ENCODED_OK(er);
}

@ -11,7 +11,7 @@
/*
* ENUMERATED basic type description.
*/
static ber_tlv_tag_t asn_DEF_ENUMERATED_tags[] = {
static const ber_tlv_tag_t asn_DEF_ENUMERATED_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
};
asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
@ -26,6 +26,8 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
INTEGER_encode_xer,
ENUMERATED_decode_uper, /* Unaligned PER decoder */
ENUMERATED_encode_uper, /* Unaligned PER encoder */
ENUMERATED_decode_aper, /* Aligned PER decoder */
ENUMERATED_encode_aper, /* Aligned PER encoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_ENUMERATED_tags,
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
@ -57,6 +59,27 @@ ENUMERATED_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td
return rval;
}
asn_dec_rval_t
ENUMERATED_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
asn_dec_rval_t rval;
ENUMERATED_t *st = (ENUMERATED_t *)*sptr;
long value;
void *vptr = &value;
if(!st) {
st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st)));
if(!st) _ASN_DECODE_FAILED;
}
rval = NativeEnumerated_decode_aper(opt_codec_ctx, td, constraints,
(void **)&vptr, pd);
if(rval.code == RC_OK)
if(asn_long2INTEGER(st, value))
rval.code = RC_FAIL;
return rval;
}
asn_enc_rval_t
ENUMERATED_encode_uper(asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
@ -69,3 +92,14 @@ ENUMERATED_encode_uper(asn_TYPE_descriptor_t *td,
return NativeEnumerated_encode_uper(td, constraints, &value, po);
}
asn_enc_rval_t
ENUMERATED_encode_aper(asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
ENUMERATED_t *st = (ENUMERATED_t *)sptr;
long value;
if(asn_INTEGER2long(st, &value))
_ASN_ENCODE_FAILED;
return NativeEnumerated_encode_aper(td, constraints, &value, po);
}

@ -8,7 +8,7 @@
/*
* GeneralString basic type description.
*/
static ber_tlv_tag_t asn_DEF_GeneralString_tags[] = {
static const ber_tlv_tag_t asn_DEF_GeneralString_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (27 << 2)), /* [UNIVERSAL 27] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
};
@ -24,6 +24,8 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
OCTET_STRING_encode_xer,
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_uper,
OCTET_STRING_decode_aper,
OCTET_STRING_encode_aper,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)

@ -14,7 +14,7 @@
#include <time.h>
#endif /* __CYGWIN__ */
#if defined(WIN32)
#if defined(_WIN32)
#pragma message( "PLEASE STOP AND READ!")
#pragma message( " localtime_r is implemented via localtime(), which may be not thread-safe.")
#pragma message( " gmtime_r is implemented via gmtime(), which may be not thread-safe.")
@ -41,7 +41,7 @@ static struct tm *gmtime_r(const time_t *tloc, struct tm *result) {
#define putenv(c) _putenv(c)
#define _EMULATE_TIMEGM
#endif /* WIN32 */
#endif /* _WIN32 */
#if defined(sun) || defined(_sun_) || defined(__solaris__)
#define _EMULATE_TIMEGM
@ -67,6 +67,14 @@ static struct tm *gmtime_r(const time_t *tloc, struct tm *result) {
#define GMTOFF(tm) (-timezone)
#endif /* HAVE_TM_GMTOFF */
#if defined(_WIN32)
#pragma message( "PLEASE STOP AND READ!")
#pragma message( " timegm() is implemented via getenv(\"TZ\")/setenv(\"TZ\"), which may be not thread-safe.")
#pragma message( " ")
#pragma message( " You must fix the code by inserting appropriate locking")
#pragma message( " if you want to use asn_GT2time() or asn_UT2time().")
#pragma message( "PLEASE STOP AND READ!")
#else
#if (defined(_EMULATE_TIMEGM) || !defined(HAVE_TM_GMTOFF))
#warning "PLEASE STOP AND READ!"
#warning " timegm() is implemented via getenv(\"TZ\")/setenv(\"TZ\"), which may be not thread-safe."
@ -75,6 +83,7 @@ static struct tm *gmtime_r(const time_t *tloc, struct tm *result) {
#warning " if you want to use asn_GT2time() or asn_UT2time()."
#warning "PLEASE STOP AND READ!"
#endif /* _EMULATE_TIMEGM */
#endif
/*
* Override our GMTOFF decision for other known platforms.
@ -128,6 +137,7 @@ static long GMTOFF(struct tm a){
tzset(); \
} while(0); } while(0);
#ifndef HAVE_TIMEGM
#ifdef _EMULATE_TIMEGM
static time_t timegm(struct tm *tm) {
time_t tloc;
@ -138,6 +148,7 @@ static time_t timegm(struct tm *tm) {
return tloc;
}
#endif /* _EMULATE_TIMEGM */
#endif
#ifndef __ASN_INTERNAL_TEST_MODE__
@ -145,7 +156,7 @@ static time_t timegm(struct tm *tm) {
/*
* GeneralizedTime basic type description.
*/
static ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {
static const ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (24 << 2)), /* [UNIVERSAL 24] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
@ -167,6 +178,8 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
GeneralizedTime_encode_xer,
OCTET_STRING_decode_uper,
OCTET_STRING_encode_uper,
OCTET_STRING_decode_aper,
OCTET_STRING_encode_aper,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
@ -314,13 +327,14 @@ asn_GT2time_prec(const GeneralizedTime_t *st, int *frac_value, int frac_digits,
while(fd > frac_digits)
fv /= 10, fd--;
while(fd < frac_digits) {
int new_fv = fv * 10;
if(new_fv / 10 != fv) {
if(fv < INT_MAX / 10) {
fv *= 10;
fd++;
} else {
/* Too long precision request */
fv = 0;
break;
}
fv = new_fv, fd++;
}
*frac_value = fv;
@ -441,16 +455,15 @@ asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, int *frac_digits,
*/
for(buf++; buf < end; buf++) {
int v = *buf;
int new_fvalue;
/* GCC 4.x is being too smart without volatile */
switch(v) {
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
new_fvalue = fvalue * 10 + (v - 0x30);
if(new_fvalue / 10 != fvalue) {
/* Not enough precision, ignore */
} else {
fvalue = new_fvalue;
if(fvalue < INT_MAX/10) {
fvalue = fvalue * 10 + (v - 0x30);
fdigits++;
} else {
/* Not enough precision, ignore */
}
continue;
default: