Relevance Behavior causes issues with cross platform relevance

This is what I was working on when coming across this issue: http://bigfix.me/analysis/details/2994801

If an operator doesn’t exist, it throws an error, even if it were never to be evaluated in the first place, or if it is written against a plural object that wouldn’t throw an error on its own.

This should always be TRUE:

Q:TRUE OR exists notAnOperator
E: The operator "notanoperator" is not defined.

This should always be TRUE:

Q:TRUE | exists notAnOperator
E: The operator "notanoperator" is not defined.

It seems like operator non-existence should evaluate to FALSE or NULL, instead of an error, at least in the case of relevance that must be either TRUE or FALSE.


On a Mac:

This works as expected, no error:

Q: registries
T: 41

This should not cause an error, similar to the above, because it is also plural:

Q: x64 registries
E: The operator "x64 registries" is not defined.

This should also not cause an error, because registries returns none, so keys is never evaluated:

Q: keys of registries
E: The operator "keys" is not defined.

This should be FALSE:

Q: exists x64 registry | FALSE
E: The operator "x64 registry" is not defined.

The if (windows of operating system) then (RELEVANCE) else FALSE should not be needed in the following: http://bigfix.me/relevance/details/3002319

2 Likes

Tackle this one first.

You are using Windows only relevance (the registry checks) so why do you not see the need for a conditional?

You could alter it to

windows of operating system AND ( (exists service "IDFEndpointService") OR (exists keys .... 

then it would go false on its own

That does not work on a Mac: (which is what I am trying to show)

Q: windows of operating system AND exists keys of x64 registry
E: The operator "x64 registry" is not defined.

This should always be FALSE:

Q: FALSE AND exists notAnOperator
E: The operator "notanoperator" is not defined.

I’m trying to write an analysis that works for both Mac & Windows. Basically the file locations are unique, but the file parsing is cross platform because the files are exactly the same.

There are no x64 registries on a Mac… in fact “registry” and “registries” are not Mac inspectors so neither should work… I think somehow we are interacting with the relevance engine here so this is strange.

“registries” on Windows returns no failure but “x32 registries” says there is no representation which is what the other should say…

Yeah I see your point now. I’m trying to see whats up there.

“registry” and “registries” are “dummy” returns on the Mac probably for a similar reason but we didn’t add any of the extensions

1 Like

It should be that all inspectors return dummy’s on non supported platforms.

Another example, that should be cross platform:

This will not work on Windows, because it needs to check the x64 folder, but it will work on all other platforms:

number of lines whose (it does not start with "#" AND it as trimmed string does not equal "") of files "hosts" of ( (folders "drivers\etc" of folders "C:\Windows\System32");(folders "/private/etc");(folders "/etc") )

This should work on all platforms, but does not due to the lack of a dummy system x64 folders operator on non-windows:

number of lines whose (it does not start with "#" AND it as trimmed string does not equal "") of files "hosts" of ( (folders "drivers\etc" of system x64 folders);(folders "/private/etc");(folders "/etc") )

right but of which would be the case for this one would also fail. You can’t specify a property of as it has none

True. In this case I suppose (system x64 folders) should be the equivalent of (folders “”) on non supported platforms, and (system x64 folder) should be equivalent of (folder “”), which would enable:

folders of ( (system x64 folder) | (folder "\Library") )

So in those cases we still can’t really do it as "folders of " doesn’t work…

Let me think on these, they are valid and I love trying to figure out how to make relevance work everywhere…

1 Like

It does work without throwing an error: (which is the other point I am trying to make)

Q:folders of folders ""
I: plural folder

This should work cross platform without error:

folders of (folders "";folders "C:";folders "/";folders "DNE")

There are multiple issues in play here. The OR / AND doesn’t short circuit evaluation in the cases of an operator not existing like it seems it probably should.

If you have a plural item that does not exist, then it does not throw an error normally, unless the operator does not exist.

Then also, there are inspectors that exists on Windows that do not exist on other platforms that should return an empty object of the equivalent type, like (folder “”) or (folders “”) … This would be a more fundamental change, but in other cases perhaps it should return a singular or plural NOTHING or NULL or FALSE or a DUMMY inspector. The issue is that when an operator is used that doesn’t exist in TRUE/FALSE relevance, it halts relevance evaluation and it is the equivalent of FALSE for the overall evaluation. This seems like the right behavior for safety reasons, but it is problematic in other cases like this where I’m trying to write simple relevance that should only be evaluated or matter on systems in which it would exist.

There is a work around for this sort of thing, but it is ugly and annoying: (there are probably some simpler versions)

Q:( if ( exists TRUE whose (if TRUE then (REPLACE_WITH_DESIRED_TF_RELEVANCE_QUERY) else FALSE) ) then (REPLACE_WITH_DESIRED_TF_RELEVANCE_QUERY) else FALSE )
A: False

As far as I know this works, but if you have to wrap every single relevance in a compound statement, it would get very very ugly. The other problem is that you cannot just wrap the whole relevance expression in a single version of the above, because then it will return FALSE no matter what, even if it should otherwise be TRUE.

Basically, IF statements can be used to hide operator non-existence errors that boolean short circuit evaluation and the pipe alternative evaluation cannot.

On Windows:

Q:( if ( exists TRUE whose (if TRUE then (windows of operating system OR REPLACE_WITH_DESIRED_REMOTE_RELEVANCE_QUERY) else FALSE) ) then (windows of operating system OR REPLACE_WITH_DESIRED_REMOTE_RELEVANCE_QUERY) else FALSE )
A: False

I am using a variation on this to guarantee a string result in my remote relevance code:

parameter "relevance_result" = "{ concatenations "~" of (base64 encode it) of unique values of (it as string) of ( if ( exists true whose (if true then (exists (it as string) of REPLACE_WITH_DESIRED_REMOTE_RELEVANCE_QUERY) else false) ) then (REPLACE_WITH_DESIRED_REMOTE_RELEVANCE_QUERY) else "Error!" ) }"

Yes that’s the most well known way around it as the whose/if combination absorbs it all. I’m surprised the “|” doesn’t as well

1 Like