NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / libasn1fix / asn1fix_bitstring.c
1 #include "asn1fix_internal.h"
2
3 static int asn1f_fix_bit_string_type(arg_t *arg);
4 static int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype);
5 static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value);
6 static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype);
7
8 int
9 asn1f_fix_bit_string(arg_t *arg) {
10         asn1p_expr_t *expr = arg->expr;
11         int r_value = 0;
12         int ret;
13
14         if(expr->meta_type == AMT_VALUE) {
15                 asn1p_expr_t *ttype;
16
17                 DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);
18
19                 ttype = asn1f_find_terminal_type(arg, expr);
20                 if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) {
21                         ret = asn1f_fix_bit_string_value(arg, ttype);
22                         RET2RVAL(ret, r_value);
23                 }
24         }
25
26         if(expr->meta_type == AMT_TYPE
27         && expr->expr_type == ASN_BASIC_BIT_STRING) {
28                 ret = asn1f_fix_bit_string_type(arg);
29                 RET2RVAL(ret, r_value);
30         }
31
32         return r_value;
33 }
34
35 static int _compare_value(asn1p_expr_t *expr1, asn1p_expr_t *expr2) {
36         return expr2->value->value.v_integer - expr1->value->value.v_integer;
37 }
38
39 static int
40 asn1f_fix_bit_string_type(arg_t *arg) {
41         asn1p_expr_t *expr = arg->expr;
42         asn1p_expr_t *v;
43         int r_value = 0;
44         int ret;
45
46         TQ_FOR(v, &(expr->members), next) {
47                 if(v->expr_type == A1TC_EXTENSIBLE) {
48                         FATAL("Extension marker (...) is not allowed "
49                                 "as a BIT STRING NamedBit at line %d ",
50                                 v->_lineno);
51                         return -1;
52                 }
53                 if(v->expr_type != A1TC_UNIVERVAL) {
54                         FATAL("BIT STRING value at line %d "
55                                 "is not an identifier", v->_lineno);
56                         return -1;
57                 }
58
59                 /* 21.1 */
60                 if(v->value == NULL) {
61                         FATAL("BIT STRING NamedBit value at line %d "
62                                 "must be explicitly specified in braces",
63                                 v->_lineno);
64                         return -1;
65                 } else if(v->value->type == ATV_REFERENCED) {
66                         /* Resolve the value */
67             if(asn1f_value_resolve(arg, v, 0))
68                 return -1;
69                 }
70                 if(v->value->type != ATV_INTEGER
71                 || v->value->value.v_integer < 0) {
72                         FATAL("BIT STRING NamedBit value at line %d: "
73                                 "non-negative integer value expected",
74                                 v->_lineno);
75                         return -1;
76                 }
77
78                 /* Check value uniqueness as per 21.4 */
79                 ret = asn1f_check_unique_expr_child(arg, v,
80                                 _compare_value, "value");
81                 RET2RVAL(ret, r_value);
82                 /* Check identifier uniqueness as per 21.5 */
83                 ret = asn1f_check_unique_expr_child(arg, v, 0, "identifier");
84                 RET2RVAL(ret, r_value);
85         }
86
87         return r_value;
88 }
89
90 static int
91 asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) {
92         asn1p_expr_t *expr = arg->expr;
93         int r_value = 0;
94
95         DEBUG("(%s) for line %d",
96                 expr->Identifier, expr->_lineno);
97
98         switch(expr->value->type) {
99         case ATV_UNPARSED:
100                 /*
101                  * Most definitely we have something like
102                  *      value BitStringType1 ::= { a, b, c }
103                  * which could not be parsed by the LALR parser, mostly
104                  * because it requires knowledge about BitStringType1
105                  * during the parsing. So, here's a little hack: we create
106                  * a buffer containing the full specification of a module,
107                  * which contains some pre-defined INTEGER type with the
108                  * opaque definition "{ a, b, c }" from the bit string.
109                  */
110                 if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) {
111                         r_value = -1;
112                         break;
113                 }
114                 /* Fall through: remove trailing zero bits */
115         /* Fall through */
116         case ATV_BITVECTOR:
117                 asn1f_BS_remove_trailing_zero_bits(expr->value);
118                 break;
119         default:
120                 break;
121         }
122
123         return r_value;
124 }
125
126 static void
127 asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) {
128         int lmfb = -1;  /* Last meaningful byte position */
129         int bits;       /* Number of bits in the BIT STRING value */
130         int b;
131
132         assert(value->type == ATV_BITVECTOR);
133
134         bits = value->value.binary_vector.size_in_bits;
135         /*
136          * Figure out the rightmost meaningful byte.
137          */
138         for(b = 0; b < ((bits + 7) >> 3); b++) {
139                 uint8_t uc = value->value.binary_vector.bits[b];
140                 if(uc && b > lmfb)
141                         lmfb = b;
142         }
143         if(lmfb == -1) {
144                 bits = 0;
145         } else {
146                 uint8_t uc;
147                 uc = value->value.binary_vector.bits[lmfb];
148                 bits = (lmfb+1) * 8;
149                 /*
150                  * Squeeze the bit string width until the rightmost
151                  * bit is set.
152                  */
153                 for(; uc && (uc & 1) == 0; uc >>= 1)
154                         bits--;
155                 if(uc == 0) {
156                         bits = lmfb * 8;
157                 }
158         }
159         value->value.binary_vector.size_in_bits = bits;
160 }
161
162 static int
163 asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) {
164         asn1p_t *asn;
165         asn1p_module_t *mod;
166         asn1p_expr_t *V;
167         asn1p_expr_t *bit;
168         asn1c_integer_t aI;
169         uint8_t *bitbuf;
170         int bits;
171         int psize;
172         char *p;
173         int ret;
174         int r_value = 0;
175
176         assert(value->type == ATV_UNPARSED);
177
178         psize = value->value.string.size + sizeof("M DEFINITIONS ::= BEGIN V ::= BIT STRING END") + 32;
179         p = malloc(psize);
180         if(p == NULL)
181                 return -1;
182
183         ret = snprintf(p, psize,
184                 "M DEFINITIONS ::=\nBEGIN\n"
185                 "V ::= #BIT STRING %s\n"
186                 "END\n",
187                 value->value.string.buf
188         );
189         assert(ret < psize);
190         psize = ret;
191
192         asn = asn1p_parse_buffer(p, psize, arg->expr->module->source_file_name,
193                              arg->expr->_lineno, A1P_EXTENDED_VALUES);
194         free(p);
195         if(asn == NULL) {
196                 FATAL("Cannot parse BIT STRING value %s "
197                         "defined as %s at line %d",
198                         arg->expr->Identifier,
199                         value->value.string.buf,
200                         arg->expr->_lineno
201                 );
202                 return -1;
203         }
204
205         mod = TQ_FIRST(&(asn->modules));
206         assert(mod);
207         V = TQ_FIRST(&(mod->members));
208         assert(V);
209         assert(strcmp(V->Identifier, "V") == 0);
210
211         /*
212          * Simple loop just to fetch the maximal bit position
213          * out of the BIT STRING value defined as NamedBitList.
214          */
215         aI = -1;
216         TQ_FOR(bit, &(V->members), next) {
217                 asn1p_expr_t *bitdef;
218                 bitdef = asn1f_lookup_child(ttype, bit->Identifier);
219                 if(bitdef && bitdef->value
220                 && bitdef->value->type == ATV_INTEGER) {
221                         if(bitdef->value->value.v_integer > aI)
222                                 aI = bitdef->value->value.v_integer;
223                 }
224         }
225
226         if(aI > 1024 * 1024 * 8) {      /* One megabyte */
227                 FATAL("Unsupportedly large BIT STRING value \"%s\" "
228                         "defined at line %d "
229                         "(larger than 1MByte)",
230                         arg->expr->Identifier,
231                         arg->expr->_lineno
232                 );
233                 asn1p_delete(asn);
234                 return -1;
235         }
236
237         bits = aI + 1;  /* Number of bits is more than a last bit position */
238         bitbuf = calloc(1, 1 + ((bits + 7) / 8));
239         if(bitbuf == NULL) {
240                 asn1p_delete(asn);
241                 return -1;
242         }
243
244         TQ_FOR(bit, &(V->members), next) {
245                 asn1p_expr_t *bitdef;
246                 int set_bit_pos;
247
248                 if(bit->value) {
249                         WARNING("Identifier \"%s\" at line %d "
250                                 "must not have a value",
251                                 bit->Identifier, bit->_lineno);
252                         RET2RVAL(1, r_value);
253                 }
254                 bitdef = asn1f_lookup_child(ttype, bit->Identifier);
255                 if(bitdef == NULL) {
256                         FATAL("Identifier \"%s\" at line %d is not defined "
257                                 "in the \"%s\" type definition at line %d",
258                                 bit->Identifier,
259                                 bit->_lineno,
260                                 ttype->Identifier,
261                                 ttype->_lineno
262                         );
263                         RET2RVAL(-1, r_value);
264                         continue;
265                 }
266                 if(bitdef->value == NULL
267                 || bitdef->value->type != ATV_INTEGER) {
268                         FATAL("Broken identifier "
269                                 "\"%s\" at line %d "
270                                 "referenced by \"%s\" at line %d",
271                                 bitdef->Identifier,
272                                 bitdef->_lineno,
273                                 arg->expr->Identifier,
274                                 arg->expr->_lineno
275                         );
276                         RET2RVAL(-1, r_value);
277                         continue;
278                 }
279
280                 assert(bitdef->value->value.v_integer < bits);
281                 set_bit_pos = bitdef->value->value.v_integer;
282                 bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8));
283         }
284
285         asn1p_delete(asn);
286         free(value->value.string.buf);
287         value->type = ATV_BITVECTOR;
288         value->value.binary_vector.bits = bitbuf;
289         value->value.binary_vector.size_in_bits = bits;
290
291         return r_value;
292 }