raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=44fe8b987ee692e40c111b441569c96eca14d3b1

commit 44fe8b987ee692e40c111b441569c96eca14d3b1
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Sun Apr 12 12:09:07 2015 +0900

    efreetd - improve sanity checking for recursive icon monitoring
    
    i found my efreetd was not just monitoring a small set of dirs but
    literally $HOME - recursively. this explains a lot of performance
    issues i have seen on spinning hdd's vs ssd's. i never knew if was in
    efreetd though... until now. for whatever reason my efret cache caused
    efreet to try monitro a list like:
    
    /
    /h
    /ho
    /hom
    /home
    /home/
    /home/r
    ... etc.
    
    when trying to monitor something like:
    
    /home/raster/.local/share/icons
    
    that means it ended up trying $HOME as wellas a vast range of dirs it
    just shouldn't sensibly ever try. i have no idea how my cache ended up
    this way, but deleting it and re-populating it fixed it. so this ads
    code to detect such insanity (as wellas give actual complaints on deep
    recursion so we can see things better later). not a bug fix as such,
    but a major improvement to detecting bugs which is what we want for
    stability.
    
    I also noticed that one legacy pixmaps dir is not recursively
    monitored, but another is - so be consistent and recurs both.
    
    Also apply checks to desktop file monitoring too.
---
 src/bin/efreet/efreetd_cache.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/bin/efreet/efreetd_cache.c b/src/bin/efreet/efreetd_cache.c
index 88f969c..35be03d 100644
--- a/src/bin/efreet/efreetd_cache.c
+++ b/src/bin/efreet/efreetd_cache.c
@@ -259,6 +259,30 @@ stat_cmp(const void *a, const void *b)
    return 1;
 }
 
+static Eina_Bool
+_check_recurse_monitor_sanity(Eina_Inarray *stack, const char *path, unsigned 
int stack_limit)
+{
+   const char *home = getenv("HOME");
+
+   // protect against too deep recursion even if it's valid.
+   if (eina_inarray_count(stack) >= stack_limit)
+     {
+        ERR("Recursing too far. Level %i. Stopping at %s\n", stack_limit, 
path);
+        return EINA_FALSE;
+     }
+   // detect if we start recursing at $HOME - a sign of something wrong
+   if ((home) && (!strcmp(home, path)))
+     {
+        char buf[PATH_MAX];
+
+        ERR("Recursively monitor homedir! Remove cache and exit.");
+        snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
+        ecore_file_recursive_rm(buf);
+        exit(-1);
+     }
+   return EINA_TRUE;
+}
+
 static void
 icon_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Bool 
base)
 {
@@ -268,8 +292,7 @@ icon_changes_listen_recursive(Eina_Inarray *stack, const 
char *path, Eina_Bool b
 
    if (stat(path, &st) == -1) return;
    if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return;
-   // protect against too deep recursion even if it's valid.
-   if (eina_inarray_count(stack) >= 8) return;
+   if (!_check_recurse_monitor_sanity(stack, path, 8)) return;
    eina_inarray_push(stack, &st);
 
    if ((!ecore_file_is_dir(path)) && (base))
@@ -306,8 +329,7 @@ desktop_changes_listen_recursive(Eina_Inarray *stack, const 
char *path, Eina_Boo
 
    if (stat(path, &st) == -1) return;
    if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return;
-   // protect against too deep recursion even if it's valid.
-   if (eina_inarray_count(stack) >= 3) return;
+   if (!_check_recurse_monitor_sanity(stack, path, 3)) return;
    eina_inarray_push(stack, &st);
    if ((!ecore_file_is_dir(path)) && (base))
      {
@@ -371,7 +393,8 @@ icon_changes_listen(void)
         icon_changes_listen_recursive(stack, buf, EINA_TRUE);
      }
 #endif
-   icon_changes_monitor_add("/usr/share/pixmaps");
+   eina_inarray_flush(stack);
+   icon_changes_listen_recursive(stack, "/usr/share/pixmaps", EINA_TRUE);
    eina_inarray_free(stack);
 }
 

-- 


Reply via email to