/pidgin/main: a53317024f50: Change Tcl plugin parsing to use g_f...

Ethan Blanton elb at pidgin.im
Tue Jan 1 18:37:41 EST 2013


Changeset: a53317024f50c1808c364513da4a45e62ad5566e
Author:	 Ethan Blanton <elb at pidgin.im>
Date:	 2013-01-01 18:37 -0500
Branch:	 release-2.x.y
URL: http://hg.pidgin.im/pidgin/main/rev/a53317024f50

Description:

Change Tcl plugin parsing to use g_file_get_contents().

The old code is bizarre and broken in several ways.  It used fgets in
a loop, and had a file size race between a stat and read.

Thanks to Andrew Shadura for finding this bug and pointing it out.

diffstat:

 ChangeLog                   |   1 +
 libpurple/plugins/tcl/tcl.c |  34 +++++++---------------------------
 2 files changed, 8 insertions(+), 27 deletions(-)

diffs (59 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@ version 2.10.7:
 	  (Bartosz Brachaczek) (#15329)
 	* Fix UPNP mappings on routers that return empty <URLBase/> elements
 	  in their response. (Ferdinand Stehle) (#15373)
+	* Tcl plugin uses saner, race-free plugin loading.
 
 	Pidgin:
 	* Make Pidgin more friendly to non-X11 GTK+, such as MacPorts' +no_x11
diff --git a/libpurple/plugins/tcl/tcl.c b/libpurple/plugins/tcl/tcl.c
--- a/libpurple/plugins/tcl/tcl.c
+++ b/libpurple/plugins/tcl/tcl.c
@@ -174,37 +174,17 @@ static gboolean tcl_probe_plugin(PurpleP
 	Tcl_Interp *interp;
 	Tcl_Parse parse;
 	Tcl_Obj *result, **listitems;
-	struct stat st;
-	FILE *fp;
-	char *buf, *cur;
+	char *buf;
 	const char *next;
-	int len, found = 0, err = 0, nelems;
+	int found = 0, err = 0, nelems;
+	gsize len;
 	gboolean status = FALSE;
-	if ((fp = g_fopen(plugin->path, "r")) == NULL)
-		return FALSE;
-	if (fstat(fileno(fp), &st)) {
-		fclose(fp);
+
+	if (!g_file_get_contents(plugin->path, &buf, &len, NULL)) {
+		purple_debug(PURPLE_DEBUG_INFO, "tcl", "Error opening plugin %s\n",
+			     plugin->path);
 		return FALSE;
 	}
-	len = st.st_size;
-
-	buf = g_malloc(len + 1);
-
-	cur = buf;
-	while (fgets(cur, GPOINTER_TO_INT(buf) - (buf - cur), fp)) {
-		cur += strlen(cur);
-		if (feof(fp))
-			break;
-	}
-
-	if (ferror(fp)) {
-		purple_debug(PURPLE_DEBUG_ERROR, "tcl", "error reading %s (%s)\n", plugin->path, g_strerror(errno));
-		g_free(buf);
-		fclose(fp);
-		return FALSE;
-	}
-
-	fclose(fp);
 
 	if ((interp = tcl_create_interp()) == NULL) {
 		return FALSE;



More information about the Commits mailing list