]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
menuselect: Resolve infinite loop in dependency scenario.
authorJoshua C. Colp <jcolp@sangoma.com>
Wed, 24 Jun 2020 10:25:47 +0000 (07:25 -0300)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Thu, 25 Jun 2020 19:30:09 +0000 (14:30 -0500)
Given a scenario where a module has a dependency on both
an external library and a module if the external library was
available and the module was not an infinite loop would
occur. This happened due to the code changing the dependecy
status to no failure on each dependency checking loop
iteration, resulting in the code thinking that it had
gone from no failure to failure each time triggering another
dependency check.

This change makes it so that the old dependency status is
preserved throughout the dependency checking allowing it to
determine that after the first iteration the dependency
status does not transition from no failure to failure.

ASTERISK-28930

Change-Id: Iea06d45d9fd6d8bfd068882a0bb7e23a53ec3e84

menuselect/menuselect.c
menuselect/menuselect.h

index 83f6098dc2f055bb71c299cf7c5e9f524238c202..a595ce85b8c5f0a9a2b67cb9f90fcc4e8d5433b3 100644 (file)
@@ -630,14 +630,14 @@ static unsigned int calc_dep_failures(int interactive, int pre_confload)
        struct member *mem;
        struct reference *dep;
        struct dep_file *dep_file;
-       unsigned int changed, old_failure;
+       unsigned int changed;
 
        AST_LIST_TRAVERSE(&categories, cat, list) {
                AST_LIST_TRAVERSE(&cat->members, mem, list) {
                        if (mem->is_separator) {
                                continue;
                        }
-                       old_failure = mem->depsfailed;
+                       mem->depsfailedold = mem->depsfailed;
                        AST_LIST_TRAVERSE(&mem->deps, dep, list) {
                                if (dep->member)
                                        continue;
@@ -655,7 +655,7 @@ static unsigned int calc_dep_failures(int interactive, int pre_confload)
                                        break; /* This dependency is not met, so we can stop now */
                                }
                        }
-                       if (old_failure == SOFT_FAILURE && mem->depsfailed != HARD_FAILURE)
+                       if (mem->depsfailedold == SOFT_FAILURE && mem->depsfailed != HARD_FAILURE)
                                mem->depsfailed = SOFT_FAILURE;
                }
        }
@@ -673,8 +673,6 @@ static unsigned int calc_dep_failures(int interactive, int pre_confload)
                                        continue;
                                }
 
-                               old_failure = mem->depsfailed;
-
                                if (mem->depsfailed == HARD_FAILURE)
                                        continue;
 
@@ -693,7 +691,7 @@ static unsigned int calc_dep_failures(int interactive, int pre_confload)
                                        }
                                }
 
-                               if (mem->depsfailed != old_failure) {
+                               if (mem->depsfailed != mem->depsfailedold) {
                                        if ((mem->depsfailed == NO_FAILURE) && mem->was_defaulted) {
                                                mem->enabled = !strcasecmp(mem->defaultenabled, "yes");
                                                print_debug("Just set %s enabled to %d\n", mem->name, mem->enabled);
@@ -702,6 +700,8 @@ static unsigned int calc_dep_failures(int interactive, int pre_confload)
                                                print_debug("Just set %s enabled to %d\n", mem->name, mem->enabled);
                                        }
                                        changed = 1;
+                                       /* We need to update the old failed deps for the next loop of this */
+                                       mem->depsfailedold = mem->depsfailed;
                                        break; /* This dependency is not met, so we can stop now */
                                }
                        }
index 78ae8eff6df9b0242a7808b9a7ad332b558c6fb9..d41859e194992d02fd7b4ad66f19fe2ec855236b 100644 (file)
@@ -78,6 +78,8 @@ struct member {
        unsigned int was_enabled:1;
        /*! This module has failed dependencies */
        unsigned int depsfailed:2;
+       /*! Previous failed dependencies when calculating */
+       unsigned int depsfailedold:2;
        /*! This module has failed conflicts */
        unsigned int conflictsfailed:2;
        /*! This module's 'enabled' flag was changed by a default only */