From f9b952f04f9527e4fb00ca7922a77dba47df4bee Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 23 Sep 2022 16:32:59 +0200 Subject: [PATCH] Ruby: Pathname use TypeTracker instead of local flow --- .../ruby/frameworks/stdlib/Pathname.qll | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll index b6381c448ec..f52c1b46ffc 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll @@ -7,6 +7,7 @@ private import codeql.ruby.DataFlow private import codeql.ruby.dataflow.FlowSummary private import codeql.ruby.dataflow.internal.DataFlowDispatch private import codeql.ruby.frameworks.data.ModelsAsData +private import codeql.ruby.typetracking.TypeTracker /** * Modeling of the `Pathname` class from the Ruby standard library. @@ -31,29 +32,31 @@ module Pathname { PathnameInstance() { this = pathnameInstance() } } - private DataFlow::Node pathnameInstance() { - // A call to `Pathname.new`. - result = API::getTopLevelMember("Pathname").getAnInstantiation() - or - // Class methods on `Pathname` that return a new `Pathname`. - result = API::getTopLevelMember("Pathname").getAMethodCall(["getwd", "pwd",]) - or - // Instance methods on `Pathname` that return a new `Pathname`. - exists(DataFlow::CallNode c | result = c | - c.getReceiver() = pathnameInstance() and - c.getMethodName() = - [ - "+", "/", "basename", "cleanpath", "expand_path", "join", "realpath", - "relative_path_from", "sub", "sub_ext", "to_path" - ] + private DataFlow::LocalSourceNode pathnameInstance(TypeTracker t) { + t.start() and + ( + // A call to `Pathname.new`. + result = API::getTopLevelMember("Pathname").getAnInstantiation() + or + // Class methods on `Pathname` that return a new `Pathname`. + result = API::getTopLevelMember("Pathname").getAMethodCall(["getwd", "pwd",]) + or + // Instance methods on `Pathname` that return a new `Pathname`. + exists(DataFlow::CallNode c | result = c | + c.getReceiver() = pathnameInstance() and + c.getMethodName() = + [ + "+", "/", "basename", "cleanpath", "expand_path", "join", "realpath", + "relative_path_from", "sub", "sub_ext", "to_path" + ] + ) ) or - exists(DataFlow::Node inst | - inst = pathnameInstance() and - inst.(DataFlow::LocalSourceNode).flowsTo(result) - ) + exists(TypeTracker t2 | result = pathnameInstance(t2).track(t2, t)) } + private DataFlow::Node pathnameInstance() { pathnameInstance(TypeTracker::end()).flowsTo(result) } + /** A call where the receiver is a `Pathname`. */ class PathnameCall extends DataFlow::CallNode { PathnameCall() { this.getReceiver() instanceof PathnameInstance }