osmo_hexparse: allow whitespace in parsed string, add ws test

This is particularly useful for hex dumps containing spaces found in a log
(e.g. osmo-nitb authentication rand token), which can now be passed in quotes
to osmo-auc-gen without having to edit the spaces away.

Change-Id: Ib7af07f674a2d26c8569acdee98835fb3e626c45
diff --git a/src/utils.c b/src/utils.c
index 34b2bca..1a4aab4 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -127,16 +127,22 @@
 int osmo_hexparse(const char *str, uint8_t *b, int max_len)
 
 {
-	int i, l, v;
-
-	l = strlen(str);
-	if ((l&1) || ((l>>1) > max_len))
-		return -1;
+	char c;
+	uint8_t v;
+	const char *strpos;
+	unsigned int nibblepos = 0;
 
 	memset(b, 0x00, max_len);
 
-	for (i=0; i<l; i++) {
-		char c = str[i];
+	for (strpos = str; (c = *strpos); strpos++) {
+		/* skip whitespace */
+		if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
+			continue;
+
+		/* If the buffer is too small, error out */
+		if (nibblepos >= (max_len << 1))
+			return -1;
+
 		if (c >= '0' && c <= '9')
 			v = c - '0';
 		else if (c >= 'a' && c <= 'f')
@@ -145,10 +151,17 @@
 			v = 10 + (c - 'A');
 		else
 			return -1;
-		b[i>>1] |= v << (i&1 ? 0 : 4);
+
+		b[nibblepos >> 1] |= v << (nibblepos & 1 ? 0 : 4);
+		nibblepos ++;
 	}
 
-	return i>>1;
+	/* In case of uneven amount of digits, the last byte is not complete
+	 * and that's an error. */
+	if (nibblepos & 1)
+		return -1;
+
+	return nibblepos >> 1;
 }
 
 static char hexd_buff[4096];