rewinding wrapped byte strings works, but needs more tests
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
index 6fe33a1..2e63e65 100644
--- a/inc/qcbor/UsefulBuf.h
+++ b/inc/qcbor/UsefulBuf.h
@@ -1,6 +1,6 @@
 /*============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2020, Laurence Lundblade.
+ Copyright (c) 2018-2021, Laurence Lundblade.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -41,6 +41,7 @@
 
  when         who             what, where, why
  --------     ----            --------------------------------------------------
+ 2/17/2021    llundblade      Method to go from a pointer to an offset.
  1/25/2020    llundblade      Add some casts so static anlyzers don't complain.
  5/21/2019    llundblade      #define configs for efficient endianness handling.
  5/16/2019    llundblade      Add UsefulOutBuf_IsBufferNULL().
@@ -589,6 +590,18 @@
 size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
 
 
+/**
+@brief Convert a pointer to an offset with bounds checking.
+
+@param[in] UB  Pointer to the UsefulInputBuf.
+@param[in] p     Pointer to convert to offet.
+
+@return SIZE_MAX if @c p is out of range, offset if not.
+*/
+// TODO: test this
+static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p);
+
+
 #if 1 // NOT_DEPRECATED
 /** Deprecated macro; use @ref UsefulBuf_FROM_SZ_LITERAL instead */
 #define SZLiteralToUsefulBufC(szString) \
@@ -1332,6 +1345,17 @@
 
 
 /**
+@brief Convert a pointer to an offset with bounds checking.
+
+@param[in] pUInBuf  Pointer to the UsefulInputBuf.
+@param[in] p     Pointer to convert to offet.
+
+@return SIZE_MAX if @c p is out of range.
+*/
+static inline size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p);
+
+
+/**
  @brief Get pointer to bytes out of the input buffer.
 
  @param[in] pUInBuf  Pointer to the UsefulInputBuf.
@@ -1626,6 +1650,23 @@
 }
 
 
+static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p)
+{
+   if(p < UB.ptr) {
+       /* given pointer is before start of buffer */
+       return SIZE_MAX;
+   }
+
+   ptrdiff_t nOffset = (uint8_t *)p - (uint8_t *)UB.ptr;
+
+   if(nOffset < 0) {
+       /* given pointer is of the end of the buffer */
+       return SIZE_MAX;
+   }
+
+   return (size_t)nOffset;
+}
+
 
 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
 {
@@ -1993,6 +2034,12 @@
 }
 
 
+static inline size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p)
+{
+   return UsefulBuf_PointerToOffset(pUInBuf->UB, p);
+}
+
+
 static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pMe, size_t uNum)
 {
    const void *pResult = UsefulInputBuf_GetBytes(pMe, uNum);
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 2ad00b0..19c6a97 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -3522,8 +3522,14 @@
       uError = QCBOR_ERR_INPUT_TOO_LARGE;
       goto Done;
    }
-   const size_t uEndOfBstr   = UsefulInputBuf_Tell(&(pMe->InBuf));
-   const size_t uStartOfBstr = uEndOfBstr - pItem->val.string.len;
+   const size_t uStartOfBstr = UsefulInputBuf_PointerToOffset(&(pMe->InBuf), pItem->val.string.ptr);
+
+   if(uStartOfBstr == SIZE_MAX) {
+      uError = QCBOR_ERR_INPUT_TOO_LARGE;
+      goto Done;
+   }
+
+   const size_t uEndOfBstr = uStartOfBstr + pItem->val.string.len;
    UsefulInputBuf_Seek(&(pMe->InBuf), uStartOfBstr);
    UsefulInputBuf_SetBufferLength(&(pMe->InBuf), uEndOfBstr);
 
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index bce459d..62184a3 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -6984,10 +6984,38 @@
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
 
+/*
+An array of an integer and an array. The second array contains a bstr-wrapped map.
+
+ [7, [h'A36D666972737420696E7465676572182A77616E206172726179206F662074776F20737472696E67738267737472696E673167737472696E67326C6D617020696E2061206D6170A467627974657320314478787878676279746573203244797979796B616E6F7468657220696E74186266746578742032781E6C6965732C2064616D6E206C69657320616E642073746174697374696373']]
+
+ {"first integer": 42, "an array of two strings": ["string1", "string2"], "map in a map": {"bytes 1": h'78787878', "bytes 2": h'79797979', "another int": 98, "text 2": "lies, damn lies and statistics"}}
+ */
 
 static const uint8_t pValidWrappedMapEncoded[] = {
-   0x82, 0x00, 0x81, 0x58, 0x97,
-  //   0x9f, 0x00, 0x9f, 0x58, 0x97,
+0x82, 0x07, 0x81, 0x58, 0x97,
+0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e,
+0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a, 0x77, 0x61, 0x6e,
+0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20,
+0x74, 0x77, 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+0x73, 0x82, 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31,
+0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x6c, 0x6d,
+0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6d, 0x61,
+0x70, 0xa4, 0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x31,
+0x44, 0x78, 0x78, 0x78, 0x78, 0x67, 0x62, 0x79, 0x74, 0x65,
+0x73, 0x20, 0x32, 0x44, 0x79, 0x79, 0x79, 0x79, 0x6b, 0x61,
+0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74,
+0x18, 0x62, 0x66, 0x74, 0x65, 0x78, 0x74, 0x20, 0x32, 0x78,
+0x1e, 0x6c, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x6d,
+0x6e, 0x20, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64,
+0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
+0x73
+};
+
+
+/* As above, but the arrays are indefinite length */
+static const uint8_t pValidIndefWrappedMapEncoded[] = {
+0x9f, 0x07, 0x9f, 0x58, 0x97,
 
 0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e,
 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a, 0x77, 0x61, 0x6e,
@@ -7464,5 +7492,35 @@
       return 600;
    }
 
+
+
+
+   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidIndefWrappedMapEncoded), 0);
+
+   QCBORDecode_EnterArray(&DCtx, NULL);
+
+   QCBORDecode_GetUInt64(&DCtx, &i);
+
+   QCBORDecode_EnterArray(&DCtx, NULL);
+
+   QCBORDecode_EnterBstrWrapped(&DCtx, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
+
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+      return (int32_t)nCBORError;
+   }
+   if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 3) {
+      return 600;
+   }
+
+   QCBORDecode_Rewind(&DCtx);
+
+
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
+      return (int32_t)nCBORError;
+   }
+   if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 3) {
+      return 600;
+   }
+
    return 0;
 }