Replace strcpy(), an oft banned function with UsefulOutBuf (#326)

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/qcbor_err_to_str.c b/src/qcbor_err_to_str.c
index f9588e5..6d8e6fa 100644
--- a/src/qcbor_err_to_str.c
+++ b/src/qcbor_err_to_str.c
@@ -13,7 +13,7 @@
  * ========================================================================== */
 
 #include "qcbor/qcbor_common.h"
-#include <string.h>
+#include "UsefulBuf.h"
 
 #define ERR_TO_STR_CASE(errpart) case errpart: return #errpart;
 
@@ -77,14 +77,17 @@
       if(uErr >= QCBOR_ERR_FIRST_USER_DEFINED && uErr <= QCBOR_ERR_LAST_USER_DEFINED) {
          /* Static buffer is not thread safe, but this is only a diagnostic */
          static char buf[20];
-         strcpy(buf, "USER_DEFINED_");
-         size_t uEndOffset = strlen(buf);
-         buf[uEndOffset]   = (char)(uErr/100 + '0');
-         buf[uEndOffset+1] = (char)(((uErr/10) % 10) + '0');
-         buf[uEndOffset+2] = (char)((uErr % 10 )+ '0');
-         buf[uEndOffset+3] = '\0';
-         return buf;
+         UsefulOutBuf OB;
 
+         /* Make NULL-terminated string "USER_DEFINED_NNN" using UsefulOutBuf */
+         UsefulOutBuf_Init(&OB, UsefulBuf_FROM_BYTE_ARRAY(buf));
+         UsefulOutBuf_AppendString(&OB, "USER_DEFINED_");
+         UsefulOutBuf_AppendByte(&OB, (uint8_t)(uErr/100 + '0'));
+         UsefulOutBuf_AppendByte(&OB, (uint8_t)(((uErr/10) % 10) + '0'));
+         UsefulOutBuf_AppendByte(&OB, (uint8_t)(((uErr/10) % 10) + '0'));
+         UsefulOutBuf_AppendByte(&OB, 0x00);
+
+         return buf;
       } else {
          return "Unidentified QCBOR error";
       }