ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
April 17th, 2024 | 14:30-16:00 SGT (UTC+8) | Online

Wireshark-dev: Re: [Wireshark-dev] [Wireshark-commits] rev 20209: /trunk/epan/ftypes/ /trunk/ep

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Sun, 24 Dec 2006 12:46:08 -0800
Jaap Keuter wrote:

It failed to build across the board, so I backed out the change, giving
ronnie the time to check in a working version.

"Working version" probably involves, at least with current versions of PCRE, setting PCRE's allocate function to ep_alloc() and its free function to a no-op function. (I'm not sure what should be done about the "frame allocate" function.) See attached patch.
Index: epan/ftypes/ftype-pcre.c
===================================================================
--- epan/ftypes/ftype-pcre.c	(revision 20210)
+++ epan/ftypes/ftype-pcre.c	(working copy)
@@ -32,6 +32,7 @@
 #endif
 
 #include <ftypes-int.h>
+#include <epan/emem.h>
 
 #ifdef HAVE_LIBPCRE
 
@@ -47,10 +48,10 @@
 	const char *pcre_error_text;
 	int pcre_error_offset;
 
-	tuple = g_malloc(sizeof(pcre_tuple_t));
-	tuple->string = g_strdup(value); /* The RE as string */
+	tuple = ep_alloc(sizeof(pcre_tuple_t));
+	tuple->string = ep_strdup(value); /* The RE as string */
 	tuple->ex = NULL;
-	/* Compile the RE */
+	/* Compile the RE; it will be stored in ep allocated memory */
 	tuple->re = pcre_compile(
 			value,				/* pattern */
 			0,					/* PCRE options */
@@ -58,23 +59,24 @@
 			&pcre_error_offset,	/* Start offset of error in pattern */
 			NULL				/* Default char tables (C locale) */
 			);
+
 	if (pcre_error_text) {
-		tuple->error = g_strdup_printf("In regular expression \"%s\":\n"
+		tuple->error = ep_strdup_printf("In regular expression \"%s\":\n"
 				"%s (character position %d)",
 				value, pcre_error_text, pcre_error_offset);
 		return tuple;
 	} else {
 		tuple->error = NULL;
 	}
-	/* Study the RE */
+	/* Study the RE; it will be stored in ep allocated memory */
 	tuple->ex = pcre_study(tuple->re, 0, &pcre_error_text);
 	if (pcre_error_text) {
 		if (tuple->error) {
-			tuple->error = g_strdup_printf("In regular expression \"%s\":\n"
+			tuple->error = ep_strdup_printf("In regular expression \"%s\":\n"
 					"%s. %s",
 					value, tuple->error, pcre_error_text);
 		} else {
-			tuple->error = g_strdup_printf("In regular expression \"%s\":\n"
+			tuple->error = ep_strdup_printf("In regular expression \"%s\":\n"
 					"%s",
 					value, pcre_error_text);
 		}
@@ -83,39 +85,16 @@
 }
 
 static void
-pcre_tuple_free(pcre_tuple_t *tuple)
-{
-	if (tuple) {
-		if (tuple->string) g_free(tuple->string);
-		if (tuple->re) g_free(tuple->re);
-		if (tuple->ex) g_free(tuple->ex);
-		if (tuple->error) g_free(tuple->error);
-		g_free(tuple);
-	}
-}
-
-static void
 pcre_fvalue_new(fvalue_t *fv)
 {
 	fv->value.re = NULL;
 }
 
-static void
-pcre_fvalue_free(fvalue_t *fv)
-{
-	if (fv->value.re) {
-		pcre_tuple_free(fv->value.re);
-	}
-}
-
 /* Generate a FT_PCRE from a parsed string pattern.
  * Uses the specified logfunc() to report errors. */
 static gboolean
 val_from_string(fvalue_t *fv, char *pattern, LogFunc logfunc)
 {
-	/* Free up the old value, if we have one */
-	pcre_fvalue_free(fv);
-
 	fv->value.re = pcre_tuple_new(pattern);
 	if (fv->value.re->error) {
 		logfunc(fv->value.re->error);
@@ -129,8 +108,6 @@
 static gboolean
 val_from_unparsed(fvalue_t *fv, char *pattern, gboolean allow_partial_value _U_, LogFunc logfunc)
 {
-	/* Free up the old value, if we have one */
-	pcre_fvalue_free(fv);
 	g_assert(! allow_partial_value);
 
 	fv->value.re = pcre_tuple_new(pattern);
@@ -161,8 +138,6 @@
 pcre_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
 {
 	g_assert(value != NULL);
-	/* Free up the old value, if we have one */
-	pcre_fvalue_free(fv);
 	g_assert(! already_copied);
 	fv->value.re = pcre_tuple_new(value);
 }
@@ -173,6 +148,16 @@
 	return fv->value.re;
 }
 
+/*
+ * Free routine - we set up the pcre library to use ep_alloc() to allocate
+ * memory, so we don't need to explicitly free the memory and thus need a
+ * free routine that does nothing.
+ */
+static void
+noop_free(void *mem _U_)
+{
+}
+
 void
 ftype_register_pcre(void)
 {
@@ -182,7 +167,7 @@
 		"Compiled Perl-Compatible Regular Expression object", /* pretty_name */
 		0,			/* wire_size */
 		pcre_fvalue_new,	/* new_value */
-		pcre_fvalue_free,	/* free_value */
+		NULL,			/* free_value */
 		val_from_unparsed,	/* val_from_unparsed */
 		val_from_string,	/* val_from_string */
 		pcre_to_repr,		/* val_to_string_repr */
@@ -211,6 +196,13 @@
 		NULL,			/* len */
 		NULL,			/* slice */
 	};
+
+	/*
+	 * Set PCRE's allocator to be ep_alloc.  That means there's
+	 * no explicit free operation.
+	 */
+	pcre_malloc = ep_alloc;
+	pcre_free = noop_free;
 	ftype_register(FT_PCRE, &pcre_type);
 }