-
Notifications
You must be signed in to change notification settings - Fork 1.9k
-
I have the following python code:
@s_module.req("aaa") @deco2 def fct() pass
The issue is that my ql code catches only the deco2 with something similar to select all FunctionExpr fe that
predicate is_deco2(FunctionExpr fe) { exists(Expr decorator | decorator = fe.getADecorator() and decorator.(Name).getId() = "deco2" ) }
I am kind of unable to catch the other decorator with the same way by modifying "deco2" to .matches("security%") for instance.?
Beta Was this translation helpful? Give feedback.
All reactions
I think the reason your query as written isn't working is that in
@security_module.req("aaa") def fct(): pass
the decorator is not a Name, but a Call (specifically security_module.req("aaa")), of which the function part (security_module.req, accessible through getFunc) is an Attribute, of which the object (security_module, accessible through getObject) is a Name, whose id matches security%. Thus, you're missing a few levels of syntax in order to match the name.
You could of course extend this to account for all of those additional bits of syntax, but I still think this is going about it the wrong way. Instead, I would again urge you to use API graphs. First identify all references to s...
Replies: 2 comments 2 replies
-
Can you be a bit more specific about what you're trying to achieve here?
E.g. is it "I want to find all functions decorated by a known decorator foo", or "I want to find all decorators of a known function bar"? (Or perhaps some third option?)
Also, it's unclear to me how .matches("security%") relates to your example code, as there is nothing named security in there. Was s_module supposed to be security_module, perhaps?
Either way, you're probably better off working at the level of API graphs, rather than using the AST interface as you do above. For that, it may be helpful to know that decorators are desugared by the Python extractor so that
@s_module.req("aaa") @deco2 def fct(): pass
behaves as if the actual code was
fct = (s_module.req("aaa"))(deco2(def fct(): pass))
if we imagine for the moment that Python allowed this kind of "function expression".
Beta Was this translation helpful? Give feedback.
All reactions
-
Can you be a bit more specific about what you're trying to achieve here?
E.g. is it "I want to find all functions decorated by a known decoratorfoo", or "I want to find all decorators of a known functionbar"? (Or perhaps some third option?)
Well, I wanted to identify all functions that have (or have not) the @security_module.req("foo") as one of its decorators.
Also, it's unclear to me how
.matches("security%")relates to your example code, as there is nothing namedsecurityin there. Wass_modulesupposed to besecurity_module, perhaps?
Yes, a little mistake on my side, @security_module.req("foo") is the correct one.
Either way, you're probably better off working at the level of API graphs, rather than using the AST interface as you do above. For that, it may be helpful to know that decorators are desugared by the Python extractor so that
@s_module.req("aaa") @deco2 def fct(): passbehaves as if the actual code was
fct = (s_module.req("aaa"))(deco2(def fct(): pass))if we imagine for the moment that Python allowed this kind of "function expression".
I am trying something like \
/** * @name Decorated functions * @kind problem * @problem.severity warning * @id python/example/empty-scope */ import python class SecurityDecoratedFunctionExpr extends FunctionExpr { SecurityDecoratedFunctionExpr() { this.getADecorator().(Name).getId().matches("security%") } } from SecurityDecoratedFunctionExpr sdfe, Expr decorator where decorator = sdfe.getADecorator() select decorator, "This is the one."
Beta Was this translation helpful? Give feedback.
All reactions
-
I think the reason your query as written isn't working is that in
@security_module.req("aaa") def fct(): pass
the decorator is not a Name, but a Call (specifically security_module.req("aaa")), of which the function part (security_module.req, accessible through getFunc) is an Attribute, of which the object (security_module, accessible through getObject) is a Name, whose id matches security%. Thus, you're missing a few levels of syntax in order to match the name.
You could of course extend this to account for all of those additional bits of syntax, but I still think this is going about it the wrong way. Instead, I would again urge you to use API graphs. First identify all references to security_module, then getMember will give you attribute accesses on these, and getACall will get you calls of these attribute accesses, and finally for the last getACall, you can ask for the first argument and it'll be the function that you're trying to find the decorators of.
Beta Was this translation helpful? Give feedback.
All reactions
-
Yes, thank you for the help
Beta Was this translation helpful? Give feedback.