blob: f90790b435fa60c1826978d315612c71ecc8a1fb [file] [log] [blame]
Laurence Lundbladeb239c652024-05-26 08:07:05 -07001/* ==========================================================================
2 * Copyright (c) 2016-2018, The Linux Foundation.
3 * Copyright (c) 2018-2024, Laurence Lundblade.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 * * Neither the name of The Linux Foundation nor the names of its
16 * contributors, nor the name "Laurence Lundblade" may be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * ========================================================================= */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080032
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080033
Laurence Lundblade624405d2018-09-18 20:10:47 -070034
Laurence Lundbladeee851742020-01-08 08:37:05 -080035/*=============================================================================
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070036 FILE: UsefulBuf.c
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080037
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070038 DESCRIPTION: General purpose input and output buffers
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080039
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070040 EDIT HISTORY FOR FILE:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080041
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070042 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080044
Laurence Lundbladeee851742020-01-08 08:37:05 -080045 when who what, where, why
46 -------- ---- ---------------------------------------------------
Laurence Lundbladeb239c652024-05-26 08:07:05 -070047 21/05/2024 llundblade Comment formatting and some code tidiness.
Laurence Lundblade5a6fec52022-12-25 11:28:43 -070048 19/12/2022 llundblade Don't pass NULL to memmove when adding empty data.
49 4/11/2022 llundblade Add GetOutPlace and Advance to UsefulOutBuf
Laurence Lundbladeb239c652024-05-26 08:07:05 -070050 3/6/2021 mcr/llundblade Fix warnings related to --Wcast-qual
Laurence Lundblade06350ea2020-01-27 19:32:40 -080051 01/28/2020 llundblade Refine integer signedness to quiet static analysis.
52 01/08/2020 llundblade Documentation corrections & improved code formatting.
Laurence Lundbladeee851742020-01-08 08:37:05 -080053 11/08/2019 llundblade Re check pointer math and update comments
54 3/6/2019 llundblade Add UsefulBuf_IsValue()
55 09/07/17 llundbla Fix critical bug in UsefulBuf_Find() -- a read off
56 the end of memory when the bytes to find is longer
57 than the bytes to search.
58 06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected comparison
59 for < or > for unequal length buffers. Added
60 UsefulBuf_Set() function.
61 05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
62 11/13/16 llundbla Initial Version.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080063
Laurence Lundbladeee851742020-01-08 08:37:05 -080064 ============================================================================*/
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070065
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070066#include "UsefulBuf.h"
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070067
Laurence Lundbladeb239c652024-05-26 08:07:05 -070068/* used to catch use of uninitialized or corrupted UsefulOutBuf */
Laurence Lundbladeee851742020-01-08 08:37:05 -080069#define USEFUL_OUT_BUF_MAGIC (0x0B0F)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070070
Laurence Lundblade041ffa52018-10-07 11:43:51 +070071
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053072/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -070073 * Public function -- see UsefulBuf.h
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053074 */
Laurence Lundblade041ffa52018-10-07 11:43:51 +070075UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
76{
Laurence Lundbladeb239c652024-05-26 08:07:05 -070077 /* Do this with subtraction so it doesn't give an erroneous
78 * result if uOffset + Src.len overflows. Right side is equivalent to
79 * uOffset + Src.len > Dest.len
80 */
81 if(uOffset > Dest.len || Src.len > Dest.len - uOffset) {
Laurence Lundblade7566b9f2018-10-12 09:13:32 +080082 return NULLUsefulBufC;
83 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080084
Laurence Lundblade570fab52018-10-13 18:28:27 +080085 memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080086
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -080087 return (UsefulBufC){Dest.ptr, Src.len + uOffset};
Laurence Lundblade041ffa52018-10-07 11:43:51 +070088}
89
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053090
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070091/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -070092 * Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070093 */
94int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
95{
Laurence Lundbladeb239c652024-05-26 08:07:05 -070096 /* Use comparisons rather than subtracting lengths to
97 * return an int instead of a size_t
98 */
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070099 if(UB1.len < UB2.len) {
100 return -1;
101 } else if (UB1.len > UB2.len) {
102 return 1;
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700103 } /* else UB1.len == UB2.len */
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800104
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700105 return memcmp(UB1.ptr, UB2.ptr, UB1.len);
106}
107
108
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800109/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700110 * Public function -- see UsefulBuf.h
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800111 */
112size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
113{
114 if(UsefulBuf_IsNULLOrEmptyC(UB)) {
115 /* Not a match */
116 return 0;
117 }
118
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800119 const uint8_t * const pEnd = (const uint8_t *)UB.ptr + UB.len;
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800120 for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
121 if(*p != uValue) {
122 /* Byte didn't match */
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700123 /* Cast from signed to unsigned. Safe because the loop increments.*/
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800124 return (size_t)(p - (const uint8_t *)UB.ptr);
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800125 }
126 }
127
128 /* Success. All bytes matched */
129 return SIZE_MAX;
130}
131
Laurence Lundbladeda3f0822018-09-18 19:49:02 -0700132
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700133/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700134 * Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700135 */
136size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
137{
138 if(BytesToSearch.len < BytesToFind.len) {
139 return SIZE_MAX;
140 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800141
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700142 for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700143 UsefulBufC SearchNext;
144
145 SearchNext.ptr = ((const uint8_t *)BytesToSearch.ptr) + uPos;
146 SearchNext.len = BytesToFind.len;
147 if(!UsefulBuf_Compare(SearchNext, BytesToFind)) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700148 return uPos;
149 }
150 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800151
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700152 return SIZE_MAX;
153}
154
155
156/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700157 * Public function -- see UsefulBuf.h
158 *
159 * Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700160 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100161void UsefulOutBuf_Init(UsefulOutBuf *pMe, UsefulBuf Storage)
Laurence Lundblade2296db52018-09-14 18:08:39 -0700162{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100163 pMe->magic = USEFUL_OUT_BUF_MAGIC;
164 UsefulOutBuf_Reset(pMe);
165 pMe->UB = Storage;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800166
Laurence Lundblade2296db52018-09-14 18:08:39 -0700167#if 0
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700168 /* This check is off by default.
169 *
170 * The following check fails on ThreadX
171 *
172 * Sanity check on the pointer and size to be sure we are not
173 * passed a buffer that goes off the end of the address space.
174 * Given this test, we know that all unsigned lengths less than
175 * me->size are valid and won't wrap in any pointer additions
176 * based off of pStorage in the rest of this code.
177 */
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530178 const uintptr_t ptrM = UINTPTR_MAX - Storage.len;
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700179 if(Storage.ptr && (uintptr_t)Storage.ptr > ptrM) /* Check #0 */
Laurence Lundblade2296db52018-09-14 18:08:39 -0700180 me->err = 1;
181#endif
182}
183
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700184
185
186/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700187 * Public function -- see UsefulBuf.h
188 *
189 * The core of UsefulOutBuf -- put some bytes in the buffer without writing off
190 * the end of it.
191 *
192 * Code Reviewers: THIS FUNCTION DOES POINTER MATH
193 *
194 * This function inserts the source buffer, NewData, into the destination
195 * buffer, me->UB.ptr.
196 *
197 * Destination is represented as:
198 * me->UB.ptr -- start of the buffer
199 * me->UB.len -- size of the buffer UB.ptr
200 * me->data_len -- length of value data in UB
201 *
202 * Source is data:
203 * NewData.ptr -- start of source buffer
204 * NewData.len -- length of source buffer
205 *
206 * Insertion point:
207 * uInsertionPos.
208 *
209 * Steps:
210 *
211 * 0. Corruption checks on UsefulOutBuf
212 *
213 * 1. Figure out if the new data will fit or not
214 *
215 * 2. Is insertion position in the range of valid data?
216 *
217 * 3. If insertion point is not at the end, slide data to the right of the
218 * insertion point to the right
219 *
220 * 4. Put the new data in at the insertion position.
221 *
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700222 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100223void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pMe, UsefulBufC NewData, size_t uInsertionPos)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700224{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100225 if(pMe->err) {
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700226 /* Already in error state. */
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700227 return;
228 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800229
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700230 /* 0. Sanity check the UsefulOutBuf structure
231 * A "counter measure". If magic number is not the right number it
232 * probably means pMe was not initialized or it was corrupted. Attackers
233 * can defeat this, but it is a hurdle and does good with very
234 * little code.
235 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100236 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
237 pMe->err = 1;
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700238 return; /* Magic number is wrong due to uninitalization or corrption */
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700239 }
240
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700241 /* Make sure valid data is less than buffer size. This would only occur
242 * if there was corruption of me, but it is also part of the checks to
243 * be sure there is no pointer arithmatic under/overflow.
244 */
245 if(pMe->data_len > pMe->UB.len) { /* Check #1 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100246 pMe->err = 1;
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700247 /* Offset of valid data is off the end of the UsefulOutBuf due to
248 * uninitialization or corruption
249 */
Laurence Lundbladeee851742020-01-08 08:37:05 -0800250 return;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700251 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800252
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700253 /* 1. Will it fit?
254 * WillItFit() is the same as: NewData.len <= (me->UB.len - me->data_len)
255 * Check #1 makes sure subtraction in RoomLeft will not wrap around
256 */
257 if(! UsefulOutBuf_WillItFit(pMe, NewData.len)) { /* Check #2 */
258 /* The new data will not fit into the the buffer. */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100259 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700260 return;
261 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800262
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700263 /* 2. Check the Insertion Position
264 * This, with Check #1, also confirms that uInsertionPos <= me->data_len and
265 * that uInsertionPos + pMe->UB.ptr will not wrap around the end of the
266 * address space.
267 */
268 if(uInsertionPos > pMe->data_len) { /* Check #3 */
269 /* Off the end of the valid data in the buffer. */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100270 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700271 return;
272 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800273
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700274 /* 3. Slide existing data to the right */
Maxim Zhukov9fab6892022-12-20 20:16:07 +0300275 if (!UsefulOutBuf_IsBufferNULL(pMe)) {
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700276 uint8_t *pSourceOfMove = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; /* PtrMath #1 */
277 size_t uNumBytesToMove = pMe->data_len - uInsertionPos; /* PtrMath #2 */
278 uint8_t *pDestinationOfMove = pSourceOfMove + NewData.len; /* PtrMath #3*/
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800279
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700280 /* To know memmove won't go off end of destination, see PtrMath #4.
281 * Use memove because it handles overlapping buffers
282 */
Laurence Lundblade74f68412018-09-13 12:18:49 -0700283 memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800284
Maxim Zhukov9fab6892022-12-20 20:16:07 +0300285 /* 4. Put the new data in */
286 uint8_t *pInsertionPoint = pSourceOfMove;
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700287 /* To know memmove won't go off end of destination, see PtrMath #5 */
Laurence Lundblade5a6fec52022-12-25 11:28:43 -0700288 if(NewData.ptr != NULL) {
289 memmove(pInsertionPoint, NewData.ptr, NewData.len);
290 }
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700291 }
Maxim Zhukov9fab6892022-12-20 20:16:07 +0300292
Laurence Lundblade61209742019-11-08 13:16:43 -0800293 pMe->data_len += NewData.len;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700294}
295
296
297/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700298 * Rationale that describes why the above pointer math is safe
299 *
300 * PtrMath #1 will never wrap around over because
301 * Check #0 in UsefulOutBuf_Init that me->UB.ptr + me->UB.len doesn't wrap
302 * Check #1 makes sure me->data_len is less than me->UB.len
303 * Check #3 makes sure uInsertionPos is less than me->data_len
304 *
305 * PtrMath #2 will never wrap around under because
306 * Check #3 makes sure uInsertionPos is less than me->data_len
307 *
308 * PtrMath #3 will never wrap around over because
309 * PtrMath #1 is checked resulting in pSourceOfMove being between me->UB.ptr and me->UB.ptr + me->data_len
310 * Check #2 that NewData.len will fit in the unused space left in me->UB
311 *
312 * PtrMath #4 will never wrap under because
313 * Calculation for extent or memmove is uRoomInDestination = me->UB.len - (uInsertionPos + NewData.len)
314 * Check #3 makes sure uInsertionPos is less than me->data_len
315 * Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
316 * This algebraically rearranges to me->size > uInsertionPos + NewData.len
317 *
318 * PtrMath #5 will never wrap under because
319 * Calculation for extent of memove is uRoomInDestination = me->UB.len - uInsertionPos;
320 * Check #1 makes sure me->data_len is less than me->size
321 * Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700322 */
323
324
325/*
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600326 * Public function for advancing data length. See qcbor/UsefulBuf.h
327 */
328void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
329{
330 /* This function is a trimmed down version of
331 * UsefulOutBuf_InsertUsefulBuf(). This could be combined with the
332 * code in UsefulOutBuf_InsertUsefulBuf(), but that would make
333 * UsefulOutBuf_InsertUsefulBuf() bigger and this will be very
334 * rarely used.
335 */
336
337 if(pMe->err) {
338 /* Already in error state. */
339 return;
340 }
341
342 /* 0. Sanity check the UsefulOutBuf structure
343 *
344 * A "counter measure". If magic number is not the right number it
345 * probably means me was not initialized or it was
346 * corrupted. Attackers can defeat this, but it is a hurdle and
347 * does good with very little code.
348 */
349 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
350 pMe->err = 1;
351 return; /* Magic number is wrong due to uninitalization or corrption */
352 }
353
354 /* Make sure valid data is less than buffer size. This would only
355 * occur if there was corruption of me, but it is also part of the
356 * checks to be sure there is no pointer arithmatic
357 * under/overflow.
358 */
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700359 if(pMe->data_len > pMe->UB.len) { /* Check #1 */
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600360 pMe->err = 1;
361 /* Offset of valid data is off the end of the UsefulOutBuf due
362 * to uninitialization or corruption.
363 */
364 return;
365 }
366
367 /* 1. Will it fit?
368 *
369 * WillItFit() is the same as: NewData.len <= (me->UB.len -
370 * me->data_len) Check #1 makes sure subtraction in RoomLeft will
371 * not wrap around
372 */
373 if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
374 /* The new data will not fit into the the buffer. */
375 pMe->err = 1;
376 return;
377 }
378
379 pMe->data_len += uAmount;
380}
381
382
383/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700384 * Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700385 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100386UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700387{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100388 if(pMe->err) {
Laurence Lundblade2296db52018-09-14 18:08:39 -0700389 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700390 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800391
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100392 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
393 pMe->err = 1;
Laurence Lundblade2296db52018-09-14 18:08:39 -0700394 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700395 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800396
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100397 return (UsefulBufC){pMe->UB.ptr, pMe->data_len};
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700398}
399
400
401/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700402 * Public function -- see UsefulBuf.h
403 *
404 * Copy out the data accumulated in to the output buffer.
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700405 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100406UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pMe, UsefulBuf pDest)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700407{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100408 const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530409 if(UsefulBuf_IsNULLC(Tmp)) {
410 return NULLUsefulBufC;
411 }
412 return UsefulBuf_Copy(pDest, Tmp);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700413}
414
415
416
417
418/*
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700419 * Public function -- see UsefulBuf.h
420 *
421 * The core of UsefulInputBuf -- consume bytes without going off end of buffer.
422 *
423 * Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700424 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100425const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pMe, size_t uAmount)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700426{
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700427 /* Already in error state. Do nothing. */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100428 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700429 return NULL;
430 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800431
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100432 if(!UsefulInputBuf_BytesAvailable(pMe, uAmount)) {
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700433 /* Number of bytes asked for is more than available */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100434 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700435 return NULL;
436 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800437
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700438 /* This is going to succeed */
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800439 const void * const result = ((const uint8_t *)pMe->UB.ptr) + pMe->cursor;
Laurence Lundbladeb239c652024-05-26 08:07:05 -0700440 /* Won't overflow because of check using UsefulInputBuf_BytesAvailable() */
Laurence Lundbladeee851742020-01-08 08:37:05 -0800441 pMe->cursor += uAmount;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700442 return result;
443}