-
Notifications
You must be signed in to change notification settings - Fork 905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support condition parse errors in rule loading results #2155
Conversation
28a7cd7
to
9e69502
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very good improvement and LGTM for the most part! I left you few comments on the code, and I'd add:
- Instead of having a static
snippet_width
, can't we make it a parameter of thesnippet()
method? - Seems like we use
YAML::Mark
just to accesspos
,line
, andcolumn
. Can't we create a small struct for this, so that we don't depend onYAML::Mark
and on other position-like structs like the one from libsinsp's parser. For sake of simplicity, even a type alias would work for now. This would work better for when a third case of position struct will come, and would also make it easier to write unit tests forrule_loader
(still a TODO) without dealing with the YAML library.
userspace/engine/rule_loader.cpp
Outdated
{ | ||
location loc = {name, YAML::Mark(), "rules content", ""}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why we do this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just so every context has some location, So for the top level context, it's a simple "somewhere in this file" location.
userspace/engine/rule_loader.cpp
Outdated
std::replace(name.begin(), name.end(), '\n', ' '); | ||
std::replace(name.begin(), name.end(), '\r', ' '); | ||
|
||
std::string item_type = "condition expression"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're starting to have many of these types. Can't we have an enum or something to centralize them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I made an enum.
userspace/engine/rule_loader.cpp
Outdated
libsinsp::filter::parser::pos_info pos; | ||
p.get_pos(pos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have a 0-params overload that allows:
libsinsp::filter::parser::pos_info pos; | |
p.get_pos(pos); | |
auto pos = p.get_pos(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a standalone location struct and YAML::Marks and parser::pos_infos are converted now.
9e69502
to
9fe7a3b
Compare
/milestone 0.33.0 |
The test failure was not related to these changes, and was actually a design flaw in the earlier PR that wasn't detected until I changed how very long snippet lines were returned. If reading rules files A and B, it's possible that reading file A has no warnings, but after reading file B there are warnings in file A, because B overrides macros/rules/lists from A. Two files that show this are https://github.com/falcosecurity/falco/blob/master/test/rules/single_rule.yaml and https://github.com/falcosecurity/falco/blob/master/test/rules/override_macro.yaml. override_macro overrides the macro is_cat, but doing that causes the list used in the original definition of is_cat to become unused. I'm going to fix that in a separate PR. It's going to have a lot of the changes that are in this PR (moving filenames into the context positions, handling long snippet lines), but it won't have the specific changes for handling condition parse errors. So putting this one on hold for now. |
acb4b0c
to
c6cdeb8
Compare
22b3269
to
0d42aeb
Compare
9ba9b62
to
cf7415b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM! I have a minor suggestion but other than that I think this is ready for approval.
userspace/engine/rule_loader.cpp
Outdated
auto it = rules_contents.find(name); | ||
if(alt_content.empty() && it == rules_contents.end()) | ||
{ | ||
if(it == rules_contents.end()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested if statement seems useless here, am I wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is redundant. I removed it.
cf7415b
to
8616dc0
Compare
In #2098 and #2158, we reworked how rules loading errors/warnings were returned to provide a richer set of information, including locations/context for the errors/warnings. That did *not* include locations within condition expressions, though. When parsing a condition expression resulted in a warning/error, the location simply pointed to the condition property of the rule. This commit improves this to handle parse errors: - When libsinsp::filter::parser::parse() throws an exception, use get_pos() to get the position within the condition string. - Add a new context() constructor that takes a filter pos_info instead of a YAML::Mark. Now that positions aren't always related to the location of yaml nodes, Make up a generic "position" struct for locations and convert YAML::Mark and parser positions to a position struct. Also allow a context to contain an alternate content string which is used to build the snippet. For contexts related to condition strings, the content is the condition. Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
8616dc0
to
3f38a08
Compare
Use an enum instead of a string for the item_type aka "parts of a rules file" field of contexts. The set of values is mostly defined by the contexts that were already created. There are a couple of forward-looking values for rule outputs/macro conditions/etc. that may be useful for later. Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Update a few tests related to rules loading to use new names for items (e.g. "rules content" for top level errors instead of "file") Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
3f38a08
to
598a4e9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/approve
LGTM label has been added. Git tree hash: b4248c68a1461f976364e8d94ada00b5b45e1fd2
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/approve
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: FedeDP, jasondellaluce, mstemm The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
In #2098, we reworked how rules loading errors/warnings were returned
to provide a richer set of information, including locations/context
for the errors/warnings.
That did not include locations within condition expressions,
though. When parsing a condition expression resulted in a
warning/error, the location simply pointed to the condition property
of the rule.
This commit improves this to handle parse errors:
get_pos() to get the position within the condition string.
of a YAML::Mark.
Doing this required some small changes to the context struct,
though. Previously, the name (e.g. yaml filename) was held separate
from the list of locations. However, condition strings don't directly
reflect any content in the yaml file. Yaml block scalars remove
whitespace/unwrap strings. Macro references/list references are
replaced with their contents.
To handle this, move the "name" (e.g. filename) from the context into
each location. This allows a chain of locations to start with file
positions but transition to offsets within a condition expression.
Also allow a context to contain an alternate content string which is
used to build the snippet. For contexts related to condition strings,
the content is the condition.
Finally, when printing snippets that contain very long lines (> a
static const 160 chars), instead of printing the entire line, print
the 160 chars surrounding the position.
Signed-off-by: Mark Stemm mark.stemm@gmail.com
What type of PR is this?
/kind feature
Any specific area of the project related to this PR?
/area engine
What this PR does / why we need it:
Add better support for parse errors in rule conditions when displaying rule load errors.
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?: