[gnome-keyring/gck-work: 17/18] [egg] Make the hex decoder more robust



commit 4aa488ea33410b7bdd6f77deff9c08c2245752cd
Author: Stef Walter <stef memberwebs com>
Date:   Mon Aug 9 20:15:43 2010 +0200

    [egg] Make the hex decoder more robust

 egg/egg-hex.c             |   68 +++++++++++++++++++++++++++++++-------------
 egg/egg-hex.h             |   12 ++++++--
 egg/tests/unit-test-hex.c |   32 ++++++++++++++++-----
 3 files changed, 81 insertions(+), 31 deletions(-)
---
diff --git a/egg/egg-hex.c b/egg/egg-hex.c
index 4984e41..04a9007 100644
--- a/egg/egg-hex.c
+++ b/egg/egg-hex.c
@@ -28,46 +28,72 @@
 static const char HEXC_UPPER[] = "0123456789ABCDEF";
 static const char HEXC_LOWER[] = "0123456789abcdef";
 
-guchar*
+gpointer
 egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
 {
+	return egg_hex_decode_full (data, n_data, 0, 1, n_decoded);
+}
+
+gpointer
+egg_hex_decode_full (const gchar *data, gssize n_data,
+                     gchar delim, guint group, gsize *n_decoded)
+{
 	guchar *result;
 	guchar *decoded;
 	gushort j;
 	gint state = 0;
+	gint part = 0;
 	const gchar* pos;
-    
+
 	g_return_val_if_fail (data || !n_data, NULL);
 	g_return_val_if_fail (n_decoded, NULL);
-	
+	g_return_val_if_fail (group >= 1, NULL);
+
 	if (n_data == -1)
 		n_data = strlen (data);
 
 	decoded = result = g_malloc0 ((n_data / 2) + 1);
 	*n_decoded = 0;
 
-	while (n_data > 0) {
-    		if (!g_ascii_isspace (*data)) {
-    			
-	        	/* Find the position */
+	while (n_data > 0 && state == 0) {
+
+		if (decoded != result && delim) {
+			if (*data != delim) {
+				state = -1;
+				break;
+			}
+
+			++data;
+			--n_data;
+		}
+
+		while (part < group && n_data > 0) {
+
+			/* Find the position */
 			pos = strchr (HEXC_UPPER, g_ascii_toupper (*data));
-			if (pos == 0)
+			if (pos == 0) {
+				if (n_data > 0)
+					state = -1;
 				break;
+			}
 
 			j = pos - HEXC_UPPER;
 			if(!state) {
 				*decoded = (j & 0xf) << 4;
 				state = 1;
-			} else {      
+			} else {
 				*decoded |= (j & 0xf);
 				(*n_decoded)++;
 				decoded++;
 				state = 0;
+				part++;
 			}
-    		}
-      
-      		++data;
-      		--n_data;
+
+			++data;
+			--n_data;
+		}
+
+		part = 0;
 	}
 
 	/* Parsing error */
@@ -79,23 +105,25 @@ egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
 	return result;
 }
 
-gchar* 
-egg_hex_encode (const guchar *data, gsize n_data)
+gchar*
+egg_hex_encode (gconstpointer data, gsize n_data)
 {
 	return egg_hex_encode_full (data, n_data, TRUE, '\0', 0);
 }
 
 gchar*
-egg_hex_encode_full (const guchar *data, gsize n_data,
+egg_hex_encode_full (gconstpointer data, gsize n_data,
                      gboolean upper_case, gchar delim, guint group)
 {
 	GString *result;
+	const gchar *input;
 	const char *hexc;
 	gsize bytes;
 	guchar j;
-	
+
 	g_return_val_if_fail (data || !n_data, NULL);
-	
+
+	input = data;
 	hexc = upper_case ? HEXC_UPPER : HEXC_LOWER;
 
 	result = g_string_sized_new (n_data * 2 + 1);
@@ -106,10 +134,10 @@ egg_hex_encode_full (const guchar *data, gsize n_data,
 		if (group && bytes && (bytes % group) == 0)
 			g_string_append_c (result, delim);
 
-		j = *(data) >> 4 & 0xf;
+		j = *(input) >> 4 & 0xf;
 		g_string_append_c (result, hexc[j]);
 		
-		j = *(data++) & 0xf;
+		j = *(input++) & 0xf;
 		g_string_append_c (result, hexc[j]);
     
 		++bytes;
diff --git a/egg/egg-hex.h b/egg/egg-hex.h
index adfea40..c20f8d8 100644
--- a/egg/egg-hex.h
+++ b/egg/egg-hex.h
@@ -24,14 +24,20 @@
 
 #include <glib.h>
 
-guchar*               egg_hex_decode                         (const gchar *data, 
+gpointer              egg_hex_decode                         (const gchar *data,
                                                               gssize n_data, 
                                                               gsize *n_decoded);
 
-gchar*                egg_hex_encode                         (const guchar *data, 
+gpointer              egg_hex_decode_full                    (const gchar *data,
+                                                              gssize n_data,
+                                                              gchar delim,
+                                                              guint group,
+                                                              gsize *n_decoded);
+
+gchar*                egg_hex_encode                         (gconstpointer data,
                                                               gsize n_data);
 
-gchar*                egg_hex_encode_full                    (const guchar *data, 
+gchar*                egg_hex_encode_full                    (gconstpointer data,
                                                               gsize n_data,
                                                               gboolean upper_case,
                                                               gchar delim,
diff --git a/egg/tests/unit-test-hex.c b/egg/tests/unit-test-hex.c
index adc2b9d..23e3944 100644
--- a/egg/tests/unit-test-hex.c
+++ b/egg/tests/unit-test-hex.c
@@ -32,7 +32,6 @@
 static const guchar TEST_DATA[] = { 0x05, 0xD6, 0x95, 0x96, 0x10, 0x12, 0xAE, 0x35 };
 static const gchar *TEST_HEX = "05D695961012AE35";
 static const gchar *TEST_HEX_DELIM = "05 D6 95 96 10 12 AE 35";
-static const gchar *TEST_HEX_SPACE = "\n05 D695 \r961012AE35\n\n";
 
 DEFINE_TEST(hex_encode)
 {
@@ -62,24 +61,41 @@ DEFINE_TEST(hex_decode)
 {
 	guchar *data;
 	gsize n_data;
-	
+
 	data = egg_hex_decode (TEST_HEX, -1, &n_data);
 	g_assert (data);
 	g_assert (n_data == sizeof (TEST_DATA));
 	g_assert (memcmp (data, TEST_DATA, n_data) == 0);
+	g_free (data);
+
+	/* Nothing in, empty out */
+	data = egg_hex_decode ("AB", 0, &n_data);
+	g_assert (data);
+	g_assert (n_data == 0);
+	g_free (data);
 
-	/* Spaces should be ignored */
-	data = egg_hex_decode (TEST_HEX_SPACE, -1, &n_data);
+	/* Delimited*/
+	data = egg_hex_decode_full (TEST_HEX_DELIM, -1, ' ', 1, &n_data);
 	g_assert (data);
 	g_assert (n_data == sizeof (TEST_DATA));
 	g_assert (memcmp (data, TEST_DATA, n_data) == 0);
+	g_free (data);
+}
+
+DEFINE_TEST(hex_decode_fail)
+{
+	guchar *data;
+	gsize n_data;
 
 	/* Invalid input, null out */
 	data = egg_hex_decode ("AB", 1, &n_data);
 	g_assert (!data);
 
-	/* Nothing in, empty out */
-	data = egg_hex_decode ("AB", 0, &n_data);
-	g_assert (data);
-	g_assert (n_data == 0);
+	/* Bad characters, null out */
+	data = egg_hex_decode ("ABXX", -1, &n_data);
+	g_assert (!data);
+
+	/* Not Delimited, null out*/
+	data = egg_hex_decode_full ("ABABAB", -1, ':', 1, &n_data);
+	g_assert (!data);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]