blob: f5149a5a661aa7fb43fe135c4fbde85b00059262 [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 Lundbladeb24faef2022-04-26 11:03:08 -06003 Copyright (c) 2018-2022, 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 Lundbladeee851742020-01-08 08:37:05 -080030 =============================================================================*/
Laurence Lundblade624405d2018-09-18 20:10:47 -070031
Laurence Lundbladeee851742020-01-08 08:37:05 -080032/*=============================================================================
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070033 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 Lundbladeee851742020-01-08 08:37:05 -080042 when who what, where, why
43 -------- ---- ---------------------------------------------------
Laurence Lundbladeb24faef2022-04-26 11:03:08 -060044 4/11/2022 llundblade Add GetOutPlace and Advance to UsefulOutBuf
Laurence Lundbladeb9702452021-03-08 21:02:57 -080045 3/6/2021 mcr/llundblade Fix warnings related to --Wcast-qual
Laurence Lundblade06350ea2020-01-27 19:32:40 -080046 01/28/2020 llundblade Refine integer signedness to quiet static analysis.
47 01/08/2020 llundblade Documentation corrections & improved code formatting.
Laurence Lundbladeee851742020-01-08 08:37:05 -080048 11/08/2019 llundblade Re check pointer math and update comments
49 3/6/2019 llundblade Add UsefulBuf_IsValue()
50 09/07/17 llundbla Fix critical bug in UsefulBuf_Find() -- a read off
51 the end of memory when the bytes to find is longer
52 than the bytes to search.
53 06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected comparison
54 for < or > for unequal length buffers. Added
55 UsefulBuf_Set() function.
56 05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
57 11/13/16 llundbla Initial Version.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080058
Laurence Lundbladeee851742020-01-08 08:37:05 -080059 ============================================================================*/
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070060
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070061#include "UsefulBuf.h"
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070062
Laurence Lundbladeee851742020-01-08 08:37:05 -080063// used to catch use of uninitialized or corrupted UsefulOutBuf
64#define USEFUL_OUT_BUF_MAGIC (0x0B0F)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070065
Laurence Lundblade041ffa52018-10-07 11:43:51 +070066
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053067/*
68 Public function -- see UsefulBuf.h
69 */
Laurence Lundblade041ffa52018-10-07 11:43:51 +070070UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
71{
Laurence Lundbladeee851742020-01-08 08:37:05 -080072 // Do this with subtraction so it doesn't give erroneous
73 // result if uOffset + Src.len overflows
Laurence Lundblade7566b9f2018-10-12 09:13:32 +080074 if(uOffset > Dest.len || Src.len > Dest.len - uOffset) { // uOffset + Src.len > Dest.len
75 return NULLUsefulBufC;
76 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080077
Laurence Lundblade570fab52018-10-13 18:28:27 +080078 memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080079
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -080080 return (UsefulBufC){Dest.ptr, Src.len + uOffset};
Laurence Lundblade041ffa52018-10-07 11:43:51 +070081}
82
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053083
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070084/*
85 Public function -- see UsefulBuf.h
86 */
87int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
88{
89 // use the comparisons rather than subtracting lengths to
90 // return an int instead of a size_t
91 if(UB1.len < UB2.len) {
92 return -1;
93 } else if (UB1.len > UB2.len) {
94 return 1;
95 } // else UB1.len == UB2.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080096
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070097 return memcmp(UB1.ptr, UB2.ptr, UB1.len);
98}
99
100
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800101/*
102 Public function -- see UsefulBuf.h
103 */
104size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
105{
106 if(UsefulBuf_IsNULLOrEmptyC(UB)) {
107 /* Not a match */
108 return 0;
109 }
110
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800111 const uint8_t * const pEnd = (const uint8_t *)UB.ptr + UB.len;
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800112 for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
113 if(*p != uValue) {
114 /* Byte didn't match */
Laurence Lundblade06350ea2020-01-27 19:32:40 -0800115 /* Cast from signed to unsigned . Safe because the loop increments.*/
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800116 return (size_t)(p - (const uint8_t *)UB.ptr);
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800117 }
118 }
119
120 /* Success. All bytes matched */
121 return SIZE_MAX;
122}
123
Laurence Lundbladeda3f0822018-09-18 19:49:02 -0700124
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700125/*
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530126 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700127 */
128size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
129{
130 if(BytesToSearch.len < BytesToFind.len) {
131 return SIZE_MAX;
132 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800133
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700134 for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800135 if(!UsefulBuf_Compare((UsefulBufC){((const uint8_t *)BytesToSearch.ptr) + uPos, BytesToFind.len}, BytesToFind)) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700136 return uPos;
137 }
138 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800139
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700140 return SIZE_MAX;
141}
142
143
144/*
145 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800146
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530147 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700148 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100149void UsefulOutBuf_Init(UsefulOutBuf *pMe, UsefulBuf Storage)
Laurence Lundblade2296db52018-09-14 18:08:39 -0700150{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100151 pMe->magic = USEFUL_OUT_BUF_MAGIC;
152 UsefulOutBuf_Reset(pMe);
153 pMe->UB = Storage;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800154
Laurence Lundblade2296db52018-09-14 18:08:39 -0700155#if 0
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530156 // This check is off by default.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800157
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530158 // The following check fails on ThreadX
159
Laurence Lundblade2296db52018-09-14 18:08:39 -0700160 // Sanity check on the pointer and size to be sure we are not
161 // passed a buffer that goes off the end of the address space.
162 // Given this test, we know that all unsigned lengths less than
163 // me->size are valid and won't wrap in any pointer additions
164 // based off of pStorage in the rest of this code.
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530165 const uintptr_t ptrM = UINTPTR_MAX - Storage.len;
166 if(Storage.ptr && (uintptr_t)Storage.ptr > ptrM) // Check #0
Laurence Lundblade2296db52018-09-14 18:08:39 -0700167 me->err = 1;
168#endif
169}
170
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700171
172
173/*
174 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800175
Laurence Lundbladeee851742020-01-08 08:37:05 -0800176 The core of UsefulOutBuf -- put some bytes in the buffer without writing off
177 the end of it.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800178
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700179 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800180
Laurence Lundbladeee851742020-01-08 08:37:05 -0800181 This function inserts the source buffer, NewData, into the destination
182 buffer, me->UB.ptr.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800183
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700184 Destination is represented as:
185 me->UB.ptr -- start of the buffer
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700186 me->UB.len -- size of the buffer UB.ptr
187 me->data_len -- length of value data in UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800188
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700189 Source is data:
190 NewData.ptr -- start of source buffer
191 NewData.len -- length of source buffer
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800192
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700193 Insertion point:
194 uInsertionPos.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800195
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700196 Steps:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800197
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700198 0. Corruption checks on UsefulOutBuf
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800199
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700200 1. Figure out if the new data will fit or not
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800201
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700202 2. Is insertion position in the range of valid data?
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800203
Laurence Lundbladeee851742020-01-08 08:37:05 -0800204 3. If insertion point is not at the end, slide data to the right of the
205 insertion point to the right
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800206
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700207 4. Put the new data in at the insertion position.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800208
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700209 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100210void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pMe, UsefulBufC NewData, size_t uInsertionPos)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700211{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100212 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700213 // Already in error state.
214 return;
215 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800216
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700217 /* 0. Sanity check the UsefulOutBuf structure */
218 // A "counter measure". If magic number is not the right number it
219 // probably means me was not initialized or it was corrupted. Attackers
220 // can defeat this, but it is a hurdle and does good with very
221 // little code.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100222 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
223 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700224 return; // Magic number is wrong due to uninitalization or corrption
225 }
226
227 // Make sure valid data is less than buffer size. This would only occur
228 // if there was corruption of me, but it is also part of the checks to
229 // be sure there is no pointer arithmatic under/overflow.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100230 if(pMe->data_len > pMe->UB.len) { // Check #1
231 pMe->err = 1;
Laurence Lundbladeee851742020-01-08 08:37:05 -0800232 // Offset of valid data is off the end of the UsefulOutBuf due to
233 // uninitialization or corruption
234 return;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700235 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800236
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700237 /* 1. Will it fit? */
Laurence Lundblade61209742019-11-08 13:16:43 -0800238 // WillItFit() is the same as: NewData.len <= (me->UB.len - me->data_len)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700239 // Check #1 makes sure subtraction in RoomLeft will not wrap around
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100240 if(! UsefulOutBuf_WillItFit(pMe, NewData.len)) { // Check #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700241 // The new data will not fit into the the buffer.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100242 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700243 return;
244 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800245
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700246 /* 2. Check the Insertion Position */
Laurence Lundblade61209742019-11-08 13:16:43 -0800247 // This, with Check #1, also confirms that uInsertionPos <= me->data_len and
248 // that uInsertionPos + pMe->UB.ptr will not wrap around the end of the
249 // address space.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100250 if(uInsertionPos > pMe->data_len) { // Check #3
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700251 // Off the end of the valid data in the buffer.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100252 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700253 return;
254 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800255
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700256 /* 3. Slide existing data to the right */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100257 uint8_t *pSourceOfMove = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; // PtrMath #1
258 size_t uNumBytesToMove = pMe->data_len - uInsertionPos; // PtrMath #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700259 uint8_t *pDestinationOfMove = pSourceOfMove + NewData.len; // PtrMath #3
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800260
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100261 if(uNumBytesToMove && pMe->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800262 // To know memmove won't go off end of destination, see PtrMath #4
Laurence Lundblade61209742019-11-08 13:16:43 -0800263 // Use memove because it handles overlapping buffers
Laurence Lundblade74f68412018-09-13 12:18:49 -0700264 memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700265 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800266
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700267 /* 4. Put the new data in */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100268 uint8_t *pInsertionPoint = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; // PtrMath #5
269 if(pMe->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800270 // To know memmove won't go off end of destination, see PtrMath #6
Laurence Lundblade74f68412018-09-13 12:18:49 -0700271 memmove(pInsertionPoint, NewData.ptr, NewData.len);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700272 }
Laurence Lundblade61209742019-11-08 13:16:43 -0800273 pMe->data_len += NewData.len;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700274}
275
276
277/*
278 Rationale that describes why the above pointer math is safe
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800279
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700280 PtrMath #1 will never wrap around over because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800281 Check #0 in UsefulOutBuf_Init makes sure me->UB.ptr + me->UB.len doesn't wrap
282 Check #1 makes sure me->data_len is less than me->UB.len
283 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800284
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700285 PtrMath #2 will never wrap around under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800286 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800287
Laurence Lundblade61209742019-11-08 13:16:43 -0800288 PtrMath #3 will never wrap around over because
289 PtrMath #1 is checked resulting in pSourceOfMove being between me->UB.ptr and me->UB.ptr + me->data_len
290 Check #2 that NewData.len will fit in the unused space left in me->UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800291
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700292 PtrMath #4 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800293 Calculation for extent or memmove is uRoomInDestination = me->UB.len - (uInsertionPos + NewData.len)
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700294 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700295 Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
296 This algebraically rearranges to me->size > uInsertionPos + NewData.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800297
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700298 PtrMath #5 is exactly the same as PtrMath #1
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800299
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700300 PtrMath #6 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800301 Calculation for extent of memove is uRoomInDestination = me->UB.len - uInsertionPos;
302 Check #1 makes sure me->data_len is less than me->size
303 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700304 */
305
306
307/*
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600308 * Public function for advancing data length. See qcbor/UsefulBuf.h
309 */
310void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
311{
312 /* This function is a trimmed down version of
313 * UsefulOutBuf_InsertUsefulBuf(). This could be combined with the
314 * code in UsefulOutBuf_InsertUsefulBuf(), but that would make
315 * UsefulOutBuf_InsertUsefulBuf() bigger and this will be very
316 * rarely used.
317 */
318
319 if(pMe->err) {
320 /* Already in error state. */
321 return;
322 }
323
324 /* 0. Sanity check the UsefulOutBuf structure
325 *
326 * A "counter measure". If magic number is not the right number it
327 * probably means me was not initialized or it was
328 * corrupted. Attackers can defeat this, but it is a hurdle and
329 * does good with very little code.
330 */
331 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
332 pMe->err = 1;
333 return; /* Magic number is wrong due to uninitalization or corrption */
334 }
335
336 /* Make sure valid data is less than buffer size. This would only
337 * occur if there was corruption of me, but it is also part of the
338 * checks to be sure there is no pointer arithmatic
339 * under/overflow.
340 */
341 if(pMe->data_len > pMe->UB.len) { // Check #1
342 pMe->err = 1;
343 /* Offset of valid data is off the end of the UsefulOutBuf due
344 * to uninitialization or corruption.
345 */
346 return;
347 }
348
349 /* 1. Will it fit?
350 *
351 * WillItFit() is the same as: NewData.len <= (me->UB.len -
352 * me->data_len) Check #1 makes sure subtraction in RoomLeft will
353 * not wrap around
354 */
355 if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
356 /* The new data will not fit into the the buffer. */
357 pMe->err = 1;
358 return;
359 }
360
361 pMe->data_len += uAmount;
362}
363
364
365/*
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800366 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700367 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100368UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700369{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100370 if(pMe->err) {
Laurence Lundblade2296db52018-09-14 18:08:39 -0700371 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700372 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800373
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100374 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
375 pMe->err = 1;
Laurence Lundblade2296db52018-09-14 18:08:39 -0700376 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700377 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800378
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100379 return (UsefulBufC){pMe->UB.ptr, pMe->data_len};
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700380}
381
382
383/*
384 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800385
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530386 Copy out the data accumulated in to the output buffer.
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700387 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100388UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pMe, UsefulBuf pDest)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700389{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100390 const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530391 if(UsefulBuf_IsNULLC(Tmp)) {
392 return NULLUsefulBufC;
393 }
394 return UsefulBuf_Copy(pDest, Tmp);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700395}
396
397
398
399
400/*
401 Public function -- see UsefulBuf.h
402
Laurence Lundbladeee851742020-01-08 08:37:05 -0800403 The core of UsefulInputBuf -- consume bytes without going off end of buffer.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800404
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700405 Code Reviewers: THIS FUNCTION DOES POINTER MATH
406 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100407const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pMe, size_t uAmount)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700408{
409 // Already in error state. Do nothing.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100410 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700411 return NULL;
412 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800413
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100414 if(!UsefulInputBuf_BytesAvailable(pMe, uAmount)) {
Laurence Lundbladeee851742020-01-08 08:37:05 -0800415 // Number of bytes asked for at current position are more than available
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100416 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700417 return NULL;
418 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800419
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700420 // This is going to succeed
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800421 const void * const result = ((const uint8_t *)pMe->UB.ptr) + pMe->cursor;
Laurence Lundbladeee851742020-01-08 08:37:05 -0800422 // Will not overflow because of check using UsefulInputBuf_BytesAvailable()
423 pMe->cursor += uAmount;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700424 return result;
425}
426