blob: 0c336b8e7e995087ba72bf77c8e0165e6d705c46 [file] [log] [blame]
Laurence Lundbladeb69cad72018-09-13 11:09:01 -07001/*==============================================================================
Laurence Lundbladed92a6162018-11-01 11:38:35 +07002 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladef0ea5f32019-01-11 20:10:26 -08003 Copyright (c) 2018-2019, Laurence Lundblade.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -08004
Laurence Lundblade0dbc9172018-11-01 14:17:21 +07005Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above
11 copyright notice, this list of conditions and the following
12 disclaimer in the documentation and/or other materials provided
13 with the distribution.
14 * Neither the name of The Linux Foundation nor the names of its
15 contributors, nor the name "Laurence Lundblade" may be used to
16 endorse or promote products derived from this software without
17 specific prior written permission.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080018
Laurence Lundblade0dbc9172018-11-01 14:17:21 +070019THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Laurence Lundblade624405d2018-09-18 20:10:47 -070030 ==============================================================================*/
31
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070032/*===================================================================================
33 FILE: UsefulBuf.c
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080034
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070035 DESCRIPTION: General purpose input and output buffers
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080036
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070037 EDIT HISTORY FOR FILE:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080038
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080041
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070042 when who what, where, why
43 -------- ---- ---------------------------------------------------
Laurence Lundblade61209742019-11-08 13:16:43 -080044 11/08/2019 llundblade Re check pointer math and update comments
Laurence Lundbladed5e101e2019-03-06 17:23:18 -080045 3/6/2019 llundblade Add UsefulBuf_IsValue()
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080046 09/07/17 llundbla Fix critical bug in UsefulBuf_Find() -- a read off
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070047 the end of memory when the bytes to find is longer
48 than the bytes to search.
49 06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected comparison
50 for < or > for unequal length buffers. Added
51 UsefulBuf_Set() function.
52 05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
53 11/13/16 llundbla Initial Version.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080054
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070055 =====================================================================================*/
56
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070057#include "UsefulBuf.h"
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070058
59#define USEFUL_OUT_BUF_MAGIC (0x0B0F) // used to catch use of uninitialized or corrupted UOBs
60
Laurence Lundblade041ffa52018-10-07 11:43:51 +070061
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053062/*
63 Public function -- see UsefulBuf.h
64 */
Laurence Lundblade041ffa52018-10-07 11:43:51 +070065UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
66{
Laurence Lundblade7566b9f2018-10-12 09:13:32 +080067 // Do this with subtraction so it doesn't give erroneous result if uOffset + Src.len overflows
68 if(uOffset > Dest.len || Src.len > Dest.len - uOffset) { // uOffset + Src.len > Dest.len
69 return NULLUsefulBufC;
70 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080071
Laurence Lundblade570fab52018-10-13 18:28:27 +080072 memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080073
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -080074 return (UsefulBufC){Dest.ptr, Src.len + uOffset};
Laurence Lundblade041ffa52018-10-07 11:43:51 +070075}
76
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053077
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070078/*
79 Public function -- see UsefulBuf.h
80 */
81int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
82{
83 // use the comparisons rather than subtracting lengths to
84 // return an int instead of a size_t
85 if(UB1.len < UB2.len) {
86 return -1;
87 } else if (UB1.len > UB2.len) {
88 return 1;
89 } // else UB1.len == UB2.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080090
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070091 return memcmp(UB1.ptr, UB2.ptr, UB1.len);
92}
93
94
Laurence Lundbladed5e101e2019-03-06 17:23:18 -080095/*
96 Public function -- see UsefulBuf.h
97 */
98size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
99{
100 if(UsefulBuf_IsNULLOrEmptyC(UB)) {
101 /* Not a match */
102 return 0;
103 }
104
105 const uint8_t * const pEnd = (uint8_t *)UB.ptr + UB.len;
106 for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
107 if(*p != uValue) {
108 /* Byte didn't match */
109 return p - (uint8_t *)UB.ptr;
110 }
111 }
112
113 /* Success. All bytes matched */
114 return SIZE_MAX;
115}
116
Laurence Lundbladeda3f0822018-09-18 19:49:02 -0700117
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700118/*
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530119 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700120 */
121size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
122{
123 if(BytesToSearch.len < BytesToFind.len) {
124 return SIZE_MAX;
125 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800126
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700127 for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
128 if(!UsefulBuf_Compare((UsefulBufC){((uint8_t *)BytesToSearch.ptr) + uPos, BytesToFind.len}, BytesToFind)) {
129 return uPos;
130 }
131 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800132
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700133 return SIZE_MAX;
134}
135
136
137/*
138 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800139
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530140 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700141 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100142void UsefulOutBuf_Init(UsefulOutBuf *pMe, UsefulBuf Storage)
Laurence Lundblade2296db52018-09-14 18:08:39 -0700143{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100144 pMe->magic = USEFUL_OUT_BUF_MAGIC;
145 UsefulOutBuf_Reset(pMe);
146 pMe->UB = Storage;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800147
Laurence Lundblade2296db52018-09-14 18:08:39 -0700148#if 0
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530149 // This check is off by default.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800150
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530151 // The following check fails on ThreadX
152
Laurence Lundblade2296db52018-09-14 18:08:39 -0700153 // Sanity check on the pointer and size to be sure we are not
154 // passed a buffer that goes off the end of the address space.
155 // Given this test, we know that all unsigned lengths less than
156 // me->size are valid and won't wrap in any pointer additions
157 // based off of pStorage in the rest of this code.
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530158 const uintptr_t ptrM = UINTPTR_MAX - Storage.len;
159 if(Storage.ptr && (uintptr_t)Storage.ptr > ptrM) // Check #0
Laurence Lundblade2296db52018-09-14 18:08:39 -0700160 me->err = 1;
161#endif
162}
163
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700164
165
166/*
167 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800168
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700169 The core of UsefulOutBuf -- put some bytes in the buffer without writing off the end of it.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800170
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700171 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800172
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700173 This function inserts the source buffer, NewData, into the destination buffer, me->UB.ptr.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800174
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700175 Destination is represented as:
176 me->UB.ptr -- start of the buffer
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700177 me->UB.len -- size of the buffer UB.ptr
178 me->data_len -- length of value data in UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800179
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700180 Source is data:
181 NewData.ptr -- start of source buffer
182 NewData.len -- length of source buffer
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800183
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700184 Insertion point:
185 uInsertionPos.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800186
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700187 Steps:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800188
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700189 0. Corruption checks on UsefulOutBuf
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800190
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700191 1. Figure out if the new data will fit or not
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800192
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700193 2. Is insertion position in the range of valid data?
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800194
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700195 3. If insertion point is not at the end, slide data to the right of the insertion point to the right
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800196
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700197 4. Put the new data in at the insertion position.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800198
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700199 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100200void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pMe, UsefulBufC NewData, size_t uInsertionPos)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700201{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100202 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700203 // Already in error state.
204 return;
205 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800206
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700207 /* 0. Sanity check the UsefulOutBuf structure */
208 // A "counter measure". If magic number is not the right number it
209 // probably means me was not initialized or it was corrupted. Attackers
210 // can defeat this, but it is a hurdle and does good with very
211 // little code.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100212 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
213 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700214 return; // Magic number is wrong due to uninitalization or corrption
215 }
216
217 // Make sure valid data is less than buffer size. This would only occur
218 // if there was corruption of me, but it is also part of the checks to
219 // be sure there is no pointer arithmatic under/overflow.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100220 if(pMe->data_len > pMe->UB.len) { // Check #1
221 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700222 return; // Offset of valid data is off the end of the UsefulOutBuf due to uninitialization or corruption
223 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800224
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700225 /* 1. Will it fit? */
Laurence Lundblade61209742019-11-08 13:16:43 -0800226 // WillItFit() is the same as: NewData.len <= (me->UB.len - me->data_len)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700227 // Check #1 makes sure subtraction in RoomLeft will not wrap around
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100228 if(! UsefulOutBuf_WillItFit(pMe, NewData.len)) { // Check #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700229 // The new data will not fit into the the buffer.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100230 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700231 return;
232 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800233
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700234 /* 2. Check the Insertion Position */
Laurence Lundblade61209742019-11-08 13:16:43 -0800235 // This, with Check #1, also confirms that uInsertionPos <= me->data_len and
236 // that uInsertionPos + pMe->UB.ptr will not wrap around the end of the
237 // address space.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100238 if(uInsertionPos > pMe->data_len) { // Check #3
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700239 // Off the end of the valid data in the buffer.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100240 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700241 return;
242 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800243
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700244 /* 3. Slide existing data to the right */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100245 uint8_t *pSourceOfMove = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; // PtrMath #1
246 size_t uNumBytesToMove = pMe->data_len - uInsertionPos; // PtrMath #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700247 uint8_t *pDestinationOfMove = pSourceOfMove + NewData.len; // PtrMath #3
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800248
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100249 if(uNumBytesToMove && pMe->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800250 // To know memmove won't go off end of destination, see PtrMath #4
Laurence Lundblade61209742019-11-08 13:16:43 -0800251 // Use memove because it handles overlapping buffers
Laurence Lundblade74f68412018-09-13 12:18:49 -0700252 memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700253 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800254
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700255 /* 4. Put the new data in */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100256 uint8_t *pInsertionPoint = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; // PtrMath #5
257 if(pMe->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800258 // To know memmove won't go off end of destination, see PtrMath #6
Laurence Lundblade74f68412018-09-13 12:18:49 -0700259 memmove(pInsertionPoint, NewData.ptr, NewData.len);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700260 }
Laurence Lundblade61209742019-11-08 13:16:43 -0800261 pMe->data_len += NewData.len;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700262}
263
264
265/*
266 Rationale that describes why the above pointer math is safe
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800267
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700268 PtrMath #1 will never wrap around over because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800269 Check #0 in UsefulOutBuf_Init makes sure me->UB.ptr + me->UB.len doesn't wrap
270 Check #1 makes sure me->data_len is less than me->UB.len
271 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800272
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700273 PtrMath #2 will never wrap around under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800274 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800275
Laurence Lundblade61209742019-11-08 13:16:43 -0800276 PtrMath #3 will never wrap around over because
277 PtrMath #1 is checked resulting in pSourceOfMove being between me->UB.ptr and me->UB.ptr + me->data_len
278 Check #2 that NewData.len will fit in the unused space left in me->UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800279
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700280 PtrMath #4 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800281 Calculation for extent or memmove is uRoomInDestination = me->UB.len - (uInsertionPos + NewData.len)
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700282 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700283 Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
284 This algebraically rearranges to me->size > uInsertionPos + NewData.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800285
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700286 PtrMath #5 is exactly the same as PtrMath #1
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800287
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700288 PtrMath #6 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800289 Calculation for extent of memove is uRoomInDestination = me->UB.len - uInsertionPos;
290 Check #1 makes sure me->data_len is less than me->size
291 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700292 */
293
294
295/*
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800296 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700297 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100298UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700299{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100300 if(pMe->err) {
Laurence Lundblade2296db52018-09-14 18:08:39 -0700301 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700302 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800303
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100304 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
305 pMe->err = 1;
Laurence Lundblade2296db52018-09-14 18:08:39 -0700306 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700307 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800308
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100309 return (UsefulBufC){pMe->UB.ptr, pMe->data_len};
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700310}
311
312
313/*
314 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800315
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530316 Copy out the data accumulated in to the output buffer.
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700317 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100318UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pMe, UsefulBuf pDest)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700319{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100320 const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530321 if(UsefulBuf_IsNULLC(Tmp)) {
322 return NULLUsefulBufC;
323 }
324 return UsefulBuf_Copy(pDest, Tmp);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700325}
326
327
328
329
330/*
331 Public function -- see UsefulBuf.h
332
333 The core of UsefulInputBuf -- consume some bytes without going off the end of the buffer.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800334
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700335 Code Reviewers: THIS FUNCTION DOES POINTER MATH
336 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100337const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pMe, size_t uAmount)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700338{
339 // Already in error state. Do nothing.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100340 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700341 return NULL;
342 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800343
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100344 if(!UsefulInputBuf_BytesAvailable(pMe, uAmount)) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700345 // The number of bytes asked for at current position are more than available
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100346 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700347 return NULL;
348 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800349
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700350 // This is going to succeed
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100351 const void * const result = ((uint8_t *)pMe->UB.ptr) + pMe->cursor;
352 pMe->cursor += uAmount; // this will not overflow because of check using UsefulInputBuf_BytesAvailable()
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700353 return result;
354}
355