/* ==========================================================================
 * Copyright (c) 2016-2018, The Linux Foundation.
 * Copyright (c) 2018-2024, Laurence Lundblade.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors, nor the name "Laurence Lundblade" may be used to
 *       endorse or promote products derived from this software without
 *       specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ========================================================================= */



/*=============================================================================
 FILE:  UsefulBuf.c

 DESCRIPTION:  General purpose input and output buffers

 EDIT HISTORY FOR FILE:

 This section contains comments describing changes made to the module.
 Notice that changes are listed in reverse chronological order.

 when        who          what, where, why
 --------    ----         ---------------------------------------------------
 21/05/2024  llundblade   Comment formatting and some code tidiness.
 19/12/2022  llundblade   Don't pass NULL to memmove when adding empty data.
 4/11/2022   llundblade   Add GetOutPlace and Advance to UsefulOutBuf
 3/6/2021    mcr/llundblade  Fix warnings related to --Wcast-qual
 01/28/2020  llundblade   Refine integer signedness to quiet static analysis.
 01/08/2020  llundblade   Documentation corrections & improved code formatting.
 11/08/2019  llundblade   Re check pointer math and update comments
 3/6/2019    llundblade   Add UsefulBuf_IsValue()
 09/07/17    llundbla     Fix critical bug in UsefulBuf_Find() -- a read off
                          the end of memory when the bytes to find is longer
                          than the bytes to search.
 06/27/17    llundbla     Fix UsefulBuf_Compare() bug. Only affected comparison
                          for < or > for unequal length buffers.  Added
                          UsefulBuf_Set() function.
 05/30/17    llundbla     Functions for NULL UsefulBufs and const / unconst
 11/13/16    llundbla     Initial Version.

 ============================================================================*/

#include "UsefulBuf.h"

/* used to catch use of uninitialized or corrupted UsefulOutBuf */
#define USEFUL_OUT_BUF_MAGIC  (0x0B0F)


/*
 * Public function -- see UsefulBuf.h
 */
UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
{
   /* Do this with subtraction so it doesn't give an erroneous
    * result if uOffset + Src.len overflows. Right side is equivalent to
    * uOffset + Src.len > Dest.len
    */
   if(uOffset > Dest.len || Src.len > Dest.len - uOffset) {
      return NULLUsefulBufC;
   }

   memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);

   return (UsefulBufC){Dest.ptr, Src.len + uOffset};
}


/*
 * Public function -- see UsefulBuf.h
 */
int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
{
   /* Use comparisons rather than subtracting lengths to
    * return an int instead of a size_t
    */
   if(UB1.len < UB2.len) {
      return -1;
   } else if (UB1.len > UB2.len) {
      return 1;
   } /* else UB1.len == UB2.len */

   return memcmp(UB1.ptr, UB2.ptr, UB1.len);
}


/*
 * Public function -- see UsefulBuf.h
 */
size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
{
   if(UsefulBuf_IsNULLOrEmptyC(UB)) {
      /* Not a match */
      return 0;
   }

   const uint8_t * const pEnd = (const uint8_t *)UB.ptr + UB.len;
   for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
      if(*p != uValue) {
         /* Byte didn't match */
         /* Cast from signed to unsigned. Safe because the loop increments.*/
         return (size_t)(p - (const uint8_t *)UB.ptr);
      }
   }

   /* Success. All bytes matched */
   return SIZE_MAX;
}


/*
 * Public function -- see UsefulBuf.h
 */
size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
{
   if(BytesToSearch.len < BytesToFind.len) {
      return SIZE_MAX;
   }

   for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
      UsefulBufC SearchNext;

      SearchNext.ptr = ((const uint8_t *)BytesToSearch.ptr) + uPos;
      SearchNext.len = BytesToFind.len;
      if(!UsefulBuf_Compare(SearchNext, BytesToFind)) {
         return uPos;
      }
   }

   return SIZE_MAX;
}


/*
 * Public function -- see UsefulBuf.h
 *
 * Code Reviewers: THIS FUNCTION DOES POINTER MATH
 */
void UsefulOutBuf_Init(UsefulOutBuf *pMe, UsefulBuf Storage)
{
    pMe->magic  = USEFUL_OUT_BUF_MAGIC;
    UsefulOutBuf_Reset(pMe);
    pMe->UB     = Storage;

#if 0
   /* This check is off by default.
    *
    * The following check fails on ThreadX
    *
    * Sanity check on the pointer and size to be sure we are not
    * passed a buffer that goes off the end of the address space.
    * Given this test, we know that all unsigned lengths less than
    * me->size are valid and won't wrap in any pointer additions
    * based off of pStorage in the rest of this code.
    */
    const uintptr_t ptrM = UINTPTR_MAX - Storage.len;
    if(Storage.ptr && (uintptr_t)Storage.ptr > ptrM) /* Check #0 */
        me->err = 1;
#endif
}



/*
 * Public function -- see UsefulBuf.h
 *
 * The core of UsefulOutBuf -- put some bytes in the buffer without writing off
 *                             the end of it.
 *
 * Code Reviewers: THIS FUNCTION DOES POINTER MATH
 *
 * This function inserts the source buffer, NewData, into the destination
 * buffer, me->UB.ptr.
 *
 * Destination is represented as:
 *   me->UB.ptr -- start of the buffer
 *   me->UB.len -- size of the buffer UB.ptr
 *   me->data_len -- length of value data in UB
 *
 * Source is data:
 *   NewData.ptr -- start of source buffer
 *   NewData.len -- length of source buffer
 *
 * Insertion point:
 *   uInsertionPos.
 *
 * Steps:
 *
 * 0. Corruption checks on UsefulOutBuf
 *
 * 1. Figure out if the new data will fit or not
 *
 * 2. Is insertion position in the range of valid data?
 *
 * 3. If insertion point is not at the end, slide data to the right of the
 *    insertion point to the right
 *
 * 4. Put the new data in at the insertion position.
 *
 */
void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pMe, UsefulBufC NewData, size_t uInsertionPos)
{
   if(pMe->err) {
      /* Already in error state. */
      return;
   }

   /* 0. Sanity check the UsefulOutBuf structure
    * A "counter measure". If magic number is not the right number it
    * probably means pMe was not initialized or it was corrupted. Attackers
    * can defeat this, but it is a hurdle and does good with very
    * little code.
    */
   if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
      pMe->err = 1;
      return;  /* Magic number is wrong due to uninitalization or corrption */
   }

   /* Make sure valid data is less than buffer size. This would only occur
    * if there was corruption of me, but it is also part of the checks to
    * be sure there is no pointer arithmatic under/overflow.
    */
   if(pMe->data_len > pMe->UB.len) {  /* Check #1 */
      pMe->err = 1;
      /* Offset of valid data is off the end of the UsefulOutBuf due to
       * uninitialization or corruption
       */
      return;
   }

   /* 1. Will it fit?
    * WillItFit() is the same as: NewData.len <= (me->UB.len - me->data_len)
    * Check #1 makes sure subtraction in RoomLeft will not wrap around
    */
   if(! UsefulOutBuf_WillItFit(pMe, NewData.len)) { /* Check #2 */
      /* The new data will not fit into the the buffer. */
      pMe->err = 1;
      return;
   }

   /* 2. Check the Insertion Position
    * This, with Check #1, also confirms that uInsertionPos <= me->data_len and
    * that uInsertionPos + pMe->UB.ptr will not wrap around the end of the
    * address space.
    */
   if(uInsertionPos > pMe->data_len) { /* Check #3 */
      /* Off the end of the valid data in the buffer. */
      pMe->err = 1;
      return;
   }

   /* 3. Slide existing data to the right */
   if (!UsefulOutBuf_IsBufferNULL(pMe)) {
      uint8_t *pSourceOfMove      = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; /* PtrMath #1 */
      size_t   uNumBytesToMove    = pMe->data_len - uInsertionPos; /* PtrMath #2 */
      uint8_t *pDestinationOfMove = pSourceOfMove + NewData.len; /* PtrMath #3*/

      /* To know memmove won't go off end of destination, see PtrMath #4.
       * Use memove because it handles overlapping buffers
       */
      memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);

      /* 4. Put the new data in */
      uint8_t *pInsertionPoint = pSourceOfMove;
      /* To know memmove won't go off end of destination, see PtrMath #5 */
      if(NewData.ptr != NULL) {
         memmove(pInsertionPoint, NewData.ptr, NewData.len);
      }
   }

   pMe->data_len += NewData.len;
}


/*
 * Rationale that describes why the above pointer math is safe
 *
 * PtrMath #1 will never wrap around over because
 *   Check #0 in UsefulOutBuf_Init that me->UB.ptr + me->UB.len doesn't wrap
 *   Check #1 makes sure me->data_len is less than me->UB.len
 *   Check #3 makes sure uInsertionPos is less than me->data_len
 *
 * PtrMath #2 will never wrap around under because
 *   Check #3 makes sure uInsertionPos is less than me->data_len
 *
 * PtrMath #3 will never wrap around over because
 *   PtrMath #1 is checked resulting in pSourceOfMove being between me->UB.ptr and me->UB.ptr + me->data_len
 *   Check #2 that NewData.len will fit in the unused space left in me->UB
 *
 * PtrMath #4 will never wrap under because
 *   Calculation for extent or memmove is uRoomInDestination  = me->UB.len - (uInsertionPos + NewData.len)
 *   Check #3 makes sure uInsertionPos is less than me->data_len
 *   Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
 *   This algebraically rearranges to me->size > uInsertionPos + NewData.len
 *
 * PtrMath #5 will never wrap under because
 *   Calculation for extent of memove is uRoomInDestination = me->UB.len - uInsertionPos;
 *   Check #1 makes sure me->data_len is less than me->size
 *   Check #3 makes sure uInsertionPos is less than me->data_len
 */


/*
 * Public function for advancing data length. See qcbor/UsefulBuf.h
 */
void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
{
   /* This function is a trimmed down version of
    * UsefulOutBuf_InsertUsefulBuf(). This could be combined with the
    * code in UsefulOutBuf_InsertUsefulBuf(), but that would make
    * UsefulOutBuf_InsertUsefulBuf() bigger and this will be very
    * rarely used.
    */

   if(pMe->err) {
      /* Already in error state. */
      return;
   }

   /* 0. Sanity check the UsefulOutBuf structure
    *
    * A "counter measure". If magic number is not the right number it
    * probably means me was not initialized or it was
    * corrupted. Attackers can defeat this, but it is a hurdle and
    * does good with very little code.
    */
   if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
      pMe->err = 1;
      return;  /* Magic number is wrong due to uninitalization or corrption */
   }

   /* Make sure valid data is less than buffer size. This would only
    * occur if there was corruption of me, but it is also part of the
    * checks to be sure there is no pointer arithmatic
    * under/overflow.
    */
   if(pMe->data_len > pMe->UB.len) {  /* Check #1 */
      pMe->err = 1;
      /* Offset of valid data is off the end of the UsefulOutBuf due
       * to uninitialization or corruption.
       */
      return;
   }

   /* 1. Will it fit?
    *
    * WillItFit() is the same as: NewData.len <= (me->UB.len -
    * me->data_len) Check #1 makes sure subtraction in RoomLeft will
    * not wrap around
    */
   if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
      /* The new data will not fit into the the buffer. */
      pMe->err = 1;
      return;
   }

   pMe->data_len += uAmount;
}


/*
 * Public function -- see UsefulBuf.h
 */
UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)
{
   if(pMe->err) {
      return NULLUsefulBufC;
   }

   if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
      pMe->err = 1;
      return NULLUsefulBufC;
   }

   return (UsefulBufC){pMe->UB.ptr, pMe->data_len};
}


/*
 * Public function -- see UsefulBuf.h
 *
 * Copy out the data accumulated in to the output buffer.
 */
UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pMe, UsefulBuf pDest)
{
   const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
   if(UsefulBuf_IsNULLC(Tmp)) {
      return NULLUsefulBufC;
   }
   return UsefulBuf_Copy(pDest, Tmp);
}




/*
 * Public function -- see UsefulBuf.h
 *
 * The core of UsefulInputBuf -- consume bytes without going off end of buffer.
 *
 * Code Reviewers: THIS FUNCTION DOES POINTER MATH
 */
const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pMe, size_t uAmount)
{
   /* Already in error state. Do nothing. */
   if(pMe->err) {
      return NULL;
   }

   if(!UsefulInputBuf_BytesAvailable(pMe, uAmount)) {
      /* Number of bytes asked for is more than available */
      pMe->err = 1;
      return NULL;
   }

   /* This is going to succeed */
   const void * const result = ((const uint8_t *)pMe->UB.ptr) + pMe->cursor;
   /* Won't overflow because of check using UsefulInputBuf_BytesAvailable() */
   pMe->cursor += uAmount;
   return result;
}
