on second thought, it doesn't hurt to supply validators with all known 
information. allows them to make more informed decisions. enhancement 
complete with a nice example.

carlos, feel free to fold this into the previous one.

>From 82a8bfab1c8f0126d4ad805c15d45707ba321990 Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Sat, 9 Oct 2010 12:26:04 +0200
Subject: [PATCH] wmmenugen: Touch up validator function

Signed-off-by: Tamas TEVESZ <[email protected]>
---
 util/wmmenugen.c                |    4 ++--
 util/wmmenugen.h                |    2 +-
 util/wmmenugen_parse_wmconfig.c |   38 +++++++++++++++++++++++++++++++++++++-
 util/wmmenugen_parse_xdg.c      |   10 ++++++++++
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/util/wmmenugen.c b/util/wmmenugen.c
index a87a001..c6d5099 100644
--- a/util/wmmenugen.c
+++ b/util/wmmenugen.c
@@ -44,7 +44,7 @@ static int menuSortFunc(const void *left, const void *right);
 static int nodeFindSubMenuByNameFunc(const void *item, const void *cdata);
 static WMTreeNode *findPositionInMenu(char *submenu);
 static void (*parse)(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
-static Bool (*validateFilename)(const char *filename);
+static Bool (*validateFilename)(const char *filename, const struct stat *st, 
int tflags, struct FTW *ftw);
 
 static WMArray *plMenuNodes;
 char *terminal;
@@ -146,7 +146,7 @@ static int dirParseFunc(const char *filename, const struct 
stat *st, int tflags,
        (void)ftw;
 
        if (validateFilename &&
-           !validateFilename(filename))
+           !validateFilename(filename, st, tflags, ftw))
                return 0;
 
        parse(filename, addWMMenuEntryCallback);
diff --git a/util/wmmenugen.h b/util/wmmenugen.h
index 61bb06a..54a162d 100644
--- a/util/wmmenugen.h
+++ b/util/wmmenugen.h
@@ -57,5 +57,5 @@ Bool fileInPath(const char *file);
  */
 void parse_xdg(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry 
*aEntry));
 void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
-Bool wmconfig_validate_file(const char *filename);
+Bool wmconfig_validate_file(const char *filename, const struct stat *st, int 
tflags, struct FTW *ftw);
 
diff --git a/util/wmmenugen_parse_wmconfig.c b/util/wmmenugen_parse_wmconfig.c
index 6b244d8..ae7b8a3 100644
--- a/util/wmmenugen_parse_wmconfig.c
+++ b/util/wmmenugen_parse_wmconfig.c
@@ -20,14 +20,24 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#if __GLIBC__ && \
+    (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) || \
+    !_XOPEN_SOURCE
+#define _XOPEN_SOURCE 500              /* nftw */
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <ctype.h>
+#include <ftw.h>
 #if DEBUG
 #include <errno.h>
 #endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "wmmenugen.h"
 
@@ -132,11 +142,37 @@ void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry
 /* an example to illustrate validateFilename.
  * with wmconfig, no special handling is needed
  */
-Bool wmconfig_validate_file(const char *filename)
+Bool wmconfig_validate_file(const char *filename, const struct stat *st, int 
tflags, struct FTW *ftw)
 {
        (void)filename;
+       (void)st;
+       (void)tflags;
+       (void)ftw;
 
        return True;
+#if 0  /* not dead code, example */
+
+       /* or we could have gone intro extremes */
+       char *base_name;
+       Bool ret;
+
+       (void)tflags;
+
+       base_name = wstrdup(filename + ftw->base);
+       ret = True;
+
+       if (!S_ISREG(st->st_mode) ||                            /* not a 
regular file */
+           (st->st_uid != 0 && st->st_uid != getuid()) ||      /* bad guy 
injected this file */
+           strpbrk(base_name, ".") ||                          /* wmconfig 
typically has no extension */
+           st->st_size >= 128 * 131072 ||                      /* noone writes 
wmconfig files > 128K */
+           st->st_size == 0 ||                                 /* nor empty 
ones */
+           ftw->level > 16)                                    /* how did we 
get this deep? */
+               ret = False;
+
+       wfree(base_name);
+
+       return ret;
+#endif
 }
 
 /* get a line allocating label, key and value as necessary */
diff --git a/util/wmmenugen_parse_xdg.c b/util/wmmenugen_parse_xdg.c
index e19c0a2..4464ab4 100644
--- a/util/wmmenugen_parse_xdg.c
+++ b/util/wmmenugen_parse_xdg.c
@@ -34,7 +34,17 @@
  * Basic validation of the .desktop file is done.
  */
 
+#if __GLIBC__ && \
+    (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) || \
+    !_XOPEN_SOURCE
+#define _XOPEN_SOURCE 500              /* nftw */
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include <ctype.h>
+#include <ftw.h>
 #if DEBUG
 #include <errno.h>
 #endif
-- 
1.7.0.4


-- 
[-]

mkdir /nonexistent
From 82a8bfab1c8f0126d4ad805c15d45707ba321990 Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Sat, 9 Oct 2010 12:26:04 +0200
Subject: [PATCH] wmmenugen: Touch up validator function

Signed-off-by: Tamas TEVESZ <[email protected]>
---
 util/wmmenugen.c                |    4 ++--
 util/wmmenugen.h                |    2 +-
 util/wmmenugen_parse_wmconfig.c |   38 +++++++++++++++++++++++++++++++++++++-
 util/wmmenugen_parse_xdg.c      |   10 ++++++++++
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/util/wmmenugen.c b/util/wmmenugen.c
index a87a001..c6d5099 100644
--- a/util/wmmenugen.c
+++ b/util/wmmenugen.c
@@ -44,7 +44,7 @@ static int menuSortFunc(const void *left, const void *right);
 static int nodeFindSubMenuByNameFunc(const void *item, const void *cdata);
 static WMTreeNode *findPositionInMenu(char *submenu);
 static void (*parse)(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
-static Bool (*validateFilename)(const char *filename);
+static Bool (*validateFilename)(const char *filename, const struct stat *st, int tflags, struct FTW *ftw);
 
 static WMArray *plMenuNodes;
 char *terminal;
@@ -146,7 +146,7 @@ static int dirParseFunc(const char *filename, const struct stat *st, int tflags,
 	(void)ftw;
 
 	if (validateFilename &&
-	    !validateFilename(filename))
+	    !validateFilename(filename, st, tflags, ftw))
 		return 0;
 
 	parse(filename, addWMMenuEntryCallback);
diff --git a/util/wmmenugen.h b/util/wmmenugen.h
index 61bb06a..54a162d 100644
--- a/util/wmmenugen.h
+++ b/util/wmmenugen.h
@@ -57,5 +57,5 @@ Bool fileInPath(const char *file);
  */
 void parse_xdg(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
 void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
-Bool wmconfig_validate_file(const char *filename);
+Bool wmconfig_validate_file(const char *filename, const struct stat *st, int tflags, struct FTW *ftw);
 
diff --git a/util/wmmenugen_parse_wmconfig.c b/util/wmmenugen_parse_wmconfig.c
index 6b244d8..ae7b8a3 100644
--- a/util/wmmenugen_parse_wmconfig.c
+++ b/util/wmmenugen_parse_wmconfig.c
@@ -20,14 +20,24 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#if __GLIBC__ && \
+    (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) || \
+    !_XOPEN_SOURCE
+#define _XOPEN_SOURCE 500		/* nftw */
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <ctype.h>
+#include <ftw.h>
 #if DEBUG
 #include <errno.h>
 #endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "wmmenugen.h"
 
@@ -132,11 +142,37 @@ void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry
 /* an example to illustrate validateFilename.
  * with wmconfig, no special handling is needed
  */
-Bool wmconfig_validate_file(const char *filename)
+Bool wmconfig_validate_file(const char *filename, const struct stat *st, int tflags, struct FTW *ftw)
 {
 	(void)filename;
+	(void)st;
+	(void)tflags;
+	(void)ftw;
 
 	return True;
+#if 0	/* not dead code, example */
+
+	/* or we could have gone intro extremes */
+	char *base_name;
+	Bool ret;
+
+	(void)tflags;
+
+	base_name = wstrdup(filename + ftw->base);
+	ret = True;
+
+	if (!S_ISREG(st->st_mode) ||				/* not a regular file */
+	    (st->st_uid != 0 && st->st_uid != getuid()) ||	/* bad guy injected this file */
+	    strpbrk(base_name, ".") ||				/* wmconfig typically has no extension */
+	    st->st_size >= 128 * 131072	||			/* noone writes wmconfig files > 128K */
+	    st->st_size == 0 ||					/* nor empty ones */
+	    ftw->level > 16)					/* how did we get this deep? */
+		ret = False;
+
+	wfree(base_name);
+
+	return ret;
+#endif
 }
 
 /* get a line allocating label, key and value as necessary */
diff --git a/util/wmmenugen_parse_xdg.c b/util/wmmenugen_parse_xdg.c
index e19c0a2..4464ab4 100644
--- a/util/wmmenugen_parse_xdg.c
+++ b/util/wmmenugen_parse_xdg.c
@@ -34,7 +34,17 @@
  * Basic validation of the .desktop file is done.
  */
 
+#if __GLIBC__ && \
+    (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) || \
+    !_XOPEN_SOURCE
+#define _XOPEN_SOURCE 500		/* nftw */
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include <ctype.h>
+#include <ftw.h>
 #if DEBUG
 #include <errno.h>
 #endif
-- 
1.7.0.4

Reply via email to