Log in

View Full Version : Crash on #rules reload


John Adams
08-12-2007, 06:30 AM
As usual, excuse my extremely novice coding knowledge... but I found a potentially evil bug in the #rules reload command. If you had not previously used #rules load, the zone (and in my case, the entire Linux server) will crash. I traced it using a breakpoint to the RulesManager::LoadRules(duh) routine... where *ruleset is expected. No check is being done if there is a valid ruleset set... The zone crash is happening inside GetRulesetID(), but can be fixed before going there by assuming "default" if a ruleset has not been loaded previously.

So I added a check. Please, if there is a better way of doing this, or if this is completely off-base, let me know. Still in learning mode here, but this fix does appear to work for me. If it's a legit bug, I will move the thread to Bugs.

Thanks!

In rulesys.cpp:
bool RuleManager::LoadRules(Database *db, const char *ruleset) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (!ruleset) // getting a crazy server crash if you don't load a set before reloading =) jadams 8/12/07
ruleset="default"; // let's try assuming ruleset='default' ?

int rsid = GetRulesetID(db, ruleset);
if(rsid < 0) {
_log(RULES__ERROR, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset);
return(false);
}

_log(RULES__CHANGE, "Loading rule set '%s' (%d)", ruleset, rsid);

m_activeRuleset = rsid;
m_activeName = ruleset;

if (db->RunQuery(query, MakeAnyLenString(&query,
"SELECT rule_name, rule_value"
" FROM rule_values"
" WHERE ruleset_id=%d", rsid), errbuf, &result))
{
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
if(!SetRule(row[0], row[1], false))
_log(RULES__ERROR, "Unable to interpret rule record for %s", row[0]);
}
mysql_free_result(result);
} else {
safe_delete_array(query);
LogFile->write(EQEMuLog::Error, "Error in LoadRules query %s: %s", query, errbuf);
return(false);
}

return(true);
}