Decode conformance for preferred serialization, CDE and dCBOR (#216)

Three conformance modes are added for decoding
- preferred serialization
- CDE
- dCBOR

This checks for sort ordering and duplicate labels when a map is decoded in CDE and dCBOR modes.

It does not support arrays and maps as map labels. They will error out, unless you use maps-as-arrays mode.

Conformance includes checking for shortest form of integers and floats and for dCBOR unification of floats and integers.


* start work on dCBOR decoding enforcement

* checkpoint

* Floating point conformane; ifdef for disabling

* Add more tests

* More dCBOR tests and conformance checks

* More test cases

* Bug fixes and more tests

* Check point stuff

* Map dup and sort order checking kind of working

* more work...

* Finish off UsefulInputBuf_Compare()

* Fix #ifdef fanout

* Fix warnings and #ifdef fan out

* sort & dup checking working and tested

* Fix test ifdef fan out

* Minor fix of one test case

* Another fan out fix

* backout map label checking; doc; test

* Stragglers

---------

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 91ffda1..4177010 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -44,6 +44,7 @@
 
  when        who          what, where, why
  --------    ----         ---------------------------------------------------
+ 1/7/2024    llundblade   Add UsefulInputBuf_Compare().
  21/05/2024  llundblade   Comment formatting and some code tidiness.
  28/02/2022  llundblade   Rearrange UsefulOutBuf_Compare().
  19/11/2023  llundblade   Add UsefulOutBuf_GetOutput().
@@ -452,6 +453,41 @@
  *
  * Code Reviewers: THIS FUNCTION DOES POINTER MATH
  */
+int
+UsefulInputBuf_Compare(UsefulInputBuf *pUInBuf,
+                       const size_t    uOffset1,
+                       const size_t    uLen1,
+                       const size_t    uOffset2,
+                       const size_t    uLen2)
+{
+   UsefulBufC UB1;
+   UsefulBufC UB2;
+
+   const size_t uInputSize = UsefulInputBuf_GetBufferLength(pUInBuf);
+
+   /* Careful length check that works even if uLen1 + uOffset1 > SIZE_MAX */
+   if(uOffset1 > uInputSize || uLen1 > uInputSize - uOffset1) {
+      return 1;
+   }
+   UB1.ptr = (const uint8_t *)pUInBuf->UB.ptr + uOffset1;
+   UB1.len = uLen1;
+
+   /* Careful length check that works even if uLen2 + uOffset2 > SIZE_MAX */
+   if(uOffset2 > uInputSize || uLen2 > uInputSize - uOffset2) {
+      return -1;
+   }
+   UB2.ptr = (const uint8_t *)pUInBuf->UB.ptr + uOffset2;
+   UB2.len = uLen2;
+
+   return UsefulBuf_Compare(UB1, UB2);
+}
+
+
+/*
+ * Public function -- see UsefulBuf.h
+ *
+ * Code Reviewers: THIS FUNCTION DOES POINTER MATH
+ */
 int UsefulOutBuf_Compare(UsefulOutBuf *pMe,
                          const size_t uStart1, const size_t uLen1,
                          const size_t uStart2, const size_t uLen2)