blob: d27c1461032d70b9c821fffa209d3ef157a4b038 [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 Lundbladed5e101e2019-03-06 17:23:18 -080044 3/6/2019 llundblade Add UsefulBuf_IsValue()
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080045 09/07/17 llundbla Fix critical bug in UsefulBuf_Find() -- a read off
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070046 the end of memory when the bytes to find is longer
47 than the bytes to search.
48 06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected comparison
49 for < or > for unequal length buffers. Added
50 UsefulBuf_Set() function.
51 05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
52 11/13/16 llundbla Initial Version.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080053
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070054 =====================================================================================*/
55
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070056#include "UsefulBuf.h"
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070057
58#define USEFUL_OUT_BUF_MAGIC (0x0B0F) // used to catch use of uninitialized or corrupted UOBs
59
Laurence Lundblade041ffa52018-10-07 11:43:51 +070060
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053061/*
62 Public function -- see UsefulBuf.h
63 */
Laurence Lundblade041ffa52018-10-07 11:43:51 +070064UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
65{
Laurence Lundblade7566b9f2018-10-12 09:13:32 +080066 // Do this with subtraction so it doesn't give erroneous result if uOffset + Src.len overflows
67 if(uOffset > Dest.len || Src.len > Dest.len - uOffset) { // uOffset + Src.len > Dest.len
68 return NULLUsefulBufC;
69 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080070
Laurence Lundblade570fab52018-10-13 18:28:27 +080071 memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080072
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -080073 return (UsefulBufC){Dest.ptr, Src.len + uOffset};
Laurence Lundblade041ffa52018-10-07 11:43:51 +070074}
75
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053076
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070077/*
78 Public function -- see UsefulBuf.h
79 */
80int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
81{
82 // use the comparisons rather than subtracting lengths to
83 // return an int instead of a size_t
84 if(UB1.len < UB2.len) {
85 return -1;
86 } else if (UB1.len > UB2.len) {
87 return 1;
88 } // else UB1.len == UB2.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080089
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070090 return memcmp(UB1.ptr, UB2.ptr, UB1.len);
91}
92
93
Laurence Lundbladed5e101e2019-03-06 17:23:18 -080094/*
95 Public function -- see UsefulBuf.h
96 */
97size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
98{
99 if(UsefulBuf_IsNULLOrEmptyC(UB)) {
100 /* Not a match */
101 return 0;
102 }
103
104 const uint8_t * const pEnd = (uint8_t *)UB.ptr + UB.len;
105 for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
106 if(*p != uValue) {
107 /* Byte didn't match */
108 return p - (uint8_t *)UB.ptr;
109 }
110 }
111
112 /* Success. All bytes matched */
113 return SIZE_MAX;
114}
115
Laurence Lundbladeda3f0822018-09-18 19:49:02 -0700116
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700117/*
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530118 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700119 */
120size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
121{
122 if(BytesToSearch.len < BytesToFind.len) {
123 return SIZE_MAX;
124 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800125
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700126 for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
127 if(!UsefulBuf_Compare((UsefulBufC){((uint8_t *)BytesToSearch.ptr) + uPos, BytesToFind.len}, BytesToFind)) {
128 return uPos;
129 }
130 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800131
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700132 return SIZE_MAX;
133}
134
135
136/*
137 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800138
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530139 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700140 */
Laurence Lundblade2296db52018-09-14 18:08:39 -0700141void UsefulOutBuf_Init(UsefulOutBuf *me, UsefulBuf Storage)
142{
143 me->magic = USEFUL_OUT_BUF_MAGIC;
144 UsefulOutBuf_Reset(me);
145 me->UB = Storage;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800146
Laurence Lundblade2296db52018-09-14 18:08:39 -0700147#if 0
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530148 // This check is off by default.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800149
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530150 // The following check fails on ThreadX
151
Laurence Lundblade2296db52018-09-14 18:08:39 -0700152 // Sanity check on the pointer and size to be sure we are not
153 // passed a buffer that goes off the end of the address space.
154 // Given this test, we know that all unsigned lengths less than
155 // me->size are valid and won't wrap in any pointer additions
156 // based off of pStorage in the rest of this code.
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530157 const uintptr_t ptrM = UINTPTR_MAX - Storage.len;
158 if(Storage.ptr && (uintptr_t)Storage.ptr > ptrM) // Check #0
Laurence Lundblade2296db52018-09-14 18:08:39 -0700159 me->err = 1;
160#endif
161}
162
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700163
164
165/*
166 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800167
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700168 The core of UsefulOutBuf -- put some bytes in the buffer without writing off the end of it.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800169
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700170 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800171
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700172 This function inserts the source buffer, NewData, into the destination buffer, me->UB.ptr.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800173
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700174 Destination is represented as:
175 me->UB.ptr -- start of the buffer
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700176 me->UB.len -- size of the buffer UB.ptr
177 me->data_len -- length of value data in UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800178
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700179 Source is data:
180 NewData.ptr -- start of source buffer
181 NewData.len -- length of source buffer
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800182
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700183 Insertion point:
184 uInsertionPos.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800185
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700186 Steps:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800187
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700188 0. Corruption checks on UsefulOutBuf
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800189
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700190 1. Figure out if the new data will fit or not
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800191
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700192 2. Is insertion position in the range of valid data?
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800193
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700194 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 -0800195
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700196 4. Put the new data in at the insertion position.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800197
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700198 */
199void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData, size_t uInsertionPos)
200{
201 if(me->err) {
202 // Already in error state.
203 return;
204 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800205
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700206 /* 0. Sanity check the UsefulOutBuf structure */
207 // A "counter measure". If magic number is not the right number it
208 // probably means me was not initialized or it was corrupted. Attackers
209 // can defeat this, but it is a hurdle and does good with very
210 // little code.
211 if(me->magic != USEFUL_OUT_BUF_MAGIC) {
212 me->err = 1;
213 return; // Magic number is wrong due to uninitalization or corrption
214 }
215
216 // Make sure valid data is less than buffer size. This would only occur
217 // if there was corruption of me, but it is also part of the checks to
218 // be sure there is no pointer arithmatic under/overflow.
Laurence Lundblade2296db52018-09-14 18:08:39 -0700219 if(me->data_len > me->UB.len) { // Check #1
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700220 me->err = 1;
221 return; // Offset of valid data is off the end of the UsefulOutBuf due to uninitialization or corruption
222 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800223
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700224 /* 1. Will it fit? */
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700225 // WillItFit() is the same as: NewData.len <= (me->size - me->data_len)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700226 // Check #1 makes sure subtraction in RoomLeft will not wrap around
227 if(! UsefulOutBuf_WillItFit(me, NewData.len)) { // Check #2
228 // The new data will not fit into the the buffer.
229 me->err = 1;
230 return;
231 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800232
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700233 /* 2. Check the Insertion Position */
Laurence Lundblade56a79322019-01-10 09:12:37 -0800234 // This, with Check #1, also confirms that uInsertionPos <= me->data_len
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530235 if(uInsertionPos > me->data_len) { // Check #3
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700236 // Off the end of the valid data in the buffer.
237 me->err = 1;
238 return;
239 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800240
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700241 /* 3. Slide existing data to the right */
242 uint8_t *pSourceOfMove = ((uint8_t *)me->UB.ptr) + uInsertionPos; // PtrMath #1
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700243 size_t uNumBytesToMove = me->data_len - uInsertionPos; // PtrMath #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700244 uint8_t *pDestinationOfMove = pSourceOfMove + NewData.len; // PtrMath #3
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800245
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700246 if(uNumBytesToMove && me->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800247 // To know memmove won't go off end of destination, see PtrMath #4
Laurence Lundblade74f68412018-09-13 12:18:49 -0700248 memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700249 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800250
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700251 /* 4. Put the new data in */
252 uint8_t *pInsertionPoint = ((uint8_t *)me->UB.ptr) + uInsertionPos; // PtrMath #5
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700253 if(me->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800254 // To know memmove won't go off end of destination, see PtrMath #6
Laurence Lundblade74f68412018-09-13 12:18:49 -0700255 memmove(pInsertionPoint, NewData.ptr, NewData.len);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700256 }
Laurence Lundblade2296db52018-09-14 18:08:39 -0700257 me->data_len += NewData.len ;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700258}
259
260
261/*
262 Rationale that describes why the above pointer math is safe
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800263
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700264 PtrMath #1 will never wrap around over because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800265 Check #0 in UsefulOutBuf_Init makes sure me->UB.ptr + me->UB.len doesn't wrap
266 Check #1 makes sure me->data_len is less than me->UB.len
267 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800268
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700269 PtrMath #2 will never wrap around under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800270 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800271
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700272 PtrMath #3 will never wrap around over because todo
Laurence Lundblade56a79322019-01-10 09:12:37 -0800273 PtrMath #1 is checked resulting in pSourceOfMove being between me->UB.ptr and a maximum valid ptr
274 Check #2 that NewData.len will fit
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800275
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700276 PtrMath #4 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800277 Calculation for extent or memmove is uRoomInDestination = me->UB.len - (uInsertionPos + NewData.len)
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700278 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700279 Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
280 This algebraically rearranges to me->size > uInsertionPos + NewData.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800281
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700282 PtrMath #5 is exactly the same as PtrMath #1
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800283
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700284 PtrMath #6 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800285 Calculation for extent of memove is uRoomInDestination = me->UB.len - uInsertionPos;
286 Check #1 makes sure me->data_len is less than me->size
287 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700288 */
289
290
291/*
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800292 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700293 */
Laurence Lundblade2296db52018-09-14 18:08:39 -0700294UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *me)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700295{
296 if(me->err) {
Laurence Lundblade2296db52018-09-14 18:08:39 -0700297 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700298 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800299
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700300 if(me->magic != USEFUL_OUT_BUF_MAGIC) {
301 me->err = 1;
Laurence Lundblade2296db52018-09-14 18:08:39 -0700302 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700303 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800304
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800305 return (UsefulBufC){me->UB.ptr,me->data_len};
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700306}
307
308
309/*
310 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800311
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530312 Copy out the data accumulated in to the output buffer.
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700313 */
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530314UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *me, UsefulBuf pDest)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700315{
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -0800316 const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(me);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530317 if(UsefulBuf_IsNULLC(Tmp)) {
318 return NULLUsefulBufC;
319 }
320 return UsefulBuf_Copy(pDest, Tmp);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700321}
322
323
324
325
326/*
327 Public function -- see UsefulBuf.h
328
329 The core of UsefulInputBuf -- consume some bytes without going off the end of the buffer.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800330
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700331 Code Reviewers: THIS FUNCTION DOES POINTER MATH
332 */
333const void * UsefulInputBuf_GetBytes(UsefulInputBuf *me, size_t uAmount)
334{
335 // Already in error state. Do nothing.
336 if(me->err) {
337 return NULL;
338 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800339
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700340 if(!UsefulInputBuf_BytesAvailable(me, uAmount)) {
341 // The number of bytes asked for at current position are more than available
342 me->err = 1;
343 return NULL;
344 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800345
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700346 // This is going to succeed
347 const void * const result = ((uint8_t *)me->UB.ptr) + me->cursor;
348 me->cursor += uAmount; // this will not overflow because of check using UsefulInputBuf_BytesAvailable()
349 return result;
350}
351