Forum OpenACS Q&A: help with a regexp

Collapse
Posted by Ravi Gadad on

anyone out there good at regexp? maybe this is simple - if anyone can help me, go for it. i'm not very experienced with re. here's what i want to do:

i have a string. within this string are tcl commands (such as [retrieve_image $image_id] and the like.. all enclosed in brackets). i need to run a subst on it, but i don't want my fellow administrators (some of whose intelligence i don't completely trust) trying to execute random tcl commands. so i need to check the string to make sure the only commands in the string are in the following (example) list: [retrieve_image ... ], [retrieve_poll ... ], [cast_quote ... ]. if there are any commands in the string that don't match the above list, the administrator is given an error.

i was thinking i could do this: create a list of the accepted commands, then [join "|"] them into a string called "accepted_commands". then i'd do the following:

regexp -all -- {[($accepted_commands) } $mystring
will this work? is this the most efficient way?

thanks for any advice you can give me!

Collapse
Posted by Ravi Gadad on
oops.  i don't know what i was thinking.  my previous idea will
obviously only tell me if the acceptable commands have been
used.. which i don't care so much about.  i just want to know if
any OTHER commands are being used.  i also would like to do
the same for variable substitution (only allow certain variables to
be substituted).

thank you again!

Collapse
Posted by Brett Schwarz on
Actually, from what I gathered from your post, it probably would be better to keep them in a list, and do a lsearch on it. lsearch can be performed either: exact, glob or regexp. You probably want glob or regexp.

If {[lsearch -glob $accepted_commands ${mystring}*] >= 0} {

    # this command was good

}


Hope that helps,

--brett

Collapse
Posted by Ravi Gadad on
thank you for your response, but i'm not sure i understand your
advice - the command you've suggested would tell me if
$mystring is an accepted command.  that doesn't really matter to
me.  i don't care if they've used accepted commands, since i'm
going to run a subst on $mystring (which, by the way, contains
more than just one command).. here's an example:

mystring:
"This is a text string that contains commands.  The command in
this sentence is [retrieve_image 142] and should be left alone,
since it's in the accepted_commands list.  However, the
command in this sentence, which is [delete_all_files] should
trigger my regexp, so I can tell the person who wrote this string
that they had an unacceptable command."

with the above example of $mystring, an error needs to be
returned.  if the command [retrieve_image] was not in the above
string, i would still get the same result - an error.  but if the
command [delete_all_files] was not in the above string, my
error-checking would just leave $mystring alone, and i would run
subst on the whole string.  does this make sense?

Collapse
Posted by Ronaldo Carpio on
First, stick the accepted commands into an array:
foreach command $accepted_command_list {
  set acceptedCommands($command) 1
}
foreach {match command} [regexp -all -inline {[(w*)[^]]*]} $mystring] {
  if {![info exists acceptedCommands($command)]} {
    error "$command is not an accepted command"
  }
}
Collapse
Posted by Ronaldo Carpio on
Woops,  my backslashes disappeared.  The regexp should have a backslash before the first [,  the w,  and the last ].