From a23b72c32af806eec744459a0d6ab89bda6bb862 Mon Sep 17 00:00:00 2001 From: Tamas TEVESZ Date: Sat, 9 Oct 2010 09:23:40 +0200 Subject: [PATCH] wmmenugen: Add file name validator function Add optional interface parsers may choose to implement that, when a directory is being scanned for files to parse, may, based on the file name, decide whether or not said file should be parsed. Signed-off-by: Tamas TEVESZ --- util/wmmenugen.c | 21 ++++++++++++------- util/wmmenugen.h | 2 ++ util/wmmenugen_parse_wmconfig.c | 46 +++++++++++++++++++++++++++++++++++++++++ util/wmmenugen_parse_xdg.c | 10 +++++++++ 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/util/wmmenugen.c b/util/wmmenugen.c index cbb55d8b..c6d5099b 100644 --- a/util/wmmenugen.c +++ b/util/wmmenugen.c @@ -44,6 +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, const struct stat *st, int tflags, struct FTW *ftw); static WMArray *plMenuNodes; char *terminal; @@ -59,6 +60,7 @@ int main(int argc, char **argv) plMenuNodes = WMCreateArray(8); /* grows on demand */ menu = (WMTreeNode *)NULL; parse = NULL; + validateFilename = NULL; /* assemblePLMenuFunc passes this around */ previousDepth = (int *)wmalloc(sizeof(int)); @@ -90,6 +92,7 @@ int main(int argc, char **argv) fputs("Using parser \"wmconfig\"\n", stderr); #endif parse = &parse_wmconfig; + validateFilename = &wmconfig_validate_file; } else { fprintf(stderr, "%s: Unknown parser \"%s\"\n", __progname, argv[i] + 8); } @@ -142,6 +145,10 @@ static int dirParseFunc(const char *filename, const struct stat *st, int tflags, (void)tflags; (void)ftw; + if (validateFilename && + !validateFilename(filename, st, tflags, ftw)) + return 0; + parse(filename, addWMMenuEntryCallback); return 0; } @@ -196,7 +203,7 @@ static void assemblePLMenuFunc(WMTreeNode *aNode, void *data) pDepth = *(int *)data; if (pDepth > cDepth) { /* just ascended out of a/several submenu(s) */ - WMPropList *last, *but; /* merge the differences */ + WMPropList *last, *but; /* merge the tail up to the current position */ int i; for (i = pDepth - cDepth; i > 0; i--) { last = WMPopFromArray(plMenuNodes); @@ -239,12 +246,12 @@ static void assemblePLMenuFunc(WMTreeNode *aNode, void *data) snprintf(buf, sizeof(buf), "%s -e \"%s\"", terminal, wm->CmdLine); else snprintf(buf, sizeof(buf), "%s", wm->CmdLine); - WMAddToPLArray(pl, WMCreatePLArray( - WMCreatePLString(wm->Name), - WMCreatePLString("SHEXEC"), - WMCreatePLString(buf), - NULL) - ); + WMAddToPLArray(pl, WMCreatePLArray( + WMCreatePLString(wm->Name), + WMCreatePLString("SHEXEC"), + WMCreatePLString(buf), + NULL) + ); } WMAddToArray(plMenuNodes, pl); } diff --git a/util/wmmenugen.h b/util/wmmenugen.h index 920c6e3d..54a162d2 100644 --- a/util/wmmenugen.h +++ b/util/wmmenugen.h @@ -57,3 +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, const struct stat *st, int tflags, struct FTW *ftw); + diff --git a/util/wmmenugen_parse_wmconfig.c b/util/wmmenugen_parse_wmconfig.c index 60c21f5a..ffd1a379 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 +#include #include +#include #if DEBUG #include #endif #include #include #include +#include #include "wmmenugen.h" @@ -129,6 +139,42 @@ 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, 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 */ static void parse_wmconfig_line(char **label, char **key, char **value, char *line) { diff --git a/util/wmmenugen_parse_xdg.c b/util/wmmenugen_parse_xdg.c index 0ee23f89..2c90a3a3 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 +#include + #include +#include #if DEBUG #include #endif -- 2.11.4.GIT