Fixed serious stack-bug in odr_cons_begin
[yaz-moved-to-github.git] / odr / odr_cons.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: odr_cons.c,v $
7  * Revision 1.7  1995-03-10 11:44:41  quinn
8  * Fixed serious stack-bug in odr_cons_begin
9  *
10  * Revision 1.6  1995/03/08  12:12:23  quinn
11  * Added better error checking.
12  *
13  * Revision 1.5  1995/02/10  18:57:25  quinn
14  * More in the way of error-checking.
15  *
16  * Revision 1.4  1995/02/10  15:55:29  quinn
17  * Bug fixes, mostly.
18  *
19  * Revision 1.3  1995/02/09  15:51:48  quinn
20  * Works better now.
21  *
22  * Revision 1.2  1995/02/07  17:52:59  quinn
23  * A damn mess, but now things work, I think.
24  *
25  * Revision 1.1  1995/02/02  16:21:53  quinn
26  * First kick.
27  *
28  */
29
30 #include <odr.h>
31
32 int odr_constructed_begin(ODR o, void *p, int class, int tag)
33 {
34     int res;
35     int cons = 1;
36
37     if (o->error)
38         return 0;
39     if (o->t_class < 0)
40     {
41         o->t_class = class;
42         o->t_tag = tag;
43     }
44     if ((res = ber_tag(o, p, o->t_class, o->t_tag, &cons, 1)) < 0)
45         return 0;
46     if (!res || !cons)
47         return 0;
48
49     if (o->stackp == ODR_MAX_STACK - 1)
50     {
51         o->error = OSTACK;
52         return 0;
53     }
54     o->stack[++(o->stackp)].lenb = o->bp;
55     if (o->direction == ODR_ENCODE || o->direction == ODR_PRINT)
56     {
57         o->stack[o->stackp].lenlen = 1;
58         o->bp++;
59         o->left--;
60     }
61     else if (o->direction == ODR_DECODE)
62     {
63         if ((res = ber_declen(o->bp, &o->stack[o->stackp].len)) < 0)
64             return 0;
65         o->stack[o->stackp].lenlen = res;
66         o->bp += res;
67         o->left -= res;
68     }
69     else return 0;
70
71     o->stack[o->stackp].base = o->bp;
72     return 1;
73 }
74
75 int odr_constructed_more(ODR o)
76 {
77     if (o->error)
78         return 0;
79     if (o->stackp < 0)
80         return 0;
81     if (o->stack[o->stackp].len >= 0)
82         return o->bp - o->stack[o->stackp].base < o->stack[o->stackp].len;
83     else
84         return (!(*o->bp == 0 && *(o->bp + 1) == 0));
85 }
86
87 int odr_constructed_end(ODR o)
88 {
89     int res;
90
91     if (o->error)
92         return 0;
93     if (o->stackp < 0)
94     {
95         o->error = OOTHER;
96         return 0;
97     }
98     switch (o->direction)
99     {
100         case ODR_DECODE:
101             if (o->stack[o->stackp].len < 0)
102             {
103                 if (*o->bp++ == 0 && *(o->bp++) == 0)
104                 {
105                     o->left -= 2;
106                     o->stackp--;
107                     return 1;
108                 }
109                 else
110                 {
111                     o->error = OOTHER;
112                     return 0;
113                 }
114             }
115             else if (o->bp - o->stack[o->stackp].base !=
116                 o->stack[o->stackp].len)
117             {
118                 o->error = OOTHER;
119                 return 0;
120             }
121             o->stackp--;
122             return 1;
123         case ODR_ENCODE:
124             if ((res = ber_enclen(o->stack[o->stackp].lenb,
125                 o->bp - o->stack[o->stackp].base,
126                 o->stack[o->stackp].lenlen, 1)) < 0)
127             {
128                 o->error = OSPACE;
129                 return 0;
130             }
131             if (res == 0)   /* indefinite encoding */
132             {
133                 *(o->bp++) = *(o->bp++) = 0;
134                 o->left--;
135             }
136             o->stackp--;
137             return 1;
138         case ODR_PRINT: return 1;
139         default:
140             o->error = OOTHER;
141             return 0;
142     }
143 }