New Rewind method for entered maps...; bug fix for entering tagged wrapping byte strings

The new QCBORDecode_Rewind method allows the pre-order traversal cursor to be reset to the beginning of an entered array, map or byte string. If nothing was entered, then the reset is to the initial state, the beginning of the input encoded CBOR.

This also fixes a bug that prevented tagged wrapping byte strings from being entered.

This also adds a method to UsefulBuf and UsefulInBuf to convert a pointer to an offset.



* first version of rewind

* Make rewind work when not bounded and reset error state

* Rewind working for maps and arrays, but not byte strings

* rewind almost working for byte strings

* src/qcbor_decode.c

* minor tidying

* rewinding wrapped byte strings works, but needs more tests

* Full testing of UsefulBuf pointer to offset functions

* tidy up rewind; tests all passing

* fix bug entering tagged byte-string wrapped CBOR; entering indefinite-length byte-string wrapped is still broken

* one more test; give up on entering indef length wrapping strings

* spelling fix

* ifdefs for disabling tests

* refactor rewind

* more nits

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/test/UsefulBuf_Tests.c b/test/UsefulBuf_Tests.c
index 1c2634e..880be02 100644
--- a/test/UsefulBuf_Tests.c
+++ b/test/UsefulBuf_Tests.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2020, Laurence Lundblade.
+ Copyright (c) 2018-2021, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -591,13 +591,46 @@
       return "Failed to find 3";
    }
 
+
+   const uint8_t pB[] = {0x01, 0x02, 0x03};
+   UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
+   // Try to map a pointer before
+   if(UsefulBuf_PointerToOffset(Boo, pB-1) != SIZE_MAX) {
+      return "Didn't error on pointer before";
+   }
+
+   // Try to map a pointer after
+   if(UsefulBuf_PointerToOffset(Boo, pB+sizeof(pB)) != SIZE_MAX) {
+      return "Didn't error on pointer after";
+   }
+
+   // Try to map a pointer inside
+   if(UsefulBuf_PointerToOffset(Boo, pB+1) != 1) {
+      return "Incorrect pointer offset";
+   }
+
+   // Try to map a pointer at the start
+   if(UsefulBuf_PointerToOffset(Boo, pB) != 0) {
+      return "Incorrect pointer offset for start";
+   }
+
+   // Try to map a pointer at the end
+   if(UsefulBuf_PointerToOffset(Boo, pB + sizeof(pB)-1) != 2) {
+      return "Incorrect pointer offset for end";
+   }
+
+   // Try to map a pointer on a NULL UB
+   if(UsefulBuf_PointerToOffset(NULLUsefulBufC, pB ) != SIZE_MAX) {
+      return "Incorrect pointer offset for start";
+   }
+
    return NULL;
 }
 
 
 const char *  UIBTest_IntegerFormat()
 {
-   UsefulOutBuf_MakeOnStack(UOB,100);
+   UsefulOutBuf_MakeOnStack(UOB, 100);
 
    const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
    const uint64_t u64 = 1984738472938472;
@@ -695,6 +728,10 @@
       return "expected error after seek";
    }
 
+   if(UsefulInputBuf_PointerToOffset(&UIB, O.ptr) != 0) {
+      return "PointerToOffset not working";
+   }
+
    return NULL;
 }