Merge pull request #707 from hvitved/csharp/bounded-fast-tc

Approved by calumgrant
This commit is contained in:
semmle-qlci 2018-12-19 19:20:42 +00:00 коммит произвёл GitHub
Родитель c57f8a6d6e e5cbac5c13
Коммит 83ccddff7a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 15 добавлений и 32 удалений

Просмотреть файл

@ -269,13 +269,6 @@ private module Internal {
* types for a given expression. * types for a given expression.
*/ */
private module SimpleTypeDataFlow { private module SimpleTypeDataFlow {
// A temporary workaround to get the right join-order in `Sink::getASource()`
private newtype ExprWrapper = TExprWrapper(Expr e)
private Expr unwrap(ExprWrapper ew) { ew = TExprWrapper(result) }
private ExprWrapper wrap(Expr e) { result = TExprWrapper(e) }
/** /**
* Holds if type `t` may be imprecise, that is, an expression of type `t` may * Holds if type `t` may be imprecise, that is, an expression of type `t` may
* in fact have a more precise type. * in fact have a more precise type.
@ -321,34 +314,27 @@ private module Internal {
typeMayBeImprecise(succ.getType()) typeMayBeImprecise(succ.getType())
} }
private predicate step(ExprWrapper succ, ExprWrapper pred) { private predicate stepTC(Expr succ, Expr pred) =
stepExpr(unwrap(succ), unwrap(pred)) fastTC(stepExpr/2)(succ, pred)
}
private predicate isSink(ExprWrapper ew) {
exists(Expr e |
e = unwrap(ew) |
e = any(DynamicMemberAccess dma | isSink(wrap(dma))).getQualifier() or
e = any(AccessorCall ac).getAnArgument() or
e = any(DispatchReflectionOrDynamicCall c).getArgument(_) or
e = any(MethodCall mc | mc.getTarget() = any(SystemObjectClass c).getGetTypeMethod()).getQualifier() or
e = any(DispatchCallImpl c).getQualifier()
)
}
private predicate stepTC(ExprWrapper succ, ExprWrapper pred) =
boundedFastTC(step/2, isSink/1)(succ, pred)
private class Source extends Expr { private class Source extends Expr {
Source() { not stepExpr(this, _) } Source() { not stepExpr(this, _) }
} }
private class Sink extends Expr { private class Sink extends Expr {
Sink() { isSink(wrap(this)) } Sink() {
this = any(DynamicMemberAccess dma | dma instanceof Sink).getQualifier()
Source getASource() { or
stepTC(wrap(this), wrap(result)) this = any(AccessorCall ac).getAnArgument()
or
this = any(DispatchReflectionOrDynamicCall c).getArgument(_)
or
this = any(MethodCall mc | mc.getTarget() = any(SystemObjectClass c).getGetTypeMethod()).getQualifier()
or
this = any(DispatchCallImpl c).getQualifier()
} }
Source getASource() { stepTC(this, result) }
} }
/** Holds if the expression `e` has an exact type. */ /** Holds if the expression `e` has an exact type. */
@ -357,10 +343,7 @@ private module Internal {
e instanceof BaseAccess e instanceof BaseAccess
} }
/** /** Gets a source type for expression `e`, using simple data flow. */
* Gets a source type for expression `e`, using simple data flow. The
* expression must be a member of the predicate `isSink()` above.
*/
Type getASourceType(Sink e, boolean isExact) { Type getASourceType(Sink e, boolean isExact) {
exists(Source s | exists(Source s |
s = e.getASource() or s = e.getASource() or