Fixed a bug on out-of-bounds array access attempts and enhanced the now-

functioning infobot.gib.
This commit is contained in:
Brian Koropoff 2003-03-01 07:24:58 +00:00
parent 2be8a851d5
commit cd3fc3569b
2 changed files with 92 additions and 53 deletions

View file

@ -27,7 +27,7 @@ domain infobot
global rcsid = "$Id$" global rcsid = "$Id$"
global facts addr_cmds cmds current_file global facts addr_cmds cmds
function infobot::makeKey { function infobot::makeKey {
return $(regex::replace $args[1] "\." -- "\_")_ return $(regex::replace $args[1] "\." -- "\_")_
@ -40,11 +40,13 @@ function infobot::hasAccess {
function infobot::defineFactoid { function infobot::defineFactoid {
if (!$infobot_restrict_factoids || $(infobot::hasAccess $args[1])) { if (!$infobot_restrict_factoids || $(infobot::hasAccess $args[1])) {
key = $(infobot::makeKey $args[2]) key = $(infobot::makeKey $args[2])
// Filter out newlines/carriage returns // Don't modify locked factoids
if ${facts.${key}[2]} { if ${facts.${key}[2]} {
return -2 return -2
} }
// Filter out newlines/carriage returns
facts.${key}[0] = $(regex::replace $args[3] "[\n\r]" g "") facts.${key}[0] = $(regex::replace $args[3] "[\n\r]" g "")
// Dump the rest at the end of the array (any meta info can be stored here)
facts.${key}[1] = @args[4:] facts.${key}[1] = @args[4:]
return 0 return 0
} }
@ -52,7 +54,6 @@ function infobot::defineFactoid {
} }
function infobot::factToString { function infobot::factToString {
local out
for i in @args[1:] { for i in @args[1:] {
out = $out, $i, "\255" out = $out, $i, "\255"
} }
@ -60,7 +61,6 @@ function infobot::factToString {
} }
function infobot::saveFactoids { function infobot::saveFactoids {
local output = ""
// Build up output to write to a file // Build up output to write to a file
for fact in %facts { for fact in %facts {
output = $output, $fact, "\255", $(infobot::factToString @facts.$fact), "\n" output = $output, $fact, "\255", $(infobot::factToString @facts.$fact), "\n"
@ -69,8 +69,6 @@ function infobot::saveFactoids {
} }
function infobot::loadFactoids { function infobot::loadFactoids {
delete facts
global facts
for line in $(split $(file::read $args[1],".fct") "\n") { for line in $(split $(file::read $args[1],".fct") "\n") {
fact = $(split $line "\255") fact = $(split $line "\255")
facts.${fact[0]} = @fact[1:] facts.${fact[0]} = @fact[1:]
@ -78,15 +76,23 @@ function infobot::loadFactoids {
current_file = $args[1] current_file = $args[1]
} }
function infobot::say {
client::printAllChat $infobot_name, ": ", $args[1], "\n"
}
function infobot::tell {
client::printChat $args[1] "[priv] ",$infobot_name, ": ", $args[1], "\n"
}
function infobot::chatEvent { function infobot::chatEvent {
// Ignore teamtalk/spectalk // Ignore teamtalk/spectalk
if $args[3] { if $args[3] {
return return
} }
from = $(client::getInfo $args[1] "name") uid = $args[1]
from = $(client::getInfo $uid "name")
mesg = $args[2] mesg = $args[2]
local res
// see if we are being addressed by name // see if we are being addressed by name
res = $(regex::extract $mesg $infobot_name, "[:,][[:space:]]+(.+)" i) res = $(regex::extract $mesg $infobot_name, "[:,][[:space:]]+(.+)" i)
@ -102,12 +108,12 @@ function infobot::chatEvent {
local key = $(infobot::makeKey $res[2]) local key = $(infobot::makeKey $res[2])
if #{facts.$key} { if #{facts.$key} {
if $addr { if $addr {
say $from, ": ", $res[2], " ", ${facts.${key}[1]}, " ", ${facts.$key}, "." infobot::say $from, ": ", $res[2], " ", ${facts.${key}[1]}, " ", ${facts.$key}, "."
} else { } else {
say "Well, ", $res[2], " ", ${facts.${key}[1]}, " ", ${facts.$key}, "." infobot::say "Well, ", $res[2], " ", ${facts.${key}[1]}, " ", ${facts.$key}, "."
} }
} else if $addr { // Nothing found, and we were addressed } else if $addr { // Nothing found, and we were addressed
say $from, ": Sorry, I don't know anything about ", $res[2], "." infobot::say $from, ": Sorry, I don't know anything about ", $res[2], "."
} }
return return
} }
@ -116,22 +122,22 @@ function infobot::chatEvent {
res = $(infobot::defineFactoid $args[1] $res[2] $res[4] $res[3]) res = $(infobot::defineFactoid $args[1] $res[2] $res[4] $res[3])
if $addr { if $addr {
if ($res == -1) { if ($res == -1) {
say $from, ": You do not have the privileges to alter factoids." infobot::say $from, ": You do not have the privileges to alter factoids."
} else if ($res == -2) { } else if ($res == -2) {
say $from, ": That factoid is locked." infobot::say $from, ": That factoid is locked."
} else { } else {
say $from, ": Understood." infobot::say $from, ": Understood."
} }
} }
return return
} }
local cmd = $(split $mesg) cmd = $(split $mesg)
if $addr { if $addr {
if #{addr_cmds.$cmd} { if #{addr_cmds.$cmd} {
${addr_cmds.$cmd} $args[1] $from @cmd[1:]; ${addr_cmds.$cmd} $args[1] $from @cmd[1:];
} else { } else {
say $from, ": I'm sorry, I don't understand." infobot::say $from, ": I'm sorry, I don't understand."
} }
} else if #{cmds.$cmd} { } else if #{cmds.$cmd} {
${cmds.$cmd} $args[1] $from @cmd[1:]; ${cmds.$cmd} $args[1] $from @cmd[1:];
@ -146,7 +152,7 @@ function infobot::cmdRegister {
cmds.$args[1] = $args[2] cmds.$args[1] = $args[2]
} }
function infobot::forgetFactoid { function infobot::forgetFactoid_f {
if ($infobot_restrict_factoids && !$(infobot::hasAccess $args[1])) { if ($infobot_restrict_factoids && !$(infobot::hasAccess $args[1])) {
say $args[2], ": You do not have the privileges to alter factoids." say $args[2], ": You do not have the privileges to alter factoids."
return return
@ -154,67 +160,97 @@ function infobot::forgetFactoid {
fact = $(infobot::makeKey $args[3]) fact = $(infobot::makeKey $args[3])
if #{facts.$fact} { if #{facts.$fact} {
delete facts.$fact delete facts.$fact
say $args[2], ": I forgot about ", $args[3], "." infobot::say $args[2], ": I forgot about ", $args[3], "."
} else { } else {
say $args[2], ": I don't know anything about ", $args[3], "." infobot::say $args[2], ": I don't know anything about ", $args[3], "."
} }
} }
function infobot::lockFactoid { function infobot::lockFactoid_f {
ifnot $(infobot::hasAccess $args[1]) { ifnot $(infobot::hasAccess $args[1]) {
say $args[2], ": You do not have the privileges to lock factoids." infobot::say $args[2], ": You do not have the privileges to lock factoids."
return return
} }
fact = $(infobot::makeKey $args[3]) fact = $(infobot::makeKey $args[3])
ifnot #{facts.$fact} { ifnot #{facts.$fact} {
say $args[2], ": No such factoid exists." infobot::say $args[2], ": No such factoid exists."
return return
} }
facts.${fact}[2] = 1 facts.${fact}[2] = 1
say $args[2], ": \"", $args[3], "\" is now locked." infobot::say $args[2], ": \"", $args[3], "\" is now locked."
} }
function infobot::unlockFactoid { function infobot::unlockFactoid_f {
ifnot $(infobot::hasAccess $args[1]) { ifnot $(infobot::hasAccess $args[1]) {
say $args[2], ": You do not have the privileges to unlock factoids." infobot::say $args[2], ": You do not have the privileges to unlock factoids."
return return
} }
fact = $(infobot::makeKey $args[3]) fact = $(infobot::makeKey $args[3])
ifnot #{facts.$fact} { ifnot #{facts.$fact} {
say $args[2], ": No such factoid exists." infobot::say $args[2], ": No such factoid exists."
return return
} }
facts.${fact}[2] = 0 facts.${fact}[2] = 0
say $args[2], ": \"", $args[3], "\" is now unlocked." infobot::say $args[2], ": \"", $args[3], "\" is now unlocked."
} }
function infobot::stats { function infobot::stats_f {
say $args[2], ": I currently reference ", $(count %facts), " factoid(s) and ", ($(count %cmds) + $(count %addr_cmds)), " command(s)." infobot::say $args[2], ": I currently reference ", $(count %facts), " factoid(s) and ", ($(count %cmds) + $(count %addr_cmds)), " command(s)."
} }
function infobot::syncFactoids { function infobot::syncFactoids_f {
ifnot $(infobot::hasAccess $args[1]) { ifnot $(infobot::hasAccess $args[1]) {
say $args[2], ": You do not have syncing privileges." infobot::say $args[2], ": You do not have syncing privileges."
return return
} }
if #args[3] { if #args[3] {
file = $args[3] file = $args[3]
} else { } else {
file = $current_file file = "default"
} }
infobot::saveFactoids $file infobot::saveFactoids $file
say $args[2], ": Factoids successfully synced to file ", $file, ".fct." infobot::say $args[2], ": Factoids successfully synced to file ", $file, ".fct."
}
function infobot::loadFactoids_f {
ifnot $(infobot::hasAccess $args[1]) {
infobot::say $args[2], ": You do not have loading privileges."
return
}
if #args[3] {
file = $args[3]
} else {
file = "default"
}
ifnot $(count $(file::find $file,".fct")) {
infobot::say $args[2], ": That factoids file does not exist."
return
}
infobot::loadFactoids $file
infobot::say $args[2], ": Factoids successfully loaded from file ", $file, ".fct."
}
function infobot::forgetAllFactoids_f {
ifnot $(infobot::hasAccess $args[1]) {
infobot::say $args[2], ": You do not have amnesia privileges."
return
}
infobot::say $args[2], ": I have forgotten all factoids."
delete facts
global facts
} }
// These are useful to the admin // These are useful to the admin
function::export infobot::saveFactoids infobot::loadFactoids function::export infobot::saveFactoids infobot::loadFactoids
event::register chat infobot::chatEvent event::register chat infobot::chatEvent
infobot::cmdAddrRegister "forget" infobot::forgetFactoid infobot::cmdAddrRegister "forget" infobot::forgetFactoid_f
infobot::cmdAddrRegister "lock" infobot::lockFactoid infobot::cmdAddrRegister "lock" infobot::lockFactoid_f
infobot::cmdAddrRegister "unlock" infobot::unlockFactoid infobot::cmdAddrRegister "unlock" infobot::unlockFactoid_f
infobot::cmdAddrRegister "infostats" infobot::stats infobot::cmdAddrRegister "infostats" infobot::stats_f
infobot::cmdAddrRegister "sync" infobot::syncFactoids infobot::cmdAddrRegister "sync" infobot::syncFactoids_f
infobot::cmdAddrRegister "load" infobot::loadFactoids_f
infobot::cmdAddrRegister "amnesia" infobot::forgetAllFactoids_f
// Set default values // Set default values
ifnot $(length $infobot_restrict_factoids) { ifnot $(length $infobot_restrict_factoids) {
@ -226,10 +262,10 @@ ifnot $(length $infobot_password) {
} }
ifnot $(length $infobot_name) { ifnot $(length $infobot_name) {
set infobot_name "Console" set infobot_name "gib"
} }
// Try to load a default factoids file // Try to load a default factoids file
if $(contains "default.fct" $(file::find *.fct)) { if $(count $(file::find default.fct)) {
infobot::loadFactoids "default" infobot::loadFactoids "default"
} }

View file

@ -117,16 +117,23 @@ GIB_Var_Get_Complex (hashtab_t ** first, hashtab_t ** second, char *key,
key[n] = 0; key[n] = 0;
break; break;
} }
if (!(var = GIB_Var_Get (*first, *second, key+start))) { if (!(var = GIB_Var_Get (*first, *second, key+start)) && create) {
if (create) { var = GIB_Var_New (key+start);
var = GIB_Var_New (key+start); if (!*first)
if (!*first) *first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0); Hash_Add (*first, var);
Hash_Add (*first, var);
} else
return 0;
} }
if (index >= var->size) {
// We are done looking up/creating var, fix up key
if (n)
key[n] = '[';
if (i < len)
key[i] = '.';
// Give up
if (!var)
return 0;
else if (index >= var->size) {
if (create) { if (create) {
var->array = var->array =
realloc (var->array, (index + 1) * sizeof (struct gib_varray_s)); realloc (var->array, (index + 1) * sizeof (struct gib_varray_s));
@ -139,10 +146,6 @@ GIB_Var_Get_Complex (hashtab_t ** first, hashtab_t ** second, char *key,
second = &zero; second = &zero;
first = &var->array[index].leaves; first = &var->array[index].leaves;
start = i+1; start = i+1;
if (n)
key[n] = '[';
if (i < len)
key[i] = '.';
} }
} }
if (!var->array[index].value) if (!var->array[index].value)