mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
JS: Also propagate through promise types
This commit is contained in:
@@ -179,6 +179,9 @@ module Public {
|
||||
/** Holds if this represents values stored at an unknown array index. */
|
||||
predicate isUnknownArrayElement() { this = MkArrayElementUnknown() }
|
||||
|
||||
/** Holds if this represents the value of a resolved promise. */
|
||||
predicate isPromiseValue() { this = MkPromiseValue() }
|
||||
|
||||
/** Holds if this represents values stored in a `Map` at an unknown key. */
|
||||
predicate isMapValueWithUnknownKey() { this = MkMapValueWithUnknownKey() }
|
||||
|
||||
@@ -266,6 +269,11 @@ module Public {
|
||||
or
|
||||
this = ContentSet::anyCapturedContent() and
|
||||
result instanceof Private::MkCapturedContent
|
||||
or
|
||||
// Although data flow will never use the special `Awaited` ContentSet in a read or store step,
|
||||
// it may appear in type-tracking and type resolution, and here it helps to treat is as `Awaited[value]`.
|
||||
this = MkAwaited() and
|
||||
result = MkPromiseValue()
|
||||
}
|
||||
|
||||
/** Gets the singleton content to be accessed. */
|
||||
|
||||
@@ -60,7 +60,7 @@ module TypeResolution {
|
||||
content.isUnknownArrayElement()
|
||||
)
|
||||
or
|
||||
// Ad-hoc support for array types. We don't support generics in general currently, we just special-case arrays.
|
||||
// Ad-hoc support for array types. We don't support generics in general currently, we just special-case arrays and promises.
|
||||
content.isUnknownArrayElement() and
|
||||
(
|
||||
memberType = host.(ArrayTypeExpr).getElementType()
|
||||
@@ -77,6 +77,9 @@ module TypeResolution {
|
||||
memberType = type.getArgument(0)
|
||||
)
|
||||
)
|
||||
or
|
||||
content.isPromiseValue() and
|
||||
memberType = unwrapPromiseType(host)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,6 +123,9 @@ module TypeResolution {
|
||||
object.(ObjectPattern).getPropertyPatternByName(contents.asPropertyName()).getValuePattern() =
|
||||
member
|
||||
or
|
||||
member.(AwaitExpr).getOperand() = object and
|
||||
contents = DataFlow::ContentSet::promiseValue()
|
||||
or
|
||||
SummaryTypeTracker::basicLoadStep(object.(AST::ValueNode).flow(),
|
||||
member.(AST::ValueNode).flow(), contents)
|
||||
}
|
||||
|
||||
@@ -14,3 +14,14 @@ function t1(c: NS.C, d: NS.D) {
|
||||
/** calls:NS.C.m */
|
||||
d.m();
|
||||
}
|
||||
|
||||
async function t2(cp: Promise<NS.C>) {
|
||||
const c = await cp;
|
||||
/** calls:NS.C.m */
|
||||
c.m();
|
||||
|
||||
cp.then(c2 => {
|
||||
/** calls:NS.C.m */
|
||||
c2.m();
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user