Coverage Report

Created: 2026-11-12 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libiec61850/src/mms/iso_mms/asn1c/NativeInteger.c
Line
Count
Source
1
/*-
2
 * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
3
 * All rights reserved.
4
 * Redistribution and modifications are permitted subject to BSD license.
5
 */
6
/*
7
 * Read the NativeInteger.h for the explanation wrt. differences between
8
 * INTEGER and NativeInteger.
9
 * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
10
 * implementation deals with the standard (machine-specific) representation
11
 * of them instead of using the platform-independent buffer.
12
 */
13
#include <asn_internal.h>
14
#include <NativeInteger.h>
15
16
/*
17
 * NativeInteger basic type description.
18
 */
19
static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
20
  (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
21
};
22
asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
23
  "INTEGER",      /* The ASN.1 type is still INTEGER */
24
  "INTEGER",
25
  NativeInteger_free,
26
  NULL,
27
  asn_generic_no_constraint,
28
  NativeInteger_decode_ber,
29
  NativeInteger_encode_der,
30
  NULL,
31
  NULL,
32
  NativeInteger_decode_uper,  /* Unaligned PER decoder */
33
  NativeInteger_encode_uper,  /* Unaligned PER encoder */
34
  0, /* Use generic outmost tag fetcher */
35
  asn_DEF_NativeInteger_tags,
36
  sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
37
  asn_DEF_NativeInteger_tags, /* Same as above */
38
  sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
39
  0,  /* No PER visible constraints */
40
  0, 0, /* No members */
41
  0 /* No specifics */
42
};
43
44
/*
45
 * Decode INTEGER type.
46
 */
47
asn_dec_rval_t
48
NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
49
  asn_TYPE_descriptor_t *td,
50
0
  void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) {
51
0
  long *native = (long *)*nint_ptr;
52
0
  asn_dec_rval_t rval;
53
0
  ber_tlv_len_t length;
54
55
  /*
56
   * If the structure is not there, allocate it.
57
   */
58
0
  if(native == NULL) {
59
0
    native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
60
0
    if(native == NULL) {
61
0
      rval.code = RC_FAIL;
62
0
      rval.consumed = 0;
63
0
      return rval;
64
0
    }
65
0
  }
66
67
0
  ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
68
0
    td->name, tag_mode);
69
70
  /*
71
   * Check tags.
72
   */
73
0
  rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
74
0
      tag_mode, 0, &length, 0);
75
0
  if(rval.code != RC_OK)
76
0
    return rval;
77
78
0
  ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
79
80
  /*
81
   * Make sure we have this length.
82
   */
83
0
  buf_ptr = ((const char *)buf_ptr) + rval.consumed;
84
0
  size -= rval.consumed;
85
0
  if(length > (ber_tlv_len_t)size) {
86
0
    rval.code = RC_WMORE;
87
0
    rval.consumed = 0;
88
0
    return rval;
89
0
  }
90
91
  /*
92
   * ASN.1 encoded INTEGER: buf_ptr, length
93
   * Fill the native, at the same time checking for overflow.
94
   * If overflow occured, return with RC_FAIL.
95
   */
96
0
  {
97
0
    INTEGER_t tmp;
98
0
    union {
99
0
      const void *constbuf;
100
0
      void *nonconstbuf;
101
0
    } unconst_buf;
102
0
    long l;
103
104
0
    unconst_buf.constbuf = buf_ptr;
105
0
    tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
106
0
    tmp.size = length;
107
108
0
    if(asn_INTEGER2long(&tmp, &l)) {
109
0
      rval.code = RC_FAIL;
110
0
      rval.consumed = 0;
111
0
      return rval;
112
0
    }
113
114
0
    *native = l;
115
0
  }
116
117
0
  rval.code = RC_OK;
118
0
  rval.consumed += length;
119
120
0
  ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
121
0
    (long)rval.consumed, (long)length, td->name, (long)*native);
122
123
0
  return rval;
124
0
}
125
126
/*
127
 * Encode the NativeInteger using the standard INTEGER type DER encoder.
128
 */
129
asn_enc_rval_t
130
NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
131
  int tag_mode, ber_tlv_tag_t tag,
132
0
  asn_app_consume_bytes_f *cb, void *app_key) {
133
0
  unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */
134
0
  asn_enc_rval_t erval;
135
0
  INTEGER_t tmp;
136
137
#ifdef  WORDS_BIGENDIAN   /* Opportunistic optimization */
138
139
  tmp.buf = (uint8_t *)&native;
140
  tmp.size = sizeof(native);
141
142
#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
143
0
  uint8_t buf[sizeof(native)];
144
0
  uint8_t *p;
145
146
  /* Prepare a fake INTEGER */
147
0
  for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
148
0
    *p = native;
149
150
0
  tmp.buf = buf;
151
0
  tmp.size = sizeof(buf);
152
0
#endif  /* WORDS_BIGENDIAN */
153
  
154
  /* Encode fake INTEGER */
155
0
  erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
156
0
  if(erval.encoded == -1) {
157
0
    assert(erval.structure_ptr == &tmp);
158
0
    erval.structure_ptr = ptr;
159
0
  }
160
0
  return erval;
161
0
}
162
163
164
asn_dec_rval_t
165
NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
166
  asn_TYPE_descriptor_t *td,
167
0
  asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
168
169
0
  asn_dec_rval_t rval;
170
0
  long *native = (long *)*sptr;
171
0
  INTEGER_t tmpint;
172
0
  void *tmpintptr = &tmpint;
173
174
0
  (void)opt_codec_ctx;
175
0
  ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
176
177
0
  if(!native) {
178
0
    native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
179
0
    if(!native) _ASN_DECODE_FAILED;
180
0
  }
181
182
0
  memset(&tmpint, 0, sizeof tmpint);
183
0
  rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
184
0
           &tmpintptr, pd);
185
0
  if(rval.code == RC_OK) {
186
0
    if(asn_INTEGER2long(&tmpint, native))
187
0
      rval.code = RC_FAIL;
188
0
    else
189
0
      ASN_DEBUG("NativeInteger %s got value %ld",
190
0
        td->name, *native);
191
0
  }
192
0
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
193
194
0
  return rval;
195
0
}
196
197
asn_enc_rval_t
198
NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
199
0
  asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
200
0
  asn_enc_rval_t er;
201
0
  long native;
202
0
  INTEGER_t tmpint;
203
204
0
  if(!sptr) _ASN_ENCODE_FAILED;
205
206
0
  native = *(long *)sptr;
207
208
0
  ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
209
210
0
  memset(&tmpint, 0, sizeof(tmpint));
211
0
  if(asn_long2INTEGER(&tmpint, native))
212
0
    _ASN_ENCODE_FAILED;
213
0
  er = INTEGER_encode_uper(td, constraints, &tmpint, po);
214
0
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
215
0
  return er;
216
0
}
217
218
void
219
0
NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
220
221
0
  if(!td || !ptr)
222
0
    return;
223
224
0
  ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
225
0
    td->name, contents_only, ptr);
226
227
0
  if(!contents_only) {
228
0
    FREEMEM(ptr);
229
0
  }
230
0
}
231