Page 1 of 1

zmfilter.pl bug with MonitorID "in set" filters

Posted: Sat Apr 03, 2010 9:06 pm
by carteriii
I believe I've tracked down a bug where zmfilter.pl executes differently than events.php with respect to filtering based on a set of monitor IDs. I've narrowed it down to a few potential lines of code, but I'm not certain of the proper fix.

I have specified a filter that restricts events to those where "Monitor ID in set 2,3". When I submit/execute this filter from the web interface, everything executes properly. The events.php code properly splits the "2,3" and then re-joins it to be a SQL "in" statement such as "in (2,3)". Here is the relevant code from events.php, lines 32-38:

Code: Select all

$countSql = "select count(E.Id) as EventCount from Monitors as M inner join Events as E on (M.Id = E.MonitorId) where";
$eventsSql = "select E.Id,E.MonitorId,M.Name As MonitorName,M.Width,M.Height,M.DefaultScale,E.Name,E.Cause,E.Notes,E.StartTime,E.Length,E.Frames,E.AlarmFrames,E.TotScore,E.AvgScore,E.MaxScore,E.Archived from Monitors as M inner join Events as E on (M.Id = E.MonitorId) where";
if ( $user['MonitorIds'] )
{
    $countSql .= " M.Id in (".join( ",", preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) ).")";
    $eventsSql .= " M.Id in (".join( ",", preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) ).")";
}
By contrast, when this same filter is executed in the background through zmfilter.pl, the split/join code isn't working properly. That code results in a query with a where clause of "in ('2,3')" Note the single apostrophe/quotation mark before the 2 and after the 3. I believe this is an indication of two problems.

First and most obvious, the code in zmfilter.pl checks for the string /^Monitor/ and then surrounds the value with apostrophes/single quotation marks. I believe this code was intended to look for "Monitor Name" and is not considering "Monitor ID" which has numeric values.

That takes care of the apostrophe, but I believe it shows that the splitting isn't happening properly either, otherwise the query would have created "in ('2','3')" with the 2 and 3 being quoted separately. Since they were quoted together, I think this is an indication that the values aren't being split properly. Here is the relevant zmfilter.pl code around lines 330-336 which does the splitting and then adds the apostrophes

Code: Select all

( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/;
foreach my $temp_value ( split( '/["\'\s]*?,["\'\s]*?/', $stripped_value ) )
{
    if ( $filter_expr->{terms}[$i]->{attr} =~ /^Monitor/ )
    {
        $value = "'$temp_value'";
    }
I cannot see why the split command isn't working, and simply removing the extra quotation of $temp_value might break a filter which is trying to use the "Monitor Name". Would one of you gurus please take a look and propose a proper fix to this situation? Thanks.

Re: zmfilter.pl bug with MonitorID "in set" filters

Posted: Fri Aug 12, 2016 10:56 pm
by carteriii
This problem still exists in 1.30, although the code has now been moved into the Filter.pm source script. I've been running my fix for years now (I created this thread 6 years ago!!!). Should I just check this into github myself? I haven't directly contributed to the source before so I'm a bit uncomfortable doing that without one of the maintainers blessing it or at least aware of it. The fix is incredibly simple, just removing the extra quotation marks/apostrophe around the monitor ID which should be treated as a plain number (not a string which requires the apostrophes). It's now line #248 in Filter.pm and simply needs to be this:

Code: Select all

$value = "$temp_value";