Rust: Model Deref trait in type inference

This commit is contained in:
Tom Hvitved
2025-12-08 13:22:36 +01:00
parent caa0e90cd8
commit 4540662ab9
16 changed files with 627 additions and 266 deletions

View File

@@ -7,6 +7,7 @@ private import PathResolution
private import Type
private import Type as T
private import TypeMention
private import typeinference.DerefChain
private import typeinference.FunctionType
private import typeinference.FunctionOverloading as FunctionOverloading
private import typeinference.BlanketImplementation as BlanketImplementation
@@ -1535,24 +1536,13 @@ private module MethodResolution {
* Same as `getACandidateReceiverTypeAt`, but without borrows.
*/
pragma[nomagic]
private Type getACandidateReceiverTypeAtNoBorrow(string derefChain, TypePath path) {
Type getACandidateReceiverTypeAtNoBorrow(DerefChain derefChain, TypePath path) {
result = this.getReceiverTypeAt(path) and
derefChain = ""
or
this.supportsAutoDerefAndBorrow() and
exists(TypePath path0, Type t0, string derefChain0 |
this.hasNoCompatibleTargetMutBorrow(derefChain0) and
t0 = this.getACandidateReceiverTypeAtNoBorrow(derefChain0, path0)
|
path0.isCons(getRefTypeParameter(_), path) and
result = t0 and
derefChain = derefChain0 + ".ref"
or
path0.isEmpty() and
path = path0 and
t0 = getStringStruct() and
result = getStrStruct() and
derefChain = derefChain0 + ".str"
exists(DerefImplItemNode impl, DerefChain suffix |
result = ImplicitDeref::getDereferencedCandidateReceiverType(this, impl, suffix, path) and
derefChain = DerefChain::cons(impl, suffix)
)
}
@@ -1566,7 +1556,7 @@ private module MethodResolution {
*/
pragma[nomagic]
private predicate hasIncompatibleTarget(
ImplOrTraitItemNode i, string derefChain, BorrowKind borrow, Type root
ImplOrTraitItemNode i, DerefChain derefChain, BorrowKind borrow, Type root
) {
exists(TypePath path |
ReceiverIsInstantiationOfSelfParam::argIsNotInstantiationOf(MkMethodCallCand(this,
@@ -1583,7 +1573,7 @@ private module MethodResolution {
*/
pragma[nomagic]
private predicate hasIncompatibleBlanketLikeTarget(
ImplItemNode impl, string derefChain, BorrowKind borrow
ImplItemNode impl, DerefChain derefChain, BorrowKind borrow
) {
ReceiverIsNotInstantiationOfBlanketLikeSelfParam::argIsNotInstantiationOf(MkMethodCallCand(this,
derefChain, borrow), impl, _, _)
@@ -1596,7 +1586,9 @@ private module MethodResolution {
* Same as `getACandidateReceiverTypeAt`, but excludes pseudo types `!` and `unknown`.
*/
pragma[nomagic]
Type getANonPseudoCandidateReceiverTypeAt(string derefChain, BorrowKind borrow, TypePath path) {
Type getANonPseudoCandidateReceiverTypeAt(
DerefChain derefChain, BorrowKind borrow, TypePath path
) {
result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) and
result != TNeverType() and
result != TUnknownType()
@@ -1604,7 +1596,7 @@ private module MethodResolution {
pragma[nomagic]
private Type getComplexStrippedType(
string derefChain, BorrowKind borrow, TypePath strippedTypePath
DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath
) {
result = this.getANonPseudoCandidateReceiverTypeAt(derefChain, borrow, strippedTypePath) and
isComplexRootStripped(strippedTypePath, result)
@@ -1612,7 +1604,7 @@ private module MethodResolution {
bindingset[derefChain, borrow, strippedTypePath, strippedType]
private predicate hasNoCompatibleNonBlanketLikeTargetCheck(
string derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType
DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType
) {
forall(ImplOrTraitItemNode i |
methodCallNonBlanketCandidate(this, _, i, _, strippedTypePath, strippedType)
@@ -1623,7 +1615,7 @@ private module MethodResolution {
bindingset[derefChain, borrow, strippedTypePath, strippedType]
private predicate hasNoCompatibleTargetCheck(
string derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType
DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType
) {
this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, borrow, strippedTypePath,
strippedType) and
@@ -1634,7 +1626,7 @@ private module MethodResolution {
bindingset[derefChain, borrow, strippedTypePath, strippedType]
private predicate hasNoCompatibleNonBlanketTargetCheck(
string derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType
DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType
) {
this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, borrow, strippedTypePath,
strippedType) and
@@ -1648,7 +1640,7 @@ private module MethodResolution {
// forex using recursion
pragma[nomagic]
private predicate hasNoCompatibleTargetNoBorrowToIndex(
string derefChain, TypePath strippedTypePath, Type strippedType, int n
DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n
) {
(
this.supportsAutoDerefAndBorrow()
@@ -1671,7 +1663,7 @@ private module MethodResolution {
* have a matching method target.
*/
pragma[nomagic]
predicate hasNoCompatibleTargetNoBorrow(string derefChain) {
predicate hasNoCompatibleTargetNoBorrow(DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleTargetNoBorrowToIndex(derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
@@ -1681,7 +1673,7 @@ private module MethodResolution {
// forex using recursion
pragma[nomagic]
private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex(
string derefChain, TypePath strippedTypePath, Type strippedType, int n
DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n
) {
(
this.supportsAutoDerefAndBorrow()
@@ -1705,7 +1697,7 @@ private module MethodResolution {
* a matching non-blanket method target.
*/
pragma[nomagic]
predicate hasNoCompatibleNonBlanketTargetNoBorrow(string derefChain) {
predicate hasNoCompatibleNonBlanketTargetNoBorrow(DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
@@ -1715,7 +1707,7 @@ private module MethodResolution {
// forex using recursion
pragma[nomagic]
private predicate hasNoCompatibleTargetSharedBorrowToIndex(
string derefChain, TypePath strippedTypePath, Type strippedType, int n
DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n
) {
this.hasNoCompatibleTargetNoBorrow(derefChain) and
strippedType =
@@ -1735,7 +1727,7 @@ private module MethodResolution {
* by a shared borrow, does not have a matching method target.
*/
pragma[nomagic]
predicate hasNoCompatibleTargetSharedBorrow(string derefChain) {
predicate hasNoCompatibleTargetSharedBorrow(DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleTargetSharedBorrowToIndex(derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
@@ -1745,7 +1737,7 @@ private module MethodResolution {
// forex using recursion
pragma[nomagic]
private predicate hasNoCompatibleTargetMutBorrowToIndex(
string derefChain, TypePath strippedTypePath, Type strippedType, int n
DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n
) {
this.hasNoCompatibleTargetSharedBorrow(derefChain) and
strippedType =
@@ -1764,7 +1756,7 @@ private module MethodResolution {
* by a `mut` borrow, does not have a matching method target.
*/
pragma[nomagic]
predicate hasNoCompatibleTargetMutBorrow(string derefChain) {
predicate hasNoCompatibleTargetMutBorrow(DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleTargetMutBorrowToIndex(derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
@@ -1774,7 +1766,7 @@ private module MethodResolution {
// forex using recursion
pragma[nomagic]
private predicate hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(
string derefChain, TypePath strippedTypePath, Type strippedType, int n
DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n
) {
this.hasNoCompatibleTargetNoBorrow(derefChain) and
strippedType =
@@ -1794,7 +1786,7 @@ private module MethodResolution {
* by a shared borrow, does not have a matching non-blanket method target.
*/
pragma[nomagic]
predicate hasNoCompatibleNonBlanketTargetSharedBorrow(string derefChain) {
predicate hasNoCompatibleNonBlanketTargetSharedBorrow(DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
@@ -1804,7 +1796,7 @@ private module MethodResolution {
// forex using recursion
pragma[nomagic]
private predicate hasNoCompatibleNonBlanketTargetMutBorrowToIndex(
string derefChain, TypePath strippedTypePath, Type strippedType, int n
DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n
) {
this.hasNoCompatibleNonBlanketTargetSharedBorrow(derefChain) and
strippedType =
@@ -1824,7 +1816,7 @@ private module MethodResolution {
* by a `mut` borrow, does not have a matching non-blanket method target.
*/
pragma[nomagic]
predicate hasNoCompatibleNonBlanketTargetMutBorrow(string derefChain) {
predicate hasNoCompatibleNonBlanketTargetMutBorrow(DerefChain derefChain) {
exists(Type strippedType |
this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(derefChain, _, strippedType,
getLastLookupTypeIndex(strippedType))
@@ -1844,7 +1836,7 @@ private module MethodResolution {
* [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
*/
pragma[nomagic]
Type getACandidateReceiverTypeAt(string derefChain, BorrowKind borrow, TypePath path) {
Type getACandidateReceiverTypeAt(DerefChain derefChain, BorrowKind borrow, TypePath path) {
result = this.getACandidateReceiverTypeAtNoBorrow(derefChain, path) and
borrow.isNoBorrow()
or
@@ -1877,21 +1869,24 @@ private module MethodResolution {
* `derefChain` and the enum `borrow`.
*/
pragma[nomagic]
Method resolveCallTarget(ImplOrTraitItemNode i, string derefChain, BorrowKind borrow) {
Method resolveCallTarget(ImplOrTraitItemNode i, DerefChain derefChain, BorrowKind borrow) {
exists(MethodCallCand mcc |
mcc = MkMethodCallCand(this, derefChain, borrow) and
result = mcc.resolveCallTarget(i)
)
}
predicate receiverHasImplicitDeref(AstNode receiver) {
exists(this.resolveCallTarget(_, ".ref", TNoBorrowKind())) and
receiver = this.getArg(any(ArgumentPosition pos | pos.isSelf()))
}
predicate argumentHasImplicitBorrow(AstNode arg, boolean isMutable) {
exists(this.resolveCallTarget(_, "", TSomeBorrowKind(isMutable))) and
arg = this.getArg(any(ArgumentPosition pos | pos.isSelf()))
/**
* Holds if the argument `arg` of this call has been implicitly dereferenced
* and borrowed according to `derefChain` and `borrow`, in order to be able to
* resolve the call target.
*/
predicate argumentHasImplicitDerefChainBorrow(
AstNode arg, DerefChain derefChain, BorrowKind borrow
) {
exists(this.resolveCallTarget(_, derefChain, borrow)) and
arg = this.getArg(any(ArgumentPosition pos | pos.isSelf())) and
not (derefChain.isEmpty() and borrow.isNoBorrow())
}
}
@@ -2029,10 +2024,14 @@ private module MethodResolution {
result = inferType(this.getArg(pos), path)
}
override predicate argumentHasImplicitBorrow(AstNode arg, boolean isMutable) {
exists(ArgumentPosition pos |
override predicate argumentHasImplicitDerefChainBorrow(
AstNode arg, DerefChain derefChain, BorrowKind borrow
) {
exists(ArgumentPosition pos, boolean isMutable |
this.implicitBorrowAt(pos, isMutable) and
arg = this.getArg(pos)
arg = this.getArg(pos) and
derefChain = DerefChain::nil() and
borrow = TSomeBorrowKind(isMutable)
)
}
@@ -2048,14 +2047,14 @@ private module MethodResolution {
}
private newtype TMethodCallCand =
MkMethodCallCand(MethodCall mc, string derefChain, BorrowKind borrow) {
MkMethodCallCand(MethodCall mc, DerefChain derefChain, BorrowKind borrow) {
exists(mc.getACandidateReceiverTypeAt(derefChain, borrow, _))
}
/** A method call with a dereference chain and a potential borrow. */
private class MethodCallCand extends MkMethodCallCand {
MethodCall mc_;
string derefChain;
DerefChain derefChain;
BorrowKind borrow;
MethodCallCand() { this = MkMethodCallCand(mc_, derefChain, borrow) }
@@ -2147,11 +2146,79 @@ private module MethodResolution {
MethodArgsAreInstantiationsOf::argsAreInstantiationsOf(this, i, result)
}
string toString() { result = mc_.toString() + " [" + derefChain + "; " + borrow + "]" }
string toString() {
result = mc_.toString() + " [" + derefChain.toString() + "; " + borrow + "]"
}
Location getLocation() { result = mc_.getLocation() }
}
/**
* Provides logic for resolving implicit `Deref::deref` calls.
*/
private module ImplicitDeref {
private newtype TMethodCallDerefCand =
MkMethodCallDerefCand(MethodCall mc, DerefChain derefChain) {
mc.supportsAutoDerefAndBorrow() and
mc.hasNoCompatibleTargetMutBorrow(derefChain) and
exists(mc.getACandidateReceiverTypeAtNoBorrow(derefChain, _))
}
/** A method call with a dereference chain. */
private class MethodCallDerefCand extends MkMethodCallDerefCand {
MethodCall mc;
DerefChain derefChain;
MethodCallDerefCand() { this = MkMethodCallDerefCand(mc, derefChain) }
Type getTypeAt(TypePath path) {
result = substituteLookupTraits(mc.getACandidateReceiverTypeAtNoBorrow(derefChain, path)) and
result != TNeverType() and
result != TUnknownType()
}
string toString() { result = mc.toString() + " [" + derefChain.toString() + "]" }
Location getLocation() { result = mc.getLocation() }
}
private module MethodCallSatisfiesDerefConstraintInput implements
SatisfiesConstraintInputSig<MethodCallDerefCand>
{
pragma[nomagic]
predicate relevantConstraint(MethodCallDerefCand mc, Type constraint) {
exists(mc) and
constraint.(TraitType).getTrait() instanceof DerefTrait
}
predicate useUniversalConditions() { none() }
}
private module MethodCallSatisfiesDerefConstraint =
SatisfiesConstraint<MethodCallDerefCand, MethodCallSatisfiesDerefConstraintInput>;
pragma[nomagic]
private AssociatedTypeTypeParameter getDerefTargetTypeParameter() {
result.getTypeAlias() = any(DerefTrait ft).getTargetType()
}
/**
* Gets the type of the receiver of `mc` at `path` after applying the implicit
* dereference inside `impl`, following the existing dereference chain `derefChain`.
*/
pragma[nomagic]
Type getDereferencedCandidateReceiverType(
MethodCall mc, DerefImplItemNode impl, DerefChain derefChain, TypePath path
) {
exists(MethodCallDerefCand mcc, TypePath exprPath |
mcc = MkMethodCallDerefCand(mc, derefChain) and
MethodCallSatisfiesDerefConstraint::satisfiesConstraintTypeThrough(mcc, impl, _, exprPath,
result) and
exprPath.isCons(getDerefTargetTypeParameter(), path)
)
}
}
private module ReceiverSatisfiesBlanketLikeConstraintInput implements
BlanketImplementation::SatisfiesBlanketConstraintInputSig<MethodCallCand>
{
@@ -2378,10 +2445,21 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
class AccessEnvironment = string;
bindingset[derefChain, borrow]
additional AccessEnvironment encodeDerefChainBorrow(string derefChain, BorrowKind borrow) {
private AccessEnvironment encodeDerefChainBorrow(DerefChain derefChain, BorrowKind borrow) {
result = derefChain + ";" + borrow
}
bindingset[derefChainBorrow]
additional predicate decodeDerefChainBorrow(
string derefChainBorrow, DerefChain derefChain, BorrowKind borrow
) {
exists(string regexp |
regexp = "^(.*);(.*)$" and
derefChain = derefChainBorrow.regexpCapture(regexp, 1) and
borrow.toString() = derefChainBorrow.regexpCapture(regexp, 2)
)
}
final private class MethodCallFinal = MethodResolution::MethodCall;
class Access extends MethodCallFinal, ContextTyping::ContextTypedCallCand {
@@ -2404,7 +2482,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
pragma[nomagic]
private Type getInferredSelfType(AccessPosition apos, string derefChainBorrow, TypePath path) {
exists(string derefChain, BorrowKind borrow |
exists(DerefChain derefChain, BorrowKind borrow |
result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) and
derefChainBorrow = encodeDerefChainBorrow(derefChain, borrow) and
apos.isSelf()
@@ -2440,7 +2518,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
}
Method getTarget(ImplOrTraitItemNode i, string derefChainBorrow) {
exists(string derefChain, BorrowKind borrow |
exists(DerefChain derefChain, BorrowKind borrow |
derefChainBorrow = encodeDerefChainBorrow(derefChain, borrow) and
result = this.resolveCallTarget(i, derefChain, borrow) // mutual recursion; resolving method calls requires resolving types and vice versa
)
@@ -2493,39 +2571,67 @@ private Type inferMethodCallType0(
}
pragma[nomagic]
private Type inferMethodCallType1(AstNode n, boolean isReturn, TypePath path) {
exists(
MethodCallMatchingInput::Access a, MethodCallMatchingInput::AccessPosition apos,
string derefChainBorrow, TypePath path0
|
result = inferMethodCallType0(a, apos, n, derefChainBorrow, path0) and
private Type inferMethodCallTypeNonSelf(AstNode n, boolean isReturn, TypePath path) {
exists(MethodCallMatchingInput::AccessPosition apos |
result = inferMethodCallType0(_, apos, n, _, path) and
not apos.isSelf() and
if apos.isReturn() then isReturn = true else isReturn = false
|
(
not apos.isSelf()
or
derefChainBorrow = ";"
) and
path = path0
or
// adjust for implicit deref
apos.isSelf() and
derefChainBorrow = MethodCallMatchingInput::encodeDerefChainBorrow(".ref", TNoBorrowKind()) and
path = TypePath::cons(getRefTypeParameter(_), path0)
or
// adjust for implicit borrow
apos.isSelf() and
derefChainBorrow = MethodCallMatchingInput::encodeDerefChainBorrow("", TSomeBorrowKind(_)) and
path0.isCons(getRefTypeParameter(_), path)
)
}
pragma[nomagic]
private Type inferMethodCallTypeSelf(
AstNode n, DerefChain derefChain, BorrowKind borrow, TypePath path
) {
exists(MethodCallMatchingInput::AccessPosition apos, string derefChainBorrow |
result = inferMethodCallType0(_, apos, n, derefChainBorrow, path) and
apos.isSelf() and
MethodCallMatchingInput::decodeDerefChainBorrow(derefChainBorrow, derefChain, borrow)
)
or
// adjust for implicit borrow
exists(TypePath path0, BorrowKind borrow0 |
result = inferMethodCallTypeSelf(n, derefChain, borrow0, path0) and
path0.isCons(borrow0.getRefType().getPositionalTypeParameter(0), path) and
borrow.isNoBorrow()
)
or
// adjust for implicit deref
exists(
DerefChain derefChain0, Type t0, TypePath path0, DerefImplItemNode impl, Type selfParamType,
TypePath selfPath
|
t0 = inferMethodCallTypeSelf(n, derefChain0, borrow, path0) and
derefChain0.isCons(impl, derefChain) and
borrow.isNoBorrow() and
selfParamType = impl.resolveSelfParamTypeStrippedAt(selfPath)
|
result = selfParamType and
path = selfPath and
not result instanceof TypeParameter
or
exists(TypeParameter tp, TypePath pathToTypeParam, TypePath suffix |
impl.returnTypeStrippedMentionsTypeParameterAt(tp, pathToTypeParam) and
path0 = pathToTypeParam.appendInverse(suffix) and
result = t0 and
path = selfPath.append(suffix)
)
)
}
private Type inferMethodCallTypePreCheck(AstNode n, boolean isReturn, TypePath path) {
result = inferMethodCallTypeNonSelf(n, isReturn, path)
or
result = inferMethodCallTypeSelf(n, DerefChain::nil(), TNoBorrowKind(), path) and
isReturn = false
}
/**
* Gets the type of `n` at `path`, where `n` is either a method call or an
* argument/receiver of a method call.
*/
private predicate inferMethodCallType =
ContextTyping::CheckContextTyping<inferMethodCallType1/3>::check/2;
ContextTyping::CheckContextTyping<inferMethodCallTypePreCheck/3>::check/2;
/**
* Provides logic for resolving calls to non-method items. This includes
@@ -3127,19 +3233,28 @@ private predicate inferOperationType =
ContextTyping::CheckContextTyping<inferOperationType0/3>::check/2;
pragma[nomagic]
private Type getFieldExprLookupType(FieldExpr fe, string name, boolean isDereferenced) {
private Type getFieldExprLookupType(FieldExpr fe, string name, DerefChain derefChain) {
exists(TypePath path |
result = inferType(fe.getContainer(), path) and
name = fe.getIdentifier().getText() and
isComplexRootStripped(path, result) and
if path.isEmpty() then isDereferenced = false else isDereferenced = true
isComplexRootStripped(path, result)
|
// TODO: Support full derefence chains as for method calls
path.isEmpty() and
derefChain = DerefChain::nil()
or
exists(DerefImplItemNode impl, TypeParamTypeParameter tp |
tp = impl.getFirstSelfTypeParameter() and
path.getHead() = tp and
derefChain = DerefChain::singleton(impl)
)
)
}
pragma[nomagic]
private Type getTupleFieldExprLookupType(FieldExpr fe, int pos, boolean isDereferenced) {
private Type getTupleFieldExprLookupType(FieldExpr fe, int pos, DerefChain derefChain) {
exists(string name |
result = getFieldExprLookupType(fe, name, isDereferenced) and
result = getFieldExprLookupType(fe, name, derefChain) and
pos = name.toInt()
)
}
@@ -3341,9 +3456,6 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
pragma[nomagic]
private StructType getStrStruct() { result = TDataType(any(Builtins::Str s)) }
pragma[nomagic]
private StructType getStringStruct() { result = TDataType(any(StringStruct s)) }
pragma[nomagic]
private Type inferLiteralType(LiteralExpr le, TypePath path, boolean certain) {
path.isEmpty() and
@@ -3800,20 +3912,27 @@ private module Cached {
/** Holds if `n` is implicitly dereferenced. */
cached
predicate implicitDeref(AstNode n) {
any(MethodResolution::MethodCall mc).receiverHasImplicitDeref(n)
or
n =
any(FieldExpr fe |
exists(resolveStructFieldExpr(fe, true))
or
exists(resolveTupleFieldExpr(fe, true))
).getContainer()
exists(DerefChain derefChain, DerefImplItemNode impl |
impl.resolveSelfTyBuiltin() instanceof Builtins::RefType and
derefChain = DerefChain::singleton(impl)
|
any(MethodResolution::MethodCall mc)
.argumentHasImplicitDerefChainBorrow(n, derefChain, TNoBorrowKind())
or
n =
any(FieldExpr fe |
exists(resolveStructFieldExpr(fe, derefChain))
or
exists(resolveTupleFieldExpr(fe, derefChain))
).getContainer()
)
}
/** Holds if `n` is implicitly borrowed. */
cached
predicate implicitBorrow(AstNode n, boolean isMutable) {
any(MethodResolution::MethodCall mc).argumentHasImplicitBorrow(n, isMutable)
any(MethodResolution::MethodCall mc)
.argumentHasImplicitDerefChainBorrow(n, DerefChain::nil(), TSomeBorrowKind(isMutable))
}
/**
@@ -3843,9 +3962,9 @@ private module Cached {
* Gets the struct field that the field expression `fe` resolves to, if any.
*/
cached
StructField resolveStructFieldExpr(FieldExpr fe, boolean isDereferenced) {
StructField resolveStructFieldExpr(FieldExpr fe, DerefChain derefChain) {
exists(string name, DataType ty |
ty = getFieldExprLookupType(fe, pragma[only_bind_into](name), isDereferenced)
ty = getFieldExprLookupType(fe, pragma[only_bind_into](name), derefChain)
|
result = ty.(StructType).getTypeItem().getStructField(pragma[only_bind_into](name)) or
result = ty.(UnionType).getTypeItem().getStructField(pragma[only_bind_into](name))
@@ -3856,10 +3975,10 @@ private module Cached {
* Gets the tuple field that the field expression `fe` resolves to, if any.
*/
cached
TupleField resolveTupleFieldExpr(FieldExpr fe, boolean isDereferenced) {
TupleField resolveTupleFieldExpr(FieldExpr fe, DerefChain derefChain) {
exists(int i |
result =
getTupleFieldExprLookupType(fe, pragma[only_bind_into](i), isDereferenced)
getTupleFieldExprLookupType(fe, pragma[only_bind_into](i), derefChain)
.(StructType)
.getTypeItem()
.getTupleField(pragma[only_bind_into](i))

View File

@@ -0,0 +1,82 @@
/** Provides logic for representing chains of implicit dereferences. */
private import rust
private import codeql.rust.internal.PathResolution
private import codeql.rust.internal.Type
private import codeql.rust.internal.TypeInference
private import codeql.rust.internal.TypeMention
private import codeql.rust.frameworks.stdlib.Stdlib
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
private import codeql.util.UnboundList as UnboundListImpl
/** An `impl` block that implements the `Deref` trait. */
class DerefImplItemNode extends ImplItemNode {
DerefImplItemNode() { this.resolveTraitTy() instanceof DerefTrait }
/** Gets the `deref` function in this `Deref` impl block. */
Function getDerefFunction() { result = this.getAssocItem("deref") }
private SelfParam getSelfParam() { result = this.getDerefFunction().getSelfParam() }
/**
* Resolves the type at `path` of the `self` parameter inside the `deref` function,
* stripped of the leading `&`.
*/
pragma[nomagic]
Type resolveSelfParamTypeStrippedAt(TypePath path) {
exists(TypePath path0 |
result = getSelfParamTypeMention(this.getSelfParam()).resolveTypeAt(path0) and
path0.isCons(getRefTypeParameter(false), path)
)
}
/**
* Holds if the return type at `path` of the `deref` function, stripped of the
* leading `&`, mentions type parameter `tp` at `path`.
*/
pragma[nomagic]
predicate returnTypeStrippedMentionsTypeParameterAt(TypeParameter tp, TypePath path) {
exists(TypePath path0 |
tp = getReturnTypeMention(this.getDerefFunction()).resolveTypeAt(path0) and
path0.isCons(getRefTypeParameter(false), path)
)
}
/** Gets the first type parameter of the type being implemented, if any. */
pragma[nomagic]
TypeParamTypeParameter getFirstSelfTypeParameter() {
result.getTypeParam() = this.resolveSelfTy().getTypeParam(0)
}
}
private module UnboundListInput implements UnboundListImpl::InputSig<Location> {
private import codeql.rust.elements.internal.generated.Raw
private import codeql.rust.elements.internal.generated.Synth
private class DerefImplItemRaw extends Raw::Impl {
DerefImplItemRaw() { this = Synth::convertAstNodeToRaw(any(DerefImplItemNode i)) }
}
private predicate id(DerefImplItemRaw x, DerefImplItemRaw y) { x = y }
private predicate idOfRaw(DerefImplItemRaw x, int y) = equivalenceRelation(id/2)(x, y)
class Element = DerefImplItemNode;
int getId(Element e) { idOfRaw(Synth::convertAstNodeToRaw(e), result) }
string getElementString(Element e) { result = e.resolveSelfTy().getName() }
int getLengthLimit() { result = 5 }
}
private import UnboundListImpl::Make<Location, UnboundListInput>
/**
* A sequence of `Deref` impl blocks representing a chain of implicit dereferences,
* encoded as a string.
*/
class DerefChain = UnboundList;
/** Provides predicates for constructing `DerefChain`s. */
module DerefChain = UnboundList;

View File

@@ -84,6 +84,7 @@
| main.rs:292:13:292:14 | * ... | main.rs:251:5:253:5 | fn deref |
| main.rs:293:5:293:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:295:28:295:37 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:296:13:296:23 | a.min(...) | {EXTERNAL LOCATION} | fn min |
| main.rs:297:5:297:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:319:28:319:36 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:321:30:321:54 | ...::take_self(...) | main.rs:309:5:311:5 | fn take_self |

View File

@@ -35,7 +35,8 @@ models
| 34 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self].Reference; Argument[0].Reference; taint |
| 35 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 36 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
| 37 | Summary: <std::path::PathBuf>::as_path; Argument[self].Reference; ReturnValue.Reference; value |
| 37 | Summary: <std::path::Path>::canonicalize; Argument[self].Reference.OptionalBarrier[normalize-path]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 38 | Summary: <std::path::PathBuf>::as_path; Argument[self].Reference; ReturnValue.Reference; value |
edges
| test.rs:12:13:12:18 | buffer | test.rs:13:14:13:19 | buffer | provenance | |
| test.rs:12:31:12:43 | ...::read | test.rs:12:31:12:55 | ...::read(...) [Ok] | provenance | Src:MaD:11 |
@@ -51,12 +52,15 @@ edges
| test.rs:22:22:22:52 | TryExpr | test.rs:22:13:22:18 | buffer | provenance | |
| test.rs:29:13:29:16 | path | test.rs:30:14:30:17 | path | provenance | |
| test.rs:29:13:29:16 | path | test.rs:31:14:31:17 | path | provenance | |
| test.rs:29:13:29:16 | path | test.rs:40:14:40:17 | path | provenance | |
| test.rs:29:13:29:16 | path | test.rs:41:14:41:17 | path | provenance | |
| test.rs:29:20:29:27 | e.path() | test.rs:29:13:29:16 | path | provenance | |
| test.rs:29:22:29:25 | path | test.rs:29:20:29:27 | e.path() | provenance | Src:MaD:4 MaD:4 |
| test.rs:30:14:30:17 | path | test.rs:30:14:30:25 | path.clone() | provenance | MaD:18 |
| test.rs:31:14:31:17 | path | test.rs:31:14:31:25 | path.clone() | provenance | MaD:18 |
| test.rs:31:14:31:25 | path.clone() | test.rs:31:14:31:35 | ... .as_path() | provenance | MaD:37 |
| test.rs:31:14:31:25 | path.clone() | test.rs:31:14:31:35 | ... .as_path() | provenance | MaD:38 |
| test.rs:40:14:40:17 | path | test.rs:40:14:40:32 | path.canonicalize() [Ok] | provenance | MaD:37 |
| test.rs:40:14:40:32 | path.canonicalize() [Ok] | test.rs:40:14:40:41 | ... .unwrap() | provenance | MaD:36 |
| test.rs:43:13:43:21 | file_name | test.rs:44:14:44:22 | file_name | provenance | |
| test.rs:43:13:43:21 | file_name | test.rs:49:14:49:22 | file_name | provenance | |
| test.rs:43:25:43:37 | e.file_name() | test.rs:43:13:43:21 | file_name | provenance | |
@@ -273,6 +277,9 @@ nodes
| test.rs:31:14:31:17 | path | semmle.label | path |
| test.rs:31:14:31:25 | path.clone() | semmle.label | path.clone() |
| test.rs:31:14:31:35 | ... .as_path() | semmle.label | ... .as_path() |
| test.rs:40:14:40:17 | path | semmle.label | path |
| test.rs:40:14:40:32 | path.canonicalize() [Ok] | semmle.label | path.canonicalize() [Ok] |
| test.rs:40:14:40:41 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:41:14:41:17 | path | semmle.label | path |
| test.rs:43:13:43:21 | file_name | semmle.label | file_name |
| test.rs:43:25:43:37 | e.file_name() | semmle.label | e.file_name() |
@@ -492,6 +499,7 @@ testFailures
| test.rs:23:14:23:19 | buffer | test.rs:22:22:22:39 | ...::read_to_string | test.rs:23:14:23:19 | buffer | $@ | test.rs:22:22:22:39 | ...::read_to_string | ...::read_to_string |
| test.rs:30:14:30:25 | path.clone() | test.rs:29:22:29:25 | path | test.rs:30:14:30:25 | path.clone() | $@ | test.rs:29:22:29:25 | path | path |
| test.rs:31:14:31:35 | ... .as_path() | test.rs:29:22:29:25 | path | test.rs:31:14:31:35 | ... .as_path() | $@ | test.rs:29:22:29:25 | path | path |
| test.rs:40:14:40:41 | ... .unwrap() | test.rs:29:22:29:25 | path | test.rs:40:14:40:41 | ... .unwrap() | $@ | test.rs:29:22:29:25 | path | path |
| test.rs:41:14:41:17 | path | test.rs:29:22:29:25 | path | test.rs:41:14:41:17 | path | $@ | test.rs:29:22:29:25 | path | path |
| test.rs:44:14:44:30 | file_name.clone() | test.rs:43:27:43:35 | file_name | test.rs:44:14:44:30 | file_name.clone() | $@ | test.rs:43:27:43:35 | file_name | file_name |
| test.rs:49:14:49:22 | file_name | test.rs:43:27:43:35 | file_name | test.rs:49:14:49:22 | file_name | $@ | test.rs:43:27:43:35 | file_name | file_name |

View File

@@ -7,6 +7,9 @@
| test.rs:51:52:51:59 | read_dir | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:54:22:54:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:55:27:55:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:57:56:57:63 | read_dir | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:60:22:60:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:61:27:61:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:65:22:65:34 | ...::read_link | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:74:31:74:45 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:79:31:79:45 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |

View File

@@ -37,7 +37,7 @@ fn test_fs() -> Result<(), Box<dyn std::error::Error>> {
sink(path.to_path_buf()); // $ MISSING: hasTaintFlow
sink(path.file_name().unwrap()); // $ MISSING: hasTaintFlow
sink(path.extension().unwrap()); // $ MISSING: hasTaintFlow
sink(path.canonicalize().unwrap()); // $ MISSING: hasTaintFlow
sink(path.canonicalize().unwrap()); // $ hasTaintFlow
sink(path); // $ hasTaintFlow
let file_name = e.file_name(); // $ Alert[rust/summary/taint-sources]
@@ -54,11 +54,11 @@ fn test_fs() -> Result<(), Box<dyn std::error::Error>> {
let path = e.path(); // $ Alert[rust/summary/taint-sources]
let file_name = e.file_name(); // $ Alert[rust/summary/taint-sources]
}
for entry in std::path::PathBuf::from("directory").read_dir()? {
for entry in std::path::PathBuf::from("directory").read_dir()? { // $ Alert[rust/summary/taint-sources]
let e = entry?;
let path = e.path(); // $ MISSING: Alert[rust/summary/taint-sources]
let file_name = e.file_name(); // $ MISSING: Alert[rust/summary/taint-sources]
let path = e.path(); // $ Alert[rust/summary/taint-sources]
let file_name = e.file_name(); // $ Alert[rust/summary/taint-sources]
}
{

View File

@@ -1,93 +1,97 @@
models
| 1 | Source: <async_std::net::tcp::stream::TcpStream>::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote |
| 2 | Source: <hyper::client::conn::http1::SendRequest>::send_request; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote |
| 3 | Source: <std::net::tcp::TcpStream>::connect; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 4 | Source: <std::net::tcp::TcpStream>::connect_timeout; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 5 | Source: <tokio::net::tcp::stream::TcpStream>::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote |
| 6 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 7 | Source: reqwest::get; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote |
| 8 | Summary: <_ as core::ops::index::Index>::index; Argument[self].Reference.Element; ReturnValue.Reference; value |
| 9 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint |
| 10 | Summary: <_ as futures_io::if_std::AsyncRead>::poll_read; Argument[self].Reference; Argument[1].Reference; taint |
| 11 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 12 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint |
| 13 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint |
| 14 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint |
| 15 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint |
| 16 | Summary: <_ as std::io::BufRead>::read_line; Argument[self].Reference; Argument[0].Reference; taint |
| 17 | Summary: <_ as std::io::Read>::read; Argument[self].Reference; Argument[0].Reference; taint |
| 18 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint |
| 19 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint |
| 20 | Summary: <core::option::Option>::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value |
| 21 | Summary: <core::pin::Pin>::new; Argument[0].Reference; ReturnValue; value |
| 22 | Summary: <core::pin::Pin>::new; Argument[0]; ReturnValue.Field[core::pin::Pin::pointer]; value |
| 23 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
| 24 | Summary: <futures_rustls::TlsConnector>::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 25 | Summary: <futures_util::io::buf_reader::BufReader>::new; Argument[0]; ReturnValue; taint |
| 26 | Summary: <reqwest::async_impl::response::Response>::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 27 | Summary: <reqwest::async_impl::response::Response>::chunk; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint |
| 28 | Summary: <reqwest::async_impl::response::Response>::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 29 | Summary: <reqwest::blocking::response::Response>::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 30 | Summary: <reqwest::blocking::response::Response>::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 31 | Summary: <reqwest::blocking::response::Response>::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 32 | Summary: <std::io::buffered::bufreader::BufReader>::new; Argument[0]; ReturnValue; taint |
| 33 | Summary: <tokio::net::tcp::stream::TcpStream>::peek; Argument[self].Reference; Argument[0].Reference; taint |
| 34 | Summary: <tokio::net::tcp::stream::TcpStream>::try_read; Argument[self].Reference; Argument[0].Reference; taint |
| 35 | Summary: <tokio::net::tcp::stream::TcpStream>::try_read_buf; Argument[self].Reference; Argument[0].Reference; taint |
| 3 | Source: <rustls::client::client_conn::connection::ClientConnection>::new; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 4 | Source: <std::net::tcp::TcpStream>::connect; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 5 | Source: <std::net::tcp::TcpStream>::connect_timeout; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 6 | Source: <tokio::net::tcp::stream::TcpStream>::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote |
| 7 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote |
| 8 | Source: reqwest::get; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote |
| 9 | Summary: <_ as core::ops::index::Index>::index; Argument[self].Reference.Element; ReturnValue.Reference; value |
| 10 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint |
| 11 | Summary: <_ as futures_io::if_std::AsyncRead>::poll_read; Argument[self].Reference; Argument[1].Reference; taint |
| 12 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 13 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint |
| 14 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint |
| 15 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint |
| 16 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint |
| 17 | Summary: <_ as std::io::BufRead>::read_line; Argument[self].Reference; Argument[0].Reference; taint |
| 18 | Summary: <_ as std::io::Read>::read; Argument[self].Reference; Argument[0].Reference; taint |
| 19 | Summary: <_ as std::io::Read>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint |
| 20 | Summary: <_ as std::io::Read>::read_to_string; Argument[self].Reference; Argument[0].Reference; taint |
| 21 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint |
| 22 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint |
| 23 | Summary: <core::option::Option>::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value |
| 24 | Summary: <core::pin::Pin>::new; Argument[0].Reference; ReturnValue; value |
| 25 | Summary: <core::pin::Pin>::new; Argument[0]; ReturnValue.Field[core::pin::Pin::pointer]; value |
| 26 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
| 27 | Summary: <futures_rustls::TlsConnector>::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 28 | Summary: <futures_util::io::buf_reader::BufReader>::new; Argument[0]; ReturnValue; taint |
| 29 | Summary: <reqwest::async_impl::response::Response>::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 30 | Summary: <reqwest::async_impl::response::Response>::chunk; Argument[self].Reference; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint |
| 31 | Summary: <reqwest::async_impl::response::Response>::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
| 32 | Summary: <reqwest::blocking::response::Response>::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 33 | Summary: <reqwest::blocking::response::Response>::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 34 | Summary: <reqwest::blocking::response::Response>::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
| 35 | Summary: <rustls::conn::ConnectionCommon>::reader; Argument[self]; ReturnValue; taint |
| 36 | Summary: <std::io::buffered::bufreader::BufReader>::new; Argument[0]; ReturnValue; taint |
| 37 | Summary: <tokio::net::tcp::stream::TcpStream>::peek; Argument[self].Reference; Argument[0].Reference; taint |
| 38 | Summary: <tokio::net::tcp::stream::TcpStream>::try_read; Argument[self].Reference; Argument[0].Reference; taint |
| 39 | Summary: <tokio::net::tcp::stream::TcpStream>::try_read_buf; Argument[self].Reference; Argument[0].Reference; taint |
edges
| test.rs:11:9:11:22 | remote_string1 | test.rs:12:10:12:23 | remote_string1 | provenance | |
| test.rs:11:26:11:47 | ...::get | test.rs:11:26:11:62 | ...::get(...) [Ok] | provenance | Src:MaD:6 |
| test.rs:11:26:11:47 | ...::get | test.rs:11:26:11:62 | ...::get(...) [Ok] | provenance | Src:MaD:7 |
| test.rs:11:26:11:62 | ...::get(...) [Ok] | test.rs:11:26:11:63 | TryExpr | provenance | |
| test.rs:11:26:11:63 | TryExpr | test.rs:11:26:11:70 | ... .text() [Ok] | provenance | MaD:30 |
| test.rs:11:26:11:63 | TryExpr | test.rs:11:26:11:70 | ... .text() [Ok] | provenance | MaD:33 |
| test.rs:11:26:11:70 | ... .text() [Ok] | test.rs:11:26:11:71 | TryExpr | provenance | |
| test.rs:11:26:11:71 | TryExpr | test.rs:11:9:11:22 | remote_string1 | provenance | |
| test.rs:14:9:14:22 | remote_string2 | test.rs:15:10:15:23 | remote_string2 | provenance | |
| test.rs:14:26:14:47 | ...::get | test.rs:14:26:14:62 | ...::get(...) [Ok] | provenance | Src:MaD:6 |
| test.rs:14:26:14:62 | ...::get(...) [Ok] | test.rs:14:26:14:71 | ... .unwrap() | provenance | MaD:23 |
| test.rs:14:26:14:71 | ... .unwrap() | test.rs:14:26:14:78 | ... .text() [Ok] | provenance | MaD:30 |
| test.rs:14:26:14:78 | ... .text() [Ok] | test.rs:14:26:14:87 | ... .unwrap() | provenance | MaD:23 |
| test.rs:14:26:14:47 | ...::get | test.rs:14:26:14:62 | ...::get(...) [Ok] | provenance | Src:MaD:7 |
| test.rs:14:26:14:62 | ...::get(...) [Ok] | test.rs:14:26:14:71 | ... .unwrap() | provenance | MaD:26 |
| test.rs:14:26:14:71 | ... .unwrap() | test.rs:14:26:14:78 | ... .text() [Ok] | provenance | MaD:33 |
| test.rs:14:26:14:78 | ... .text() [Ok] | test.rs:14:26:14:87 | ... .unwrap() | provenance | MaD:26 |
| test.rs:14:26:14:87 | ... .unwrap() | test.rs:14:9:14:22 | remote_string2 | provenance | |
| test.rs:17:9:17:22 | remote_string3 | test.rs:18:10:18:23 | remote_string3 | provenance | |
| test.rs:17:26:17:47 | ...::get | test.rs:17:26:17:62 | ...::get(...) [Ok] | provenance | Src:MaD:6 |
| test.rs:17:26:17:62 | ...::get(...) [Ok] | test.rs:17:26:17:71 | ... .unwrap() | provenance | MaD:23 |
| test.rs:17:26:17:71 | ... .unwrap() | test.rs:17:26:17:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:31 |
| test.rs:17:26:17:98 | ... .text_with_charset(...) [Ok] | test.rs:17:26:17:107 | ... .unwrap() | provenance | MaD:23 |
| test.rs:17:26:17:47 | ...::get | test.rs:17:26:17:62 | ...::get(...) [Ok] | provenance | Src:MaD:7 |
| test.rs:17:26:17:62 | ...::get(...) [Ok] | test.rs:17:26:17:71 | ... .unwrap() | provenance | MaD:26 |
| test.rs:17:26:17:71 | ... .unwrap() | test.rs:17:26:17:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:34 |
| test.rs:17:26:17:98 | ... .text_with_charset(...) [Ok] | test.rs:17:26:17:107 | ... .unwrap() | provenance | MaD:26 |
| test.rs:17:26:17:107 | ... .unwrap() | test.rs:17:9:17:22 | remote_string3 | provenance | |
| test.rs:20:9:20:22 | remote_string4 | test.rs:21:10:21:23 | remote_string4 | provenance | |
| test.rs:20:26:20:47 | ...::get | test.rs:20:26:20:62 | ...::get(...) [Ok] | provenance | Src:MaD:6 |
| test.rs:20:26:20:62 | ...::get(...) [Ok] | test.rs:20:26:20:71 | ... .unwrap() | provenance | MaD:23 |
| test.rs:20:26:20:71 | ... .unwrap() | test.rs:20:26:20:79 | ... .bytes() [Ok] | provenance | MaD:29 |
| test.rs:20:26:20:79 | ... .bytes() [Ok] | test.rs:20:26:20:88 | ... .unwrap() | provenance | MaD:23 |
| test.rs:20:26:20:47 | ...::get | test.rs:20:26:20:62 | ...::get(...) [Ok] | provenance | Src:MaD:7 |
| test.rs:20:26:20:62 | ...::get(...) [Ok] | test.rs:20:26:20:71 | ... .unwrap() | provenance | MaD:26 |
| test.rs:20:26:20:71 | ... .unwrap() | test.rs:20:26:20:79 | ... .bytes() [Ok] | provenance | MaD:32 |
| test.rs:20:26:20:79 | ... .bytes() [Ok] | test.rs:20:26:20:88 | ... .unwrap() | provenance | MaD:26 |
| test.rs:20:26:20:88 | ... .unwrap() | test.rs:20:9:20:22 | remote_string4 | provenance | |
| test.rs:23:9:23:22 | remote_string5 | test.rs:24:10:24:23 | remote_string5 | provenance | |
| test.rs:23:26:23:37 | ...::get | test.rs:23:26:23:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:7 |
| test.rs:23:26:23:37 | ...::get | test.rs:23:26:23:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:8 |
| test.rs:23:26:23:52 | ...::get(...) [future, Ok] | test.rs:23:26:23:58 | await ... [Ok] | provenance | |
| test.rs:23:26:23:58 | await ... [Ok] | test.rs:23:26:23:59 | TryExpr | provenance | |
| test.rs:23:26:23:59 | TryExpr | test.rs:23:26:23:66 | ... .text() [future, Ok] | provenance | MaD:28 |
| test.rs:23:26:23:59 | TryExpr | test.rs:23:26:23:66 | ... .text() [future, Ok] | provenance | MaD:31 |
| test.rs:23:26:23:66 | ... .text() [future, Ok] | test.rs:23:26:23:72 | await ... [Ok] | provenance | |
| test.rs:23:26:23:72 | await ... [Ok] | test.rs:23:26:23:73 | TryExpr | provenance | |
| test.rs:23:26:23:73 | TryExpr | test.rs:23:9:23:22 | remote_string5 | provenance | |
| test.rs:26:9:26:22 | remote_string6 | test.rs:27:10:27:23 | remote_string6 | provenance | |
| test.rs:26:26:26:37 | ...::get | test.rs:26:26:26:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:7 |
| test.rs:26:26:26:37 | ...::get | test.rs:26:26:26:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:8 |
| test.rs:26:26:26:52 | ...::get(...) [future, Ok] | test.rs:26:26:26:58 | await ... [Ok] | provenance | |
| test.rs:26:26:26:58 | await ... [Ok] | test.rs:26:26:26:59 | TryExpr | provenance | |
| test.rs:26:26:26:59 | TryExpr | test.rs:26:26:26:67 | ... .bytes() [future, Ok] | provenance | MaD:26 |
| test.rs:26:26:26:59 | TryExpr | test.rs:26:26:26:67 | ... .bytes() [future, Ok] | provenance | MaD:29 |
| test.rs:26:26:26:67 | ... .bytes() [future, Ok] | test.rs:26:26:26:73 | await ... [Ok] | provenance | |
| test.rs:26:26:26:73 | await ... [Ok] | test.rs:26:26:26:74 | TryExpr | provenance | |
| test.rs:26:26:26:74 | TryExpr | test.rs:26:9:26:22 | remote_string6 | provenance | |
| test.rs:29:9:29:20 | mut request1 | test.rs:30:10:30:17 | request1 | provenance | |
| test.rs:29:9:29:20 | mut request1 | test.rs:31:29:31:36 | request1 | provenance | |
| test.rs:29:24:29:35 | ...::get | test.rs:29:24:29:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:7 |
| test.rs:29:24:29:35 | ...::get | test.rs:29:24:29:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:8 |
| test.rs:29:24:29:50 | ...::get(...) [future, Ok] | test.rs:29:24:29:56 | await ... [Ok] | provenance | |
| test.rs:29:24:29:56 | await ... [Ok] | test.rs:29:24:29:57 | TryExpr | provenance | |
| test.rs:29:24:29:57 | TryExpr | test.rs:29:9:29:20 | mut request1 | provenance | |
| test.rs:30:10:30:17 | request1 | test.rs:30:10:30:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:27 |
| test.rs:30:10:30:17 | request1 | test.rs:30:10:30:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:30 |
| test.rs:30:10:30:25 | request1.chunk() [future, Ok, Some] | test.rs:30:10:30:31 | await ... [Ok, Some] | provenance | |
| test.rs:30:10:30:31 | await ... [Ok, Some] | test.rs:30:10:30:32 | TryExpr [Some] | provenance | |
| test.rs:30:10:30:32 | TryExpr [Some] | test.rs:30:10:30:41 | ... .unwrap() | provenance | MaD:20 |
| test.rs:30:10:30:32 | TryExpr [Some] | test.rs:30:10:30:41 | ... .unwrap() | provenance | MaD:23 |
| test.rs:31:15:31:25 | Some(...) [Some] | test.rs:31:20:31:24 | chunk | provenance | |
| test.rs:31:20:31:24 | chunk | test.rs:32:14:32:18 | chunk | provenance | |
| test.rs:31:29:31:36 | request1 | test.rs:31:29:31:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:27 |
| test.rs:31:29:31:36 | request1 | test.rs:31:29:31:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:30 |
| test.rs:31:29:31:44 | request1.chunk() [future, Ok, Some] | test.rs:31:29:31:50 | await ... [Ok, Some] | provenance | |
| test.rs:31:29:31:50 | await ... [Ok, Some] | test.rs:31:29:31:51 | TryExpr [Some] | provenance | |
| test.rs:31:29:31:51 | TryExpr [Some] | test.rs:31:15:31:25 | Some(...) [Some] | provenance | |
@@ -105,24 +109,24 @@ edges
| test.rs:67:31:67:42 | send_request | test.rs:67:24:67:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:2 |
| test.rs:68:11:68:18 | response | test.rs:68:10:68:18 | &response | provenance | |
| test.rs:155:13:155:22 | mut stream | test.rs:162:17:162:22 | stream | provenance | |
| test.rs:155:26:155:53 | ...::connect | test.rs:155:26:155:62 | ...::connect(...) [Ok] | provenance | Src:MaD:3 |
| test.rs:155:26:155:53 | ...::connect | test.rs:155:26:155:62 | ...::connect(...) [Ok] | provenance | Src:MaD:4 |
| test.rs:155:26:155:62 | ...::connect(...) [Ok] | test.rs:155:26:155:63 | TryExpr | provenance | |
| test.rs:155:26:155:63 | TryExpr | test.rs:155:13:155:22 | mut stream | provenance | |
| test.rs:162:17:162:22 | stream | test.rs:162:29:162:39 | [post] &mut buffer [&ref] | provenance | MaD:17 |
| test.rs:162:17:162:22 | stream | test.rs:162:29:162:39 | [post] &mut buffer [&ref] | provenance | MaD:18 |
| test.rs:162:29:162:39 | [post] &mut buffer [&ref] | test.rs:162:34:162:39 | [post] buffer | provenance | |
| test.rs:162:34:162:39 | [post] buffer | test.rs:165:15:165:20 | buffer | provenance | |
| test.rs:162:34:162:39 | [post] buffer | test.rs:166:14:166:19 | buffer | provenance | |
| test.rs:165:15:165:20 | buffer | test.rs:165:14:165:20 | &buffer | provenance | |
| test.rs:166:14:166:19 | buffer | test.rs:166:14:166:22 | buffer[0] | provenance | MaD:8 |
| test.rs:166:14:166:19 | buffer | test.rs:166:14:166:22 | buffer[0] | provenance | MaD:9 |
| test.rs:174:13:174:22 | mut stream | test.rs:182:58:182:63 | stream | provenance | |
| test.rs:174:26:174:61 | ...::connect_timeout | test.rs:174:26:174:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:4 |
| test.rs:174:26:174:61 | ...::connect_timeout | test.rs:174:26:174:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:5 |
| test.rs:174:26:174:105 | ...::connect_timeout(...) [Ok] | test.rs:174:26:174:106 | TryExpr | provenance | |
| test.rs:174:26:174:106 | TryExpr | test.rs:174:13:174:22 | mut stream | provenance | |
| test.rs:182:21:182:30 | mut reader | test.rs:185:27:185:32 | reader | provenance | |
| test.rs:182:34:182:64 | ...::new(...) | test.rs:182:34:182:74 | ... .take(...) | provenance | MaD:18 |
| test.rs:182:34:182:64 | ...::new(...) | test.rs:182:34:182:74 | ... .take(...) | provenance | MaD:21 |
| test.rs:182:34:182:74 | ... .take(...) | test.rs:182:21:182:30 | mut reader | provenance | |
| test.rs:182:58:182:63 | stream | test.rs:182:34:182:64 | ...::new(...) | provenance | MaD:32 |
| test.rs:185:27:185:32 | reader | test.rs:185:44:185:52 | [post] &mut line [&ref] | provenance | MaD:16 |
| test.rs:182:58:182:63 | stream | test.rs:182:34:182:64 | ...::new(...) | provenance | MaD:36 |
| test.rs:185:27:185:32 | reader | test.rs:185:44:185:52 | [post] &mut line [&ref] | provenance | MaD:17 |
| test.rs:185:44:185:52 | [post] &mut line [&ref] | test.rs:185:49:185:52 | [post] line | provenance | |
| test.rs:185:49:185:52 | [post] line | test.rs:192:35:192:38 | line | provenance | |
| test.rs:192:35:192:38 | line | test.rs:192:34:192:38 | &line | provenance | |
@@ -130,30 +134,53 @@ edges
| test.rs:224:9:224:24 | mut tokio_stream | test.rs:236:18:236:29 | tokio_stream | provenance | |
| test.rs:224:9:224:24 | mut tokio_stream | test.rs:252:19:252:30 | tokio_stream | provenance | |
| test.rs:224:9:224:24 | mut tokio_stream | test.rs:275:19:275:30 | tokio_stream | provenance | |
| test.rs:224:28:224:57 | ...::connect | test.rs:224:28:224:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:5 |
| test.rs:224:28:224:57 | ...::connect | test.rs:224:28:224:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:6 |
| test.rs:224:28:224:66 | ...::connect(...) [future, Ok] | test.rs:224:28:224:72 | await ... [Ok] | provenance | |
| test.rs:224:28:224:72 | await ... [Ok] | test.rs:224:28:224:73 | TryExpr | provenance | |
| test.rs:224:28:224:73 | TryExpr | test.rs:224:9:224:24 | mut tokio_stream | provenance | |
| test.rs:232:17:232:28 | tokio_stream | test.rs:232:35:232:46 | [post] &mut buffer1 [&ref] | provenance | MaD:33 |
| test.rs:232:17:232:28 | tokio_stream | test.rs:232:35:232:46 | [post] &mut buffer1 [&ref] | provenance | MaD:37 |
| test.rs:232:35:232:46 | [post] &mut buffer1 [&ref] | test.rs:232:40:232:46 | [post] buffer1 | provenance | |
| test.rs:232:40:232:46 | [post] buffer1 | test.rs:239:15:239:21 | buffer1 | provenance | |
| test.rs:232:40:232:46 | [post] buffer1 | test.rs:240:14:240:20 | buffer1 | provenance | |
| test.rs:236:18:236:29 | tokio_stream | test.rs:236:36:236:47 | [post] &mut buffer2 [&ref] | provenance | MaD:19 |
| test.rs:236:18:236:29 | tokio_stream | test.rs:236:36:236:47 | [post] &mut buffer2 [&ref] | provenance | MaD:22 |
| test.rs:236:36:236:47 | [post] &mut buffer2 [&ref] | test.rs:236:41:236:47 | [post] buffer2 | provenance | |
| test.rs:236:41:236:47 | [post] buffer2 | test.rs:243:15:243:21 | buffer2 | provenance | |
| test.rs:236:41:236:47 | [post] buffer2 | test.rs:244:14:244:20 | buffer2 | provenance | |
| test.rs:239:15:239:21 | buffer1 | test.rs:239:14:239:21 | &buffer1 | provenance | |
| test.rs:240:14:240:20 | buffer1 | test.rs:240:14:240:23 | buffer1[0] | provenance | MaD:8 |
| test.rs:240:14:240:20 | buffer1 | test.rs:240:14:240:23 | buffer1[0] | provenance | MaD:9 |
| test.rs:243:15:243:21 | buffer2 | test.rs:243:14:243:21 | &buffer2 | provenance | |
| test.rs:244:14:244:20 | buffer2 | test.rs:244:14:244:23 | buffer2[0] | provenance | MaD:8 |
| test.rs:252:19:252:30 | tokio_stream | test.rs:252:41:252:51 | [post] &mut buffer [&ref] | provenance | MaD:34 |
| test.rs:244:14:244:20 | buffer2 | test.rs:244:14:244:23 | buffer2[0] | provenance | MaD:9 |
| test.rs:252:19:252:30 | tokio_stream | test.rs:252:41:252:51 | [post] &mut buffer [&ref] | provenance | MaD:38 |
| test.rs:252:41:252:51 | [post] &mut buffer [&ref] | test.rs:252:46:252:51 | [post] buffer | provenance | |
| test.rs:252:46:252:51 | [post] buffer | test.rs:259:27:259:32 | buffer | provenance | |
| test.rs:259:27:259:32 | buffer | test.rs:259:26:259:32 | &buffer | provenance | |
| test.rs:275:19:275:30 | tokio_stream | test.rs:275:45:275:55 | [post] &mut buffer [&ref] | provenance | MaD:35 |
| test.rs:275:19:275:30 | tokio_stream | test.rs:275:45:275:55 | [post] &mut buffer [&ref] | provenance | MaD:39 |
| test.rs:275:45:275:55 | [post] &mut buffer [&ref] | test.rs:275:50:275:55 | [post] buffer | provenance | |
| test.rs:275:50:275:55 | [post] buffer | test.rs:282:27:282:32 | buffer | provenance | |
| test.rs:282:27:282:32 | buffer | test.rs:282:26:282:32 | &buffer | provenance | |
| test.rs:332:9:332:18 | mut client | test.rs:333:22:333:27 | client | provenance | |
| test.rs:332:22:332:50 | ...::new | test.rs:332:22:332:75 | ...::new(...) [Ok] | provenance | Src:MaD:3 |
| test.rs:332:22:332:75 | ...::new(...) [Ok] | test.rs:332:22:332:84 | ... .unwrap() | provenance | MaD:26 |
| test.rs:332:22:332:84 | ... .unwrap() | test.rs:332:9:332:18 | mut client | provenance | |
| test.rs:333:9:333:18 | mut reader | test.rs:334:11:334:16 | reader | provenance | |
| test.rs:333:9:333:18 | mut reader | test.rs:338:22:338:27 | reader | provenance | |
| test.rs:333:9:333:18 | mut reader | test.rs:344:22:344:27 | reader | provenance | |
| test.rs:333:9:333:18 | mut reader | test.rs:350:22:350:27 | reader | provenance | |
| test.rs:333:22:333:27 | client | test.rs:333:22:333:36 | client.reader() | provenance | MaD:35 |
| test.rs:333:22:333:36 | client.reader() | test.rs:333:9:333:18 | mut reader | provenance | |
| test.rs:334:11:334:16 | reader | test.rs:334:10:334:16 | &reader | provenance | |
| test.rs:338:22:338:27 | reader | test.rs:338:34:338:44 | [post] &mut buffer [&ref] | provenance | MaD:18 |
| test.rs:338:34:338:44 | [post] &mut buffer [&ref] | test.rs:338:39:338:44 | [post] buffer | provenance | |
| test.rs:338:39:338:44 | [post] buffer | test.rs:339:15:339:20 | buffer | provenance | |
| test.rs:339:15:339:20 | buffer | test.rs:339:14:339:20 | &buffer | provenance | |
| test.rs:344:22:344:27 | reader | test.rs:344:41:344:51 | [post] &mut buffer [&ref] | provenance | MaD:19 |
| test.rs:344:41:344:51 | [post] &mut buffer [&ref] | test.rs:344:46:344:51 | [post] buffer | provenance | |
| test.rs:344:46:344:51 | [post] buffer | test.rs:345:15:345:20 | buffer | provenance | |
| test.rs:345:15:345:20 | buffer | test.rs:345:14:345:20 | &buffer | provenance | |
| test.rs:350:22:350:27 | reader | test.rs:350:44:350:54 | [post] &mut buffer [&ref] | provenance | MaD:20 |
| test.rs:350:44:350:54 | [post] &mut buffer [&ref] | test.rs:350:49:350:54 | [post] buffer | provenance | |
| test.rs:350:49:350:54 | [post] buffer | test.rs:351:15:351:20 | buffer | provenance | |
| test.rs:351:15:351:20 | buffer | test.rs:351:14:351:20 | &buffer | provenance | |
| test.rs:373:13:373:15 | tcp | test.rs:374:15:374:17 | tcp | provenance | |
| test.rs:373:13:373:15 | tcp | test.rs:380:57:380:59 | tcp | provenance | |
| test.rs:373:19:373:36 | ...::connect | test.rs:373:19:373:41 | ...::connect(...) [future, Ok] | provenance | Src:MaD:1 |
@@ -169,38 +196,38 @@ edges
| test.rs:380:26:380:60 | connector.connect(...) [future, Ok] | test.rs:380:26:380:66 | await ... [Ok] | provenance | |
| test.rs:380:26:380:66 | await ... [Ok] | test.rs:380:26:380:67 | TryExpr | provenance | |
| test.rs:380:26:380:67 | TryExpr | test.rs:380:13:380:22 | mut reader | provenance | |
| test.rs:380:57:380:59 | tcp | test.rs:380:26:380:60 | connector.connect(...) [future, Ok] | provenance | MaD:24 |
| test.rs:380:57:380:59 | tcp | test.rs:380:26:380:60 | connector.connect(...) [future, Ok] | provenance | MaD:27 |
| test.rs:381:15:381:20 | reader | test.rs:381:14:381:20 | &reader | provenance | |
| test.rs:386:17:386:26 | mut pinned | test.rs:387:19:387:24 | pinned | provenance | |
| test.rs:386:17:386:26 | mut pinned | test.rs:389:30:389:35 | pinned | provenance | |
| test.rs:386:17:386:26 | mut pinned [Pin, &ref] | test.rs:387:19:387:24 | pinned [Pin, &ref] | provenance | |
| test.rs:386:30:386:50 | ...::new(...) | test.rs:386:17:386:26 | mut pinned | provenance | |
| test.rs:386:30:386:50 | ...::new(...) [Pin, &ref] | test.rs:386:17:386:26 | mut pinned [Pin, &ref] | provenance | |
| test.rs:386:39:386:49 | &mut reader [&ref] | test.rs:386:30:386:50 | ...::new(...) | provenance | MaD:21 |
| test.rs:386:39:386:49 | &mut reader [&ref] | test.rs:386:30:386:50 | ...::new(...) [Pin, &ref] | provenance | MaD:22 |
| test.rs:386:39:386:49 | &mut reader [&ref] | test.rs:386:30:386:50 | ...::new(...) | provenance | MaD:24 |
| test.rs:386:39:386:49 | &mut reader [&ref] | test.rs:386:30:386:50 | ...::new(...) [Pin, &ref] | provenance | MaD:25 |
| test.rs:386:44:386:49 | reader | test.rs:386:39:386:49 | &mut reader [&ref] | provenance | |
| test.rs:387:19:387:24 | pinned | test.rs:387:18:387:24 | &pinned | provenance | |
| test.rs:387:19:387:24 | pinned [Pin, &ref] | test.rs:387:18:387:24 | &pinned | provenance | |
| test.rs:389:30:389:35 | pinned | test.rs:389:56:389:66 | [post] &mut buffer [&ref] | provenance | MaD:10 |
| test.rs:389:30:389:35 | pinned | test.rs:389:56:389:66 | [post] &mut buffer [&ref] | provenance | MaD:11 |
| test.rs:389:56:389:66 | [post] &mut buffer [&ref] | test.rs:389:61:389:66 | [post] buffer | provenance | |
| test.rs:389:61:389:66 | [post] buffer | test.rs:391:23:391:28 | buffer | provenance | |
| test.rs:389:61:389:66 | [post] buffer | test.rs:392:23:392:28 | buffer | provenance | |
| test.rs:389:61:389:66 | [post] buffer | test.rs:392:23:392:33 | buffer[...] | provenance | |
| test.rs:391:23:391:28 | buffer | test.rs:391:22:391:28 | &buffer | provenance | |
| test.rs:392:23:392:28 | buffer | test.rs:392:23:392:33 | buffer[...] | provenance | MaD:8 |
| test.rs:392:23:392:28 | buffer | test.rs:392:23:392:33 | buffer[...] | provenance | MaD:9 |
| test.rs:392:23:392:33 | buffer[...] | test.rs:392:22:392:33 | &... | provenance | |
| test.rs:399:63:399:73 | &mut reader [&ref] | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | provenance | MaD:14 |
| test.rs:399:63:399:73 | &mut reader [&ref] | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | provenance | MaD:15 |
| test.rs:399:68:399:73 | reader | test.rs:399:63:399:73 | &mut reader [&ref] | provenance | |
| test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | test.rs:399:81:399:87 | [post] buffer1 | provenance | |
| test.rs:399:81:399:87 | [post] buffer1 | test.rs:400:19:400:25 | buffer1 | provenance | |
| test.rs:399:81:399:87 | [post] buffer1 | test.rs:400:19:400:40 | buffer1[...] | provenance | |
| test.rs:400:19:400:25 | buffer1 | test.rs:400:19:400:40 | buffer1[...] | provenance | MaD:8 |
| test.rs:400:19:400:25 | buffer1 | test.rs:400:19:400:40 | buffer1[...] | provenance | MaD:9 |
| test.rs:400:19:400:40 | buffer1[...] | test.rs:400:18:400:40 | &... | provenance | |
| test.rs:403:31:403:36 | reader | test.rs:403:43:403:54 | [post] &mut buffer2 [&ref] | provenance | MaD:14 |
| test.rs:403:31:403:36 | reader | test.rs:403:43:403:54 | [post] &mut buffer2 [&ref] | provenance | MaD:15 |
| test.rs:403:43:403:54 | [post] &mut buffer2 [&ref] | test.rs:403:48:403:54 | [post] buffer2 | provenance | |
| test.rs:403:48:403:54 | [post] buffer2 | test.rs:405:19:405:25 | buffer2 | provenance | |
| test.rs:403:48:403:54 | [post] buffer2 | test.rs:405:19:405:40 | buffer2[...] | provenance | |
| test.rs:405:19:405:25 | buffer2 | test.rs:405:19:405:40 | buffer2[...] | provenance | MaD:8 |
| test.rs:405:19:405:25 | buffer2 | test.rs:405:19:405:40 | buffer2[...] | provenance | MaD:9 |
| test.rs:405:19:405:40 | buffer2[...] | test.rs:405:18:405:40 | &... | provenance | |
| test.rs:408:13:408:23 | mut reader2 | test.rs:409:15:409:21 | reader2 | provenance | |
| test.rs:408:13:408:23 | mut reader2 | test.rs:413:44:413:50 | reader2 | provenance | |
@@ -215,30 +242,30 @@ edges
| test.rs:408:13:408:23 | mut reader2 | test.rs:493:31:493:37 | reader2 | provenance | |
| test.rs:408:13:408:23 | mut reader2 | test.rs:500:31:500:37 | reader2 | provenance | |
| test.rs:408:27:408:61 | ...::new(...) | test.rs:408:13:408:23 | mut reader2 | provenance | |
| test.rs:408:55:408:60 | reader | test.rs:408:27:408:61 | ...::new(...) | provenance | MaD:25 |
| test.rs:408:55:408:60 | reader | test.rs:408:27:408:61 | ...::new(...) | provenance | MaD:28 |
| test.rs:409:15:409:21 | reader2 | test.rs:409:14:409:21 | &reader2 | provenance | |
| test.rs:413:17:413:26 | mut pinned | test.rs:414:19:414:24 | pinned | provenance | |
| test.rs:413:17:413:26 | mut pinned | test.rs:416:26:416:31 | pinned | provenance | |
| test.rs:413:17:413:26 | mut pinned [Pin, &ref] | test.rs:414:19:414:24 | pinned [Pin, &ref] | provenance | |
| test.rs:413:30:413:51 | ...::new(...) | test.rs:413:17:413:26 | mut pinned | provenance | |
| test.rs:413:30:413:51 | ...::new(...) [Pin, &ref] | test.rs:413:17:413:26 | mut pinned [Pin, &ref] | provenance | |
| test.rs:413:39:413:50 | &mut reader2 [&ref] | test.rs:413:30:413:51 | ...::new(...) | provenance | MaD:21 |
| test.rs:413:39:413:50 | &mut reader2 [&ref] | test.rs:413:30:413:51 | ...::new(...) [Pin, &ref] | provenance | MaD:22 |
| test.rs:413:39:413:50 | &mut reader2 [&ref] | test.rs:413:30:413:51 | ...::new(...) | provenance | MaD:24 |
| test.rs:413:39:413:50 | &mut reader2 [&ref] | test.rs:413:30:413:51 | ...::new(...) [Pin, &ref] | provenance | MaD:25 |
| test.rs:413:44:413:50 | reader2 | test.rs:413:39:413:50 | &mut reader2 [&ref] | provenance | |
| test.rs:414:19:414:24 | pinned | test.rs:414:18:414:24 | &pinned | provenance | |
| test.rs:414:19:414:24 | pinned [Pin, &ref] | test.rs:414:18:414:24 | &pinned | provenance | |
| test.rs:416:17:416:22 | buffer [Ready, Ok] | test.rs:417:20:417:39 | ...::Ready(...) [Ready, Ok] | provenance | |
| test.rs:416:17:416:22 | buffer [Ready, Ok] | test.rs:418:23:418:28 | buffer [Ready, Ok] | provenance | |
| test.rs:416:26:416:31 | pinned | test.rs:416:26:416:54 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:9 |
| test.rs:416:26:416:31 | pinned | test.rs:416:26:416:54 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:10 |
| test.rs:416:26:416:54 | pinned.poll_fill_buf(...) [Ready, Ok] | test.rs:416:17:416:22 | buffer [Ready, Ok] | provenance | |
| test.rs:417:20:417:39 | ...::Ready(...) [Ready, Ok] | test.rs:417:32:417:38 | Ok(...) [Ok] | provenance | |
| test.rs:417:32:417:38 | Ok(...) [Ok] | test.rs:417:35:417:37 | buf | provenance | |
| test.rs:417:35:417:37 | buf | test.rs:419:22:419:24 | buf | provenance | |
| test.rs:418:23:418:28 | buffer [Ready, Ok] | test.rs:418:22:418:28 | &buffer | provenance | |
| test.rs:423:17:423:23 | buffer2 [Ready, Ok] | test.rs:424:20:424:26 | buffer2 [Ready, Ok] | provenance | |
| test.rs:423:27:423:48 | ...::new(...) | test.rs:423:27:423:71 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:9 |
| test.rs:423:27:423:48 | ...::new(...) | test.rs:423:27:423:71 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:10 |
| test.rs:423:27:423:71 | ... .poll_fill_buf(...) [Ready, Ok] | test.rs:423:17:423:23 | buffer2 [Ready, Ok] | provenance | |
| test.rs:423:36:423:47 | &mut reader2 [&ref] | test.rs:423:27:423:48 | ...::new(...) | provenance | MaD:21 |
| test.rs:423:36:423:47 | &mut reader2 [&ref] | test.rs:423:27:423:48 | ...::new(...) | provenance | MaD:24 |
| test.rs:423:41:423:47 | reader2 | test.rs:423:36:423:47 | &mut reader2 [&ref] | provenance | |
| test.rs:424:20:424:26 | buffer2 [Ready, Ok] | test.rs:425:17:425:36 | ...::Ready(...) [Ready, Ok] | provenance | |
| test.rs:424:20:424:26 | buffer2 [Ready, Ok] | test.rs:426:27:426:33 | buffer2 [Ready, Ok] | provenance | |
@@ -247,7 +274,7 @@ edges
| test.rs:425:32:425:34 | buf | test.rs:427:26:427:28 | buf | provenance | |
| test.rs:426:27:426:33 | buffer2 [Ready, Ok] | test.rs:426:26:426:33 | &buffer2 | provenance | |
| test.rs:437:17:437:22 | buffer | test.rs:438:18:438:23 | buffer | provenance | |
| test.rs:437:26:437:32 | reader2 | test.rs:437:26:437:43 | reader2.fill_buf() [future, Ok] | provenance | MaD:11 |
| test.rs:437:26:437:32 | reader2 | test.rs:437:26:437:43 | reader2.fill_buf() [future, Ok] | provenance | MaD:12 |
| test.rs:437:26:437:43 | reader2.fill_buf() [future, Ok] | test.rs:437:26:437:49 | await ... [Ok] | provenance | |
| test.rs:437:26:437:49 | await ... [Ok] | test.rs:437:26:437:50 | TryExpr | provenance | |
| test.rs:437:26:437:50 | TryExpr | test.rs:437:17:437:22 | buffer | provenance | |
@@ -256,64 +283,64 @@ edges
| test.rs:444:17:444:26 | mut pinned [Pin, &ref] | test.rs:445:19:445:24 | pinned [Pin, &ref] | provenance | |
| test.rs:444:30:444:51 | ...::new(...) | test.rs:444:17:444:26 | mut pinned | provenance | |
| test.rs:444:30:444:51 | ...::new(...) [Pin, &ref] | test.rs:444:17:444:26 | mut pinned [Pin, &ref] | provenance | |
| test.rs:444:39:444:50 | &mut reader2 [&ref] | test.rs:444:30:444:51 | ...::new(...) | provenance | MaD:21 |
| test.rs:444:39:444:50 | &mut reader2 [&ref] | test.rs:444:30:444:51 | ...::new(...) [Pin, &ref] | provenance | MaD:22 |
| test.rs:444:39:444:50 | &mut reader2 [&ref] | test.rs:444:30:444:51 | ...::new(...) | provenance | MaD:24 |
| test.rs:444:39:444:50 | &mut reader2 [&ref] | test.rs:444:30:444:51 | ...::new(...) [Pin, &ref] | provenance | MaD:25 |
| test.rs:444:44:444:50 | reader2 | test.rs:444:39:444:50 | &mut reader2 [&ref] | provenance | |
| test.rs:445:19:445:24 | pinned | test.rs:445:18:445:24 | &pinned | provenance | |
| test.rs:445:19:445:24 | pinned [Pin, &ref] | test.rs:445:18:445:24 | &pinned | provenance | |
| test.rs:447:30:447:35 | pinned | test.rs:447:56:447:66 | [post] &mut buffer [&ref] | provenance | MaD:10 |
| test.rs:447:30:447:35 | pinned | test.rs:447:56:447:66 | [post] &mut buffer [&ref] | provenance | MaD:11 |
| test.rs:447:56:447:66 | [post] &mut buffer [&ref] | test.rs:447:61:447:66 | [post] buffer | provenance | |
| test.rs:447:61:447:66 | [post] buffer | test.rs:448:19:448:24 | buffer | provenance | |
| test.rs:447:61:447:66 | [post] buffer | test.rs:450:23:450:28 | buffer | provenance | |
| test.rs:447:61:447:66 | [post] buffer | test.rs:450:23:450:33 | buffer[...] | provenance | |
| test.rs:448:19:448:24 | buffer | test.rs:448:18:448:24 | &buffer | provenance | |
| test.rs:450:23:450:28 | buffer | test.rs:450:23:450:33 | buffer[...] | provenance | MaD:8 |
| test.rs:450:23:450:28 | buffer | test.rs:450:23:450:33 | buffer[...] | provenance | MaD:9 |
| test.rs:450:23:450:33 | buffer[...] | test.rs:450:22:450:33 | &... | provenance | |
| test.rs:457:63:457:74 | &mut reader2 [&ref] | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | provenance | MaD:14 |
| test.rs:457:63:457:74 | &mut reader2 [&ref] | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | provenance | MaD:15 |
| test.rs:457:68:457:74 | reader2 | test.rs:457:63:457:74 | &mut reader2 [&ref] | provenance | |
| test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | test.rs:457:82:457:88 | [post] buffer1 | provenance | |
| test.rs:457:82:457:88 | [post] buffer1 | test.rs:458:19:458:25 | buffer1 | provenance | |
| test.rs:457:82:457:88 | [post] buffer1 | test.rs:458:19:458:40 | buffer1[...] | provenance | |
| test.rs:458:19:458:25 | buffer1 | test.rs:458:19:458:40 | buffer1[...] | provenance | MaD:8 |
| test.rs:458:19:458:25 | buffer1 | test.rs:458:19:458:40 | buffer1[...] | provenance | MaD:9 |
| test.rs:458:19:458:40 | buffer1[...] | test.rs:458:18:458:40 | &... | provenance | |
| test.rs:461:31:461:37 | reader2 | test.rs:461:44:461:55 | [post] &mut buffer2 [&ref] | provenance | MaD:14 |
| test.rs:461:31:461:37 | reader2 | test.rs:461:44:461:55 | [post] &mut buffer2 [&ref] | provenance | MaD:15 |
| test.rs:461:44:461:55 | [post] &mut buffer2 [&ref] | test.rs:461:49:461:55 | [post] buffer2 | provenance | |
| test.rs:461:49:461:55 | [post] buffer2 | test.rs:462:19:462:25 | buffer2 | provenance | |
| test.rs:461:49:461:55 | [post] buffer2 | test.rs:462:19:462:40 | buffer2[...] | provenance | |
| test.rs:462:19:462:25 | buffer2 | test.rs:462:19:462:40 | buffer2[...] | provenance | MaD:8 |
| test.rs:462:19:462:25 | buffer2 | test.rs:462:19:462:40 | buffer2[...] | provenance | MaD:9 |
| test.rs:462:19:462:40 | buffer2[...] | test.rs:462:18:462:40 | &... | provenance | |
| test.rs:467:17:467:26 | mut pinned | test.rs:468:19:468:24 | pinned | provenance | |
| test.rs:467:17:467:26 | mut pinned | test.rs:470:26:470:31 | pinned | provenance | |
| test.rs:467:17:467:26 | mut pinned [Pin, &ref] | test.rs:468:19:468:24 | pinned [Pin, &ref] | provenance | |
| test.rs:467:30:467:51 | ...::new(...) | test.rs:467:17:467:26 | mut pinned | provenance | |
| test.rs:467:30:467:51 | ...::new(...) [Pin, &ref] | test.rs:467:17:467:26 | mut pinned [Pin, &ref] | provenance | |
| test.rs:467:39:467:50 | &mut reader2 [&ref] | test.rs:467:30:467:51 | ...::new(...) | provenance | MaD:21 |
| test.rs:467:39:467:50 | &mut reader2 [&ref] | test.rs:467:30:467:51 | ...::new(...) [Pin, &ref] | provenance | MaD:22 |
| test.rs:467:39:467:50 | &mut reader2 [&ref] | test.rs:467:30:467:51 | ...::new(...) | provenance | MaD:24 |
| test.rs:467:39:467:50 | &mut reader2 [&ref] | test.rs:467:30:467:51 | ...::new(...) [Pin, &ref] | provenance | MaD:25 |
| test.rs:467:44:467:50 | reader2 | test.rs:467:39:467:50 | &mut reader2 [&ref] | provenance | |
| test.rs:468:19:468:24 | pinned | test.rs:468:18:468:24 | &pinned | provenance | |
| test.rs:468:19:468:24 | pinned [Pin, &ref] | test.rs:468:18:468:24 | &pinned | provenance | |
| test.rs:470:17:470:22 | buffer [Ready, Ok] | test.rs:471:19:471:24 | buffer [Ready, Ok] | provenance | |
| test.rs:470:17:470:22 | buffer [Ready, Ok] | test.rs:472:20:472:39 | ...::Ready(...) [Ready, Ok] | provenance | |
| test.rs:470:26:470:31 | pinned | test.rs:470:26:470:54 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:9 |
| test.rs:470:26:470:31 | pinned | test.rs:470:26:470:54 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:10 |
| test.rs:470:26:470:54 | pinned.poll_fill_buf(...) [Ready, Ok] | test.rs:470:17:470:22 | buffer [Ready, Ok] | provenance | |
| test.rs:471:19:471:24 | buffer [Ready, Ok] | test.rs:471:18:471:24 | &buffer | provenance | |
| test.rs:472:20:472:39 | ...::Ready(...) [Ready, Ok] | test.rs:472:32:472:38 | Ok(...) [Ok] | provenance | |
| test.rs:472:32:472:38 | Ok(...) [Ok] | test.rs:472:35:472:37 | buf | provenance | |
| test.rs:472:35:472:37 | buf | test.rs:473:22:473:24 | buf | provenance | |
| test.rs:479:17:479:22 | buffer | test.rs:480:18:480:23 | buffer | provenance | |
| test.rs:479:26:479:32 | reader2 | test.rs:479:26:479:43 | reader2.fill_buf() [future, Ok] | provenance | MaD:11 |
| test.rs:479:26:479:32 | reader2 | test.rs:479:26:479:43 | reader2.fill_buf() [future, Ok] | provenance | MaD:12 |
| test.rs:479:26:479:43 | reader2.fill_buf() [future, Ok] | test.rs:479:26:479:49 | await ... [Ok] | provenance | |
| test.rs:479:26:479:49 | await ... [Ok] | test.rs:479:26:479:50 | TryExpr | provenance | |
| test.rs:479:26:479:50 | TryExpr | test.rs:479:17:479:22 | buffer | provenance | |
| test.rs:486:31:486:37 | reader2 | test.rs:486:57:486:65 | [post] &mut line [&ref] | provenance | MaD:13 |
| test.rs:486:31:486:37 | reader2 | test.rs:486:57:486:65 | [post] &mut line [&ref] | provenance | MaD:14 |
| test.rs:486:57:486:65 | [post] &mut line [&ref] | test.rs:486:62:486:65 | [post] line | provenance | |
| test.rs:486:62:486:65 | [post] line | test.rs:487:19:487:22 | line | provenance | |
| test.rs:487:19:487:22 | line | test.rs:487:18:487:22 | &line | provenance | |
| test.rs:493:31:493:37 | reader2 | test.rs:493:49:493:57 | [post] &mut line [&ref] | provenance | MaD:12 |
| test.rs:493:31:493:37 | reader2 | test.rs:493:49:493:57 | [post] &mut line [&ref] | provenance | MaD:13 |
| test.rs:493:49:493:57 | [post] &mut line [&ref] | test.rs:493:54:493:57 | [post] line | provenance | |
| test.rs:493:54:493:57 | [post] line | test.rs:494:19:494:22 | line | provenance | |
| test.rs:494:19:494:22 | line | test.rs:494:18:494:22 | &line | provenance | |
| test.rs:500:31:500:37 | reader2 | test.rs:500:51:500:61 | [post] &mut buffer [&ref] | provenance | MaD:15 |
| test.rs:500:31:500:37 | reader2 | test.rs:500:51:500:61 | [post] &mut buffer [&ref] | provenance | MaD:16 |
| test.rs:500:51:500:61 | [post] &mut buffer [&ref] | test.rs:500:56:500:61 | [post] buffer | provenance | |
| test.rs:500:56:500:61 | [post] buffer | test.rs:501:19:501:24 | buffer | provenance | |
| test.rs:501:19:501:24 | buffer | test.rs:501:18:501:24 | &buffer | provenance | |
@@ -449,6 +476,30 @@ nodes
| test.rs:275:50:275:55 | [post] buffer | semmle.label | [post] buffer |
| test.rs:282:26:282:32 | &buffer | semmle.label | &buffer |
| test.rs:282:27:282:32 | buffer | semmle.label | buffer |
| test.rs:332:9:332:18 | mut client | semmle.label | mut client |
| test.rs:332:22:332:50 | ...::new | semmle.label | ...::new |
| test.rs:332:22:332:75 | ...::new(...) [Ok] | semmle.label | ...::new(...) [Ok] |
| test.rs:332:22:332:84 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:333:9:333:18 | mut reader | semmle.label | mut reader |
| test.rs:333:22:333:27 | client | semmle.label | client |
| test.rs:333:22:333:36 | client.reader() | semmle.label | client.reader() |
| test.rs:334:10:334:16 | &reader | semmle.label | &reader |
| test.rs:334:11:334:16 | reader | semmle.label | reader |
| test.rs:338:22:338:27 | reader | semmle.label | reader |
| test.rs:338:34:338:44 | [post] &mut buffer [&ref] | semmle.label | [post] &mut buffer [&ref] |
| test.rs:338:39:338:44 | [post] buffer | semmle.label | [post] buffer |
| test.rs:339:14:339:20 | &buffer | semmle.label | &buffer |
| test.rs:339:15:339:20 | buffer | semmle.label | buffer |
| test.rs:344:22:344:27 | reader | semmle.label | reader |
| test.rs:344:41:344:51 | [post] &mut buffer [&ref] | semmle.label | [post] &mut buffer [&ref] |
| test.rs:344:46:344:51 | [post] buffer | semmle.label | [post] buffer |
| test.rs:345:14:345:20 | &buffer | semmle.label | &buffer |
| test.rs:345:15:345:20 | buffer | semmle.label | buffer |
| test.rs:350:22:350:27 | reader | semmle.label | reader |
| test.rs:350:44:350:54 | [post] &mut buffer [&ref] | semmle.label | [post] &mut buffer [&ref] |
| test.rs:350:49:350:54 | [post] buffer | semmle.label | [post] buffer |
| test.rs:351:14:351:20 | &buffer | semmle.label | &buffer |
| test.rs:351:15:351:20 | buffer | semmle.label | buffer |
| test.rs:373:13:373:15 | tcp | semmle.label | tcp |
| test.rs:373:19:373:36 | ...::connect | semmle.label | ...::connect |
| test.rs:373:19:373:41 | ...::connect(...) [future, Ok] | semmle.label | ...::connect(...) [future, Ok] |
@@ -626,6 +677,10 @@ testFailures
| test.rs:244:14:244:23 | buffer2[0] | test.rs:224:28:224:57 | ...::connect | test.rs:244:14:244:23 | buffer2[0] | $@ | test.rs:224:28:224:57 | ...::connect | ...::connect |
| test.rs:259:26:259:32 | &buffer | test.rs:224:28:224:57 | ...::connect | test.rs:259:26:259:32 | &buffer | $@ | test.rs:224:28:224:57 | ...::connect | ...::connect |
| test.rs:282:26:282:32 | &buffer | test.rs:224:28:224:57 | ...::connect | test.rs:282:26:282:32 | &buffer | $@ | test.rs:224:28:224:57 | ...::connect | ...::connect |
| test.rs:334:10:334:16 | &reader | test.rs:332:22:332:50 | ...::new | test.rs:334:10:334:16 | &reader | $@ | test.rs:332:22:332:50 | ...::new | ...::new |
| test.rs:339:14:339:20 | &buffer | test.rs:332:22:332:50 | ...::new | test.rs:339:14:339:20 | &buffer | $@ | test.rs:332:22:332:50 | ...::new | ...::new |
| test.rs:345:14:345:20 | &buffer | test.rs:332:22:332:50 | ...::new | test.rs:345:14:345:20 | &buffer | $@ | test.rs:332:22:332:50 | ...::new | ...::new |
| test.rs:351:14:351:20 | &buffer | test.rs:332:22:332:50 | ...::new | test.rs:351:14:351:20 | &buffer | $@ | test.rs:332:22:332:50 | ...::new | ...::new |
| test.rs:374:14:374:17 | &tcp | test.rs:373:19:373:36 | ...::connect | test.rs:374:14:374:17 | &tcp | $@ | test.rs:373:19:373:36 | ...::connect | ...::connect |
| test.rs:381:14:381:20 | &reader | test.rs:373:19:373:36 | ...::connect | test.rs:381:14:381:20 | &reader | $@ | test.rs:373:19:373:36 | ...::connect | ...::connect |
| test.rs:387:18:387:24 | &pinned | test.rs:373:19:373:36 | ...::connect | test.rs:387:18:387:24 | &pinned | $@ | test.rs:373:19:373:36 | ...::connect | ...::connect |

View File

@@ -330,25 +330,25 @@ fn test_rustls() -> std::io::Result<()> {
let server_name = rustls::pki_types::ServerName::try_from("www.example.com").unwrap();
let config_arc = std::sync::Arc::new(config);
let mut client = rustls::ClientConnection::new(config_arc, server_name).unwrap(); // $ Alert[rust/summary/taint-sources]
let mut reader = client.reader(); // We cannot resolve the `reader` call because it comes from `Deref`: https://docs.rs/rustls/latest/rustls/client/struct.ClientConnection.html#deref-methods-ConnectionCommon%3CClientConnectionData%3E
sink(&reader); // $ MISSING: hasTaintFlow=config_arc
let mut reader = client.reader();
sink(&reader); // $ hasTaintFlow=config_arc
{
let mut buffer = [0u8; 100];
let _bytes = reader.read(&mut buffer)?;
sink(&buffer); // $ MISSING: hasTaintFlow=config_arc
sink(&buffer); // $ hasTaintFlow=config_arc
}
{
let mut buffer = Vec::<u8>::new();
let _bytes = reader.read_to_end(&mut buffer)?;
sink(&buffer); // $ MISSING: hasTaintFlow=config_arc
sink(&buffer); // $ hasTaintFlow=config_arc
}
{
let mut buffer = String::new();
let _bytes = reader.read_to_string(&mut buffer)?;
sink(&buffer); // $ MISSING: hasTaintFlow=config_arc
sink(&buffer); // $ hasTaintFlow=config_arc
}
Ok(())

View File

@@ -287,7 +287,7 @@ fn test_private_info(
sink(&info.medical_notes); // $ sensitive=private
sink(info.medical_notes[0].as_str()); // $ sensitive=private
for n in info.medical_notes.iter() {
sink(n.as_str()); // $ MISSING: sensitive=private
sink(n.as_str()); // $ sensitive=private
}
sink(info.confidentialMessage.as_str()); // $ sensitive=secret
sink(info.confidentialMessage.to_lowercase()); // $ sensitive=secret

View File

@@ -53,9 +53,9 @@ mod basic_blanket_impl {
println!("{x4:?}");
let x5 = S1::duplicate(&S1); // $ target=Clone1duplicate
println!("{x5:?}");
let x6 = S2.duplicate(); // $ MISSING: target=Clone1duplicate
let x6 = S2.duplicate(); // $ target=Clone1duplicate
println!("{x6:?}");
let x7 = (&S2).duplicate(); // $ MISSING: target=Clone1duplicate
let x7 = (&S2).duplicate(); // $ target=Clone1duplicate
println!("{x7:?}");
}
}

View File

@@ -102,18 +102,18 @@ fn explicit_box_dereference() {
fn implicit_dereference() {
// Call method on implicitly dereferenced value
let x = MyIntPointer { value: 34i64 };
let _y = x.is_positive(); // $ MISSING: target=is_positive type=_y:bool
let _y = x.is_positive(); // $ target=is_positive type=_y:bool
// Call method on implicitly dereferenced value
let x = MySmartPointer { value: 34i64 };
let _y = x.is_positive(); // $ MISSING: target=is_positive type=_y:bool
let _y = x.is_positive(); // $ target=is_positive type=_y:bool
let z = MySmartPointer { value: S(0i64) };
let z_ = z.foo(); // $ MISSING: target=foo type=z_:TRef.i64
let z_ = z.foo(); // $ target=foo type=z_:TRef.i64
let v = Vec::new(); // $ target=new $ MISSING: type=v:T.i32
let v = Vec::new(); // $ target=new type=v:T.i32
let mut x = MySmartPointer { value: v };
x.push(0); // $ MISSING: target=push
x.push(0); // $ target=push
}
mod implicit_deref_coercion_cycle {

View File

@@ -2902,8 +2902,8 @@ pub mod path_buf {
let path3 = path2.unwrap(); // $ target=unwrap type=path3:PathBuf
let pathbuf1 = PathBuf::new(); // $ target=new certainType=pathbuf1:PathBuf
let pathbuf2 = pathbuf1.canonicalize(); // $ MISSING: target=canonicalize
let pathbuf3 = pathbuf2.unwrap(); // $ MISSING: target=unwrap type=pathbuf3:PathBuf
let pathbuf2 = pathbuf1.canonicalize(); // $ target=canonicalize
let pathbuf3 = pathbuf2.unwrap(); // $ target=unwrap type=pathbuf3:PathBuf
}
}

View File

@@ -4608,13 +4608,18 @@ inferType
| blanket_impl.rs:55:18:55:25 | ...::_print(...) | | {EXTERNAL LOCATION} | () |
| blanket_impl.rs:55:18:55:25 | { ... } | | {EXTERNAL LOCATION} | () |
| blanket_impl.rs:55:20:55:21 | x5 | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:56:13:56:14 | x6 | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:56:18:56:19 | S2 | | blanket_impl.rs:9:5:10:14 | S2 |
| blanket_impl.rs:56:18:56:31 | S2.duplicate() | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:57:18:57:25 | "{x6:?}\\n" | | {EXTERNAL LOCATION} | & |
| blanket_impl.rs:57:18:57:25 | "{x6:?}\\n" | TRef | {EXTERNAL LOCATION} | str |
| blanket_impl.rs:57:18:57:25 | ...::_print(...) | | {EXTERNAL LOCATION} | () |
| blanket_impl.rs:57:18:57:25 | { ... } | | {EXTERNAL LOCATION} | () |
| blanket_impl.rs:57:20:57:21 | x6 | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:58:13:58:14 | x7 | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:58:18:58:22 | (...) | | {EXTERNAL LOCATION} | & |
| blanket_impl.rs:58:18:58:22 | (...) | TRef | blanket_impl.rs:9:5:10:14 | S2 |
| blanket_impl.rs:58:18:58:34 | ... .duplicate() | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:58:19:58:21 | &S2 | | {EXTERNAL LOCATION} | & |
| blanket_impl.rs:58:19:58:21 | &S2 | TRef | blanket_impl.rs:9:5:10:14 | S2 |
| blanket_impl.rs:58:20:58:21 | S2 | | blanket_impl.rs:9:5:10:14 | S2 |
@@ -4622,6 +4627,7 @@ inferType
| blanket_impl.rs:59:18:59:25 | "{x7:?}\\n" | TRef | {EXTERNAL LOCATION} | str |
| blanket_impl.rs:59:18:59:25 | ...::_print(...) | | {EXTERNAL LOCATION} | () |
| blanket_impl.rs:59:18:59:25 | { ... } | | {EXTERNAL LOCATION} | () |
| blanket_impl.rs:59:20:59:21 | x7 | | blanket_impl.rs:6:5:7:14 | S1 |
| blanket_impl.rs:68:24:68:24 | x | | {EXTERNAL LOCATION} | i64 |
| blanket_impl.rs:68:32:68:32 | y | | blanket_impl.rs:67:5:69:5 | Self [trait Trait1] |
| blanket_impl.rs:72:24:72:24 | x | | {EXTERNAL LOCATION} | i64 |
@@ -5249,14 +5255,18 @@ inferType
| dereference.rs:104:9:104:9 | x | | dereference.rs:5:1:7:1 | MyIntPointer |
| dereference.rs:104:13:104:41 | MyIntPointer {...} | | dereference.rs:5:1:7:1 | MyIntPointer |
| dereference.rs:104:35:104:39 | 34i64 | | {EXTERNAL LOCATION} | i64 |
| dereference.rs:105:9:105:10 | _y | | {EXTERNAL LOCATION} | bool |
| dereference.rs:105:14:105:14 | x | | dereference.rs:5:1:7:1 | MyIntPointer |
| dereference.rs:105:14:105:28 | x.is_positive() | | {EXTERNAL LOCATION} | bool |
| dereference.rs:108:9:108:9 | x | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:108:9:108:9 | x | T | {EXTERNAL LOCATION} | i64 |
| dereference.rs:108:13:108:43 | MySmartPointer {...} | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:108:13:108:43 | MySmartPointer {...} | T | {EXTERNAL LOCATION} | i64 |
| dereference.rs:108:37:108:41 | 34i64 | | {EXTERNAL LOCATION} | i64 |
| dereference.rs:109:9:109:10 | _y | | {EXTERNAL LOCATION} | bool |
| dereference.rs:109:14:109:14 | x | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:109:14:109:14 | x | T | {EXTERNAL LOCATION} | i64 |
| dereference.rs:109:14:109:28 | x.is_positive() | | {EXTERNAL LOCATION} | bool |
| dereference.rs:111:9:111:9 | z | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:111:9:111:9 | z | T | dereference.rs:38:1:38:15 | S |
| dereference.rs:111:9:111:9 | z | T.T | {EXTERNAL LOCATION} | i64 |
@@ -5266,24 +5276,35 @@ inferType
| dereference.rs:111:37:111:43 | S(...) | | dereference.rs:38:1:38:15 | S |
| dereference.rs:111:37:111:43 | S(...) | T | {EXTERNAL LOCATION} | i64 |
| dereference.rs:111:39:111:42 | 0i64 | | {EXTERNAL LOCATION} | i64 |
| dereference.rs:112:9:112:10 | z_ | | {EXTERNAL LOCATION} | & |
| dereference.rs:112:9:112:10 | z_ | TRef | {EXTERNAL LOCATION} | i64 |
| dereference.rs:112:14:112:14 | z | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:112:14:112:14 | z | T | dereference.rs:38:1:38:15 | S |
| dereference.rs:112:14:112:14 | z | T.T | {EXTERNAL LOCATION} | i64 |
| dereference.rs:112:14:112:20 | z.foo() | | {EXTERNAL LOCATION} | & |
| dereference.rs:112:14:112:20 | z.foo() | TRef | {EXTERNAL LOCATION} | i64 |
| dereference.rs:114:9:114:9 | v | | {EXTERNAL LOCATION} | Vec |
| dereference.rs:114:9:114:9 | v | A | {EXTERNAL LOCATION} | Global |
| dereference.rs:114:9:114:9 | v | T | {EXTERNAL LOCATION} | i32 |
| dereference.rs:114:13:114:22 | ...::new(...) | | {EXTERNAL LOCATION} | Vec |
| dereference.rs:114:13:114:22 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
| dereference.rs:114:13:114:22 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 |
| dereference.rs:115:13:115:13 | x | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:115:13:115:13 | x | T | {EXTERNAL LOCATION} | Vec |
| dereference.rs:115:13:115:13 | x | T.A | {EXTERNAL LOCATION} | Global |
| dereference.rs:115:13:115:13 | x | T.T | {EXTERNAL LOCATION} | i32 |
| dereference.rs:115:17:115:43 | MySmartPointer {...} | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:115:17:115:43 | MySmartPointer {...} | T | {EXTERNAL LOCATION} | Vec |
| dereference.rs:115:17:115:43 | MySmartPointer {...} | T.A | {EXTERNAL LOCATION} | Global |
| dereference.rs:115:17:115:43 | MySmartPointer {...} | T.T | {EXTERNAL LOCATION} | i32 |
| dereference.rs:115:41:115:41 | v | | {EXTERNAL LOCATION} | Vec |
| dereference.rs:115:41:115:41 | v | A | {EXTERNAL LOCATION} | Global |
| dereference.rs:115:41:115:41 | v | T | {EXTERNAL LOCATION} | i32 |
| dereference.rs:116:5:116:5 | x | | dereference.rs:18:1:20:1 | MySmartPointer |
| dereference.rs:116:5:116:5 | x | T | {EXTERNAL LOCATION} | Vec |
| dereference.rs:116:5:116:5 | x | T.A | {EXTERNAL LOCATION} | Global |
| dereference.rs:116:5:116:5 | x | T.T | {EXTERNAL LOCATION} | i32 |
| dereference.rs:116:5:116:13 | x.push(...) | | {EXTERNAL LOCATION} | () |
| dereference.rs:116:12:116:12 | 0 | | {EXTERNAL LOCATION} | i32 |
| dereference.rs:143:19:151:5 | { ... } | | {EXTERNAL LOCATION} | () |
| dereference.rs:144:17:144:26 | key_to_key | | {EXTERNAL LOCATION} | HashMap |
@@ -10781,7 +10802,18 @@ inferType
| main.rs:2902:21:2902:34 | path2.unwrap() | | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2904:13:2904:20 | pathbuf1 | | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2904:24:2904:37 | ...::new(...) | | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2905:13:2905:20 | pathbuf2 | | {EXTERNAL LOCATION} | Result |
| main.rs:2905:13:2905:20 | pathbuf2 | E | {EXTERNAL LOCATION} | () |
| main.rs:2905:13:2905:20 | pathbuf2 | T | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2905:24:2905:31 | pathbuf1 | | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2905:24:2905:46 | pathbuf1.canonicalize() | | {EXTERNAL LOCATION} | Result |
| main.rs:2905:24:2905:46 | pathbuf1.canonicalize() | E | {EXTERNAL LOCATION} | () |
| main.rs:2905:24:2905:46 | pathbuf1.canonicalize() | T | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2906:13:2906:20 | pathbuf3 | | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2906:24:2906:31 | pathbuf2 | | {EXTERNAL LOCATION} | Result |
| main.rs:2906:24:2906:31 | pathbuf2 | E | {EXTERNAL LOCATION} | () |
| main.rs:2906:24:2906:31 | pathbuf2 | T | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2906:24:2906:40 | pathbuf2.unwrap() | | main.rs:2879:5:2879:25 | PathBuf |
| main.rs:2912:14:2912:18 | SelfParam | | {EXTERNAL LOCATION} | & |
| main.rs:2912:14:2912:18 | SelfParam | TRef | main.rs:2911:5:2913:5 | Self [trait MyTrait] |
| main.rs:2919:14:2919:18 | SelfParam | | {EXTERNAL LOCATION} | & |

View File

@@ -1,7 +1,8 @@
#select
| src/main.rs:11:5:11:22 | ...::read_to_string | src/main.rs:7:11:7:19 | file_name | src/main.rs:11:5:11:22 | ...::read_to_string | This path depends on a $@. | src/main.rs:7:11:7:19 | file_name | user-provided value |
| src/main.rs:58:5:58:22 | ...::read_to_string | src/main.rs:50:51:50:59 | file_path | src/main.rs:58:5:58:22 | ...::read_to_string | This path depends on a $@. | src/main.rs:50:51:50:59 | file_path | user-provided value |
| src/main.rs:46:5:46:22 | ...::read_to_string | src/main.rs:38:11:38:19 | file_path | src/main.rs:46:5:46:22 | ...::read_to_string | This path depends on a $@. | src/main.rs:38:11:38:19 | file_path | user-provided value |
| src/main.rs:71:5:71:22 | ...::read_to_string | src/main.rs:63:11:63:19 | file_path | src/main.rs:71:5:71:22 | ...::read_to_string | This path depends on a $@. | src/main.rs:63:11:63:19 | file_path | user-provided value |
| src/main.rs:85:5:85:22 | ...::read_to_string | src/main.rs:76:11:76:19 | file_path | src/main.rs:85:5:85:22 | ...::read_to_string | This path depends on a $@. | src/main.rs:76:11:76:19 | file_path | user-provided value |
| src/main.rs:99:5:99:22 | ...::read_to_string | src/main.rs:90:11:90:19 | file_path | src/main.rs:99:5:99:22 | ...::read_to_string | This path depends on a $@. | src/main.rs:90:11:90:19 | file_path | user-provided value |
| src/main.rs:104:13:104:31 | ...::open | src/main.rs:103:17:103:30 | ...::args | src/main.rs:104:13:104:31 | ...::open | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
| src/main.rs:107:13:107:31 | ...::open | src/main.rs:103:17:103:30 | ...::args | src/main.rs:107:13:107:31 | ...::open | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
@@ -19,28 +20,36 @@ edges
| src/main.rs:9:9:9:17 | file_path | src/main.rs:11:24:11:32 | file_path | provenance | |
| src/main.rs:9:21:9:44 | ...::from(...) | src/main.rs:9:9:9:17 | file_path | provenance | |
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:9 |
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:14 |
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:15 |
| src/main.rs:11:24:11:32 | file_path | src/main.rs:11:5:11:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
| src/main.rs:50:51:50:59 | file_path | src/main.rs:52:32:52:40 | file_path | provenance | |
| src/main.rs:52:9:52:17 | file_path [&ref] | src/main.rs:53:21:53:29 | file_path [&ref] | provenance | |
| src/main.rs:52:21:52:41 | ...::new(...) [&ref] | src/main.rs:52:9:52:17 | file_path [&ref] | provenance | |
| src/main.rs:52:31:52:40 | &file_path [&ref] | src/main.rs:52:21:52:41 | ...::new(...) [&ref] | provenance | MaD:13 |
| src/main.rs:52:32:52:40 | file_path | src/main.rs:52:31:52:40 | &file_path [&ref] | provenance | |
| src/main.rs:53:9:53:17 | file_path | src/main.rs:58:24:58:32 | file_path | provenance | |
| src/main.rs:53:21:53:29 | file_path [&ref] | src/main.rs:53:21:53:44 | file_path.canonicalize() [Ok] | provenance | Config |
| src/main.rs:53:21:53:44 | file_path.canonicalize() [Ok] | src/main.rs:53:21:53:53 | ... .unwrap() | provenance | MaD:12 |
| src/main.rs:53:21:53:53 | ... .unwrap() | src/main.rs:53:9:53:17 | file_path | provenance | |
| src/main.rs:58:24:58:32 | file_path | src/main.rs:58:5:58:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
| src/main.rs:38:11:38:19 | file_path | src/main.rs:41:52:41:60 | file_path | provenance | |
| src/main.rs:41:9:41:17 | file_path | src/main.rs:46:24:46:32 | file_path | provenance | |
| src/main.rs:41:21:41:62 | public_path.join(...) | src/main.rs:41:9:41:17 | file_path | provenance | |
| src/main.rs:41:38:41:61 | ...::from(...) | src/main.rs:41:21:41:62 | public_path.join(...) | provenance | MaD:13 |
| src/main.rs:41:52:41:60 | file_path | src/main.rs:41:38:41:61 | ...::from(...) | provenance | MaD:9 |
| src/main.rs:41:52:41:60 | file_path | src/main.rs:41:38:41:61 | ...::from(...) | provenance | MaD:15 |
| src/main.rs:46:24:46:32 | file_path | src/main.rs:46:5:46:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
| src/main.rs:63:11:63:19 | file_path | src/main.rs:66:32:66:40 | file_path | provenance | |
| src/main.rs:66:9:66:17 | file_path [&ref] | src/main.rs:71:24:71:32 | file_path [&ref] | provenance | |
| src/main.rs:66:21:66:41 | ...::new(...) [&ref] | src/main.rs:66:9:66:17 | file_path [&ref] | provenance | |
| src/main.rs:66:31:66:40 | &file_path [&ref] | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | provenance | MaD:13 |
| src/main.rs:66:31:66:40 | &file_path [&ref] | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | provenance | MaD:14 |
| src/main.rs:66:32:66:40 | file_path | src/main.rs:66:31:66:40 | &file_path [&ref] | provenance | |
| src/main.rs:71:24:71:32 | file_path [&ref] | src/main.rs:71:5:71:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
| src/main.rs:76:11:76:19 | file_path | src/main.rs:79:52:79:60 | file_path | provenance | |
| src/main.rs:79:9:79:17 | file_path | src/main.rs:80:21:80:29 | file_path | provenance | |
| src/main.rs:79:21:79:62 | public_path.join(...) | src/main.rs:79:9:79:17 | file_path | provenance | |
| src/main.rs:79:38:79:61 | ...::from(...) | src/main.rs:79:21:79:62 | public_path.join(...) | provenance | MaD:13 |
| src/main.rs:79:52:79:60 | file_path | src/main.rs:79:38:79:61 | ...::from(...) | provenance | MaD:9 |
| src/main.rs:79:52:79:60 | file_path | src/main.rs:79:38:79:61 | ...::from(...) | provenance | MaD:15 |
| src/main.rs:80:9:80:17 | file_path | src/main.rs:85:24:85:32 | file_path | provenance | |
| src/main.rs:80:21:80:29 | file_path | src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | provenance | Config |
| src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | src/main.rs:80:21:80:53 | ... .unwrap() | provenance | MaD:12 |
| src/main.rs:80:21:80:53 | ... .unwrap() | src/main.rs:80:9:80:17 | file_path | provenance | |
| src/main.rs:85:24:85:32 | file_path | src/main.rs:85:5:85:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
| src/main.rs:90:11:90:19 | file_path | src/main.rs:93:32:93:40 | file_path | provenance | |
| src/main.rs:93:9:93:17 | file_path [&ref] | src/main.rs:98:21:98:29 | file_path [&ref] | provenance | |
| src/main.rs:93:21:93:41 | ...::new(...) [&ref] | src/main.rs:93:9:93:17 | file_path [&ref] | provenance | |
| src/main.rs:93:31:93:40 | &file_path [&ref] | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | provenance | MaD:13 |
| src/main.rs:93:31:93:40 | &file_path [&ref] | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | provenance | MaD:14 |
| src/main.rs:93:32:93:40 | file_path | src/main.rs:93:31:93:40 | &file_path [&ref] | provenance | |
| src/main.rs:98:9:98:17 | file_path | src/main.rs:99:24:99:32 | file_path | provenance | |
| src/main.rs:98:21:98:29 | file_path [&ref] | src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | provenance | Config |
@@ -82,7 +91,7 @@ edges
| src/main.rs:113:39:113:43 | path4 | src/main.rs:113:13:113:37 | ...::open | provenance | MaD:1 Sink:MaD:1 |
| src/main.rs:115:9:115:13 | path5 [&ref] | src/main.rs:116:33:116:37 | path5 [&ref] | provenance | |
| src/main.rs:115:17:115:44 | ...::new(...) [&ref] | src/main.rs:115:9:115:13 | path5 [&ref] | provenance | |
| src/main.rs:115:38:115:43 | &path1 [&ref] | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | provenance | MaD:13 |
| src/main.rs:115:38:115:43 | &path1 [&ref] | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | provenance | MaD:14 |
| src/main.rs:115:39:115:43 | path1 | src/main.rs:115:38:115:43 | &path1 [&ref] | provenance | |
| src/main.rs:116:33:116:37 | path5 [&ref] | src/main.rs:116:13:116:31 | ...::open | provenance | MaD:2 Sink:MaD:2 |
| src/main.rs:116:33:116:37 | path5 [&ref] | src/main.rs:118:17:118:21 | path5 [&ref] | provenance | |
@@ -99,7 +108,7 @@ edges
| src/main.rs:170:16:170:29 | ...: ... [&ref] | src/main.rs:174:36:174:43 | path_str [&ref] | provenance | |
| src/main.rs:172:9:172:12 | path [&ref] | src/main.rs:173:8:173:11 | path [&ref] | provenance | |
| src/main.rs:172:16:172:34 | ...::new(...) [&ref] | src/main.rs:172:9:172:12 | path [&ref] | provenance | |
| src/main.rs:172:26:172:33 | path_str [&ref] | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | provenance | MaD:13 |
| src/main.rs:172:26:172:33 | path_str [&ref] | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | provenance | MaD:14 |
| src/main.rs:173:8:173:11 | path [&ref] | src/main.rs:173:13:173:18 | exists | provenance | MaD:3 Sink:MaD:3 |
| src/main.rs:173:8:173:11 | path [&ref] | src/main.rs:177:36:177:39 | path [&ref] | provenance | |
| src/main.rs:174:36:174:43 | path_str [&ref] | src/main.rs:174:25:174:34 | ...::open | provenance | MaD:2 Sink:MaD:2 |
@@ -124,8 +133,9 @@ models
| 10 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Reference.Element; ReturnValue.Field[core::option::Option::Some(0)]; value |
| 11 | Summary: <core::option::Option>::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value |
| 12 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
| 13 | Summary: <std::path::Path>::new; Argument[0].Reference; ReturnValue.Reference; value |
| 14 | Summary: <std::path::PathBuf as core::convert::From>::from; Argument[0]; ReturnValue; taint |
| 13 | Summary: <std::path::Path>::join; Argument[0]; ReturnValue; taint |
| 14 | Summary: <std::path::Path>::new; Argument[0].Reference; ReturnValue.Reference; value |
| 15 | Summary: <std::path::PathBuf as core::convert::From>::from; Argument[0]; ReturnValue; taint |
nodes
| src/main.rs:7:11:7:19 | file_name | semmle.label | file_name |
| src/main.rs:9:9:9:17 | file_path | semmle.label | file_path |
@@ -133,17 +143,13 @@ nodes
| src/main.rs:9:35:9:43 | file_name | semmle.label | file_name |
| src/main.rs:11:5:11:22 | ...::read_to_string | semmle.label | ...::read_to_string |
| src/main.rs:11:24:11:32 | file_path | semmle.label | file_path |
| src/main.rs:50:51:50:59 | file_path | semmle.label | file_path |
| src/main.rs:52:9:52:17 | file_path [&ref] | semmle.label | file_path [&ref] |
| src/main.rs:52:21:52:41 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] |
| src/main.rs:52:31:52:40 | &file_path [&ref] | semmle.label | &file_path [&ref] |
| src/main.rs:52:32:52:40 | file_path | semmle.label | file_path |
| src/main.rs:53:9:53:17 | file_path | semmle.label | file_path |
| src/main.rs:53:21:53:29 | file_path [&ref] | semmle.label | file_path [&ref] |
| src/main.rs:53:21:53:44 | file_path.canonicalize() [Ok] | semmle.label | file_path.canonicalize() [Ok] |
| src/main.rs:53:21:53:53 | ... .unwrap() | semmle.label | ... .unwrap() |
| src/main.rs:58:5:58:22 | ...::read_to_string | semmle.label | ...::read_to_string |
| src/main.rs:58:24:58:32 | file_path | semmle.label | file_path |
| src/main.rs:38:11:38:19 | file_path | semmle.label | file_path |
| src/main.rs:41:9:41:17 | file_path | semmle.label | file_path |
| src/main.rs:41:21:41:62 | public_path.join(...) | semmle.label | public_path.join(...) |
| src/main.rs:41:38:41:61 | ...::from(...) | semmle.label | ...::from(...) |
| src/main.rs:41:52:41:60 | file_path | semmle.label | file_path |
| src/main.rs:46:5:46:22 | ...::read_to_string | semmle.label | ...::read_to_string |
| src/main.rs:46:24:46:32 | file_path | semmle.label | file_path |
| src/main.rs:63:11:63:19 | file_path | semmle.label | file_path |
| src/main.rs:66:9:66:17 | file_path [&ref] | semmle.label | file_path [&ref] |
| src/main.rs:66:21:66:41 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] |
@@ -151,6 +157,17 @@ nodes
| src/main.rs:66:32:66:40 | file_path | semmle.label | file_path |
| src/main.rs:71:5:71:22 | ...::read_to_string | semmle.label | ...::read_to_string |
| src/main.rs:71:24:71:32 | file_path [&ref] | semmle.label | file_path [&ref] |
| src/main.rs:76:11:76:19 | file_path | semmle.label | file_path |
| src/main.rs:79:9:79:17 | file_path | semmle.label | file_path |
| src/main.rs:79:21:79:62 | public_path.join(...) | semmle.label | public_path.join(...) |
| src/main.rs:79:38:79:61 | ...::from(...) | semmle.label | ...::from(...) |
| src/main.rs:79:52:79:60 | file_path | semmle.label | file_path |
| src/main.rs:80:9:80:17 | file_path | semmle.label | file_path |
| src/main.rs:80:21:80:29 | file_path | semmle.label | file_path |
| src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | semmle.label | file_path.canonicalize() [Ok] |
| src/main.rs:80:21:80:53 | ... .unwrap() | semmle.label | ... .unwrap() |
| src/main.rs:85:5:85:22 | ...::read_to_string | semmle.label | ...::read_to_string |
| src/main.rs:85:24:85:32 | file_path | semmle.label | file_path |
| src/main.rs:90:11:90:19 | file_path | semmle.label | file_path |
| src/main.rs:93:9:93:17 | file_path [&ref] | semmle.label | file_path [&ref] |
| src/main.rs:93:21:93:41 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] |

View File

@@ -30,12 +30,12 @@ fn tainted_path_handler_folder_good(Query(file_path): Query<String>) -> Result<S
if !file_path.starts_with(public_path) {
return Err(Error::from_status(StatusCode::BAD_REQUEST));
}
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink MISSING: path-injection-checked
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink path-injection-checked
}
//#[handler]
fn tainted_path_handler_folder_almost_good1(
Query(file_path): Query<String>, // $ MISSING: Source=remote2
Query(file_path): Query<String>, // $ Source=remote2
) -> Result<String> {
let public_path = PathBuf::from("/var/www/public_html");
let file_path = public_path.join(PathBuf::from(file_path));
@@ -43,11 +43,11 @@ fn tainted_path_handler_folder_almost_good1(
if !file_path.starts_with(public_path) {
return Err(Error::from_status(StatusCode::BAD_REQUEST));
}
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink MISSING: path-injection-checked Alert[rust/path-injection]=remote2 -- we cannot resolve the `join` call above, because it needs a `PathBuf -> Path` `Deref`
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink path-injection-checked Alert[rust/path-injection]=remote2
}
//#[handler]
fn tainted_path_handler_folder_good_simpler(Query(file_path): Query<String>) -> Result<String> { // $ Source=remote6
fn tainted_path_handler_folder_good_simpler(Query(file_path): Query<String>) -> Result<String> {
let public_path = "/var/www/public_html";
let file_path = Path::new(&file_path);
let file_path = file_path.canonicalize().unwrap();
@@ -55,7 +55,7 @@ fn tainted_path_handler_folder_good_simpler(Query(file_path): Query<String>) ->
if !file_path.starts_with(public_path) {
return Err(Error::from_status(StatusCode::BAD_REQUEST));
}
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink MISSING: path-injection-checked SPURIOUS: Alert[rust/path-injection]=remote6
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink path-injection-checked
}
//#[handler]
@@ -73,7 +73,7 @@ fn tainted_path_handler_folder_almost_good1_simpler(
//#[handler]
fn tainted_path_handler_folder_almost_good2(
Query(file_path): Query<String>, // $ MISSING: Source=remote4
Query(file_path): Query<String>, // $ Source=remote4
) -> Result<String> {
let public_path = PathBuf::from("/var/www/public_html");
let file_path = public_path.join(PathBuf::from(file_path));
@@ -82,7 +82,7 @@ fn tainted_path_handler_folder_almost_good2(
if file_path.starts_with(public_path) {
return Err(Error::from_status(StatusCode::BAD_REQUEST));
}
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink MISSING: path-injection-checked Alert[rust/path-injection]=remote4 -- we cannot resolve the `join` call above, because it needs a `PathBuf -> Path` `Deref`
fs::read_to_string(file_path).map_err(InternalServerError) // $ path-injection-sink Alert[rust/path-injection]=remote4 $ MISSING: path-injection-checked
}
//#[handler]

View File

@@ -857,10 +857,16 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
{
private import Input
pragma[nomagic]
private Type getTypeAt(HasTypeTree term, TypePath path) {
relevantConstraint(term, _) and
result = term.getTypeAt(path)
}
/** Holds if the type tree has the type `type` and should satisfy `constraint`. */
pragma[nomagic]
private predicate hasTypeConstraint(HasTypeTree term, Type type, Type constraint) {
type = term.getTypeAt(TypePath::nil()) and
type = getTypeAt(term, TypePath::nil()) and
relevantConstraint(term, constraint)
}
@@ -967,36 +973,74 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
)
}
pragma[nomagic]
private predicate satisfiesConstraintTypeMention1(
HasTypeTree tt, Type constraint, TypePath path, TypePath pathToTypeParamInSub
pragma[inline]
private predicate satisfiesConstraintTypeMention1Inline(
HasTypeTree tt, TypeAbstraction abs, Type constraint, TypePath path,
TypePath pathToTypeParamInSub
) {
exists(TypeAbstraction abs, TypeMention sub, TypeParameter tp |
exists(TypeMention sub, TypeParameter tp |
satisfiesConstraintTypeMention0(tt, constraint, abs, sub, path, tp) and
tp = abs.getATypeParameter() and
sub.resolveTypeAt(pathToTypeParamInSub) = tp
)
}
pragma[nomagic]
private predicate satisfiesConstraintTypeMention1(
HasTypeTree tt, Type constraint, TypePath path, TypePath pathToTypeParamInSub
) {
satisfiesConstraintTypeMention1Inline(tt, _, constraint, path, pathToTypeParamInSub)
}
pragma[nomagic]
private predicate satisfiesConstraintTypeMention1Through(
HasTypeTree tt, TypeAbstraction abs, Type constraint, TypePath path,
TypePath pathToTypeParamInSub
) {
satisfiesConstraintTypeMention1Inline(tt, abs, constraint, path, pathToTypeParamInSub)
}
pragma[inline]
private predicate satisfiesConstraintTypeNonTypeParamInline(
HasTypeTree tt, TypeAbstraction abs, Type constraint, TypePath path, Type t
) {
satisfiesConstraintTypeMention0(tt, constraint, abs, _, path, t) and
not t = abs.getATypeParameter()
}
/**
* Holds if the type tree at `tt` satisfies the constraint `constraint`
* with the type `t` at `path`.
*/
pragma[nomagic]
predicate satisfiesConstraintType(HasTypeTree tt, Type constraint, TypePath path, Type t) {
exists(TypeAbstraction abs |
satisfiesConstraintTypeMention0(tt, constraint, abs, _, path, t) and
not t = abs.getATypeParameter()
)
satisfiesConstraintTypeNonTypeParamInline(tt, _, constraint, path, t)
or
exists(TypePath prefix0, TypePath pathToTypeParamInSub, TypePath suffix |
satisfiesConstraintTypeMention1(tt, constraint, prefix0, pathToTypeParamInSub) and
tt.getTypeAt(pathToTypeParamInSub.appendInverse(suffix)) = t and
getTypeAt(tt, pathToTypeParamInSub.appendInverse(suffix)) = t and
path = prefix0.append(suffix)
)
or
hasTypeConstraint(tt, constraint, constraint) and
t = tt.getTypeAt(path)
t = getTypeAt(tt, path)
}
/**
* Holds if the type tree at `tt` satisfies the constraint `constraint`
* through `abs` with the type `t` at `path`.
*/
pragma[nomagic]
predicate satisfiesConstraintTypeThrough(
HasTypeTree tt, TypeAbstraction abs, Type constraint, TypePath path, Type t
) {
satisfiesConstraintTypeNonTypeParamInline(tt, abs, constraint, path, t)
or
exists(TypePath prefix0, TypePath pathToTypeParamInSub, TypePath suffix |
satisfiesConstraintTypeMention1Through(tt, abs, constraint, prefix0, pathToTypeParamInSub) and
getTypeAt(tt, pathToTypeParamInSub.appendInverse(suffix)) = t and
path = prefix0.append(suffix)
)
}
/**