Skip to content

Commit cd8e5e6

Browse files
committed
PS: Subclass AnyElement into positional or key-ional.
1 parent b452339 commit cd8e5e6

File tree

6 files changed

+293
-171
lines changed

6 files changed

+293
-171
lines changed

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,13 @@ private module Cached {
333333

334334
cached
335335
newtype TContentSet =
336-
TSingletonContent(Content c) or
337-
TAnyElementContent() or
338-
TKnownOrUnknownElementContent(Content::KnownElementContent c)
339-
340-
private predicate trackKnownValue(ConstantValue cv) {
341-
exists(cv.asString())
342-
or
343-
cv.asInt() = [0 .. 10]
344-
}
336+
TSingletonContentSet(Content c) or
337+
TAnyElementContentSet() or
338+
TAnyPositionalContentSet() or
339+
TKnownOrUnknownKeyContentSet(Content::KnownKeyContent c) or
340+
TKnownOrUnknownPositionalContentSet(Content::KnownPositionalContent c) or
341+
TUnknownPositionalElementContentSet() or
342+
TUnknownKeyContentSet()
345343

346344
cached
347345
newtype TContent =
@@ -350,20 +348,41 @@ private module Cached {
350348
or
351349
name = any(MemberExpr me).getMemberName()
352350
} or
353-
TKnownElementContent(ConstantValue cv) { trackKnownValue(cv) } or
354-
TUnknownElementContent()
351+
// A known map key
352+
TKnownKeyContent(ConstantValue cv) { exists(cv.asString()) } or
353+
// A known array index
354+
TKnownPositionalContent(ConstantValue cv) { cv.asInt() = [0 .. 10] } or
355+
// An unknown key
356+
TUnknownKeyContent() or
357+
// An unknown positional element
358+
TUnknownPositionalContent() or
359+
// A unknown position or key - and we dont even know what kind it is
360+
TUnknownKeyOrPositionContent()
355361

356362
cached
357363
newtype TContentApprox =
364+
// A field
358365
TNonElementContentApprox(Content c) { not c instanceof Content::ElementContent } or
359-
TUnknownElementContentApprox() or
360-
TKnownIntegerElementContentApprox() or
361-
TKnownElementContentApprox(string approx) { approx = approxKnownElementIndex(_) }
366+
// An unknown key
367+
TUnkownKeyContentApprox() or
368+
// A known map key
369+
TKnownKeyContentApprox(string approx) { approx = approxKnownElementIndex(_) } or
370+
// A known positional element
371+
TKnownPositionalContentApprox() or
372+
// An unknown positional element
373+
TUnknownPositionalContentApprox() or
374+
TUnknownContentApprox()
362375

363376
cached
364377
newtype TDataFlowType = TUnknownDataFlowType()
365378
}
366379

380+
class TKnownElementContent = TKnownKeyContent or TKnownPositionalContent;
381+
382+
class TKnownKindContent = TUnknownPositionalContent or TUnknownKeyContent;
383+
384+
class TUnknownElementContent = TKnownKindContent or TUnknownKeyOrPositionContent;
385+
367386
class TElementContent = TKnownElementContent or TUnknownElementContent;
368387

369388
/** Gets a string for approximating known element indices. */
@@ -923,45 +942,45 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
923942
e.getValue() = ec.getIndex()
924943
)
925944
or
926-
not exists(e.getValue().asInt()) and
945+
not exists(Content::KnownElementContent ec | ec.getIndex() = e.getValue()) and
927946
c.isAnyElement()
928947
)
929948
or
930949
exists(Content::KnownElementContent ec, int index, CfgNodes::ExprCfgNode e |
931950
e = node1.asExpr() and
932951
not arrayExprStore(node1, _, _, e) and
933952
node2.asExpr().(CfgNodes::ExprNodes::ArrayLiteralCfgNode).getExpr(index) = e and
934-
c.isKnownOrUnknownElement(ec) and
953+
c.isKnownOrUnknownPositional(ec) and
935954
index = ec.getIndex().asInt()
936955
)
937956
or
938957
exists(CfgNodes::ExprCfgNode key |
939958
node2.asExpr().(CfgNodes::ExprNodes::HashTableExprCfgNode).getValueFromKey(key) = node1.asExpr()
940959
|
941960
exists(Content::KnownElementContent ec |
942-
c.isKnownOrUnknownElement(ec) and
943-
ec.getIndex() = key.getValue()
961+
c.isKnownOrUnknownKeyContent(ec) and
962+
key.getValue() = ec.getIndex()
944963
)
945964
or
946-
not exists(key.getValue()) and
947-
c.isAnyElement()
965+
not exists(Content::KnownKeyContent ec | ec.getIndex() = key.getValue()) and
966+
c.isUnknownKeyContent()
948967
)
949968
or
950969
arrayExprStore(node1, c, node2, _)
951970
or
952-
c.isAnyElement() and
971+
c.isUnknownPositionalContent() and
953972
exists(CfgNode cfgNode |
954973
node1 = TPreReturnNodeImpl(cfgNode, false) and
955974
node2.(ReturnNodeImpl).getCfgScope() = cfgNode.getScope()
956975
)
957976
or
958-
c.isAnyElement() and
977+
c.isUnknownPositionalContent() and
959978
exists(CfgNode cfgNode |
960979
node1 = TImplicitWrapNode(cfgNode, true) and
961980
node2.(ReturnNodeImpl).getCfgScope() = cfgNode.getScope()
962981
)
963982
or
964-
c.isAnyElement() and
983+
c.isUnknownPositionalContent() and
965984
exists(CfgNodes::ExprNodes::PipelineArgumentCfgNode arg |
966985
node1 = TPrePipelineArgumentNode(arg) and
967986
node2 = TPipelineArgumentNode(arg)
@@ -992,7 +1011,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
9921011
e.getValue() = ec.getIndex()
9931012
)
9941013
or
995-
not exists(e.getValue()) and
1014+
not exists(Content::KnownElementContent ec | ec.getIndex() = e.getValue()) and
9961015
c.isAnyElement()
9971016
)
9981017
or
@@ -1044,7 +1063,7 @@ predicate clearsContent(Node n, ContentSet c) {
10441063
c.isAnyElement()
10451064
or
10461065
n instanceof PrePipelineArgumentNodeImpl and
1047-
c.isAnyElement()
1066+
c.isAnyPositional()
10481067
}
10491068

10501069
/**
@@ -1061,7 +1080,7 @@ predicate expectsContent(Node n, ContentSet c) {
10611080
c.isSingleton(any(Content::UnknownElementContent ec))
10621081
or
10631082
n instanceof PipelineArgumentNode and
1064-
c.isAnyElement()
1083+
c.isAnyPositional()
10651084
}
10661085

10671086
class DataFlowType extends TDataFlowType {
@@ -1338,18 +1357,38 @@ class ContentApprox extends TContentApprox {
13381357

13391358
/** Gets an approximated value for content `c`. */
13401359
ContentApprox getContentApprox(Content c) {
1341-
c instanceof Content::UnknownElementContent and
1342-
result = TUnknownElementContentApprox()
1360+
c instanceof Content::KnownPositionalContent and
1361+
result = TKnownPositionalContentApprox()
13431362
or
1344-
exists(c.(Content::KnownElementContent).getIndex().asInt()) and
1345-
result = TKnownIntegerElementContentApprox()
1346-
or
1347-
result =
1348-
TKnownElementContentApprox(approxKnownElementIndex(c.(Content::KnownElementContent).getIndex()))
1363+
result = TKnownKeyContentApprox(approxKnownElementIndex(c.(Content::KnownKeyContent).getIndex()))
13491364
or
13501365
result = TNonElementContentApprox(c)
1366+
or
1367+
c instanceof Content::UnknownKeyContent and
1368+
result = TUnkownKeyContentApprox()
1369+
or
1370+
c instanceof Content::UnknownPositionalContent and
1371+
result = TUnknownPositionalContentApprox()
1372+
or
1373+
c instanceof Content::UnknownKeyOrPositionContent and
1374+
result = TUnknownContentApprox()
13511375
}
13521376

1377+
// TFieldContent(string name) {
1378+
// name = any(PropertyMember member).getName()
1379+
// or
1380+
// name = any(MemberExpr me).getMemberName()
1381+
// } or
1382+
// // A known map key
1383+
// TKnownKeyContent(ConstantValue cv) { exists(cv.asString()) } or
1384+
// // A known array index
1385+
// TKnownPositionalContent(ConstantValue cv) { cv.asInt() = [0 .. 10] } or
1386+
// // An unknown key
1387+
// TUnknownKeyContent() or
1388+
// // An unknown positional element
1389+
// TUnknownPositionalContent() or
1390+
// // A unknown position or key - and we dont even know what kind it is
1391+
// TUnknownKeyOrPositionContent()
13531392
/**
13541393
* A unit class for adding additional jump steps.
13551394
*

0 commit comments

Comments
 (0)