[PATCH] Improve hex parser robustness.

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/baseband-devel@lists.osmocom.org/.

Max Max.Suraev at fairwaves.ru
Mon Jan 14 17:14:30 UTC 2013


---
 include/osmocom/core/utils.h |    2 ++
 src/utils.c                  |   48 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 03861d7..05cb2a4 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -15,6 +15,7 @@
 #define OSMO_MIN(a, b) ((a) >= (b) ? (b) : (a))
 
 #include <stdint.h>
+#include <stdbool.h>
 
 /*! \brief A mapping between human-readable string and numeric value */
 struct value_string {
@@ -30,6 +31,7 @@ char osmo_bcd2char(uint8_t bcd);
 /* only works for numbers in ascci */
 uint8_t osmo_char2bcd(char c);
 
+int osmo_hexparse_adv(const char *str, uint8_t *b, int max_len, bool allow_odd);
 int osmo_hexparse(const char *str, uint8_t *b, int max_len);
 
 char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
diff --git a/src/utils.c b/src/utils.c
index c36979c..8c1849e 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -3,7 +3,7 @@
 #include <stdint.h>
 #include <errno.h>
 #include <stdio.h>
-
+#include <stdbool.h>
 #include <osmocom/core/utils.h>
 
 /*! \addtogroup utils
@@ -73,24 +73,60 @@ uint8_t osmo_char2bcd(char c)
 	return c - 0x30;
 }
 
-/*! \brief Parse a string ocntaining hexadecimal digits
+/*! \brief Parse a string ocntaining hexadecimal digits, optionally prefixed with 0x
  *  \param[in] str string containing ASCII encoded hexadecimal digits
  *  \param[out] b output buffer
  *  \param[in] max_len maximum space in output buffer
  */
 int osmo_hexparse(const char *str, uint8_t *b, int max_len)
+{
+    return osmo_hexparse_adv(str, b, max_len, false);
+}
 
+/*! \brief Parse a string ocntaining hexadecimal digits, optionally prefixed with 0x
+ *  \param[in] str string containing ASCII encoded hexadecimal digits
+ *  \param[out] b output buffer
+ *  \param[in] max_len maximum space in output buffer
+ *  \param[in] allow_odd allow odd length (prefix with 0 on the left side)
+ */
+int osmo_hexparse_adv(const char *str, uint8_t *b, int max_len, bool allow_odd)
 {
-	int i, l, v;
+	int v;
+	size_t i, l = strlen(str);
+	const char * src;
+
+	if (l > 2) { /* remove 0x prefix if any */
+	    if ('0' == str[0] && 'x' == str[1]) {
+		l -= 2;
+		str += 2;
+	    }
+	}
+
+	if (allow_odd) {
+	    if (l & 1) i = l + 1;
+	    else i = l;
+	    char hs[i]; /* enough space to store additional leading 0 if str length is odd */
+
+	    if (l & 1) {
+		memcpy(hs + 1, str, l);
+		hs[0] = '0';
+	    } else {
+		memcpy(hs, str, l);
+	    }
+	    src = hs;
+	} else {
+	    if (l & 1)
+		return -1;
+	    src = str;
+	}
 
-	l = strlen(str);
-	if ((l&1) || ((l>>1) > max_len))
+	if ((l>>1) > max_len)
 		return -1;
 
 	memset(b, 0x00, max_len);
 
 	for (i=0; i<l; i++) {
-		char c = str[i];
+		char c = src[i];
 		if (c >= '0' && c <= '9')
 			v = c - '0';
 		else if (c >= 'a' && c <= 'f')
-- 
1.7.10.4


--------------070900070504060905060402--




More information about the baseband-devel mailing list