From 71b96b598206160a95522c2c7bfe49b524d5463a Mon Sep 17 00:00:00 2001 From: v0-e Date: Fri, 2 Feb 2024 10:17:23 +0000 Subject: [PATCH 1/3] copy: Implementation for all types --- asn1-tools/unber/libasn1_unber_tool.c | 9 +++++ skeletons/ANY.c | 1 + skeletons/ANY.h | 1 + skeletons/BIT_STRING.c | 35 +++++++++++++++++ skeletons/BIT_STRING.h | 1 + skeletons/BMPString.c | 1 + skeletons/BMPString.h | 1 + skeletons/BOOLEAN.c | 27 +++++++++++++ skeletons/BOOLEAN.h | 1 + skeletons/ENUMERATED.c | 1 + skeletons/ENUMERATED.h | 1 + skeletons/GeneralString.c | 1 + skeletons/GeneralString.h | 1 + skeletons/GeneralizedTime.c | 1 + skeletons/GeneralizedTime.h | 1 + skeletons/GraphicString.c | 1 + skeletons/GraphicString.h | 1 + skeletons/IA5String.c | 1 + skeletons/IA5String.h | 1 + skeletons/INTEGER.c | 38 ++++++++++++++++++ skeletons/INTEGER.h | 1 + skeletons/ISO646String.c | 1 + skeletons/ISO646String.h | 1 + skeletons/NULL.c | 13 +++++++ skeletons/NULL.h | 1 + skeletons/NativeEnumerated.c | 1 + skeletons/NativeEnumerated.h | 1 + skeletons/NativeInteger.c | 28 ++++++++++++++ skeletons/NativeInteger.h | 1 + skeletons/NativeReal.c | 30 ++++++++++++++ skeletons/NativeReal.h | 1 + skeletons/NumericString.c | 1 + skeletons/NumericString.h | 1 + skeletons/OBJECT_IDENTIFIER.c | 1 + skeletons/OBJECT_IDENTIFIER.h | 1 + skeletons/OCTET_STRING.c | 38 ++++++++++++++++++ skeletons/OCTET_STRING.h | 1 + skeletons/OPEN_TYPE.c | 1 + skeletons/OPEN_TYPE.h | 1 + skeletons/ObjectDescriptor.c | 1 + skeletons/PrintableString.c | 1 + skeletons/PrintableString.h | 1 + skeletons/REAL.c | 36 +++++++++++++++++ skeletons/REAL.h | 1 + skeletons/RELATIVE-OID.c | 1 + skeletons/RELATIVE-OID.h | 1 + skeletons/T61String.c | 1 + skeletons/T61String.h | 1 + skeletons/TeletexString.c | 1 + skeletons/TeletexString.h | 1 + skeletons/UTCTime.c | 1 + skeletons/UTCTime.h | 1 + skeletons/UTF8String.c | 1 + skeletons/UTF8String.h | 1 + skeletons/UniversalString.c | 1 + skeletons/UniversalString.h | 1 + skeletons/VideotexString.c | 1 + skeletons/VideotexString.h | 1 + skeletons/VisibleString.c | 1 + skeletons/VisibleString.h | 1 + skeletons/constr_CHOICE.c | 54 ++++++++++++++++++++++++++ skeletons/constr_CHOICE.h | 1 + skeletons/constr_SEQUENCE.c | 51 ++++++++++++++++++++++++ skeletons/constr_SEQUENCE.h | 1 + skeletons/constr_SEQUENCE_OF.c | 1 + skeletons/constr_SEQUENCE_OF.h | 1 + skeletons/constr_SET.c | 51 ++++++++++++++++++++++++ skeletons/constr_SET.h | 1 + skeletons/constr_SET_OF.c | 56 +++++++++++++++++++++++++++ skeletons/constr_SET_OF.h | 1 + skeletons/constr_TYPE.h | 11 ++++++ 71 files changed, 534 insertions(+) diff --git a/asn1-tools/unber/libasn1_unber_tool.c b/asn1-tools/unber/libasn1_unber_tool.c index cb3838bd6..0985261a3 100644 --- a/asn1-tools/unber/libasn1_unber_tool.c +++ b/asn1-tools/unber/libasn1_unber_tool.c @@ -866,6 +866,15 @@ OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *a, return 0; } +int +OCTET_STRING_copy(const asn_TYPE_descriptor_t *td, void **a, + const void *b) { + (void)td; + (void)a; + (void)b; + return 0; +} + intmax_t asn_random_between(intmax_t a, intmax_t b) { (void)b; diff --git a/skeletons/ANY.c b/skeletons/ANY.c index 19e552bba..3cbe1e272 100644 --- a/skeletons/ANY.c +++ b/skeletons/ANY.c @@ -18,6 +18,7 @@ asn_TYPE_operation_t asn_OP_ANY = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, OCTET_STRING_encode_der, diff --git a/skeletons/ANY.h b/skeletons/ANY.h index 10b4a9638..6434aab71 100644 --- a/skeletons/ANY.h +++ b/skeletons/ANY.h @@ -29,6 +29,7 @@ extern asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define ANY_compare OCTET_STRING_compare +#define ANY_copy OCTET_STRING_copy #define ANY_constraint asn_generic_no_constraint diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c index 3babea53e..208ac14c7 100644 --- a/skeletons/BIT_STRING.c +++ b/skeletons/BIT_STRING.c @@ -24,6 +24,7 @@ asn_TYPE_operation_t asn_OP_BIT_STRING = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ BIT_STRING_compare, + BIT_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ @@ -213,3 +214,37 @@ BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, return 1; } } + +int +BIT_STRING_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + const asn_OCTET_STRING_specifics_t *specs = td->specifics; + BIT_STRING_t *a = (BIT_STRING_t *)*aptr; + const BIT_STRING_t *b = (const BIT_STRING_t *)bptr; + + if(!b) { + if(a) { + FREEMEM(a->buf); + FREEMEM(a); + *aptr = 0; + } + return 0; + } + + if(!a) { + a = *aptr = CALLOC(1, specs->struct_size); + if(!a) return -1; + } + + uint8_t* buf = MALLOC(b->size + 1); + if(!buf) return -1; + memcpy(buf, b->buf, b->size); + buf[b->size] = 0; + + FREEMEM(a->buf); + a->buf = buf; + a->size = b->size; + a->bits_unused = b->bits_unused; + + return 0; +} diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h index 6d103575d..0b71feb7b 100644 --- a/skeletons/BIT_STRING.h +++ b/skeletons/BIT_STRING.h @@ -31,6 +31,7 @@ asn_struct_print_f BIT_STRING_print; /* Human-readable output */ #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f BIT_STRING_compare; +asn_struct_copy_f BIT_STRING_copy; asn_constr_check_f BIT_STRING_constraint; diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c index ec7fbd4be..177d37df4 100644 --- a/skeletons/BMPString.c +++ b/skeletons/BMPString.c @@ -32,6 +32,7 @@ asn_TYPE_operation_t asn_OP_BMPString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, OCTET_STRING_encode_der, diff --git a/skeletons/BMPString.h b/skeletons/BMPString.h index 1863ecab7..3b32cf3c8 100644 --- a/skeletons/BMPString.h +++ b/skeletons/BMPString.h @@ -28,6 +28,7 @@ asn_struct_print_f BMPString_print; /* Human-readable output */ #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define BMPString_compare OCTET_STRING_compare +#define BMPString_copy OCTET_STRING_copy asn_constr_check_f BMPString_constraint; diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c index f284ab341..7075f095b 100644 --- a/skeletons/BOOLEAN.c +++ b/skeletons/BOOLEAN.c @@ -19,6 +19,7 @@ asn_TYPE_operation_t asn_OP_BOOLEAN = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ BOOLEAN_compare, + BOOLEAN_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) BOOLEAN_decode_ber, BOOLEAN_encode_der, @@ -128,3 +129,29 @@ BOOLEAN_compare(const asn_TYPE_descriptor_t *td, const void *aptr, return 1; } } + +int +BOOLEAN_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + BOOLEAN_t *a = *aptr; + const BOOLEAN_t *b = bptr; + + (void)td; + + if(!b) { + if(a) { + FREEMEM(a); + *aptr = 0; + } + return 0; + } + + if(!a) { + a = *aptr = MALLOC(sizeof(BOOLEAN_t)); + if(!a) return -1; + } + + *a = *b; + + return 0; +} diff --git a/skeletons/BOOLEAN.h b/skeletons/BOOLEAN.h index 6eaefdf7e..8b9b496b4 100644 --- a/skeletons/BOOLEAN.h +++ b/skeletons/BOOLEAN.h @@ -28,6 +28,7 @@ asn_struct_print_f BOOLEAN_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f BOOLEAN_compare; +asn_struct_copy_f BOOLEAN_copy; #define BOOLEAN_constraint asn_generic_no_constraint diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c index c3df5029c..97bc9b1eb 100644 --- a/skeletons/ENUMERATED.c +++ b/skeletons/ENUMERATED.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_ENUMERATED = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ INTEGER_compare, /* Implemented in terms of INTEGER */ + INTEGER_copy, /* Implemented in terms of INTEGER */ #if !defined(ASN_DISABLE_BER_SUPPORT) ber_decode_primitive, INTEGER_encode_der, /* Implemented in terms of INTEGER */ diff --git a/skeletons/ENUMERATED.h b/skeletons/ENUMERATED.h index b9a07d0b9..b1519030b 100644 --- a/skeletons/ENUMERATED.h +++ b/skeletons/ENUMERATED.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_ENUMERATED; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define ENUMERATED_compare INTEGER_compare +#define ENUMERATED_copy INTEGER_copy #define ENUMERATED_constraint asn_generic_no_constraint diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c index 2555d2211..fe77e64fc 100644 --- a/skeletons/GeneralString.c +++ b/skeletons/GeneralString.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_GeneralString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/GeneralString.h b/skeletons/GeneralString.h index ed3082e42..2815245cd 100644 --- a/skeletons/GeneralString.h +++ b/skeletons/GeneralString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_GeneralString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define GeneralString_compare OCTET_STRING_compare +#define GeneralString_copy OCTET_STRING_copy #define GeneralString_constraint asn_generic_unknown_constraint diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c index 633d2c6f4..f0baa0afd 100644 --- a/skeletons/GeneralizedTime.c +++ b/skeletons/GeneralizedTime.c @@ -182,6 +182,7 @@ asn_TYPE_operation_t asn_OP_GeneralizedTime = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ GeneralizedTime_compare, + GeneralizedTime_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ GeneralizedTime_encode_der, diff --git a/skeletons/GeneralizedTime.h b/skeletons/GeneralizedTime.h index ffe78ccc6..8a00738d5 100644 --- a/skeletons/GeneralizedTime.h +++ b/skeletons/GeneralizedTime.h @@ -23,6 +23,7 @@ asn_struct_print_f GeneralizedTime_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f GeneralizedTime_compare; +#define GeneralizedTime_copy OCTET_STRING_copy asn_constr_check_f GeneralizedTime_constraint; diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c index 5a885ccbe..0f2fc39ba 100644 --- a/skeletons/GraphicString.c +++ b/skeletons/GraphicString.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_GraphicString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/GraphicString.h b/skeletons/GraphicString.h index cf1ad39a9..9368e507b 100644 --- a/skeletons/GraphicString.h +++ b/skeletons/GraphicString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_GraphicString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define GraphicString_compare OCTET_STRING_compare +#define GraphicString_copy OCTET_STRING_copy #define GraphicString_constraint asn_generic_unknown_constraint diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c index a3640e6ef..5266f8918 100644 --- a/skeletons/IA5String.c +++ b/skeletons/IA5String.c @@ -27,6 +27,7 @@ asn_TYPE_operation_t asn_OP_IA5String = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/IA5String.h b/skeletons/IA5String.h index e2f067c6e..0a408a526 100644 --- a/skeletons/IA5String.h +++ b/skeletons/IA5String.h @@ -26,6 +26,7 @@ extern asn_TYPE_operation_t asn_OP_IA5String; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define IA5String_compare OCTET_STRING_compare +#define IA5String_copy OCTET_STRING_copy asn_constr_check_f IA5String_constraint; diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c index 80ddde996..f811c23c8 100644 --- a/skeletons/INTEGER.c +++ b/skeletons/INTEGER.c @@ -22,6 +22,7 @@ asn_TYPE_operation_t asn_OP_INTEGER = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ INTEGER_compare, + INTEGER_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) ber_decode_primitive, INTEGER_encode_der, @@ -738,3 +739,40 @@ INTEGER_compare(const asn_TYPE_descriptor_t *td, const void *aptr, } } + +int +INTEGER_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + (void)td; + INTEGER_t *a = *aptr; + const INTEGER_t *b = bptr; + + if(!b) { + if(a) { + FREEMEM(a->buf); + FREEMEM(a); + *aptr = 0; + } + return 0; + } + + if(!a) { + a = *aptr = CALLOC(1, sizeof(*a)); + if(!a) return -1; + } + + if(b->size) { + uint8_t* buf = MALLOC(b->size); + if(!buf) return -1; + memcpy(buf, b->buf, b->size); + FREEMEM(a->buf); + a->buf = buf; + a->size = b->size; + } else { + FREEMEM(a->buf); + a->buf = 0; + a->size = 0; + } + + return 0; +} diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h index 952603532..aa24be18c 100644 --- a/skeletons/INTEGER.h +++ b/skeletons/INTEGER.h @@ -47,6 +47,7 @@ asn_struct_print_f INTEGER_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f INTEGER_compare; +asn_struct_copy_f INTEGER_copy; #define INTEGER_constraint asn_generic_no_constraint diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c index a552d5e84..b5eeb78fc 100644 --- a/skeletons/ISO646String.c +++ b/skeletons/ISO646String.c @@ -27,6 +27,7 @@ asn_TYPE_operation_t asn_OP_ISO646String = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/ISO646String.h b/skeletons/ISO646String.h index 9cafa6ff9..76382d71d 100644 --- a/skeletons/ISO646String.h +++ b/skeletons/ISO646String.h @@ -24,6 +24,7 @@ extern asn_TYPE_operation_t asn_OP_ISO646String; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define ISO646String_compare OCTET_STRING_compare +#define ISO646String_copy OCTET_STRING_copy #define ISO646String_constraint VisibleString_constraint diff --git a/skeletons/NULL.c b/skeletons/NULL.c index b239dd051..372929147 100644 --- a/skeletons/NULL.c +++ b/skeletons/NULL.c @@ -19,6 +19,7 @@ asn_TYPE_operation_t asn_OP_NULL = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ NULL_compare, + NULL_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) NULL_decode_ber, NULL_encode_der, /* Special handling of DER encoding */ @@ -113,3 +114,15 @@ NULL_compare(const asn_TYPE_descriptor_t *td, const void *a, const void *b) { (void)b; return 0; } + +int +NULL_copy(const asn_TYPE_descriptor_t *td, void **a, const void *b) { + (void)td; + + if(b && !*a) { + *a = CALLOC(1, sizeof(NULL_t)); + if (!*a) return -1; + } + + return 0; +} diff --git a/skeletons/NULL.h b/skeletons/NULL.h index 6e70ec51e..ca9d6fab9 100644 --- a/skeletons/NULL.h +++ b/skeletons/NULL.h @@ -27,6 +27,7 @@ asn_struct_print_f NULL_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f NULL_compare; +asn_struct_copy_f NULL_copy; #define NULL_constraint asn_generic_no_constraint diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c index 9749ac5bd..148cb8fb4 100644 --- a/skeletons/NativeEnumerated.c +++ b/skeletons/NativeEnumerated.c @@ -26,6 +26,7 @@ asn_TYPE_operation_t asn_OP_NativeEnumerated = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ NativeInteger_compare, + NativeInteger_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) NativeInteger_decode_ber, NativeInteger_encode_der, diff --git a/skeletons/NativeEnumerated.h b/skeletons/NativeEnumerated.h index 557d5a813..8c045e524 100644 --- a/skeletons/NativeEnumerated.h +++ b/skeletons/NativeEnumerated.h @@ -29,6 +29,7 @@ extern asn_TYPE_operation_t asn_OP_NativeEnumerated; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define NativeEnumerated_compare NativeInteger_compare +#define NativeEnumerated_copy NativeInteger_copy #define NativeEnumerated_constraint asn_generic_no_constraint diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c index 5483b2b75..8957b65c3 100644 --- a/skeletons/NativeInteger.c +++ b/skeletons/NativeInteger.c @@ -27,6 +27,7 @@ asn_TYPE_operation_t asn_OP_NativeInteger = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ NativeInteger_compare, + NativeInteger_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) NativeInteger_decode_ber, NativeInteger_encode_der, @@ -152,3 +153,30 @@ NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const v return 1; } } + +int +NativeInteger_copy(const asn_TYPE_descriptor_t *td, void **aptr, const void *bptr) { + unsigned long *a = *aptr; + const unsigned long *b = bptr; + + (void)td; + + /* Check if source has data */ + if(!b) { + /* Clear destination */ + if(a) { + FREEMEM(a); + *aptr = 0; + } + return 0; + } + + if(!a) { + a = *aptr = MALLOC(sizeof(*a)); + if(!a) return -1; + } + + *a = *b; + + return 0; +} diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h index 42d435071..352926b41 100644 --- a/skeletons/NativeInteger.h +++ b/skeletons/NativeInteger.h @@ -29,6 +29,7 @@ asn_struct_print_f NativeInteger_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f NativeInteger_compare; +asn_struct_copy_f NativeInteger_copy; #define NativeInteger_constraint asn_generic_no_constraint diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c index 97bcccdf3..f1b245979 100644 --- a/skeletons/NativeReal.c +++ b/skeletons/NativeReal.c @@ -46,6 +46,7 @@ asn_TYPE_operation_t asn_OP_NativeReal = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ NativeReal_compare, + NativeReal_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) NativeReal_decode_ber, NativeReal_encode_der, @@ -149,6 +150,35 @@ NativeReal_compare(const asn_TYPE_descriptor_t *td, const void *aptr, } } +int +NativeReal_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + size_t float_size = NativeReal__float_size(td); + void *a = *aptr; + const void *b = bptr; + + if(!b) { + if(a) { + FREEMEM(a); + *aptr = 0; + } + return 0; + } + + if(!a) { + a = *aptr = MALLOC(float_size); + if(!a) return -1; + } + + if(float_size == sizeof(float)) { + *(float *)a = *(const float *)b; + } else { + *(double *)a = *(const double *)b; + } + + return 0; +} + void NativeReal_free(const asn_TYPE_descriptor_t *td, void *ptr, enum asn_struct_free_method method) { diff --git a/skeletons/NativeReal.h b/skeletons/NativeReal.h index 063865b24..2007fbde7 100644 --- a/skeletons/NativeReal.h +++ b/skeletons/NativeReal.h @@ -37,6 +37,7 @@ asn_struct_print_f NativeReal_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f NativeReal_compare; +asn_struct_copy_f NativeReal_copy; #define NativeReal_constraint asn_generic_no_constraint diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c index 10b2c3165..a80eaca7a 100644 --- a/skeletons/NumericString.c +++ b/skeletons/NumericString.c @@ -47,6 +47,7 @@ asn_TYPE_operation_t asn_OP_NumericString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/NumericString.h b/skeletons/NumericString.h index 2a87e7a6f..c0c121017 100644 --- a/skeletons/NumericString.h +++ b/skeletons/NumericString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_NumericString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define NumericString_compare OCTET_STRING_compare +#define NumericString_copy OCTET_STRING_copy asn_constr_check_f NumericString_constraint; diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index d009256e9..c5ab38ea3 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -24,6 +24,7 @@ asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, /* Implemented in terms of a string comparison */ + OCTET_STRING_copy, /* Implemented in terms of a string copy */ #if !defined(ASN_DISABLE_BER_SUPPORT) ber_decode_primitive, der_encode_primitive, diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h index 4d8492352..cef8c6cde 100644 --- a/skeletons/OBJECT_IDENTIFIER.h +++ b/skeletons/OBJECT_IDENTIFIER.h @@ -32,6 +32,7 @@ asn_struct_print_f OBJECT_IDENTIFIER_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define OBJECT_IDENTIFIER_compare OCTET_STRING_compare +#define OBJECT_IDENTIFIER_copy OCTET_STRING_copy asn_constr_check_f OBJECT_IDENTIFIER_constraint; diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index 5935c18c7..fc983b4e2 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -26,6 +26,7 @@ asn_TYPE_operation_t asn_OP_OCTET_STRING = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, OCTET_STRING_encode_der, @@ -249,6 +250,43 @@ OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, } +int +OCTET_STRING_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + const asn_OCTET_STRING_specifics_t *specs = + td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + OCTET_STRING_t *a = *aptr; + const OCTET_STRING_t *b = bptr; + + if(!b) { + if(a) { + FREEMEM(a->buf); + a->buf = 0; + a->size = 0; + FREEMEM(a); + } + *aptr = 0; + return 0; + } + + if(!a) { + a = *aptr = (OCTET_STRING_t *)CALLOC(1, specs->struct_size); + if(!a) return -1; + } + + void *buf = MALLOC(b->size + 1); + if(!buf) return -1; + memcpy(buf, b->buf, b->size); + ((uint8_t *)buf)[b->size] = '\0'; + + FREEMEM(a->buf); + a->buf = (uint8_t *)buf; + a->size = b->size; + + return 0; +} + #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) int OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h index eca41881d..1340865da 100644 --- a/skeletons/OCTET_STRING.h +++ b/skeletons/OCTET_STRING.h @@ -29,6 +29,7 @@ asn_struct_print_f OCTET_STRING_print_utf8; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f OCTET_STRING_compare; +asn_struct_copy_f OCTET_STRING_copy; #define OCTET_STRING_constraint asn_generic_no_constraint diff --git a/skeletons/OPEN_TYPE.c b/skeletons/OPEN_TYPE.c index b80c3997c..75f9b9585 100644 --- a/skeletons/OPEN_TYPE.c +++ b/skeletons/OPEN_TYPE.c @@ -14,6 +14,7 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OPEN_TYPE_compare, + OPEN_TYPE_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OPEN_TYPE_decode_ber, OPEN_TYPE_encode_der, diff --git a/skeletons/OPEN_TYPE.h b/skeletons/OPEN_TYPE.h index e9eff48b7..c4b5d1b81 100644 --- a/skeletons/OPEN_TYPE.h +++ b/skeletons/OPEN_TYPE.h @@ -33,6 +33,7 @@ extern "C" { #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define OPEN_TYPE_compare CHOICE_compare +#define OPEN_TYPE_copy CHOICE_copy #define OPEN_TYPE_constraint CHOICE_constraint diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c index 72aaa0449..4b3560af1 100644 --- a/skeletons/ObjectDescriptor.c +++ b/skeletons/ObjectDescriptor.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_ObjectDescriptor = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c index 80b1769cb..da4dabc72 100644 --- a/skeletons/PrintableString.c +++ b/skeletons/PrintableString.c @@ -57,6 +57,7 @@ asn_TYPE_operation_t asn_OP_PrintableString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/PrintableString.h b/skeletons/PrintableString.h index 030da708e..aa37f39a3 100644 --- a/skeletons/PrintableString.h +++ b/skeletons/PrintableString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_PrintableString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define PrintableString_compare OCTET_STRING_compare +#define PrintableString_copy OCTET_STRING_copy asn_constr_check_f PrintableString_constraint; diff --git a/skeletons/REAL.c b/skeletons/REAL.c index 00c7d27b5..5ff83e44f 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -62,6 +62,7 @@ asn_TYPE_operation_t asn_OP_REAL = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ REAL_compare, + REAL_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) ber_decode_primitive, der_encode_primitive, @@ -361,6 +362,41 @@ REAL_compare(const asn_TYPE_descriptor_t *td, const void *aptr, } } +int +REAL_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + REAL_t *a = *aptr; + const REAL_t *b = bptr; + + (void)td; + + if(!b) { + if(a) { + FREEMEM(a->buf); + FREEMEM(a); + *aptr = 0; + } + return 0; + } + + if(!a) { + a = *aptr = CALLOC(1, sizeof(*a)); + if(!a) return -1; + } + + if(b->size) { + uint8_t* buf = (uint8_t*)MALLOC(b->size); + if(!buf) return -1; + memcpy(buf, b->buf, b->size); + + FREEMEM(a->buf); + a->buf = buf; + a->size = b->size; + } + + return 0; +} + int asn_REAL2double(const REAL_t *st, double *dbl_value) { unsigned int octv; diff --git a/skeletons/REAL.h b/skeletons/REAL.h index e7ecca3e9..2aa470ed8 100644 --- a/skeletons/REAL.h +++ b/skeletons/REAL.h @@ -54,6 +54,7 @@ asn_struct_print_f REAL_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f REAL_compare; +asn_struct_copy_f REAL_copy; #define REAL_constraint asn_generic_no_constraint diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index 5dd0a0d13..d9bcbac6d 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -22,6 +22,7 @@ asn_TYPE_operation_t asn_OP_RELATIVE_OID = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, /* Implemented in terms of opaque comparison */ + OCTET_STRING_copy, /* Implemented in terms of opaque copy */ #if !defined(ASN_DISABLE_BER_SUPPORT) ber_decode_primitive, der_encode_primitive, diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h index ce8f1f939..4246feae5 100644 --- a/skeletons/RELATIVE-OID.h +++ b/skeletons/RELATIVE-OID.h @@ -28,6 +28,7 @@ asn_struct_print_f RELATIVE_OID_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define RELATIVE_OID_compare OCTET_STRING_compare +#define RELATIVE_OID_copy OCTET_STRING_copy #define RELATIVE_OID_constraint asn_generic_no_constraint diff --git a/skeletons/T61String.c b/skeletons/T61String.c index 5a6b056b7..a29f0cba6 100644 --- a/skeletons/T61String.c +++ b/skeletons/T61String.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_T61String = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/T61String.h b/skeletons/T61String.h index 5c40b9186..640b1f55a 100644 --- a/skeletons/T61String.h +++ b/skeletons/T61String.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_T61String; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define T61String_compare OCTET_STRING_compare +#define T61String_copy OCTET_STRING_copy #define T61String_constraint asn_generic_unknown_constraint diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c index c2defc2cc..25fa6967f 100644 --- a/skeletons/TeletexString.c +++ b/skeletons/TeletexString.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_TeletexString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/TeletexString.h b/skeletons/TeletexString.h index dd8131664..e8ec03132 100644 --- a/skeletons/TeletexString.h +++ b/skeletons/TeletexString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_TeletexString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define TeletexString_compare OCTET_STRING_compare +#define TeletexString_copy OCTET_STRING_copy #define TeletexString_constraint asn_generic_unknown_constraint diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c index 736e52648..0ab547dac 100644 --- a/skeletons/UTCTime.c +++ b/skeletons/UTCTime.c @@ -38,6 +38,7 @@ asn_TYPE_operation_t asn_OP_UTCTime = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ UTCTime_compare, + UTCTime_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ diff --git a/skeletons/UTCTime.h b/skeletons/UTCTime.h index 5ccdb5060..bdcf1a92f 100644 --- a/skeletons/UTCTime.h +++ b/skeletons/UTCTime.h @@ -23,6 +23,7 @@ asn_struct_print_f UTCTime_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f UTCTime_compare; +#define UTCTime_copy OCTET_STRING_copy asn_constr_check_f UTCTime_constraint; diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c index fc4222a01..bb627d988 100644 --- a/skeletons/UTF8String.c +++ b/skeletons/UTF8String.c @@ -21,6 +21,7 @@ asn_TYPE_operation_t asn_OP_UTF8String = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/UTF8String.h b/skeletons/UTF8String.h index b70927f6a..e1fefeee6 100644 --- a/skeletons/UTF8String.h +++ b/skeletons/UTF8String.h @@ -23,6 +23,7 @@ asn_struct_print_f UTF8String_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define UTF8String_compare OCTET_STRING_compare +#define UTF8String_copy OCTET_STRING_copy asn_constr_check_f UTF8String_constraint; diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c index fb521fa2d..4246e1b30 100644 --- a/skeletons/UniversalString.c +++ b/skeletons/UniversalString.c @@ -32,6 +32,7 @@ asn_TYPE_operation_t asn_OP_UniversalString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, OCTET_STRING_encode_der, diff --git a/skeletons/UniversalString.h b/skeletons/UniversalString.h index 862065bd2..3bddfbfb4 100644 --- a/skeletons/UniversalString.h +++ b/skeletons/UniversalString.h @@ -24,6 +24,7 @@ asn_struct_print_f UniversalString_print; /* Human-readable output */ #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define UniversalString_compare OCTET_STRING_compare +#define UniversalString_copy OCTET_STRING_copy asn_constr_check_f UniversalString_constraint; diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c index 2d44e4fe0..0a5a15709 100644 --- a/skeletons/VideotexString.c +++ b/skeletons/VideotexString.c @@ -20,6 +20,7 @@ asn_TYPE_operation_t asn_OP_VideotexString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/VideotexString.h b/skeletons/VideotexString.h index 37d63117d..ea991dfc8 100644 --- a/skeletons/VideotexString.h +++ b/skeletons/VideotexString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_VideotexString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define VideotexString_compare OCTET_STRING_compare +#define VideotexString_copy OCTET_STRING_copy #define VideotexString_constraint asn_generic_unknown_constraint diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c index 4e26366b5..f583b6203 100644 --- a/skeletons/VisibleString.c +++ b/skeletons/VisibleString.c @@ -27,6 +27,7 @@ asn_TYPE_operation_t asn_OP_VisibleString = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ OCTET_STRING_compare, + OCTET_STRING_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, diff --git a/skeletons/VisibleString.h b/skeletons/VisibleString.h index a3a54c5ad..013f12f0c 100644 --- a/skeletons/VisibleString.h +++ b/skeletons/VisibleString.h @@ -23,6 +23,7 @@ extern asn_TYPE_operation_t asn_OP_VisibleString; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ #define VisibleString_compare OCTET_STRING_compare +#define VisibleString_copy OCTET_STRING_copy asn_constr_check_f VisibleString_constraint; diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index 2ddfeb406..2a20583a1 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -13,6 +13,7 @@ asn_TYPE_operation_t asn_OP_CHOICE = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ CHOICE_compare, + CHOICE_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) CHOICE_decode_ber, CHOICE_encode_der, @@ -314,6 +315,59 @@ CHOICE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bp } } +int +CHOICE_copy(const asn_TYPE_descriptor_t *td, void **aptr, const void *bptr) { + if(!td) return -1; + + void *st = *aptr; + const asn_CHOICE_specifics_t *specs = + (const asn_CHOICE_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm; /* CHOICE's element */ + int present; + int ret; + void *amemb; + void **amembp; + const void *bmemb; + + if(!bptr) { + if(st) { + ASN_STRUCT_FREE(*td, st); + *aptr = NULL; + } + return 0; + } + + if(!st) { + st = *aptr = CALLOC(1, specs->struct_size); + if(!st) return -1; + } + + present = _fetch_present_idx(bptr, + specs->pres_offset, specs->pres_size); + + if(present <= 0 && (unsigned)present > td->elements_count) return -1; + --present; + + elm = &td->elements[present]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + amembp = (void **)((char *)st + elm->memb_offset); + bmemb = *(const void* const*)((const char*)bptr + elm->memb_offset); + } else { + amemb = (char *)st + elm->memb_offset; + amembp = &amemb; + bmemb = (const void*)((const char*)bptr + elm->memb_offset); + } + ret = elm->type->op->copy_struct(elm->type, amembp, bmemb); + if (ret != 0) return ret; + + _set_present_idx(st, + specs->pres_offset, + specs->pres_size, present + 1); + + return 0; +} + /* * Return the 1-based choice variant presence index. * Returns 0 in case of error. diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h index 3d5ea7447..1bec3cab8 100644 --- a/skeletons/constr_CHOICE.h +++ b/skeletons/constr_CHOICE.h @@ -46,6 +46,7 @@ asn_struct_print_f CHOICE_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f CHOICE_compare; +asn_struct_copy_f CHOICE_copy; asn_constr_check_f CHOICE_constraint; diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index ab7fe3252..a77b68fac 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -14,6 +14,7 @@ asn_TYPE_operation_t asn_OP_SEQUENCE = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ SEQUENCE_compare, + SEQUENCE_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) SEQUENCE_decode_ber, SEQUENCE_encode_der, @@ -198,3 +199,53 @@ SEQUENCE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, return 0; } + +int +SEQUENCE_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + if(!td) return -1; + + const asn_SEQUENCE_specifics_t *specs = + (const asn_SEQUENCE_specifics_t *)td->specifics; + size_t edx; + void *st = *aptr; /* Target structure */ + + if(!bptr) { + if(st) { + SEQUENCE_free(td, st, 0); + *aptr = 0; + } + return 0; + } + + /* + * Create the target structure if it is not present already. + */ + if(st == 0) { + st = *aptr = CALLOC(1, specs->struct_size); + if(st == 0) return -1; + } + + for(edx = 0; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *amemb; + void **amembp; + const void *bmemb; + int ret; + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + amembp = (void **)((char *)st + elm->memb_offset); + bmemb = *(const void* const*)((const char*)bptr + elm->memb_offset); + } else { + amemb = (char *)st + elm->memb_offset; + amembp = &amemb; + bmemb = (const void*)((const char*)bptr + elm->memb_offset); + } + + ret = elm->type->op->copy_struct(elm->type, amembp, bmemb); + if(ret != 0) return ret; + } + + return 0; +} diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h index dca90628c..a3f50d112 100644 --- a/skeletons/constr_SEQUENCE.h +++ b/skeletons/constr_SEQUENCE.h @@ -51,6 +51,7 @@ asn_struct_print_f SEQUENCE_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f SEQUENCE_compare; +asn_struct_copy_f SEQUENCE_copy; asn_constr_check_f SEQUENCE_constraint; diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c index 622098862..6ec388857 100644 --- a/skeletons/constr_SEQUENCE_OF.c +++ b/skeletons/constr_SEQUENCE_OF.c @@ -15,6 +15,7 @@ asn_TYPE_operation_t asn_OP_SEQUENCE_OF = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ SEQUENCE_OF_compare, + SEQUENCE_OF_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) SEQUENCE_OF_decode_ber, SEQUENCE_OF_encode_der, diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h index 79589f13a..978ad8e2a 100644 --- a/skeletons/constr_SEQUENCE_OF.h +++ b/skeletons/constr_SEQUENCE_OF.h @@ -23,6 +23,7 @@ extern "C" { #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f SEQUENCE_OF_compare; +#define SEQUENCE_OF_copy SET_OF_copy #define SEQUENCE_OF_constraint SET_OF_constraint diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index baf56bbb2..1d9466ce8 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -14,6 +14,7 @@ asn_TYPE_operation_t asn_OP_SET = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ SET_compare, + SET_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) SET_decode_ber, SET_encode_der, @@ -216,3 +217,53 @@ SET_compare(const asn_TYPE_descriptor_t *td, const void *aptr, return 0; } + +int +SET_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + if(!td) return -1; + + const asn_SET_specifics_t *specs = + (const asn_SET_specifics_t *)td->specifics; + size_t edx; + void *st = *aptr; /* Target structure */ + + if(!bptr) { + if(st) { + SET_free(td, st, ASFM_FREE_EVERYTHING); + *aptr = 0; + } + return 0; + } + + /* + * Create the target structure if it is not present already. + */ + if(st == 0) { + st = *aptr = CALLOC(1, specs->struct_size); + if(st == 0) return -1; + } + + for(edx = 0; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *amemb; + void **amembp; + const void *bmemb; + int ret; + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + amembp = (void **)((char *)st + elm->memb_offset); + bmemb = *(const void* const*)((const char*)bptr + elm->memb_offset); + } else { + amemb = (char *)st + elm->memb_offset; + amembp = &amemb; + bmemb = (const void*)((const char*)bptr + elm->memb_offset); + } + + ret = elm->type->op->copy_struct(elm->type, amembp, bmemb); + if(ret != 0) return ret; + } + + return 0; +} diff --git a/skeletons/constr_SET.h b/skeletons/constr_SET.h index c695031dc..9dd447577 100644 --- a/skeletons/constr_SET.h +++ b/skeletons/constr_SET.h @@ -52,6 +52,7 @@ asn_struct_print_f SET_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f SET_compare; +asn_struct_copy_f SET_copy; asn_constr_check_f SET_constraint; diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index 6bbdeb789..f5cc3bac9 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -14,6 +14,7 @@ asn_TYPE_operation_t asn_OP_SET_OF = { 0, #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ SET_OF_compare, + SET_OF_copy, #if !defined(ASN_DISABLE_BER_SUPPORT) SET_OF_decode_ber, SET_OF_encode_der, @@ -371,3 +372,58 @@ SET_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr, return 0; } + +int +SET_OF_copy(const asn_TYPE_descriptor_t *td, void **aptr, + const void *bptr) { + if(!td) return -1; + + const asn_SET_OF_specifics_t *specs = + (const asn_SET_OF_specifics_t *)td->specifics; + void *st = *aptr; + + if(!bptr) { + if(*aptr) { + asn_set_empty(_A_SET_FROM_VOID(*aptr)); + *aptr = 0; + } + return 0; + } + + if(st == 0) { + st = *aptr = CALLOC(1, specs->struct_size); + if(st == 0) return -1; + } + + asn_anonymous_set_ *a = _A_SET_FROM_VOID(*aptr); + const asn_anonymous_set_ *b = _A_CSET_FROM_VOID(bptr); + + if(b->size) { + void *_new_arr; + _new_arr = REALLOC(a->array, b->size * sizeof(b->array[0])); + if(_new_arr) { + a->array = (void **)_new_arr; + a->size = b->size; + } else { + return -1; + } + a->count = b->count; + + for(int i = 0; i < b->count; i++) { + void *bmemb = b->array[i]; + if(bmemb) { + void *amemb = 0; + int ret; + ret = td->elements->type->op->copy_struct( + td->elements->type, + &amemb, bmemb); + if(ret != 0) return ret; + a->array[i] = amemb; + } else { + a->array[i] = 0; + } + } + } + + return 0; +} diff --git a/skeletons/constr_SET_OF.h b/skeletons/constr_SET_OF.h index 9a98be3f1..82ead586b 100644 --- a/skeletons/constr_SET_OF.h +++ b/skeletons/constr_SET_OF.h @@ -33,6 +33,7 @@ asn_struct_print_f SET_OF_print; #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */ asn_struct_compare_f SET_OF_compare; +asn_struct_copy_f SET_OF_copy; asn_constr_check_f SET_OF_constraint; diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h index dfb173440..94c0a37da 100644 --- a/skeletons/constr_TYPE.h +++ b/skeletons/constr_TYPE.h @@ -143,6 +143,16 @@ typedef int (asn_struct_compare_f)( const void *struct_A, const void *struct_B); +/* + * Copies struct B into struct A. + * Allocates memory for struct A, if necessary. + */ +typedef int (asn_struct_copy_f)( + const struct asn_TYPE_descriptor_s *type_descriptor, + void **struct_A, + const void *struct_B + ); + /* * Return the outmost tag of the type. * If the type is untagged CHOICE, the dynamic operation is performed. @@ -175,6 +185,7 @@ typedef struct asn_TYPE_operation_s { asn_struct_free_f *free_struct; /* Free the structure */ asn_struct_print_f *print_struct; /* Human readable output */ asn_struct_compare_f *compare_struct; /* Compare two structures */ + asn_struct_copy_f *copy_struct; /* Copy method */ ber_type_decoder_f *ber_decoder; /* Generic BER decoder */ der_type_encoder_f *der_encoder; /* Canonical DER encoder */ xer_type_decoder_f *xer_decoder; /* Generic XER decoder */ From c19e515fe78af843f33d5e7fc743d130a657b5f4 Mon Sep 17 00:00:00 2001 From: v0-e Date: Fri, 2 Feb 2024 10:19:44 +0000 Subject: [PATCH 2/3] copy: Add asn_copy() interface --- skeletons/constr_TYPE.c | 20 ++++++++++++++++++++ skeletons/constr_TYPE.h | 11 +++++++++++ 2 files changed, 31 insertions(+) diff --git a/skeletons/constr_TYPE.c b/skeletons/constr_TYPE.c index e634e750f..a9e6d0974 100644 --- a/skeletons/constr_TYPE.c +++ b/skeletons/constr_TYPE.c @@ -54,6 +54,26 @@ asn_fprint(FILE *stream, const asn_TYPE_descriptor_t *td, return fflush(stream); } +/* + * Copy a structuture. + */ +int +asn_copy(const asn_TYPE_descriptor_t *td, + void **struct_dst, const void *struct_src) { + + if(!td || !struct_dst || !struct_src) { + errno = EINVAL; + return -1; + } + + if(!td->op) { + errno = ENOSYS; + return -1; + } + + return td->op->copy_struct(td, struct_dst, struct_src); +} + /* Dump the data into the specified stdio stream */ static int _print2fp(const void *buffer, size_t size, void *app_key) { diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h index 94c0a37da..b64d5b5ea 100644 --- a/skeletons/constr_TYPE.h +++ b/skeletons/constr_TYPE.h @@ -302,6 +302,17 @@ int asn_fprint(FILE *stream, /* Destination stream descriptor */ const asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */ const void *struct_ptr); /* Structure to be printed */ +/* + * Copies a source structure (struct_src) into destination structure + * (struct_dst). Allocates memory for the destination structure, if necessary. + * RETURN VALUES: + * 0: Copy OK. + * -1: Problem copying the structure. + */ +int asn_copy(const asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */ + void **struct_dst, /* Structure to be populated */ + const void *struct_src); /* Structure to be copied */ + #ifdef __cplusplus } #endif From edfc7e7f7f6a2e98a7395b58d4797263b0966aea Mon Sep 17 00:00:00 2001 From: v0-e Date: Fri, 2 Feb 2024 16:28:56 +0000 Subject: [PATCH 3/3] copy: Add tests --- tests/tests-randomized/check-bundles.sh | 10 ++ tests/tests-randomized/random-test-driver.c | 84 ++++++++++++++- tests/tests-skeletons/Makefile.am | 5 + tests/tests-skeletons/check-copy.c | 107 ++++++++++++++++++++ 4 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 tests/tests-skeletons/check-copy.c diff --git a/tests/tests-randomized/check-bundles.sh b/tests/tests-randomized/check-bundles.sh index 61c1bbc75..35310c6de 100755 --- a/tests/tests-randomized/check-bundles.sh +++ b/tests/tests-randomized/check-bundles.sh @@ -187,6 +187,16 @@ compile_and_test() { return 3 fi + echo "Checking random data copy" + copy_check_cmd="${ASAN_ENV_FLAGS} ./random-test-driver -s ${rmax} ${encodings} -y" + echo "(${reproduce_make} && ${copy_check_cmd})" > .test-reproduce + if eval "$copy_check_cmd"; then + echo "Copy test OK" + else + { echo "RETRY:"; cat .test-reproduce ; } + return 3 + fi + echo "Generating new random data" rm -rf random-data cmd="${ASAN_ENV_FLAGS} UBSAN_OPTIONS=print_stacktrace=1" diff --git a/tests/tests-randomized/random-test-driver.c b/tests/tests-randomized/random-test-driver.c index e24f334e1..b61d23ad0 100644 --- a/tests/tests-randomized/random-test-driver.c +++ b/tests/tests-randomized/random-test-driver.c @@ -327,12 +327,85 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, size_t max_random_value_ enc.name); } +static void +check_copy_op(enum asn_transfer_syntax syntax, size_t max_random_value_size, int iterations, int debug) { + struct encoding_map enc; + + for(size_t i = 0; i < sizeof(encodings)/sizeof(encodings[0]); i++) { + enc = encodings[i]; + if(enc.syntax == syntax) { + fprintf(stderr, "Testing %d iterations of round-trip for %s\n", + iterations, enc.name); + break; + } + } + + for(int i = 0; i < iterations; i++) { + T_t *structure = 0; + T_t *new_structure = 0; + + if(asn_random_fill(&asn_DEF_T, (void **)&structure, + max_random_value_size) + == -1) { + assert(structure == 0); + fprintf(stderr, "Can't generate %d'th value, skipping\n", i); + continue; + } + assert(structure != 0); + + if(debug) { + fprintf(stderr, "Random structure %s:\n", + sizeof(ASN1_STR) > 60 ? "T" : ASN1_STR); + asn_fprint(stderr, &asn_DEF_T, structure); + xer_fprint(stderr, &asn_DEF_T, structure); + } + + int cr = asn_DEF_T.op->copy_struct(&asn_DEF_T, (void**)&new_structure, + structure); + if(cr != 0) { + fprintf(stderr, "Copying structure %s:\n", + sizeof(ASN1_STR) > 60 ? "T" : ASN1_STR); + asn_fprint(stderr, &asn_DEF_T, structure); + assert(cr == 0); + exit(EX_SOFTWARE); + } + assert(new_structure != 0); + + /* + * Confirm that we decoded the same data. + */ + int cmp = asn_DEF_T.op->compare_struct(&asn_DEF_T, structure, + new_structure); + if(cmp != 0 || debug) { + fprintf(stderr, "Random %s value:\n", ASN1_STR); + asn_fprint(stderr, &asn_DEF_T, structure); + xer_fprint(stderr, &asn_DEF_T, structure); + fprintf(stderr, "Copied %s value:\n", ASN1_STR); + asn_fprint(stderr, &asn_DEF_T, new_structure); + xer_fprint(stderr, &asn_DEF_T, new_structure); + assert(cmp == 0); + } + ASN_STRUCT_FREE(asn_DEF_T, structure); + ASN_STRUCT_FREE(asn_DEF_T, new_structure); + + if(i < 5) { + fprintf(stderr, "[%03d] copy OK\n", i); + } else if(i == 5) { + fprintf(stderr, "... and so on\n"); + } + } + + fprintf(stderr, "OK %d iterations of copy-op for %s\n", iterations, + enc.name); +} + int main(int argc, char **argv) { uint32_t enabled_encodings = 0; enum { MODE_UNKNOWN, MODE_GENERATE_RANDOM_DATA, - MODE_CHECK_RANDOM_ROUNDTRIP + MODE_CHECK_RANDOM_ROUNDTRIP, + MODE_CHECK_COPY_OP } mode = MODE_UNKNOWN; const char *generate_into_dir = NULL; int iterations = 100; @@ -340,7 +413,7 @@ int main(int argc, char **argv) { int debug = 0; int c; - while((c = getopt(argc, argv, "cde:g:hn:s:")) != -1) { + while((c = getopt(argc, argv, "cde:g:hn:s:y")) != -1) { switch(c) { case 'c': mode = MODE_CHECK_RANDOM_ROUNDTRIP; @@ -377,6 +450,9 @@ int main(int argc, char **argv) { } max_random_value_size = atoi(optarg); break; + case 'y': + mode = MODE_CHECK_COPY_OP; + break; default: usage(argv[0]); exit(2); @@ -408,6 +484,10 @@ int main(int argc, char **argv) { check_random_roundtrip(syntax, max_random_value_size, iterations, debug); break; + case MODE_CHECK_COPY_OP: + check_copy_op(syntax, max_random_value_size, + iterations, debug); + break; } } } diff --git a/tests/tests-skeletons/Makefile.am b/tests/tests-skeletons/Makefile.am index f5adf30f4..2654bfcfd 100644 --- a/tests/tests-skeletons/Makefile.am +++ b/tests/tests-skeletons/Makefile.am @@ -4,6 +4,7 @@ check_PROGRAMS = \ check-ber_tlv_tag \ check-length \ check-bits \ + check-copy \ check-OIDs \ check-GeneralizedTime \ check-OCTET_STRING \ @@ -27,6 +28,7 @@ check_PROGRAMS += \ check-32-ber_tlv_tag \ check-32-length \ check-32-bits \ + check-32-copy \ check-32-OIDs \ check-32-GeneralizedTime \ check-32-OCTET_STRING \ @@ -54,6 +56,9 @@ check_32_length_SOURCES=check-length.c check_32_bits_CFLAGS=$(CFLAGS_M32) check_32_bits_LDADD=$(LDADD_32) check_32_bits_SOURCES=check-bits.c +check_32_copy_CFLAGS=$(CFLAGS_M32) +check_32_copy_LDADD=$(LDADD_32) +check_32_copy_SOURCES=check-copy.c check_32_OIDs_CFLAGS=$(CFLAGS_M32) check_32_OIDs_LDADD=$(LDADD_32) check_32_OIDs_SOURCES=check-OIDs.c diff --git a/tests/tests-skeletons/check-copy.c b/tests/tests-skeletons/check-copy.c new file mode 100644 index 000000000..483d08e14 --- /dev/null +++ b/tests/tests-skeletons/check-copy.c @@ -0,0 +1,107 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#define check(td, a, b) test(__LINE__, td, a, b) + +static int +copy(asn_TYPE_descriptor_t *td, void **a, const void *b) { + return asn_copy(td, a, b) != 0; +} + +static int +compare(asn_TYPE_descriptor_t *td, void *a, void *b) { + return td->op->compare_struct(td, a, b) != 0; +} + +static int +test(int lineno, asn_TYPE_descriptor_t *td, void **a, void *b) { + int rv; + + rv = copy(td, a, b); + if(rv) { + fprintf(stderr, "%03d: copy() failed\n", lineno); + assert(rv == 0); + } + rv = compare(td, *a, b); + if(rv) { + fprintf(stderr, "%03d: compare() failed\n", lineno); + assert(rv == 0); + } + + ASN_STRUCT_FREE(*td, *a); + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, b); + + return 0; +} + +int +main(int ac, char **av) { + (void)ac; + (void)av; + + /* OCTET STRING */ + { + OCTET_STRING_t b = { 0 }; + OCTET_STRING_fromBuf(&b, "Hello", 5); + OCTET_STRING_t* a = NULL; + check(&asn_DEF_OCTET_STRING, (void**)&a, &b); + } + + /* INTEGER */ + { + INTEGER_t b = { 0 }; + asn_ulong2INTEGER(&b, 123); + INTEGER_t* a = NULL; + check(&asn_DEF_INTEGER, (void**)&a, &b); + } + { + INTEGER_t b = { 0 }; + INTEGER_t* a = NULL; + check(&asn_DEF_INTEGER, (void**)&a, &b); + } + + /* BIT STRING */ + { + BIT_STRING_t b = { 0 }; + b.buf = MALLOC(2); + b.size = 2; + b.buf[0] = 0x80; + b.buf[1] = 0x02; + b.bits_unused = 1; + BIT_STRING_t* a = NULL; + check(&asn_DEF_BIT_STRING, (void**)&a, &b); + } + + /* BOOLEAN */ + { + BOOLEAN_t b = { 0 }; + b = 1; + BIT_STRING_t* a = NULL; + check(&asn_DEF_BOOLEAN, (void**)&a, &b); + } + + /* NULL */ + { + NULL_t b = { 0 }; + NULL_t* a = NULL; + check(&asn_DEF_NULL, (void**)&a, &b); + } + + /* REAL */ + { + REAL_t b = { 0 }; + asn_double2REAL(&b, 123.456); + REAL_t* a = NULL; + check(&asn_DEF_REAL, (void**)&a, &b); + } + + return 0; +} +