Skip to content

Commit 308aca6

Browse files
committed
C#: Make support for Attribute.Getter and Attribute.Setter in MaD.
1 parent 368ba1c commit 308aca6

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ private import FlowSummaryImpl::Private::External
9696
private import semmle.code.csharp.commons.QualifiedName
9797
private import semmle.code.csharp.dispatch.OverridableCallable
9898
private import semmle.code.csharp.frameworks.System
99+
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
99100
private import codeql.mad.ModelValidation as SharedModelVal
100101

101102
/**
@@ -194,8 +195,6 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
194195

195196
/** Provides a query predicate to check the MaD models for validation errors. */
196197
module ModelValidation {
197-
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
198-
199198
private predicate getRelevantAccessPath(string path) {
200199
summaryModel(_, _, _, _, _, _, path, _, _, _, _) or
201200
summaryModel(_, _, _, _, _, _, _, path, _, _, _) or
@@ -289,7 +288,7 @@ module ModelValidation {
289288
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
290289
result = "Dubious signature \"" + signature + "\" in " + pred + " model."
291290
or
292-
not ext.regexpMatch("|Attribute") and
291+
not ext = ["", "Attribute", "Attribute.Getter", "Attribute.Setter"] and
293292
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
294293
or
295294
invalidProvenance(provenance) and
@@ -406,6 +405,30 @@ Declaration interpretBaseDeclaration(string namespace, string type, string name,
406405
)
407406
}
408407

408+
pragma[inline]
409+
private Declaration interpretExt(Declaration d, ExtPath ext) {
410+
ext = "" and result = d
411+
or
412+
ext.getToken(0) = "Attribute" and
413+
(
414+
not exists(ext.getToken(1)) and
415+
result.(Attributable).getAnAttribute().getType() = d and
416+
not result instanceof Property and
417+
not result instanceof Indexer
418+
or
419+
exists(string accessor | accessor = ext.getToken(1) |
420+
result.(Accessor).getDeclaration().getAnAttribute().getType() = d and
421+
(
422+
result instanceof Getter and
423+
accessor = "Getter"
424+
or
425+
result instanceof Setter and
426+
accessor = "Setter"
427+
)
428+
)
429+
)
430+
}
431+
409432
/** Gets the source/sink/summary/neutral element corresponding to the supplied parameters. */
410433
pragma[nomagic]
411434
Declaration interpretElement(
@@ -425,14 +448,18 @@ Declaration interpretElement(
425448
)
426449
)
427450
|
428-
ext = "" and result = d
429-
or
430-
ext = "Attribute" and
431-
result.(Attributable).getAnAttribute().getType() = d and
432-
not result instanceof Property
451+
result = interpretExt(d, ext)
433452
)
434453
}
435454

455+
private predicate relevantExt(string ext) {
456+
summaryModel(_, _, _, _, _, ext, _, _, _, _, _) or
457+
sourceModel(_, _, _, _, _, ext, _, _, _, _) or
458+
sinkModel(_, _, _, _, _, ext, _, _, _, _)
459+
}
460+
461+
private class ExtPath = AccessPathSyntax::AccessPath<relevantExt/1>::AccessPath;
462+
436463
private predicate parseSynthField(AccessPathToken c, string name) {
437464
c.getName() = "SyntheticField" and name = c.getAnArgument()
438465
}

0 commit comments

Comments
 (0)