Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
asn1c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
asn1c
Commits
6c52784d
Commit
6c52784d
authored
Feb 09, 2014
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PER-encoding of integers wider than 32 bits
parent
bfc76e8f
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
393 additions
and
37 deletions
+393
-37
ChangeLog
ChangeLog
+1
-0
asn1c/tests/check-134.-gen-PER.c
asn1c/tests/check-134.-gen-PER.c
+115
-0
skeletons/INTEGER.c
skeletons/INTEGER.c
+30
-33
skeletons/per_support.c
skeletons/per_support.c
+55
-3
skeletons/per_support.h
skeletons/per_support.h
+8
-1
tests/127-per-long-OK.asn1
tests/127-per-long-OK.asn1
+2
-0
tests/134-per-long-OK.asn1
tests/134-per-long-OK.asn1
+21
-0
tests/134-per-long-OK.asn1.-Pgen-PER
tests/134-per-long-OK.asn1.-Pgen-PER
+161
-0
No files found.
ChangeLog
View file @
6c52784d
...
...
@@ -8,6 +8,7 @@
* Default constraint checking fix.
Thanks to Bartosz Marcinkiewicz <bma@megawatt.com.pl>
* Get rid of non-standard pointer arithmetics on void* pointer.
* PER-encoding of integers wider than 32 bits.
0.9.24: 2013-Mar-16
...
...
asn1c/tests/check-134.-gen-PER.c
0 → 100644
View file @
6c52784d
/*
* Verify INTEGER values with greater than 32 bits range.
*/
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <T.h>
#ifndef _LP64
int
main
()
{
assert
(
sizeof
(
void
*
)
<
8
);
return
;
}
#else
/* 64-bit platform */
static
unsigned
long
i2ul
(
const
INTEGER_t
*
i
)
{
unsigned
long
l
;
int
ret
=
asn_INTEGER2ulong
(
i
,
&
l
);
assert
(
ret
==
0
);
return
l
;
}
static
void
ul2i
(
INTEGER_t
*
i
,
unsigned
long
l
)
{
int
ret
=
asn_ulong2INTEGER
(
i
,
l
);
assert
(
ret
==
0
);
}
static
void
verify
(
int
testNo
,
T_t
*
ti
)
{
asn_enc_rval_t
er
;
asn_dec_rval_t
rv
;
unsigned
char
buf
[
16
];
T_t
*
to
=
0
;
fprintf
(
stderr
,
"%d IN: { %lu, %lu }
\n
"
,
testNo
,
i2ul
(
&
ti
->
unsigned33
),
i2ul
(
&
ti
->
unsigned42
));
er
=
uper_encode_to_buffer
(
&
asn_DEF_T
,
ti
,
buf
,
sizeof
buf
);
assert
(
er
.
encoded
==
33
+
42
);
rv
=
uper_decode
(
0
,
&
asn_DEF_T
,
(
void
*
)
&
to
,
buf
,
sizeof
buf
,
0
,
0
);
assert
(
rv
.
code
==
RC_OK
);
fprintf
(
stderr
,
"%d ENC: %2x%2x%2x%2x %2x%2x%2x%2x
\n
"
,
testNo
,
buf
[
0
],
buf
[
1
],
buf
[
2
],
buf
[
3
],
buf
[
4
],
buf
[
5
],
buf
[
6
],
buf
[
7
]);
fprintf
(
stderr
,
"%d OUT: { %lu, %lu } vs { %lu, %lu }
\n
"
,
testNo
,
i2ul
(
&
ti
->
unsigned33
),
i2ul
(
&
ti
->
unsigned42
),
i2ul
(
&
to
->
unsigned33
),
i2ul
(
&
to
->
unsigned42
));
assert
(
i2ul
(
&
ti
->
unsigned33
)
==
i2ul
(
&
to
->
unsigned33
));
assert
(
i2ul
(
&
ti
->
unsigned42
)
==
i2ul
(
&
to
->
unsigned42
));
xer_fprint
(
stderr
,
&
asn_DEF_T
,
ti
);
xer_fprint
(
stderr
,
&
asn_DEF_T
,
to
);
}
static
void
NO_encode
(
int
testNo
,
T_t
*
ti
)
{
asn_enc_rval_t
er
;
unsigned
char
buf
[
16
];
fprintf
(
stderr
,
"%d IN: { %lu, %lu }
\n
"
,
testNo
,
i2ul
(
&
ti
->
unsigned33
),
i2ul
(
&
ti
->
unsigned42
));
er
=
uper_encode_to_buffer
(
&
asn_DEF_T
,
ti
,
buf
,
sizeof
buf
);
assert
(
er
.
encoded
==
-
1
);
}
int
main
()
{
T_t
ti
;
memset
(
&
ti
,
0
,
sizeof
(
ti
));
ul2i
(
&
ti
.
unsigned33
,
0
);
ul2i
(
&
ti
.
unsigned42
,
0
);
verify
(
1
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
1
);
ul2i
(
&
ti
.
unsigned42
,
1
);
verify
(
2
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
5000000000
);
ul2i
(
&
ti
.
unsigned42
,
3153600000000
);
verify
(
3
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
-
1
);
ul2i
(
&
ti
.
unsigned42
,
0
);
NO_encode
(
4
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
0
);
ul2i
(
&
ti
.
unsigned42
,
-
1
);
NO_encode
(
5
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
5000000000
+
1
);
ul2i
(
&
ti
.
unsigned42
,
0
);
NO_encode
(
6
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
0
);
ul2i
(
&
ti
.
unsigned42
,
3153600000000
+
1
);
NO_encode
(
7
,
&
ti
);
ul2i
(
&
ti
.
unsigned33
,
5000000000
-
1
);
ul2i
(
&
ti
.
unsigned42
,
3153600000000
-
1
);
verify
(
8
,
&
ti
);
return
0
;
}
#endif
/* 64-bit platform */
skeletons/INTEGER.c
View file @
6c52784d
/*-
* Copyright (c) 2003
, 2004, 2005, 2006, 2007
Lev Walkin <vlm@lionet.info>.
* Copyright (c) 2003
-2014
Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
...
...
@@ -595,30 +595,35 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
}
}
/* X.691
, #12.2.2
*/
/* X.691
-2008/11, #13.2.2, constrained whole number
*/
if
(
ct
&&
ct
->
flags
!=
APC_UNCONSTRAINED
)
{
/* #1
0
.5.6 */
/* #1
1
.5.6 */
ASN_DEBUG
(
"Integer with range %d bits"
,
ct
->
range_bits
);
if
(
ct
->
range_bits
>=
0
)
{
long
value
;
if
(
ct
->
range_bits
==
32
)
{
long
lhalf
;
value
=
per_get_few_bits
(
pd
,
16
);
if
(
value
<
0
)
_ASN_DECODE_STARVED
;
lhalf
=
per_get_few_bits
(
pd
,
16
);
if
(
lhalf
<
0
)
_ASN_DECODE_STARVED
;
value
=
(
value
<<
16
)
|
lhalf
;
if
((
size_t
)
ct
->
range_bits
>
8
*
sizeof
(
unsigned
long
))
_ASN_DECODE_FAILED
;
if
(
specs
&&
specs
->
field_unsigned
)
{
unsigned
long
uvalue
;
if
(
uper_get_constrained_whole_number
(
pd
,
&
uvalue
,
ct
->
range_bits
))
_ASN_DECODE_STARVED
;
ASN_DEBUG
(
"Got value %lu + low %ld"
,
uvalue
,
ct
->
lower_bound
);
uvalue
+=
ct
->
lower_bound
;
if
(
asn_ulong2INTEGER
(
st
,
uvalue
))
_ASN_DECODE_FAILED
;
}
else
{
value
=
per_get_few_bits
(
pd
,
ct
->
range_bits
);
if
(
value
<
0
)
_ASN_DECODE_STARVED
;
unsigned
long
svalue
;
if
(
uper_get_constrained_whole_number
(
pd
,
&
svalue
,
ct
->
range_bits
))
_ASN_DECODE_STARVED
;
ASN_DEBUG
(
"Got value %ld + low %ld"
,
svalue
,
ct
->
lower_bound
);
svalue
+=
ct
->
lower_bound
;
if
(
asn_long2INTEGER
(
st
,
svalue
))
_ASN_DECODE_FAILED
;
}
ASN_DEBUG
(
"Got value %ld + low %ld"
,
value
,
ct
->
lower_bound
);
value
+=
ct
->
lower_bound
;
if
((
specs
&&
specs
->
field_unsigned
)
?
asn_ulong2INTEGER
(
st
,
value
)
:
asn_long2INTEGER
(
st
,
value
))
_ASN_DECODE_FAILED
;
return
rval
;
}
}
else
{
...
...
@@ -725,22 +730,14 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
}
/* X.691
, #12.2.2
*/
/* X.691
-11/2008, #13.2.2, test if constrained whole number
*/
if
(
ct
&&
ct
->
range_bits
>=
0
)
{
/* #1
0.5.6
*/
/* #1
1.5.6 -> #11.3
*/
ASN_DEBUG
(
"Encoding integer with range %d bits"
,
ct
->
range_bits
);
if
(
ct
->
range_bits
==
32
)
{
/* TODO: extend to >32 bits */
long
v
=
value
-
ct
->
lower_bound
;
if
(
per_put_few_bits
(
po
,
v
>>
1
,
31
)
||
per_put_few_bits
(
po
,
v
,
1
))
_ASN_ENCODE_FAILED
;
}
else
{
if
(
per_put_few_bits
(
po
,
value
-
ct
->
lower_bound
,
ct
->
range_bits
))
_ASN_ENCODE_FAILED
;
}
long
v
=
value
-
ct
->
lower_bound
;
if
(
uper_put_constrained_whole_number_s
(
po
,
v
,
ct
->
range_bits
))
_ASN_ENCODE_FAILED
;
_ASN_ENCODED_OK
(
er
);
}
...
...
skeletons/per_support.c
View file @
6c52784d
/*
* 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.
*/
...
...
@@ -238,8 +238,8 @@ uper_get_nsnnwn(asn_per_data_t *pd) {
}
/*
*
Put the normally small non-negative whole number.
*
X.691, #10.6
*
X.691-11/2008, #11.6
*
Encoding of a normally small non-negative whole number
*/
int
uper_put_nsnnwn
(
asn_per_outp_t
*
po
,
int
n
)
{
...
...
@@ -264,6 +264,58 @@ uper_put_nsnnwn(asn_per_outp_t *po, int n) {
}
/* X.691-2008/11, #11.5.6 -> #11.3 */
int
uper_get_constrained_whole_number
(
asn_per_data_t
*
pd
,
unsigned
long
*
out_value
,
int
nbits
)
{
unsigned
long
lhalf
;
/* Lower half of the number*/
long
half
;
if
(
nbits
<=
31
)
{
half
=
per_get_few_bits
(
pd
,
nbits
);
if
(
half
<
0
)
return
-
1
;
*
out_value
=
half
;
return
0
;
}
if
((
size_t
)
nbits
>
8
*
sizeof
(
*
out_value
))
return
-
1
;
/* RANGE */
half
=
per_get_few_bits
(
pd
,
31
);
if
(
half
<
0
)
return
-
1
;
if
(
uper_get_constrained_whole_number
(
pd
,
&
lhalf
,
nbits
-
31
))
return
-
1
;
*
out_value
=
((
unsigned
long
)
half
<<
(
nbits
-
31
))
|
lhalf
;
return
0
;
}
/* X.691-2008/11, #11.5.6 -> #11.3 */
int
uper_put_constrained_whole_number_s
(
asn_per_outp_t
*
po
,
long
v
,
int
nbits
)
{
/*
* Assume signed number can be safely coerced into
* unsigned of the same range.
* The following testing code will likely be optimized out
* by compiler if it is true.
*/
unsigned
long
uvalue1
=
ULONG_MAX
;
long
svalue
=
uvalue1
;
unsigned
long
uvalue2
=
svalue
;
assert
(
uvalue1
==
uvalue2
);
return
uper_put_constrained_whole_number_u
(
po
,
v
,
nbits
);
}
int
uper_put_constrained_whole_number_u
(
asn_per_outp_t
*
po
,
unsigned
long
v
,
int
nbits
)
{
if
(
nbits
<=
31
)
{
return
per_put_few_bits
(
po
,
v
,
nbits
);
}
else
{
/* Put higher portion first, followed by lower 31-bit */
if
(
uper_put_constrained_whole_number_u
(
po
,
v
>>
31
,
nbits
-
31
))
return
-
1
;
return
per_put_few_bits
(
po
,
v
,
31
);
}
}
/*
* Put a small number of bits (<= 31).
*/
...
...
skeletons/per_support.h
View file @
6c52784d
/*
* 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.
*/
...
...
@@ -81,6 +81,9 @@ ssize_t uper_get_nslength(asn_per_data_t *pd);
*/
ssize_t
uper_get_nsnnwn
(
asn_per_data_t
*
pd
);
/* X.691-2008/11, #11.5.6 */
int
uper_get_constrained_whole_number
(
asn_per_data_t
*
pd
,
unsigned
long
*
v
,
int
nbits
);
/* Non-thread-safe debugging function, don't use it */
char
*
per_data_string
(
asn_per_data_t
*
pd
);
...
...
@@ -103,6 +106,10 @@ int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits);
/* Output a large number of bits */
int
per_put_many_bits
(
asn_per_outp_t
*
po
,
const
uint8_t
*
src
,
int
put_nbits
);
/* X.691-2008/11, #11.5 */
int
uper_put_constrained_whole_number_s
(
asn_per_outp_t
*
po
,
long
v
,
int
nbits
);
int
uper_put_constrained_whole_number_u
(
asn_per_outp_t
*
po
,
unsigned
long
v
,
int
nbits
);
/*
* Put the length "n" to the Unaligned PER stream.
* This function returns the number of units which may be flushed
...
...
tests/127-per-long-OK.asn1
View file @
6c52784d
-- OK: Everything is fine
-- Also see .134 for wider integer types.
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
...
...
@@ -12,6 +13,7 @@ ModulePERLong
BEGIN
T ::= SEQUENCE {
-- Should be supported on all 32-bit platforms and above.
small32range INTEGER (-2000000000..2000000000),
full32range INTEGER (-2147483648..2147483647),
unsigned32 INTEGER (0..4294967295),
...
...
tests/134-per-long-OK.asn1
0 → 100644
View file @
6c52784d
-- OK: Everything is fine
-- Also see .127 for narrower integer types.
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .134
ModulePERLong
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 134 }
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
-- Supported only on 64-bit platforms.
T ::= SEQUENCE {
unsigned33 INTEGER (0..5000000000), -- range 33 bits
unsigned42 INTEGER (0..3153600000000) -- range 42 bits
}
END
tests/134-per-long-OK.asn1.-Pgen-PER
0 → 100644
View file @
6c52784d
/*** <<< INCLUDES [T] >>> ***/
#include <INTEGER.h>
#include <constr_SEQUENCE.h>
/*** <<< TYPE-DECLS [T] >>> ***/
typedef struct T {
INTEGER_t unsigned33;
INTEGER_t unsigned42;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} T_t;
/*** <<< FUNC-DECLS [T] >>> ***/
extern asn_TYPE_descriptor_t asn_DEF_T;
/*** <<< CODE [T] >>> ***/
static int
memb_unsigned33_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
const INTEGER_t *st = (const INTEGER_t *)sptr;
long value;
if(!sptr) {
_ASN_CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
if(asn_INTEGER2long(st, &value)) {
_ASN_CTFAIL(app_key, td, sptr,
"%s: value too large (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
if((value >= 0 && value <= 5000000000)) {
/* Constraint check succeeded */
return 0;
} else {
_ASN_CTFAIL(app_key, td, sptr,
"%s: constraint failed (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
}
static int
memb_unsigned42_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
const INTEGER_t *st = (const INTEGER_t *)sptr;
long value;
if(!sptr) {
_ASN_CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
if(asn_INTEGER2long(st, &value)) {
_ASN_CTFAIL(app_key, td, sptr,
"%s: value too large (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
if((value >= 0 && value <= 3153600000000)) {
/* Constraint check succeeded */
return 0;
} else {
_ASN_CTFAIL(app_key, td, sptr,
"%s: constraint failed (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
}
/*** <<< CTDEFS [T] >>> ***/
static asn_per_constraints_t asn_PER_memb_unsigned33_constr_2 GCC_NOTUSED = {
{ APC_CONSTRAINED, 33, -1, 0, 5000000000 } /* (0..5000000000) */,
{ APC_UNCONSTRAINED, -1, -1, 0, 0 },
0, 0 /* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_unsigned42_constr_3 GCC_NOTUSED = {
{ APC_CONSTRAINED, 42, -1, 0, 3153600000000 } /* (0..3153600000000) */,
{ APC_UNCONSTRAINED, -1, -1, 0, 0 },
0, 0 /* No PER value map */
};
/*** <<< STAT-DEFS [T] >>> ***/
static asn_TYPE_member_t asn_MBR_T_1[] = {
{ ATF_NOFLAGS, 0, offsetof(struct T, unsigned33),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_INTEGER,
.memb_constraints = memb_unsigned33_constraint_1,
.per_constraints = &asn_PER_memb_unsigned33_constr_2,
.default_value = 0,
.name = "unsigned33"
},
{ ATF_NOFLAGS, 0, offsetof(struct T, unsigned42),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_INTEGER,
.memb_constraints = memb_unsigned42_constraint_1,
.per_constraints = &asn_PER_memb_unsigned42_constr_3,
.default_value = 0,
.name = "unsigned42"
},
};
static ber_tlv_tag_t asn_DEF_T_tags_1[] = {
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_TYPE_tag2member_t asn_MAP_T_tag2el_1[] = {
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* unsigned33 */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* unsigned42 */
};
static asn_SEQUENCE_specifics_t asn_SPC_T_specs_1 = {
sizeof(struct T),
offsetof(struct T, _asn_ctx),
asn_MAP_T_tag2el_1,
2, /* Count of tags in the map */
0, 0, 0, /* Optional elements (not needed) */
-1, /* Start extensions */
-1 /* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_T = {
"T",
"T",
SEQUENCE_free,
SEQUENCE_print,
SEQUENCE_constraint,
SEQUENCE_decode_ber,
SEQUENCE_encode_der,
SEQUENCE_decode_xer,
SEQUENCE_encode_xer,
SEQUENCE_decode_uper,
SEQUENCE_encode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_T_tags_1,
sizeof(asn_DEF_T_tags_1)
/sizeof(asn_DEF_T_tags_1[0]), /* 1 */
asn_DEF_T_tags_1, /* Same as above */
sizeof(asn_DEF_T_tags_1)
/sizeof(asn_DEF_T_tags_1[0]), /* 1 */
0, /* No PER visible constraints */
asn_MBR_T_1,
2, /* Elements count */
&asn_SPC_T_specs_1 /* Additional specs */
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment