xref: /aosp_15_r20/external/open-dice/src/cbor_reader.c (revision 60b67249c2e226f42f35cc6cfe66c6048e0bae6b)
1*60b67249SAndroid Build Coastguard Worker // Copyright 2021 Google LLC
2*60b67249SAndroid Build Coastguard Worker //
3*60b67249SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*60b67249SAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*60b67249SAndroid Build Coastguard Worker // the License at
6*60b67249SAndroid Build Coastguard Worker //
7*60b67249SAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*60b67249SAndroid Build Coastguard Worker //
9*60b67249SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*60b67249SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*60b67249SAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*60b67249SAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*60b67249SAndroid Build Coastguard Worker // the License.
14*60b67249SAndroid Build Coastguard Worker 
15*60b67249SAndroid Build Coastguard Worker #include "dice/cbor_reader.h"
16*60b67249SAndroid Build Coastguard Worker 
17*60b67249SAndroid Build Coastguard Worker enum CborType {
18*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_UINT = 0,
19*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_NINT = 1,
20*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_BSTR = 2,
21*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_TSTR = 3,
22*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_ARRAY = 4,
23*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_MAP = 5,
24*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_TAG = 6,
25*60b67249SAndroid Build Coastguard Worker   CBOR_TYPE_SIMPLE = 7,
26*60b67249SAndroid Build Coastguard Worker };
27*60b67249SAndroid Build Coastguard Worker 
CborReadWouldOverflow(size_t size,struct CborIn * in)28*60b67249SAndroid Build Coastguard Worker static bool CborReadWouldOverflow(size_t size, struct CborIn* in) {
29*60b67249SAndroid Build Coastguard Worker   return size > SIZE_MAX - in->cursor || in->cursor + size > in->buffer_size;
30*60b67249SAndroid Build Coastguard Worker }
31*60b67249SAndroid Build Coastguard Worker 
CborPeekInitialValueAndArgument(struct CborIn * in,uint8_t * size,enum CborType * type,uint64_t * val)32*60b67249SAndroid Build Coastguard Worker static enum CborReadResult CborPeekInitialValueAndArgument(struct CborIn* in,
33*60b67249SAndroid Build Coastguard Worker                                                            uint8_t* size,
34*60b67249SAndroid Build Coastguard Worker                                                            enum CborType* type,
35*60b67249SAndroid Build Coastguard Worker                                                            uint64_t* val) {
36*60b67249SAndroid Build Coastguard Worker   uint8_t initial_byte;
37*60b67249SAndroid Build Coastguard Worker   uint8_t additional_information;
38*60b67249SAndroid Build Coastguard Worker   uint64_t value;
39*60b67249SAndroid Build Coastguard Worker   uint8_t bytes = 1;
40*60b67249SAndroid Build Coastguard Worker   if (CborInAtEnd(in)) {
41*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_END;
42*60b67249SAndroid Build Coastguard Worker   }
43*60b67249SAndroid Build Coastguard Worker   initial_byte = in->buffer[in->cursor];
44*60b67249SAndroid Build Coastguard Worker   *type = initial_byte >> 5;
45*60b67249SAndroid Build Coastguard Worker   additional_information = initial_byte & 0x1f;
46*60b67249SAndroid Build Coastguard Worker   if (additional_information <= 23) {
47*60b67249SAndroid Build Coastguard Worker     value = additional_information;
48*60b67249SAndroid Build Coastguard Worker   } else if (additional_information <= 27) {
49*60b67249SAndroid Build Coastguard Worker     bytes += 1 << (additional_information - 24);
50*60b67249SAndroid Build Coastguard Worker     if (CborReadWouldOverflow(bytes, in)) {
51*60b67249SAndroid Build Coastguard Worker       return CBOR_READ_RESULT_END;
52*60b67249SAndroid Build Coastguard Worker     }
53*60b67249SAndroid Build Coastguard Worker     value = 0;
54*60b67249SAndroid Build Coastguard Worker     if (bytes == 2) {
55*60b67249SAndroid Build Coastguard Worker       value |= in->buffer[in->cursor + 1];
56*60b67249SAndroid Build Coastguard Worker     } else if (bytes == 3) {
57*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 1] << 8;
58*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 2];
59*60b67249SAndroid Build Coastguard Worker     } else if (bytes == 5) {
60*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 1] << 24;
61*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 2] << 16;
62*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 3] << 8;
63*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 4];
64*60b67249SAndroid Build Coastguard Worker     } else if (bytes == 9) {
65*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 1] << 56;
66*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 2] << 48;
67*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 3] << 40;
68*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 4] << 32;
69*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 5] << 24;
70*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 6] << 16;
71*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 7] << 8;
72*60b67249SAndroid Build Coastguard Worker       value |= (uint64_t)in->buffer[in->cursor + 8];
73*60b67249SAndroid Build Coastguard Worker     }
74*60b67249SAndroid Build Coastguard Worker   } else {
75*60b67249SAndroid Build Coastguard Worker     // Indefinite lengths and reserved values are not supported.
76*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_MALFORMED;
77*60b67249SAndroid Build Coastguard Worker   }
78*60b67249SAndroid Build Coastguard Worker   *val = value;
79*60b67249SAndroid Build Coastguard Worker   *size = bytes;
80*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
81*60b67249SAndroid Build Coastguard Worker }
82*60b67249SAndroid Build Coastguard Worker 
CborReadSize(struct CborIn * in,enum CborType type,size_t * size)83*60b67249SAndroid Build Coastguard Worker static enum CborReadResult CborReadSize(struct CborIn* in, enum CborType type,
84*60b67249SAndroid Build Coastguard Worker                                         size_t* size) {
85*60b67249SAndroid Build Coastguard Worker   uint8_t bytes;
86*60b67249SAndroid Build Coastguard Worker   enum CborType in_type;
87*60b67249SAndroid Build Coastguard Worker   uint64_t raw;
88*60b67249SAndroid Build Coastguard Worker   enum CborReadResult res =
89*60b67249SAndroid Build Coastguard Worker       CborPeekInitialValueAndArgument(in, &bytes, &in_type, &raw);
90*60b67249SAndroid Build Coastguard Worker   if (res != CBOR_READ_RESULT_OK) {
91*60b67249SAndroid Build Coastguard Worker     return res;
92*60b67249SAndroid Build Coastguard Worker   }
93*60b67249SAndroid Build Coastguard Worker   if (in_type != type) {
94*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_NOT_FOUND;
95*60b67249SAndroid Build Coastguard Worker   }
96*60b67249SAndroid Build Coastguard Worker   if (raw > SIZE_MAX) {
97*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_MALFORMED;
98*60b67249SAndroid Build Coastguard Worker   }
99*60b67249SAndroid Build Coastguard Worker   *size = (size_t)raw;
100*60b67249SAndroid Build Coastguard Worker   in->cursor += bytes;
101*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
102*60b67249SAndroid Build Coastguard Worker }
103*60b67249SAndroid Build Coastguard Worker 
CborReadStr(struct CborIn * in,enum CborType type,size_t * data_size,const uint8_t ** data)104*60b67249SAndroid Build Coastguard Worker static enum CborReadResult CborReadStr(struct CborIn* in, enum CborType type,
105*60b67249SAndroid Build Coastguard Worker                                        size_t* data_size,
106*60b67249SAndroid Build Coastguard Worker                                        const uint8_t** data) {
107*60b67249SAndroid Build Coastguard Worker   size_t size;
108*60b67249SAndroid Build Coastguard Worker   struct CborIn peeker = *in;
109*60b67249SAndroid Build Coastguard Worker   enum CborReadResult res = CborReadSize(&peeker, type, &size);
110*60b67249SAndroid Build Coastguard Worker   if (res != CBOR_READ_RESULT_OK) {
111*60b67249SAndroid Build Coastguard Worker     return res;
112*60b67249SAndroid Build Coastguard Worker   }
113*60b67249SAndroid Build Coastguard Worker   if (CborReadWouldOverflow(size, &peeker)) {
114*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_END;
115*60b67249SAndroid Build Coastguard Worker   }
116*60b67249SAndroid Build Coastguard Worker   *data_size = size;
117*60b67249SAndroid Build Coastguard Worker   *data = &in->buffer[peeker.cursor];
118*60b67249SAndroid Build Coastguard Worker   in->cursor = peeker.cursor + size;
119*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
120*60b67249SAndroid Build Coastguard Worker }
121*60b67249SAndroid Build Coastguard Worker 
CborReadSimple(struct CborIn * in,uint8_t val)122*60b67249SAndroid Build Coastguard Worker static enum CborReadResult CborReadSimple(struct CborIn* in, uint8_t val) {
123*60b67249SAndroid Build Coastguard Worker   uint8_t bytes;
124*60b67249SAndroid Build Coastguard Worker   enum CborType type;
125*60b67249SAndroid Build Coastguard Worker   uint64_t raw;
126*60b67249SAndroid Build Coastguard Worker   enum CborReadResult res =
127*60b67249SAndroid Build Coastguard Worker       CborPeekInitialValueAndArgument(in, &bytes, &type, &raw);
128*60b67249SAndroid Build Coastguard Worker   if (res != CBOR_READ_RESULT_OK) {
129*60b67249SAndroid Build Coastguard Worker     return res;
130*60b67249SAndroid Build Coastguard Worker   }
131*60b67249SAndroid Build Coastguard Worker   if (type != CBOR_TYPE_SIMPLE || raw != val) {
132*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_NOT_FOUND;
133*60b67249SAndroid Build Coastguard Worker   }
134*60b67249SAndroid Build Coastguard Worker   in->cursor += bytes;
135*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
136*60b67249SAndroid Build Coastguard Worker }
137*60b67249SAndroid Build Coastguard Worker 
CborReadInt(struct CborIn * in,int64_t * val)138*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadInt(struct CborIn* in, int64_t* val) {
139*60b67249SAndroid Build Coastguard Worker   uint8_t bytes;
140*60b67249SAndroid Build Coastguard Worker   enum CborType type;
141*60b67249SAndroid Build Coastguard Worker   uint64_t raw;
142*60b67249SAndroid Build Coastguard Worker   enum CborReadResult res =
143*60b67249SAndroid Build Coastguard Worker       CborPeekInitialValueAndArgument(in, &bytes, &type, &raw);
144*60b67249SAndroid Build Coastguard Worker   if (res != CBOR_READ_RESULT_OK) {
145*60b67249SAndroid Build Coastguard Worker     return res;
146*60b67249SAndroid Build Coastguard Worker   }
147*60b67249SAndroid Build Coastguard Worker   if (type != CBOR_TYPE_UINT && type != CBOR_TYPE_NINT) {
148*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_NOT_FOUND;
149*60b67249SAndroid Build Coastguard Worker   }
150*60b67249SAndroid Build Coastguard Worker   if (raw > INT64_MAX) {
151*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_MALFORMED;
152*60b67249SAndroid Build Coastguard Worker   }
153*60b67249SAndroid Build Coastguard Worker   *val = (type == CBOR_TYPE_NINT) ? (-1 - (int64_t)raw) : (int64_t)raw;
154*60b67249SAndroid Build Coastguard Worker   in->cursor += bytes;
155*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
156*60b67249SAndroid Build Coastguard Worker }
157*60b67249SAndroid Build Coastguard Worker 
CborReadUint(struct CborIn * in,uint64_t * val)158*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadUint(struct CborIn* in, uint64_t* val) {
159*60b67249SAndroid Build Coastguard Worker   uint8_t bytes;
160*60b67249SAndroid Build Coastguard Worker   enum CborType type;
161*60b67249SAndroid Build Coastguard Worker   enum CborReadResult res =
162*60b67249SAndroid Build Coastguard Worker       CborPeekInitialValueAndArgument(in, &bytes, &type, val);
163*60b67249SAndroid Build Coastguard Worker   if (res != CBOR_READ_RESULT_OK) {
164*60b67249SAndroid Build Coastguard Worker     return res;
165*60b67249SAndroid Build Coastguard Worker   }
166*60b67249SAndroid Build Coastguard Worker   if (type != CBOR_TYPE_UINT) {
167*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_NOT_FOUND;
168*60b67249SAndroid Build Coastguard Worker   }
169*60b67249SAndroid Build Coastguard Worker   in->cursor += bytes;
170*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
171*60b67249SAndroid Build Coastguard Worker }
172*60b67249SAndroid Build Coastguard Worker 
CborReadBstr(struct CborIn * in,size_t * data_size,const uint8_t ** data)173*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadBstr(struct CborIn* in, size_t* data_size,
174*60b67249SAndroid Build Coastguard Worker                                  const uint8_t** data) {
175*60b67249SAndroid Build Coastguard Worker   return CborReadStr(in, CBOR_TYPE_BSTR, data_size, data);
176*60b67249SAndroid Build Coastguard Worker }
177*60b67249SAndroid Build Coastguard Worker 
CborReadTstr(struct CborIn * in,size_t * size,const char ** str)178*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadTstr(struct CborIn* in, size_t* size,
179*60b67249SAndroid Build Coastguard Worker                                  const char** str) {
180*60b67249SAndroid Build Coastguard Worker   return CborReadStr(in, CBOR_TYPE_TSTR, size, (const uint8_t**)str);
181*60b67249SAndroid Build Coastguard Worker }
182*60b67249SAndroid Build Coastguard Worker 
CborReadArray(struct CborIn * in,size_t * num_elements)183*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadArray(struct CborIn* in, size_t* num_elements) {
184*60b67249SAndroid Build Coastguard Worker   return CborReadSize(in, CBOR_TYPE_ARRAY, num_elements);
185*60b67249SAndroid Build Coastguard Worker }
186*60b67249SAndroid Build Coastguard Worker 
CborReadMap(struct CborIn * in,size_t * num_pairs)187*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadMap(struct CborIn* in, size_t* num_pairs) {
188*60b67249SAndroid Build Coastguard Worker   return CborReadSize(in, CBOR_TYPE_MAP, num_pairs);
189*60b67249SAndroid Build Coastguard Worker }
190*60b67249SAndroid Build Coastguard Worker 
CborReadTag(struct CborIn * in,uint64_t * tag)191*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadTag(struct CborIn* in, uint64_t* tag) {
192*60b67249SAndroid Build Coastguard Worker   uint8_t bytes;
193*60b67249SAndroid Build Coastguard Worker   enum CborType type;
194*60b67249SAndroid Build Coastguard Worker   enum CborReadResult res =
195*60b67249SAndroid Build Coastguard Worker       CborPeekInitialValueAndArgument(in, &bytes, &type, tag);
196*60b67249SAndroid Build Coastguard Worker   if (res != CBOR_READ_RESULT_OK) {
197*60b67249SAndroid Build Coastguard Worker     return res;
198*60b67249SAndroid Build Coastguard Worker   }
199*60b67249SAndroid Build Coastguard Worker   if (type != CBOR_TYPE_TAG) {
200*60b67249SAndroid Build Coastguard Worker     return CBOR_READ_RESULT_NOT_FOUND;
201*60b67249SAndroid Build Coastguard Worker   }
202*60b67249SAndroid Build Coastguard Worker   in->cursor += bytes;
203*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
204*60b67249SAndroid Build Coastguard Worker }
205*60b67249SAndroid Build Coastguard Worker 
CborReadFalse(struct CborIn * in)206*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadFalse(struct CborIn* in) {
207*60b67249SAndroid Build Coastguard Worker   return CborReadSimple(in, /*val=*/20);
208*60b67249SAndroid Build Coastguard Worker }
209*60b67249SAndroid Build Coastguard Worker 
CborReadTrue(struct CborIn * in)210*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadTrue(struct CborIn* in) {
211*60b67249SAndroid Build Coastguard Worker   return CborReadSimple(in, /*val=*/21);
212*60b67249SAndroid Build Coastguard Worker }
213*60b67249SAndroid Build Coastguard Worker 
CborReadNull(struct CborIn * in)214*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadNull(struct CborIn* in) {
215*60b67249SAndroid Build Coastguard Worker   return CborReadSimple(in, /*val=*/22);
216*60b67249SAndroid Build Coastguard Worker }
217*60b67249SAndroid Build Coastguard Worker 
CborReadSkip(struct CborIn * in)218*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadSkip(struct CborIn* in) {
219*60b67249SAndroid Build Coastguard Worker   struct CborIn peeker = *in;
220*60b67249SAndroid Build Coastguard Worker   size_t size_stack[CBOR_READ_SKIP_STACK_SIZE];
221*60b67249SAndroid Build Coastguard Worker   size_t stack_size = 0;
222*60b67249SAndroid Build Coastguard Worker 
223*60b67249SAndroid Build Coastguard Worker   size_stack[stack_size++] = 1;
224*60b67249SAndroid Build Coastguard Worker 
225*60b67249SAndroid Build Coastguard Worker   while (stack_size > 0) {
226*60b67249SAndroid Build Coastguard Worker     // Get the type
227*60b67249SAndroid Build Coastguard Worker     uint8_t bytes;
228*60b67249SAndroid Build Coastguard Worker     enum CborType type;
229*60b67249SAndroid Build Coastguard Worker     uint64_t val;
230*60b67249SAndroid Build Coastguard Worker     enum CborReadResult res;
231*60b67249SAndroid Build Coastguard Worker 
232*60b67249SAndroid Build Coastguard Worker     res = CborPeekInitialValueAndArgument(&peeker, &bytes, &type, &val);
233*60b67249SAndroid Build Coastguard Worker     if (res != CBOR_READ_RESULT_OK) {
234*60b67249SAndroid Build Coastguard Worker       return res;
235*60b67249SAndroid Build Coastguard Worker     }
236*60b67249SAndroid Build Coastguard Worker 
237*60b67249SAndroid Build Coastguard Worker     if (CborReadWouldOverflow(bytes, &peeker)) {
238*60b67249SAndroid Build Coastguard Worker       return CBOR_READ_RESULT_END;
239*60b67249SAndroid Build Coastguard Worker     }
240*60b67249SAndroid Build Coastguard Worker     peeker.cursor += bytes;
241*60b67249SAndroid Build Coastguard Worker 
242*60b67249SAndroid Build Coastguard Worker     if (--size_stack[stack_size - 1] == 0) {
243*60b67249SAndroid Build Coastguard Worker       --stack_size;
244*60b67249SAndroid Build Coastguard Worker     }
245*60b67249SAndroid Build Coastguard Worker 
246*60b67249SAndroid Build Coastguard Worker     switch (type) {
247*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_UINT:
248*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_NINT:
249*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_SIMPLE:
250*60b67249SAndroid Build Coastguard Worker         continue;
251*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_BSTR:
252*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_TSTR:
253*60b67249SAndroid Build Coastguard Worker         if (val > SIZE_MAX || CborReadWouldOverflow((size_t)val, &peeker)) {
254*60b67249SAndroid Build Coastguard Worker           return CBOR_READ_RESULT_END;
255*60b67249SAndroid Build Coastguard Worker         }
256*60b67249SAndroid Build Coastguard Worker         peeker.cursor += val;
257*60b67249SAndroid Build Coastguard Worker         continue;
258*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_MAP:
259*60b67249SAndroid Build Coastguard Worker         if (val > UINT64_MAX / 2) {
260*60b67249SAndroid Build Coastguard Worker           return CBOR_READ_RESULT_END;
261*60b67249SAndroid Build Coastguard Worker         }
262*60b67249SAndroid Build Coastguard Worker         val *= 2;
263*60b67249SAndroid Build Coastguard Worker         break;
264*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_TAG:
265*60b67249SAndroid Build Coastguard Worker         val = 1;
266*60b67249SAndroid Build Coastguard Worker         break;
267*60b67249SAndroid Build Coastguard Worker       case CBOR_TYPE_ARRAY:
268*60b67249SAndroid Build Coastguard Worker         break;
269*60b67249SAndroid Build Coastguard Worker       default:
270*60b67249SAndroid Build Coastguard Worker         return CBOR_READ_RESULT_MALFORMED;
271*60b67249SAndroid Build Coastguard Worker     }
272*60b67249SAndroid Build Coastguard Worker 
273*60b67249SAndroid Build Coastguard Worker     // Push a new level of nesting to the stack.
274*60b67249SAndroid Build Coastguard Worker     if (val == 0) {
275*60b67249SAndroid Build Coastguard Worker       continue;
276*60b67249SAndroid Build Coastguard Worker     }
277*60b67249SAndroid Build Coastguard Worker     if (stack_size == CBOR_READ_SKIP_STACK_SIZE) {
278*60b67249SAndroid Build Coastguard Worker       return CBOR_READ_RESULT_MALFORMED;
279*60b67249SAndroid Build Coastguard Worker     }
280*60b67249SAndroid Build Coastguard Worker     if (val > SIZE_MAX) {
281*60b67249SAndroid Build Coastguard Worker       return CBOR_READ_RESULT_END;
282*60b67249SAndroid Build Coastguard Worker     }
283*60b67249SAndroid Build Coastguard Worker     size_stack[stack_size++] = (size_t)val;
284*60b67249SAndroid Build Coastguard Worker   }
285*60b67249SAndroid Build Coastguard Worker 
286*60b67249SAndroid Build Coastguard Worker   in->cursor = peeker.cursor;
287*60b67249SAndroid Build Coastguard Worker   return CBOR_READ_RESULT_OK;
288*60b67249SAndroid Build Coastguard Worker }
289