mirror of
https://github.com/github/codeql.git
synced 2026-05-04 21:25:44 +02:00
Merge remote-tracking branch 'upstream/master' into ir-crement-load
Conflicts: cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected
This commit is contained in:
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ private newtype TOpcode =
|
||||
TUnmodeledDefinition() or
|
||||
TUnmodeledUse() or
|
||||
TAliasedDefinition() or
|
||||
TInitializeNonLocal() or
|
||||
TAliasedUse() or
|
||||
TPhi() or
|
||||
TBuiltIn() or
|
||||
@@ -596,6 +597,14 @@ module Opcode {
|
||||
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof EscapedMemoryAccess }
|
||||
}
|
||||
|
||||
class InitializeNonLocal extends Opcode, TInitializeNonLocal {
|
||||
final override string toString() { result = "InitializeNonLocal" }
|
||||
|
||||
final override MemoryAccessKind getWriteMemoryAccess() {
|
||||
result instanceof NonLocalMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
class AliasedUse extends Opcode, TAliasedUse {
|
||||
final override string toString() { result = "AliasedUse" }
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
|
||||
|
||||
final override string toStringInternal() { result = "{AllNonLocal}" }
|
||||
|
||||
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }
|
||||
final override AliasedVirtualVariable getVirtualVariable() { result.getIRFunction() = irFunc }
|
||||
|
||||
final override Language::LanguageType getType() {
|
||||
result = any(IRUnknownType type).getCanonicalLanguageType()
|
||||
@@ -311,6 +311,14 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
|
||||
final override string getUniqueId() { result = "{AllNonLocal}" }
|
||||
|
||||
final override predicate isMayAccess() { isMayAccess = true }
|
||||
|
||||
override predicate canDefineReadOnly() {
|
||||
// A "must" access that defines all non-local memory appears only on the `InitializeNonLocal`
|
||||
// instruction, which provides the initial definition for all memory outside of the current
|
||||
// function's stack frame. This memory includes string literals and other read-only globals, so
|
||||
// we allow such an access to be the definition for a use of a read-only location.
|
||||
not isMayAccess()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,16 +349,6 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
|
||||
|
||||
class AliasedVirtualVariable extends AllAliasedMemory, VirtualVariable {
|
||||
AliasedVirtualVariable() { not isMayAccess() }
|
||||
|
||||
override predicate canDefineReadOnly() {
|
||||
// A must-def of all aliased memory is only used in two places:
|
||||
// 1. In the prologue of the function, to provide a definition for all memory defined before the
|
||||
// function was called. In this case, it needs to provide a definition even for read-only
|
||||
// non-local variables.
|
||||
// 2. As the result of a `Chi` instruction. These don't participate in overlap analysis, so it's
|
||||
// OK if we let this predicate hold in that case.
|
||||
any()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,10 +403,16 @@ private Overlap getExtentOverlap(MemoryLocation def, MemoryLocation use) {
|
||||
use instanceof AllNonLocalMemory and
|
||||
result instanceof MustExactlyOverlap
|
||||
or
|
||||
// AllNonLocalMemory may partially overlap any location within the same virtual variable,
|
||||
// except a local variable.
|
||||
result instanceof MayPartiallyOverlap and
|
||||
not use.isAlwaysAllocatedOnStack()
|
||||
not use instanceof AllNonLocalMemory and
|
||||
not use.isAlwaysAllocatedOnStack() and
|
||||
if use instanceof VariableMemoryLocation
|
||||
then
|
||||
// AllNonLocalMemory totally overlaps any non-local variable.
|
||||
result instanceof MustTotallyOverlap
|
||||
else
|
||||
// AllNonLocalMemory may partially overlap any other location within the same virtual
|
||||
// variable, except a stack variable.
|
||||
result instanceof MayPartiallyOverlap
|
||||
)
|
||||
or
|
||||
def.getVirtualVariable() = use.getVirtualVariable() and
|
||||
|
||||
@@ -759,7 +759,21 @@ module DefUse {
|
||||
then defLocation = useLocation
|
||||
else (
|
||||
definitionHasPhiNode(defLocation, block) and
|
||||
defLocation = useLocation.getVirtualVariable()
|
||||
defLocation = useLocation.getVirtualVariable() and
|
||||
// Handle the unusual case where a virtual variable does not overlap one of its member
|
||||
// locations. For example, a definition of the virtual variable representing all aliased
|
||||
// memory does not overlap a use of a string literal, because the contents of a string
|
||||
// literal can never be redefined. The string literal's location could still be a member of
|
||||
// the `AliasedVirtualVariable` due to something like:
|
||||
// ```
|
||||
// char s[10];
|
||||
// strcpy(s, p);
|
||||
// const char* p = b ? "SomeLiteral" : s;
|
||||
// return p[3];
|
||||
// ```
|
||||
// In the above example, `p[3]` may access either the string literal or the local variable
|
||||
// `s`, so both of those locations must be members of the `AliasedVirtualVariable`.
|
||||
exists(Alias::getOverlap(defLocation, useLocation))
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -26,6 +26,7 @@ newtype TInstructionTag =
|
||||
UnmodeledDefinitionTag() or
|
||||
UnmodeledUseTag() or
|
||||
AliasedDefinitionTag() or
|
||||
InitializeNonLocalTag() or
|
||||
AliasedUseTag() or
|
||||
SwitchBranchTag() or
|
||||
CallTargetTag() or
|
||||
@@ -120,6 +121,8 @@ string getInstructionTagId(TInstructionTag tag) {
|
||||
or
|
||||
tag = AliasedDefinitionTag() and result = "AliasedDef"
|
||||
or
|
||||
tag = InitializeNonLocalTag() and result = "InitNonLocal"
|
||||
or
|
||||
tag = AliasedUseTag() and result = "AliasedUse"
|
||||
or
|
||||
tag = SwitchBranchTag() and result = "SwitchBranch"
|
||||
|
||||
@@ -71,6 +71,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
||||
result = getInstruction(AliasedDefinitionTag())
|
||||
or
|
||||
tag = AliasedDefinitionTag() and
|
||||
result = getInstruction(InitializeNonLocalTag())
|
||||
or
|
||||
tag = InitializeNonLocalTag() and
|
||||
result = getInstruction(UnmodeledDefinitionTag())
|
||||
or
|
||||
(
|
||||
@@ -144,6 +147,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
||||
opcode instanceof Opcode::AliasedDefinition and
|
||||
resultType = getUnknownType()
|
||||
or
|
||||
tag = InitializeNonLocalTag() and
|
||||
opcode instanceof Opcode::InitializeNonLocal and
|
||||
resultType = getUnknownType()
|
||||
or
|
||||
tag = InitializeThisTag() and
|
||||
opcode instanceof Opcode::InitializeThis and
|
||||
resultType = getTypeForGLValue(getThisType())
|
||||
|
||||
@@ -759,7 +759,21 @@ module DefUse {
|
||||
then defLocation = useLocation
|
||||
else (
|
||||
definitionHasPhiNode(defLocation, block) and
|
||||
defLocation = useLocation.getVirtualVariable()
|
||||
defLocation = useLocation.getVirtualVariable() and
|
||||
// Handle the unusual case where a virtual variable does not overlap one of its member
|
||||
// locations. For example, a definition of the virtual variable representing all aliased
|
||||
// memory does not overlap a use of a string literal, because the contents of a string
|
||||
// literal can never be redefined. The string literal's location could still be a member of
|
||||
// the `AliasedVirtualVariable` due to something like:
|
||||
// ```
|
||||
// char s[10];
|
||||
// strcpy(s, p);
|
||||
// const char* p = b ? "SomeLiteral" : s;
|
||||
// return p[3];
|
||||
// ```
|
||||
// In the above example, `p[3]` may access either the string literal or the local variable
|
||||
// `s`, so both of those locations must be members of the `AliasedVirtualVariable`.
|
||||
exists(Alias::getOverlap(defLocation, useLocation))
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -187,6 +187,13 @@ private predicate boundFlowStepSsa(
|
||||
guard.controls(op2.getUse().getBlock(), testIsTrue) and
|
||||
reason = TCondReason(guard)
|
||||
)
|
||||
or
|
||||
exists(IRGuardCondition guard, boolean testIsTrue, SafeCastInstruction cast |
|
||||
valueNumberOfOperand(op2) = valueNumber(cast.getUnary()) and
|
||||
guard = boundFlowCond(valueNumber(cast), op1, delta, upper, testIsTrue) and
|
||||
guard.controls(op2.getUse().getBlock(), testIsTrue) and
|
||||
reason = TCondReason(guard)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,7 +266,7 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
|
||||
|
||||
private class SafeCastInstruction extends ConvertInstruction {
|
||||
SafeCastInstruction() {
|
||||
safeCast(getResultType(), getUnary().getResultType())
|
||||
safeCast(getUnary().getResultType(), getResultType())
|
||||
or
|
||||
getResultType() instanceof PointerType and
|
||||
getUnary().getResultType() instanceof PointerType
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -249,4 +249,16 @@ char *VoidStarIndirectParameters(char *src, int size) {
|
||||
*src = 'a';
|
||||
memcpy(dst, src, size);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
char StringLiteralAliasing2(bool b) {
|
||||
if (b) {
|
||||
ExternalFunc();
|
||||
}
|
||||
else {
|
||||
ExternalFunc();
|
||||
}
|
||||
|
||||
const char* s = "Literal";
|
||||
return s[2];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -59,3 +59,6 @@
|
||||
| test.cpp:183:10:183:10 | Load: i | test.cpp:175:23:175:23 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 |
|
||||
| test.cpp:185:10:185:10 | Load: i | test.cpp:175:23:175:23 | InitializeParameter: x | 0 | true | CompareLT: ... < ... | test.cpp:176:7:176:11 | test.cpp:176:7:176:11 |
|
||||
| test.cpp:187:10:187:10 | Store: i | test.cpp:175:23:175:23 | InitializeParameter: x | 0 | false | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 |
|
||||
| test.cpp:199:10:199:10 | Load: i | test.cpp:197:25:197:25 | InitializeParameter: l | -1 | true | CompareLT: ... < ... | test.cpp:198:7:198:11 | test.cpp:198:7:198:11 |
|
||||
| test.cpp:202:11:202:11 | Load: i | test.cpp:197:25:197:25 | InitializeParameter: l | -3 | true | CompareLT: ... < ... | test.cpp:201:7:201:15 | test.cpp:201:7:201:15 |
|
||||
| test.cpp:208:10:208:10 | Load: x | test.cpp:206:24:206:24 | InitializeParameter: y | -3 | true | CompareLT: ... < ... | test.cpp:207:7:207:15 | test.cpp:207:7:207:15 |
|
||||
|
||||
@@ -186,3 +186,25 @@ int test15(int i, int x) {
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// safe integer type conversion
|
||||
int test16(int i) {
|
||||
long l;
|
||||
l = i;
|
||||
}
|
||||
|
||||
// implicit integer casts
|
||||
void test17(int i, long l) {
|
||||
if (i < l) {
|
||||
sink(i);
|
||||
}
|
||||
if (i < l - 2) {
|
||||
sink (i);
|
||||
}
|
||||
}
|
||||
|
||||
void test18(int x, int y) {
|
||||
if (x < y - 2) {
|
||||
sink(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,20 @@ test.cpp:
|
||||
# 1| v1_1(void) = EnterFunction :
|
||||
# 1| m1_2(unknown) = AliasedDefinition :
|
||||
# 1| valnum = unique
|
||||
# 1| mu1_3(unknown) = UnmodeledDefinition :
|
||||
# 1| m1_3(unknown) = InitializeNonLocal :
|
||||
# 1| valnum = unique
|
||||
# 1| r1_4(glval<int>) = VariableAddress[p0] :
|
||||
# 1| valnum = r1_4
|
||||
# 1| m1_5(int) = InitializeParameter[p0] : &:r1_4
|
||||
# 1| valnum = m1_5
|
||||
# 1| r1_6(glval<int>) = VariableAddress[p1] :
|
||||
# 1| m1_4(unknown) = Chi : total:m1_2, partial:m1_3
|
||||
# 1| valnum = unique
|
||||
# 1| mu1_5(unknown) = UnmodeledDefinition :
|
||||
# 1| valnum = unique
|
||||
# 1| r1_6(glval<int>) = VariableAddress[p0] :
|
||||
# 1| valnum = r1_6
|
||||
# 1| m1_7(int) = InitializeParameter[p1] : &:r1_6
|
||||
# 1| m1_7(int) = InitializeParameter[p0] : &:r1_6
|
||||
# 1| valnum = m1_7
|
||||
# 1| r1_8(glval<int>) = VariableAddress[p1] :
|
||||
# 1| valnum = r1_8
|
||||
# 1| m1_9(int) = InitializeParameter[p1] : &:r1_8
|
||||
# 1| valnum = m1_9
|
||||
# 2| r2_1(glval<int>) = VariableAddress[x] :
|
||||
# 2| valnum = r2_1
|
||||
# 2| m2_2(int) = Uninitialized[x] : &:r2_1
|
||||
@@ -27,13 +31,13 @@ test.cpp:
|
||||
# 3| m3_2(unsigned char) = Uninitialized[b] : &:r3_1
|
||||
# 3| valnum = unique
|
||||
# 5| r5_1(glval<int>) = VariableAddress[p0] :
|
||||
# 5| valnum = r1_4
|
||||
# 5| r5_2(int) = Load : &:r5_1, m1_5
|
||||
# 5| valnum = m1_5
|
||||
# 5| r5_3(glval<int>) = VariableAddress[p1] :
|
||||
# 5| valnum = r1_6
|
||||
# 5| r5_4(int) = Load : &:r5_3, m1_7
|
||||
# 5| r5_2(int) = Load : &:r5_1, m1_7
|
||||
# 5| valnum = m1_7
|
||||
# 5| r5_3(glval<int>) = VariableAddress[p1] :
|
||||
# 5| valnum = r1_8
|
||||
# 5| r5_4(int) = Load : &:r5_3, m1_9
|
||||
# 5| valnum = m1_9
|
||||
# 5| r5_5(int) = Add : r5_2, r5_4
|
||||
# 5| valnum = r5_5
|
||||
# 5| r5_6(glval<int>) = VariableAddress[x] :
|
||||
@@ -41,13 +45,13 @@ test.cpp:
|
||||
# 5| m5_7(int) = Store : &:r5_6, r5_5
|
||||
# 5| valnum = r5_5
|
||||
# 6| r6_1(glval<int>) = VariableAddress[p0] :
|
||||
# 6| valnum = r1_4
|
||||
# 6| r6_2(int) = Load : &:r6_1, m1_5
|
||||
# 6| valnum = m1_5
|
||||
# 6| r6_3(glval<int>) = VariableAddress[p1] :
|
||||
# 6| valnum = r1_6
|
||||
# 6| r6_4(int) = Load : &:r6_3, m1_7
|
||||
# 6| r6_2(int) = Load : &:r6_1, m1_7
|
||||
# 6| valnum = m1_7
|
||||
# 6| r6_3(glval<int>) = VariableAddress[p1] :
|
||||
# 6| valnum = r1_8
|
||||
# 6| r6_4(int) = Load : &:r6_3, m1_9
|
||||
# 6| valnum = m1_9
|
||||
# 6| r6_5(int) = Add : r6_2, r6_4
|
||||
# 6| valnum = r5_5
|
||||
# 6| r6_6(glval<int>) = VariableAddress[x] :
|
||||
@@ -63,28 +67,32 @@ test.cpp:
|
||||
# 7| m7_4(int) = Store : &:r7_3, r7_2
|
||||
# 7| valnum = r5_5
|
||||
# 8| v8_1(void) = NoOp :
|
||||
# 1| r1_8(glval<int>) = VariableAddress[#return] :
|
||||
# 1| r1_10(glval<int>) = VariableAddress[#return] :
|
||||
# 1| valnum = unique
|
||||
# 1| v1_9(void) = ReturnValue : &:r1_8
|
||||
# 1| v1_10(void) = UnmodeledUse : mu*
|
||||
# 1| v1_11(void) = AliasedUse : ~m1_2
|
||||
# 1| v1_12(void) = ExitFunction :
|
||||
# 1| v1_11(void) = ReturnValue : &:r1_10
|
||||
# 1| v1_12(void) = UnmodeledUse : mu*
|
||||
# 1| v1_13(void) = AliasedUse : m1_3
|
||||
# 1| v1_14(void) = ExitFunction :
|
||||
|
||||
# 12| int test01(int, int)
|
||||
# 12| Block 0
|
||||
# 12| v12_1(void) = EnterFunction :
|
||||
# 12| m12_2(unknown) = AliasedDefinition :
|
||||
# 12| valnum = unique
|
||||
# 12| mu12_3(unknown) = UnmodeledDefinition :
|
||||
# 12| m12_3(unknown) = InitializeNonLocal :
|
||||
# 12| valnum = unique
|
||||
# 12| r12_4(glval<int>) = VariableAddress[p0] :
|
||||
# 12| valnum = r12_4
|
||||
# 12| m12_5(int) = InitializeParameter[p0] : &:r12_4
|
||||
# 12| valnum = m12_5
|
||||
# 12| r12_6(glval<int>) = VariableAddress[p1] :
|
||||
# 12| m12_4(unknown) = Chi : total:m12_2, partial:m12_3
|
||||
# 12| valnum = unique
|
||||
# 12| mu12_5(unknown) = UnmodeledDefinition :
|
||||
# 12| valnum = unique
|
||||
# 12| r12_6(glval<int>) = VariableAddress[p0] :
|
||||
# 12| valnum = r12_6
|
||||
# 12| m12_7(int) = InitializeParameter[p1] : &:r12_6
|
||||
# 12| m12_7(int) = InitializeParameter[p0] : &:r12_6
|
||||
# 12| valnum = m12_7
|
||||
# 12| r12_8(glval<int>) = VariableAddress[p1] :
|
||||
# 12| valnum = r12_8
|
||||
# 12| m12_9(int) = InitializeParameter[p1] : &:r12_8
|
||||
# 12| valnum = m12_9
|
||||
# 13| r13_1(glval<int>) = VariableAddress[x] :
|
||||
# 13| valnum = r13_1
|
||||
# 13| m13_2(int) = Uninitialized[x] : &:r13_1
|
||||
@@ -98,18 +106,18 @@ test.cpp:
|
||||
# 14| m14_2(unsigned char) = Uninitialized[b] : &:r14_1
|
||||
# 14| valnum = unique
|
||||
# 16| r16_1(glval<int>) = VariableAddress[p0] :
|
||||
# 16| valnum = r12_4
|
||||
# 16| r16_2(int) = Load : &:r16_1, m12_5
|
||||
# 16| valnum = m12_5
|
||||
# 16| r16_3(glval<int>) = VariableAddress[p1] :
|
||||
# 16| valnum = r12_6
|
||||
# 16| r16_4(int) = Load : &:r16_3, m12_7
|
||||
# 16| r16_2(int) = Load : &:r16_1, m12_7
|
||||
# 16| valnum = m12_7
|
||||
# 16| r16_3(glval<int>) = VariableAddress[p1] :
|
||||
# 16| valnum = r12_8
|
||||
# 16| r16_4(int) = Load : &:r16_3, m12_9
|
||||
# 16| valnum = m12_9
|
||||
# 16| r16_5(int) = Add : r16_2, r16_4
|
||||
# 16| valnum = r16_5
|
||||
# 16| r16_6(glval<int>) = VariableAddress[global01] :
|
||||
# 16| valnum = r16_6
|
||||
# 16| r16_7(int) = Load : &:r16_6, ~m12_2
|
||||
# 16| r16_7(int) = Load : &:r16_6, ~m12_3
|
||||
# 16| valnum = unique
|
||||
# 16| r16_8(int) = Add : r16_5, r16_7
|
||||
# 16| valnum = r16_8
|
||||
@@ -118,18 +126,18 @@ test.cpp:
|
||||
# 16| m16_10(int) = Store : &:r16_9, r16_8
|
||||
# 16| valnum = r16_8
|
||||
# 17| r17_1(glval<int>) = VariableAddress[p0] :
|
||||
# 17| valnum = r12_4
|
||||
# 17| r17_2(int) = Load : &:r17_1, m12_5
|
||||
# 17| valnum = m12_5
|
||||
# 17| r17_3(glval<int>) = VariableAddress[p1] :
|
||||
# 17| valnum = r12_6
|
||||
# 17| r17_4(int) = Load : &:r17_3, m12_7
|
||||
# 17| r17_2(int) = Load : &:r17_1, m12_7
|
||||
# 17| valnum = m12_7
|
||||
# 17| r17_3(glval<int>) = VariableAddress[p1] :
|
||||
# 17| valnum = r12_8
|
||||
# 17| r17_4(int) = Load : &:r17_3, m12_9
|
||||
# 17| valnum = m12_9
|
||||
# 17| r17_5(int) = Add : r17_2, r17_4
|
||||
# 17| valnum = r16_5
|
||||
# 17| r17_6(glval<int>) = VariableAddress[global01] :
|
||||
# 17| valnum = r16_6
|
||||
# 17| r17_7(int) = Load : &:r17_6, ~m12_2
|
||||
# 17| r17_7(int) = Load : &:r17_6, ~m12_3
|
||||
# 17| valnum = unique
|
||||
# 17| r17_8(int) = Add : r17_5, r17_7
|
||||
# 17| valnum = r17_8
|
||||
@@ -146,28 +154,32 @@ test.cpp:
|
||||
# 18| m18_4(int) = Store : &:r18_3, r18_2
|
||||
# 18| valnum = r17_8
|
||||
# 19| v19_1(void) = NoOp :
|
||||
# 12| r12_8(glval<int>) = VariableAddress[#return] :
|
||||
# 12| r12_10(glval<int>) = VariableAddress[#return] :
|
||||
# 12| valnum = unique
|
||||
# 12| v12_9(void) = ReturnValue : &:r12_8
|
||||
# 12| v12_10(void) = UnmodeledUse : mu*
|
||||
# 12| v12_11(void) = AliasedUse : ~m12_2
|
||||
# 12| v12_12(void) = ExitFunction :
|
||||
# 12| v12_11(void) = ReturnValue : &:r12_10
|
||||
# 12| v12_12(void) = UnmodeledUse : mu*
|
||||
# 12| v12_13(void) = AliasedUse : m12_3
|
||||
# 12| v12_14(void) = ExitFunction :
|
||||
|
||||
# 25| int test02(int, int)
|
||||
# 25| Block 0
|
||||
# 25| v25_1(void) = EnterFunction :
|
||||
# 25| m25_2(unknown) = AliasedDefinition :
|
||||
# 25| valnum = unique
|
||||
# 25| mu25_3(unknown) = UnmodeledDefinition :
|
||||
# 25| m25_3(unknown) = InitializeNonLocal :
|
||||
# 25| valnum = unique
|
||||
# 25| r25_4(glval<int>) = VariableAddress[p0] :
|
||||
# 25| valnum = r25_4
|
||||
# 25| m25_5(int) = InitializeParameter[p0] : &:r25_4
|
||||
# 25| valnum = m25_5
|
||||
# 25| r25_6(glval<int>) = VariableAddress[p1] :
|
||||
# 25| m25_4(unknown) = Chi : total:m25_2, partial:m25_3
|
||||
# 25| valnum = unique
|
||||
# 25| mu25_5(unknown) = UnmodeledDefinition :
|
||||
# 25| valnum = unique
|
||||
# 25| r25_6(glval<int>) = VariableAddress[p0] :
|
||||
# 25| valnum = r25_6
|
||||
# 25| m25_7(int) = InitializeParameter[p1] : &:r25_6
|
||||
# 25| m25_7(int) = InitializeParameter[p0] : &:r25_6
|
||||
# 25| valnum = m25_7
|
||||
# 25| r25_8(glval<int>) = VariableAddress[p1] :
|
||||
# 25| valnum = r25_8
|
||||
# 25| m25_9(int) = InitializeParameter[p1] : &:r25_8
|
||||
# 25| valnum = m25_9
|
||||
# 26| r26_1(glval<int>) = VariableAddress[x] :
|
||||
# 26| valnum = r26_1
|
||||
# 26| m26_2(int) = Uninitialized[x] : &:r26_1
|
||||
@@ -181,18 +193,18 @@ test.cpp:
|
||||
# 27| m27_2(unsigned char) = Uninitialized[b] : &:r27_1
|
||||
# 27| valnum = unique
|
||||
# 29| r29_1(glval<int>) = VariableAddress[p0] :
|
||||
# 29| valnum = r25_4
|
||||
# 29| r29_2(int) = Load : &:r29_1, m25_5
|
||||
# 29| valnum = m25_5
|
||||
# 29| r29_3(glval<int>) = VariableAddress[p1] :
|
||||
# 29| valnum = r25_6
|
||||
# 29| r29_4(int) = Load : &:r29_3, m25_7
|
||||
# 29| r29_2(int) = Load : &:r29_1, m25_7
|
||||
# 29| valnum = m25_7
|
||||
# 29| r29_3(glval<int>) = VariableAddress[p1] :
|
||||
# 29| valnum = r25_8
|
||||
# 29| r29_4(int) = Load : &:r29_3, m25_9
|
||||
# 29| valnum = m25_9
|
||||
# 29| r29_5(int) = Add : r29_2, r29_4
|
||||
# 29| valnum = r29_5
|
||||
# 29| r29_6(glval<int>) = VariableAddress[global02] :
|
||||
# 29| valnum = r29_6
|
||||
# 29| r29_7(int) = Load : &:r29_6, ~m25_2
|
||||
# 29| r29_7(int) = Load : &:r29_6, ~m25_3
|
||||
# 29| valnum = unique
|
||||
# 29| r29_8(int) = Add : r29_5, r29_7
|
||||
# 29| valnum = r29_8
|
||||
@@ -203,18 +215,18 @@ test.cpp:
|
||||
# 30| r30_1(glval<unknown>) = FunctionAddress[change_global02] :
|
||||
# 30| valnum = unique
|
||||
# 30| v30_2(void) = Call : func:r30_1
|
||||
# 30| m30_3(unknown) = ^CallSideEffect : ~m25_2
|
||||
# 30| m30_3(unknown) = ^CallSideEffect : ~m25_4
|
||||
# 30| valnum = unique
|
||||
# 30| m30_4(unknown) = Chi : total:m25_2, partial:m30_3
|
||||
# 30| m30_4(unknown) = Chi : total:m25_4, partial:m30_3
|
||||
# 30| valnum = unique
|
||||
# 31| r31_1(glval<int>) = VariableAddress[p0] :
|
||||
# 31| valnum = r25_4
|
||||
# 31| r31_2(int) = Load : &:r31_1, m25_5
|
||||
# 31| valnum = m25_5
|
||||
# 31| r31_3(glval<int>) = VariableAddress[p1] :
|
||||
# 31| valnum = r25_6
|
||||
# 31| r31_4(int) = Load : &:r31_3, m25_7
|
||||
# 31| r31_2(int) = Load : &:r31_1, m25_7
|
||||
# 31| valnum = m25_7
|
||||
# 31| r31_3(glval<int>) = VariableAddress[p1] :
|
||||
# 31| valnum = r25_8
|
||||
# 31| r31_4(int) = Load : &:r31_3, m25_9
|
||||
# 31| valnum = m25_9
|
||||
# 31| r31_5(int) = Add : r31_2, r31_4
|
||||
# 31| valnum = r29_5
|
||||
# 31| r31_6(glval<int>) = VariableAddress[global02] :
|
||||
@@ -236,35 +248,39 @@ test.cpp:
|
||||
# 32| m32_4(int) = Store : &:r32_3, r32_2
|
||||
# 32| valnum = r31_8
|
||||
# 33| v33_1(void) = NoOp :
|
||||
# 25| r25_8(glval<int>) = VariableAddress[#return] :
|
||||
# 25| r25_10(glval<int>) = VariableAddress[#return] :
|
||||
# 25| valnum = unique
|
||||
# 25| v25_9(void) = ReturnValue : &:r25_8
|
||||
# 25| v25_10(void) = UnmodeledUse : mu*
|
||||
# 25| v25_11(void) = AliasedUse : ~m30_4
|
||||
# 25| v25_12(void) = ExitFunction :
|
||||
# 25| v25_11(void) = ReturnValue : &:r25_10
|
||||
# 25| v25_12(void) = UnmodeledUse : mu*
|
||||
# 25| v25_13(void) = AliasedUse : ~m30_4
|
||||
# 25| v25_14(void) = ExitFunction :
|
||||
|
||||
# 39| int test03(int, int, int*)
|
||||
# 39| Block 0
|
||||
# 39| v39_1(void) = EnterFunction :
|
||||
# 39| m39_2(unknown) = AliasedDefinition :
|
||||
# 39| valnum = unique
|
||||
# 39| mu39_3(unknown) = UnmodeledDefinition :
|
||||
# 39| m39_3(unknown) = InitializeNonLocal :
|
||||
# 39| valnum = unique
|
||||
# 39| r39_4(glval<int>) = VariableAddress[p0] :
|
||||
# 39| valnum = r39_4
|
||||
# 39| m39_5(int) = InitializeParameter[p0] : &:r39_4
|
||||
# 39| valnum = m39_5
|
||||
# 39| r39_6(glval<int>) = VariableAddress[p1] :
|
||||
# 39| m39_4(unknown) = Chi : total:m39_2, partial:m39_3
|
||||
# 39| valnum = unique
|
||||
# 39| mu39_5(unknown) = UnmodeledDefinition :
|
||||
# 39| valnum = unique
|
||||
# 39| r39_6(glval<int>) = VariableAddress[p0] :
|
||||
# 39| valnum = r39_6
|
||||
# 39| m39_7(int) = InitializeParameter[p1] : &:r39_6
|
||||
# 39| m39_7(int) = InitializeParameter[p0] : &:r39_6
|
||||
# 39| valnum = m39_7
|
||||
# 39| r39_8(glval<int *>) = VariableAddress[p2] :
|
||||
# 39| r39_8(glval<int>) = VariableAddress[p1] :
|
||||
# 39| valnum = r39_8
|
||||
# 39| m39_9(int *) = InitializeParameter[p2] : &:r39_8
|
||||
# 39| m39_9(int) = InitializeParameter[p1] : &:r39_8
|
||||
# 39| valnum = m39_9
|
||||
# 39| r39_10(int *) = Load : &:r39_8, m39_9
|
||||
# 39| valnum = m39_9
|
||||
# 39| m39_11(unknown) = InitializeIndirection[p2] : &:r39_10
|
||||
# 39| r39_10(glval<int *>) = VariableAddress[p2] :
|
||||
# 39| valnum = r39_10
|
||||
# 39| m39_11(int *) = InitializeParameter[p2] : &:r39_10
|
||||
# 39| valnum = m39_11
|
||||
# 39| r39_12(int *) = Load : &:r39_10, m39_11
|
||||
# 39| valnum = m39_11
|
||||
# 39| m39_13(unknown) = InitializeIndirection[p2] : &:r39_12
|
||||
# 39| valnum = unique
|
||||
# 40| r40_1(glval<int>) = VariableAddress[x] :
|
||||
# 40| valnum = r40_1
|
||||
@@ -279,18 +295,18 @@ test.cpp:
|
||||
# 41| m41_2(unsigned char) = Uninitialized[b] : &:r41_1
|
||||
# 41| valnum = unique
|
||||
# 43| r43_1(glval<int>) = VariableAddress[p0] :
|
||||
# 43| valnum = r39_4
|
||||
# 43| r43_2(int) = Load : &:r43_1, m39_5
|
||||
# 43| valnum = m39_5
|
||||
# 43| r43_3(glval<int>) = VariableAddress[p1] :
|
||||
# 43| valnum = r39_6
|
||||
# 43| r43_4(int) = Load : &:r43_3, m39_7
|
||||
# 43| r43_2(int) = Load : &:r43_1, m39_7
|
||||
# 43| valnum = m39_7
|
||||
# 43| r43_3(glval<int>) = VariableAddress[p1] :
|
||||
# 43| valnum = r39_8
|
||||
# 43| r43_4(int) = Load : &:r43_3, m39_9
|
||||
# 43| valnum = m39_9
|
||||
# 43| r43_5(int) = Add : r43_2, r43_4
|
||||
# 43| valnum = r43_5
|
||||
# 43| r43_6(glval<int>) = VariableAddress[global03] :
|
||||
# 43| valnum = r43_6
|
||||
# 43| r43_7(int) = Load : &:r43_6, ~m39_2
|
||||
# 43| r43_7(int) = Load : &:r43_6, ~m39_3
|
||||
# 43| valnum = unique
|
||||
# 43| r43_8(int) = Add : r43_5, r43_7
|
||||
# 43| valnum = r43_8
|
||||
@@ -301,28 +317,28 @@ test.cpp:
|
||||
# 44| r44_1(int) = Constant[0] :
|
||||
# 44| valnum = r44_1
|
||||
# 44| r44_2(glval<int *>) = VariableAddress[p2] :
|
||||
# 44| valnum = r39_8
|
||||
# 44| r44_3(int *) = Load : &:r44_2, m39_9
|
||||
# 44| valnum = m39_9
|
||||
# 44| valnum = r39_10
|
||||
# 44| r44_3(int *) = Load : &:r44_2, m39_11
|
||||
# 44| valnum = m39_11
|
||||
# 44| r44_4(glval<int>) = CopyValue : r44_3
|
||||
# 44| valnum = m39_9
|
||||
# 44| valnum = m39_11
|
||||
# 44| m44_5(int) = Store : &:r44_4, r44_1
|
||||
# 44| valnum = r44_1
|
||||
# 44| m44_6(unknown) = Chi : total:m39_11, partial:m44_5
|
||||
# 44| m44_6(unknown) = Chi : total:m39_13, partial:m44_5
|
||||
# 44| valnum = unique
|
||||
# 45| r45_1(glval<int>) = VariableAddress[p0] :
|
||||
# 45| valnum = r39_4
|
||||
# 45| r45_2(int) = Load : &:r45_1, m39_5
|
||||
# 45| valnum = m39_5
|
||||
# 45| r45_3(glval<int>) = VariableAddress[p1] :
|
||||
# 45| valnum = r39_6
|
||||
# 45| r45_4(int) = Load : &:r45_3, m39_7
|
||||
# 45| r45_2(int) = Load : &:r45_1, m39_7
|
||||
# 45| valnum = m39_7
|
||||
# 45| r45_3(glval<int>) = VariableAddress[p1] :
|
||||
# 45| valnum = r39_8
|
||||
# 45| r45_4(int) = Load : &:r45_3, m39_9
|
||||
# 45| valnum = m39_9
|
||||
# 45| r45_5(int) = Add : r45_2, r45_4
|
||||
# 45| valnum = r43_5
|
||||
# 45| r45_6(glval<int>) = VariableAddress[global03] :
|
||||
# 45| valnum = r43_6
|
||||
# 45| r45_7(int) = Load : &:r45_6, ~m39_2
|
||||
# 45| r45_7(int) = Load : &:r45_6, ~m39_3
|
||||
# 45| valnum = unique
|
||||
# 45| r45_8(int) = Add : r45_5, r45_7
|
||||
# 45| valnum = r45_8
|
||||
@@ -339,36 +355,40 @@ test.cpp:
|
||||
# 46| m46_4(int) = Store : &:r46_3, r46_2
|
||||
# 46| valnum = r45_8
|
||||
# 47| v47_1(void) = NoOp :
|
||||
# 39| v39_12(void) = ReturnIndirection : &:r39_10, ~m44_6
|
||||
# 39| r39_13(glval<int>) = VariableAddress[#return] :
|
||||
# 39| v39_14(void) = ReturnIndirection : &:r39_12, ~m44_6
|
||||
# 39| r39_15(glval<int>) = VariableAddress[#return] :
|
||||
# 39| valnum = unique
|
||||
# 39| v39_14(void) = ReturnValue : &:r39_13
|
||||
# 39| v39_15(void) = UnmodeledUse : mu*
|
||||
# 39| v39_16(void) = AliasedUse : ~m39_2
|
||||
# 39| v39_17(void) = ExitFunction :
|
||||
# 39| v39_16(void) = ReturnValue : &:r39_15
|
||||
# 39| v39_17(void) = UnmodeledUse : mu*
|
||||
# 39| v39_18(void) = AliasedUse : m39_3
|
||||
# 39| v39_19(void) = ExitFunction :
|
||||
|
||||
# 49| unsigned int my_strspn(char const*, char const*)
|
||||
# 49| Block 0
|
||||
# 49| v49_1(void) = EnterFunction :
|
||||
# 49| m49_2(unknown) = AliasedDefinition :
|
||||
# 49| valnum = unique
|
||||
# 49| mu49_3(unknown) = UnmodeledDefinition :
|
||||
# 49| m49_3(unknown) = InitializeNonLocal :
|
||||
# 49| valnum = unique
|
||||
# 49| r49_4(glval<char *>) = VariableAddress[str] :
|
||||
# 49| valnum = r49_4
|
||||
# 49| m49_5(char *) = InitializeParameter[str] : &:r49_4
|
||||
# 49| valnum = m49_5
|
||||
# 49| r49_6(char *) = Load : &:r49_4, m49_5
|
||||
# 49| valnum = m49_5
|
||||
# 49| m49_7(unknown) = InitializeIndirection[str] : &:r49_6
|
||||
# 49| m49_4(unknown) = Chi : total:m49_2, partial:m49_3
|
||||
# 49| valnum = unique
|
||||
# 49| r49_8(glval<char *>) = VariableAddress[chars] :
|
||||
# 49| valnum = r49_8
|
||||
# 49| m49_9(char *) = InitializeParameter[chars] : &:r49_8
|
||||
# 49| valnum = m49_9
|
||||
# 49| r49_10(char *) = Load : &:r49_8, m49_9
|
||||
# 49| valnum = m49_9
|
||||
# 49| m49_11(unknown) = InitializeIndirection[chars] : &:r49_10
|
||||
# 49| mu49_5(unknown) = UnmodeledDefinition :
|
||||
# 49| valnum = unique
|
||||
# 49| r49_6(glval<char *>) = VariableAddress[str] :
|
||||
# 49| valnum = r49_6
|
||||
# 49| m49_7(char *) = InitializeParameter[str] : &:r49_6
|
||||
# 49| valnum = m49_7
|
||||
# 49| r49_8(char *) = Load : &:r49_6, m49_7
|
||||
# 49| valnum = m49_7
|
||||
# 49| m49_9(unknown) = InitializeIndirection[str] : &:r49_8
|
||||
# 49| valnum = unique
|
||||
# 49| r49_10(glval<char *>) = VariableAddress[chars] :
|
||||
# 49| valnum = r49_10
|
||||
# 49| m49_11(char *) = InitializeParameter[chars] : &:r49_10
|
||||
# 49| valnum = m49_11
|
||||
# 49| r49_12(char *) = Load : &:r49_10, m49_11
|
||||
# 49| valnum = m49_11
|
||||
# 49| m49_13(unknown) = InitializeIndirection[chars] : &:r49_12
|
||||
# 49| valnum = unique
|
||||
# 50| r50_1(glval<char *>) = VariableAddress[ptr] :
|
||||
# 50| valnum = r50_1
|
||||
@@ -386,10 +406,10 @@ test.cpp:
|
||||
# 53| m53_1(unsigned int) = Phi : from 0:m51_3, from 8:m62_5
|
||||
# 53| valnum = m53_1
|
||||
# 53| r53_2(glval<char *>) = VariableAddress[str] :
|
||||
# 53| valnum = r49_4
|
||||
# 53| r53_3(char *) = Load : &:r53_2, m49_5
|
||||
# 53| valnum = m49_5
|
||||
# 53| r53_4(char) = Load : &:r53_3, ~m49_7
|
||||
# 53| valnum = r49_6
|
||||
# 53| r53_3(char *) = Load : &:r53_2, m49_7
|
||||
# 53| valnum = m49_7
|
||||
# 53| r53_4(char) = Load : &:r53_3, ~m49_9
|
||||
# 53| valnum = unique
|
||||
# 53| r53_5(int) = Convert : r53_4
|
||||
# 53| valnum = unique
|
||||
@@ -403,13 +423,13 @@ test.cpp:
|
||||
|
||||
# 55| Block 2
|
||||
# 55| r55_1(glval<char *>) = VariableAddress[chars] :
|
||||
# 55| valnum = r49_8
|
||||
# 55| r55_2(char *) = Load : &:r55_1, m49_9
|
||||
# 55| valnum = m49_9
|
||||
# 55| valnum = r49_10
|
||||
# 55| r55_2(char *) = Load : &:r55_1, m49_11
|
||||
# 55| valnum = m49_11
|
||||
# 55| r55_3(glval<char *>) = VariableAddress[ptr] :
|
||||
# 55| valnum = r50_1
|
||||
# 55| m55_4(char *) = Store : &:r55_3, r55_2
|
||||
# 55| valnum = m49_9
|
||||
# 55| valnum = m49_11
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 56| Block 3
|
||||
@@ -419,15 +439,15 @@ test.cpp:
|
||||
# 56| valnum = r50_1
|
||||
# 56| r56_3(char *) = Load : &:r56_2, m56_1
|
||||
# 56| valnum = m56_1
|
||||
# 56| r56_4(char) = Load : &:r56_3, ~m49_2
|
||||
# 56| r56_4(char) = Load : &:r56_3, ~m49_4
|
||||
# 56| valnum = unique
|
||||
# 56| r56_5(int) = Convert : r56_4
|
||||
# 56| valnum = unique
|
||||
# 56| r56_6(glval<char *>) = VariableAddress[str] :
|
||||
# 56| valnum = r49_4
|
||||
# 56| r56_7(char *) = Load : &:r56_6, m49_5
|
||||
# 56| valnum = m49_5
|
||||
# 56| r56_8(char) = Load : &:r56_7, ~m49_7
|
||||
# 56| valnum = r49_6
|
||||
# 56| r56_7(char *) = Load : &:r56_6, m49_7
|
||||
# 56| valnum = m49_7
|
||||
# 56| r56_8(char) = Load : &:r56_7, ~m49_9
|
||||
# 56| valnum = unique
|
||||
# 56| r56_9(int) = Convert : r56_8
|
||||
# 56| valnum = unique
|
||||
@@ -442,7 +462,7 @@ test.cpp:
|
||||
# 56| valnum = r50_1
|
||||
# 56| r56_13(char *) = Load : &:r56_12, m56_1
|
||||
# 56| valnum = m56_1
|
||||
# 56| r56_14(char) = Load : &:r56_13, ~m49_2
|
||||
# 56| r56_14(char) = Load : &:r56_13, ~m49_4
|
||||
# 56| valnum = unique
|
||||
# 56| r56_15(int) = Convert : r56_14
|
||||
# 56| valnum = unique
|
||||
@@ -472,7 +492,7 @@ test.cpp:
|
||||
# 59| valnum = r50_1
|
||||
# 59| r59_2(char *) = Load : &:r59_1, m56_1
|
||||
# 59| valnum = m56_1
|
||||
# 59| r59_3(char) = Load : &:r59_2, ~m49_2
|
||||
# 59| r59_3(char) = Load : &:r59_2, ~m49_4
|
||||
# 59| valnum = unique
|
||||
# 59| r59_4(int) = Convert : r59_3
|
||||
# 59| valnum = unique
|
||||
@@ -511,29 +531,33 @@ test.cpp:
|
||||
# 65| valnum = m53_1
|
||||
# 65| m65_4(unsigned int) = Store : &:r65_1, r65_3
|
||||
# 65| valnum = m53_1
|
||||
# 49| v49_12(void) = ReturnIndirection : &:r49_6, m49_7
|
||||
# 49| v49_13(void) = ReturnIndirection : &:r49_10, m49_11
|
||||
# 49| r49_14(glval<unsigned int>) = VariableAddress[#return] :
|
||||
# 49| v49_14(void) = ReturnIndirection : &:r49_8, m49_9
|
||||
# 49| v49_15(void) = ReturnIndirection : &:r49_12, m49_13
|
||||
# 49| r49_16(glval<unsigned int>) = VariableAddress[#return] :
|
||||
# 49| valnum = r65_1
|
||||
# 49| v49_15(void) = ReturnValue : &:r49_14, m65_4
|
||||
# 49| v49_16(void) = UnmodeledUse : mu*
|
||||
# 49| v49_17(void) = AliasedUse : ~m49_2
|
||||
# 49| v49_18(void) = ExitFunction :
|
||||
# 49| v49_17(void) = ReturnValue : &:r49_16, m65_4
|
||||
# 49| v49_18(void) = UnmodeledUse : mu*
|
||||
# 49| v49_19(void) = AliasedUse : m49_3
|
||||
# 49| v49_20(void) = ExitFunction :
|
||||
|
||||
# 75| void test04(two_values*)
|
||||
# 75| Block 0
|
||||
# 75| v75_1(void) = EnterFunction :
|
||||
# 75| m75_2(unknown) = AliasedDefinition :
|
||||
# 75| valnum = unique
|
||||
# 75| mu75_3(unknown) = UnmodeledDefinition :
|
||||
# 75| m75_3(unknown) = InitializeNonLocal :
|
||||
# 75| valnum = unique
|
||||
# 75| r75_4(glval<two_values *>) = VariableAddress[vals] :
|
||||
# 75| valnum = r75_4
|
||||
# 75| m75_5(two_values *) = InitializeParameter[vals] : &:r75_4
|
||||
# 75| valnum = m75_5
|
||||
# 75| r75_6(two_values *) = Load : &:r75_4, m75_5
|
||||
# 75| valnum = m75_5
|
||||
# 75| m75_7(unknown) = InitializeIndirection[vals] : &:r75_6
|
||||
# 75| m75_4(unknown) = Chi : total:m75_2, partial:m75_3
|
||||
# 75| valnum = unique
|
||||
# 75| mu75_5(unknown) = UnmodeledDefinition :
|
||||
# 75| valnum = unique
|
||||
# 75| r75_6(glval<two_values *>) = VariableAddress[vals] :
|
||||
# 75| valnum = r75_6
|
||||
# 75| m75_7(two_values *) = InitializeParameter[vals] : &:r75_6
|
||||
# 75| valnum = m75_7
|
||||
# 75| r75_8(two_values *) = Load : &:r75_6, m75_7
|
||||
# 75| valnum = m75_7
|
||||
# 75| m75_9(unknown) = InitializeIndirection[vals] : &:r75_8
|
||||
# 75| valnum = unique
|
||||
# 77| r77_1(glval<signed short>) = VariableAddress[v] :
|
||||
# 77| valnum = r77_1
|
||||
@@ -541,9 +565,9 @@ test.cpp:
|
||||
# 77| valnum = unique
|
||||
# 77| r77_3(int) = Call : func:r77_2
|
||||
# 77| valnum = unique
|
||||
# 77| m77_4(unknown) = ^CallSideEffect : ~m75_2
|
||||
# 77| m77_4(unknown) = ^CallSideEffect : ~m75_4
|
||||
# 77| valnum = unique
|
||||
# 77| m77_5(unknown) = Chi : total:m75_2, partial:m77_4
|
||||
# 77| m77_5(unknown) = Chi : total:m75_4, partial:m77_4
|
||||
# 77| valnum = unique
|
||||
# 77| r77_6(signed short) = Convert : r77_3
|
||||
# 77| valnum = r77_6
|
||||
@@ -556,22 +580,22 @@ test.cpp:
|
||||
# 79| r79_3(int) = Convert : r79_2
|
||||
# 79| valnum = unique
|
||||
# 79| r79_4(glval<two_values *>) = VariableAddress[vals] :
|
||||
# 79| valnum = r75_4
|
||||
# 79| r79_5(two_values *) = Load : &:r79_4, m75_5
|
||||
# 79| valnum = m75_5
|
||||
# 79| valnum = r75_6
|
||||
# 79| r79_5(two_values *) = Load : &:r79_4, m75_7
|
||||
# 79| valnum = m75_7
|
||||
# 79| r79_6(glval<signed short>) = FieldAddress[val1] : r79_5
|
||||
# 79| valnum = unique
|
||||
# 79| r79_7(signed short) = Load : &:r79_6, ~m75_7
|
||||
# 79| r79_7(signed short) = Load : &:r79_6, ~m75_9
|
||||
# 79| valnum = unique
|
||||
# 79| r79_8(int) = Convert : r79_7
|
||||
# 79| valnum = unique
|
||||
# 79| r79_9(glval<two_values *>) = VariableAddress[vals] :
|
||||
# 79| valnum = r75_4
|
||||
# 79| r79_10(two_values *) = Load : &:r79_9, m75_5
|
||||
# 79| valnum = m75_5
|
||||
# 79| valnum = r75_6
|
||||
# 79| r79_10(two_values *) = Load : &:r79_9, m75_7
|
||||
# 79| valnum = m75_7
|
||||
# 79| r79_11(glval<signed short>) = FieldAddress[val2] : r79_10
|
||||
# 79| valnum = unique
|
||||
# 79| r79_12(signed short) = Load : &:r79_11, ~m75_7
|
||||
# 79| r79_12(signed short) = Load : &:r79_11, ~m75_9
|
||||
# 79| valnum = unique
|
||||
# 79| r79_13(int) = Convert : r79_12
|
||||
# 79| valnum = unique
|
||||
@@ -604,48 +628,52 @@ test.cpp:
|
||||
# 82| m82_1(unknown) = Phi : from 0:~m77_5, from 1:~m80_4
|
||||
# 82| valnum = unique
|
||||
# 82| v82_2(void) = NoOp :
|
||||
# 75| v75_8(void) = ReturnIndirection : &:r75_6, m75_7
|
||||
# 75| v75_9(void) = ReturnVoid :
|
||||
# 75| v75_10(void) = UnmodeledUse : mu*
|
||||
# 75| v75_11(void) = AliasedUse : ~m82_1
|
||||
# 75| v75_12(void) = ExitFunction :
|
||||
# 75| v75_10(void) = ReturnIndirection : &:r75_8, m75_9
|
||||
# 75| v75_11(void) = ReturnVoid :
|
||||
# 75| v75_12(void) = UnmodeledUse : mu*
|
||||
# 75| v75_13(void) = AliasedUse : ~m82_1
|
||||
# 75| v75_14(void) = ExitFunction :
|
||||
|
||||
# 84| void test05(int, int, void*)
|
||||
# 84| Block 0
|
||||
# 84| v84_1(void) = EnterFunction :
|
||||
# 84| m84_2(unknown) = AliasedDefinition :
|
||||
# 84| v84_1(void) = EnterFunction :
|
||||
# 84| m84_2(unknown) = AliasedDefinition :
|
||||
# 84| valnum = unique
|
||||
# 84| mu84_3(unknown) = UnmodeledDefinition :
|
||||
# 84| m84_3(unknown) = InitializeNonLocal :
|
||||
# 84| valnum = unique
|
||||
# 84| r84_4(glval<int>) = VariableAddress[x] :
|
||||
# 84| valnum = r84_4
|
||||
# 84| m84_5(int) = InitializeParameter[x] : &:r84_4
|
||||
# 84| valnum = m84_5
|
||||
# 84| r84_6(glval<int>) = VariableAddress[y] :
|
||||
# 84| m84_4(unknown) = Chi : total:m84_2, partial:m84_3
|
||||
# 84| valnum = unique
|
||||
# 84| mu84_5(unknown) = UnmodeledDefinition :
|
||||
# 84| valnum = unique
|
||||
# 84| r84_6(glval<int>) = VariableAddress[x] :
|
||||
# 84| valnum = r84_6
|
||||
# 84| m84_7(int) = InitializeParameter[y] : &:r84_6
|
||||
# 84| m84_7(int) = InitializeParameter[x] : &:r84_6
|
||||
# 84| valnum = m84_7
|
||||
# 84| r84_8(glval<void *>) = VariableAddress[p] :
|
||||
# 84| r84_8(glval<int>) = VariableAddress[y] :
|
||||
# 84| valnum = r84_8
|
||||
# 84| m84_9(void *) = InitializeParameter[p] : &:r84_8
|
||||
# 84| m84_9(int) = InitializeParameter[y] : &:r84_8
|
||||
# 84| valnum = m84_9
|
||||
# 84| r84_10(void *) = Load : &:r84_8, m84_9
|
||||
# 84| valnum = m84_9
|
||||
# 84| m84_11(unknown) = InitializeIndirection[p] : &:r84_10
|
||||
# 84| r84_10(glval<void *>) = VariableAddress[p] :
|
||||
# 84| valnum = r84_10
|
||||
# 84| m84_11(void *) = InitializeParameter[p] : &:r84_10
|
||||
# 84| valnum = m84_11
|
||||
# 84| r84_12(void *) = Load : &:r84_10, m84_11
|
||||
# 84| valnum = m84_11
|
||||
# 84| m84_13(unknown) = InitializeIndirection[p] : &:r84_12
|
||||
# 84| valnum = unique
|
||||
# 86| r86_1(glval<int>) = VariableAddress[v] :
|
||||
# 86| r86_1(glval<int>) = VariableAddress[v] :
|
||||
# 86| valnum = r86_1
|
||||
# 86| m86_2(int) = Uninitialized[v] : &:r86_1
|
||||
# 86| m86_2(int) = Uninitialized[v] : &:r86_1
|
||||
# 86| valnum = unique
|
||||
# 88| r88_1(glval<void *>) = VariableAddress[p] :
|
||||
# 88| valnum = r84_8
|
||||
# 88| r88_2(void *) = Load : &:r88_1, m84_9
|
||||
# 88| valnum = m84_9
|
||||
# 88| r88_3(void *) = Constant[0] :
|
||||
# 88| r88_1(glval<void *>) = VariableAddress[p] :
|
||||
# 88| valnum = r84_10
|
||||
# 88| r88_2(void *) = Load : &:r88_1, m84_11
|
||||
# 88| valnum = m84_11
|
||||
# 88| r88_3(void *) = Constant[0] :
|
||||
# 88| valnum = unique
|
||||
# 88| r88_4(bool) = CompareNE : r88_2, r88_3
|
||||
# 88| r88_4(bool) = CompareNE : r88_2, r88_3
|
||||
# 88| valnum = unique
|
||||
# 88| v88_5(void) = ConditionalBranch : r88_4
|
||||
# 88| v88_5(void) = ConditionalBranch : r88_4
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
@@ -661,32 +689,32 @@ test.cpp:
|
||||
# 88| m88_10(int) = Store : &:r88_9, r88_8
|
||||
# 88| valnum = m88_6
|
||||
# 89| v89_1(void) = NoOp :
|
||||
# 84| v84_12(void) = ReturnIndirection : &:r84_10, m84_11
|
||||
# 84| v84_13(void) = ReturnVoid :
|
||||
# 84| v84_14(void) = UnmodeledUse : mu*
|
||||
# 84| v84_15(void) = AliasedUse : ~m84_2
|
||||
# 84| v84_16(void) = ExitFunction :
|
||||
# 84| v84_14(void) = ReturnIndirection : &:r84_12, m84_13
|
||||
# 84| v84_15(void) = ReturnVoid :
|
||||
# 84| v84_16(void) = UnmodeledUse : mu*
|
||||
# 84| v84_17(void) = AliasedUse : m84_3
|
||||
# 84| v84_18(void) = ExitFunction :
|
||||
|
||||
# 88| Block 2
|
||||
# 88| r88_11(glval<int>) = VariableAddress[x] :
|
||||
# 88| valnum = r84_4
|
||||
# 88| r88_12(int) = Load : &:r88_11, m84_5
|
||||
# 88| valnum = m84_5
|
||||
# 88| valnum = r84_6
|
||||
# 88| r88_12(int) = Load : &:r88_11, m84_7
|
||||
# 88| valnum = m84_7
|
||||
# 88| r88_13(glval<int>) = VariableAddress[#temp88:7] :
|
||||
# 88| valnum = r88_7
|
||||
# 88| m88_14(int) = Store : &:r88_13, r88_12
|
||||
# 88| valnum = m84_5
|
||||
# 88| valnum = m84_7
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 88| Block 3
|
||||
# 88| r88_15(glval<int>) = VariableAddress[y] :
|
||||
# 88| valnum = r84_6
|
||||
# 88| r88_16(int) = Load : &:r88_15, m84_7
|
||||
# 88| valnum = m84_7
|
||||
# 88| valnum = r84_8
|
||||
# 88| r88_16(int) = Load : &:r88_15, m84_9
|
||||
# 88| valnum = m84_9
|
||||
# 88| r88_17(glval<int>) = VariableAddress[#temp88:7] :
|
||||
# 88| valnum = r88_7
|
||||
# 88| m88_18(int) = Store : &:r88_17, r88_16
|
||||
# 88| valnum = m84_7
|
||||
# 88| valnum = m84_9
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 91| int regression_test00()
|
||||
@@ -694,7 +722,11 @@ test.cpp:
|
||||
# 91| v91_1(void) = EnterFunction :
|
||||
# 91| m91_2(unknown) = AliasedDefinition :
|
||||
# 91| valnum = unique
|
||||
# 91| mu91_3(unknown) = UnmodeledDefinition :
|
||||
# 91| m91_3(unknown) = InitializeNonLocal :
|
||||
# 91| valnum = unique
|
||||
# 91| m91_4(unknown) = Chi : total:m91_2, partial:m91_3
|
||||
# 91| valnum = unique
|
||||
# 91| mu91_5(unknown) = UnmodeledDefinition :
|
||||
# 91| valnum = unique
|
||||
# 92| r92_1(glval<int>) = VariableAddress[x] :
|
||||
# 92| valnum = r92_1
|
||||
@@ -716,48 +748,52 @@ test.cpp:
|
||||
# 93| valnum = r92_2
|
||||
# 93| m93_4(int) = Store : &:r93_1, r93_3
|
||||
# 93| valnum = r92_2
|
||||
# 91| r91_4(glval<int>) = VariableAddress[#return] :
|
||||
# 91| r91_6(glval<int>) = VariableAddress[#return] :
|
||||
# 91| valnum = r93_1
|
||||
# 91| v91_5(void) = ReturnValue : &:r91_4, m93_4
|
||||
# 91| v91_6(void) = UnmodeledUse : mu*
|
||||
# 91| v91_7(void) = AliasedUse : ~m91_2
|
||||
# 91| v91_8(void) = ExitFunction :
|
||||
# 91| v91_7(void) = ReturnValue : &:r91_6, m93_4
|
||||
# 91| v91_8(void) = UnmodeledUse : mu*
|
||||
# 91| v91_9(void) = AliasedUse : m91_3
|
||||
# 91| v91_10(void) = ExitFunction :
|
||||
|
||||
# 104| int inheritanceConversions(Derived*)
|
||||
# 104| Block 0
|
||||
# 104| v104_1(void) = EnterFunction :
|
||||
# 104| m104_2(unknown) = AliasedDefinition :
|
||||
# 104| valnum = unique
|
||||
# 104| mu104_3(unknown) = UnmodeledDefinition :
|
||||
# 104| m104_3(unknown) = InitializeNonLocal :
|
||||
# 104| valnum = unique
|
||||
# 104| r104_4(glval<Derived *>) = VariableAddress[pd] :
|
||||
# 104| valnum = r104_4
|
||||
# 104| m104_5(Derived *) = InitializeParameter[pd] : &:r104_4
|
||||
# 104| valnum = m104_5
|
||||
# 104| r104_6(Derived *) = Load : &:r104_4, m104_5
|
||||
# 104| valnum = m104_5
|
||||
# 104| m104_7(unknown) = InitializeIndirection[pd] : &:r104_6
|
||||
# 104| m104_4(unknown) = Chi : total:m104_2, partial:m104_3
|
||||
# 104| valnum = unique
|
||||
# 104| mu104_5(unknown) = UnmodeledDefinition :
|
||||
# 104| valnum = unique
|
||||
# 104| r104_6(glval<Derived *>) = VariableAddress[pd] :
|
||||
# 104| valnum = r104_6
|
||||
# 104| m104_7(Derived *) = InitializeParameter[pd] : &:r104_6
|
||||
# 104| valnum = m104_7
|
||||
# 104| r104_8(Derived *) = Load : &:r104_6, m104_7
|
||||
# 104| valnum = m104_7
|
||||
# 104| m104_9(unknown) = InitializeIndirection[pd] : &:r104_8
|
||||
# 104| valnum = unique
|
||||
# 105| r105_1(glval<int>) = VariableAddress[x] :
|
||||
# 105| valnum = unique
|
||||
# 105| r105_2(glval<Derived *>) = VariableAddress[pd] :
|
||||
# 105| valnum = r104_4
|
||||
# 105| r105_3(Derived *) = Load : &:r105_2, m104_5
|
||||
# 105| valnum = m104_5
|
||||
# 105| valnum = r104_6
|
||||
# 105| r105_3(Derived *) = Load : &:r105_2, m104_7
|
||||
# 105| valnum = m104_7
|
||||
# 105| r105_4(Base *) = ConvertToNonVirtualBase[Derived : Base] : r105_3
|
||||
# 105| valnum = r105_4
|
||||
# 105| r105_5(glval<int>) = FieldAddress[b] : r105_4
|
||||
# 105| valnum = r105_5
|
||||
# 105| r105_6(int) = Load : &:r105_5, ~m104_7
|
||||
# 105| r105_6(int) = Load : &:r105_5, ~m104_9
|
||||
# 105| valnum = r105_6
|
||||
# 105| m105_7(int) = Store : &:r105_1, r105_6
|
||||
# 105| valnum = r105_6
|
||||
# 106| r106_1(glval<Base *>) = VariableAddress[pb] :
|
||||
# 106| valnum = r106_1
|
||||
# 106| r106_2(glval<Derived *>) = VariableAddress[pd] :
|
||||
# 106| valnum = r104_4
|
||||
# 106| r106_3(Derived *) = Load : &:r106_2, m104_5
|
||||
# 106| valnum = m104_5
|
||||
# 106| valnum = r104_6
|
||||
# 106| r106_3(Derived *) = Load : &:r106_2, m104_7
|
||||
# 106| valnum = m104_7
|
||||
# 106| r106_4(Base *) = ConvertToNonVirtualBase[Derived : Base] : r106_3
|
||||
# 106| valnum = r105_4
|
||||
# 106| m106_5(Base *) = Store : &:r106_1, r106_4
|
||||
@@ -770,7 +806,7 @@ test.cpp:
|
||||
# 107| valnum = r105_4
|
||||
# 107| r107_4(glval<int>) = FieldAddress[b] : r107_3
|
||||
# 107| valnum = r105_5
|
||||
# 107| r107_5(int) = Load : &:r107_4, ~m104_7
|
||||
# 107| r107_5(int) = Load : &:r107_4, ~m104_9
|
||||
# 107| valnum = r107_5
|
||||
# 107| m107_6(int) = Store : &:r107_1, r107_5
|
||||
# 107| valnum = r107_5
|
||||
@@ -782,20 +818,24 @@ test.cpp:
|
||||
# 109| valnum = r107_5
|
||||
# 109| m109_4(int) = Store : &:r109_1, r109_3
|
||||
# 109| valnum = r107_5
|
||||
# 104| v104_8(void) = ReturnIndirection : &:r104_6, m104_7
|
||||
# 104| r104_9(glval<int>) = VariableAddress[#return] :
|
||||
# 104| v104_10(void) = ReturnIndirection : &:r104_8, m104_9
|
||||
# 104| r104_11(glval<int>) = VariableAddress[#return] :
|
||||
# 104| valnum = r109_1
|
||||
# 104| v104_10(void) = ReturnValue : &:r104_9, m109_4
|
||||
# 104| v104_11(void) = UnmodeledUse : mu*
|
||||
# 104| v104_12(void) = AliasedUse : ~m104_2
|
||||
# 104| v104_13(void) = ExitFunction :
|
||||
# 104| v104_12(void) = ReturnValue : &:r104_11, m109_4
|
||||
# 104| v104_13(void) = UnmodeledUse : mu*
|
||||
# 104| v104_14(void) = AliasedUse : m104_3
|
||||
# 104| v104_15(void) = ExitFunction :
|
||||
|
||||
# 112| void test06()
|
||||
# 112| Block 0
|
||||
# 112| v112_1(void) = EnterFunction :
|
||||
# 112| m112_2(unknown) = AliasedDefinition :
|
||||
# 112| valnum = unique
|
||||
# 112| mu112_3(unknown) = UnmodeledDefinition :
|
||||
# 112| m112_3(unknown) = InitializeNonLocal :
|
||||
# 112| valnum = unique
|
||||
# 112| m112_4(unknown) = Chi : total:m112_2, partial:m112_3
|
||||
# 112| valnum = unique
|
||||
# 112| mu112_5(unknown) = UnmodeledDefinition :
|
||||
# 112| valnum = unique
|
||||
# 113| r113_1(glval<char[2]>) = StringConstant["a"] :
|
||||
# 113| valnum = r113_1
|
||||
@@ -806,7 +846,7 @@ test.cpp:
|
||||
# 116| r116_1(glval<char[2]>) = StringConstant["c"] :
|
||||
# 116| valnum = unique
|
||||
# 117| v117_1(void) = NoOp :
|
||||
# 112| v112_4(void) = ReturnVoid :
|
||||
# 112| v112_5(void) = UnmodeledUse : mu*
|
||||
# 112| v112_6(void) = AliasedUse : ~m112_2
|
||||
# 112| v112_7(void) = ExitFunction :
|
||||
# 112| v112_6(void) = ReturnVoid :
|
||||
# 112| v112_7(void) = UnmodeledUse : mu*
|
||||
# 112| v112_8(void) = AliasedUse : m112_3
|
||||
# 112| v112_9(void) = ExitFunction :
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ private newtype TOpcode =
|
||||
TUnmodeledDefinition() or
|
||||
TUnmodeledUse() or
|
||||
TAliasedDefinition() or
|
||||
TInitializeNonLocal() or
|
||||
TAliasedUse() or
|
||||
TPhi() or
|
||||
TBuiltIn() or
|
||||
@@ -596,6 +597,14 @@ module Opcode {
|
||||
final override MemoryAccessKind getWriteMemoryAccess() { result instanceof EscapedMemoryAccess }
|
||||
}
|
||||
|
||||
class InitializeNonLocal extends Opcode, TInitializeNonLocal {
|
||||
final override string toString() { result = "InitializeNonLocal" }
|
||||
|
||||
final override MemoryAccessKind getWriteMemoryAccess() {
|
||||
result instanceof NonLocalMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
class AliasedUse extends Opcode, TAliasedUse {
|
||||
final override string toString() { result = "AliasedUse" }
|
||||
|
||||
|
||||
@@ -759,7 +759,21 @@ module DefUse {
|
||||
then defLocation = useLocation
|
||||
else (
|
||||
definitionHasPhiNode(defLocation, block) and
|
||||
defLocation = useLocation.getVirtualVariable()
|
||||
defLocation = useLocation.getVirtualVariable() and
|
||||
// Handle the unusual case where a virtual variable does not overlap one of its member
|
||||
// locations. For example, a definition of the virtual variable representing all aliased
|
||||
// memory does not overlap a use of a string literal, because the contents of a string
|
||||
// literal can never be redefined. The string literal's location could still be a member of
|
||||
// the `AliasedVirtualVariable` due to something like:
|
||||
// ```
|
||||
// char s[10];
|
||||
// strcpy(s, p);
|
||||
// const char* p = b ? "SomeLiteral" : s;
|
||||
// return p[3];
|
||||
// ```
|
||||
// In the above example, `p[3]` may access either the string literal or the local variable
|
||||
// `s`, so both of those locations must be members of the `AliasedVirtualVariable`.
|
||||
exists(Alias::getOverlap(defLocation, useLocation))
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -167,6 +167,7 @@ class CompileTimeConstantExpr extends Expr {
|
||||
/**
|
||||
* Gets the string value of this expression, where possible.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
string getStringValue() {
|
||||
result = this.(StringLiteral).getRepresentedString()
|
||||
or
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2041,12 +2041,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
|
||||
result = getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid |
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = result.getNode() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
result instanceof PathNodeSink and
|
||||
result.getConfiguration() = unbind(mid.getConfiguration())
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
65
java/ql/test/library-tests/dataflow/taint-ioutils/Test.java
Normal file
65
java/ql/test/library-tests/dataflow/taint-ioutils/Test.java
Normal file
@@ -0,0 +1,65 @@
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
class Test {
|
||||
public static void ioutils() {
|
||||
InputStream inp = new FileInputStream("test"); // user input
|
||||
|
||||
InputStream buf = IOUtils.buffer(inp);
|
||||
List<String> lines = IOUtils.readLines(inp, "UTF-8");
|
||||
byte[] bytes = IOUtils.readFully(inp, 1000);
|
||||
InputStream buf2 = IOUtils.toBufferedInputStream(inp);
|
||||
Reader bufread = IOUtils.toBufferedReader(new InputStreamReader(inp));
|
||||
byte[] bytes2 = IOUtils.toByteArray(inp, 1000);
|
||||
char[] chars = IOUtils.toCharArray(inp, "UTF-8");
|
||||
String s = IOUtils.toString(inp, "UTF-8");
|
||||
InputStream is = IOUtils.toInputStream(s, "UTF-8");
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.copy(inp, writer, "UTF-8");
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.copyLarge(bufread, writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
byte x;
|
||||
byte[] tgt = new byte[100];
|
||||
x = tgt[0]; // not tainted
|
||||
IOUtils.read(inp, tgt);
|
||||
x = tgt[0]; // tainted
|
||||
|
||||
tgt = new byte[100];
|
||||
x = tgt[0]; // not tainted
|
||||
IOUtils.readFully(inp, tgt);
|
||||
x = tgt[0]; // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.write(chars, writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.writeChunked(chars, writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.writeLines(lines, "\n", writer);
|
||||
writer.toString(); // tainted
|
||||
|
||||
writer = new StringWriter();
|
||||
writer.toString(); // not tainted
|
||||
IOUtils.writeLines(new ArrayList<String>(), s, writer);
|
||||
writer.toString(); // tainted
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
| Test.java:12:21:12:47 | new FileInputStream(...) |
|
||||
| Test.java:14:21:14:39 | buffer(...) |
|
||||
| Test.java:14:36:14:38 | inp |
|
||||
| Test.java:15:24:15:54 | readLines(...) |
|
||||
| Test.java:15:42:15:44 | inp |
|
||||
| Test.java:16:18:16:45 | readFully(...) |
|
||||
| Test.java:16:36:16:38 | inp |
|
||||
| Test.java:17:22:17:55 | toBufferedInputStream(...) |
|
||||
| Test.java:17:52:17:54 | inp |
|
||||
| Test.java:18:20:18:71 | toBufferedReader(...) |
|
||||
| Test.java:18:45:18:70 | new InputStreamReader(...) |
|
||||
| Test.java:18:67:18:69 | inp |
|
||||
| Test.java:19:19:19:48 | toByteArray(...) |
|
||||
| Test.java:19:39:19:41 | inp |
|
||||
| Test.java:20:18:20:50 | toCharArray(...) |
|
||||
| Test.java:20:38:20:40 | inp |
|
||||
| Test.java:21:14:21:43 | toString(...) |
|
||||
| Test.java:21:31:21:33 | inp |
|
||||
| Test.java:22:20:22:52 | toInputStream(...) |
|
||||
| Test.java:22:42:22:42 | s |
|
||||
| Test.java:26:16:26:18 | inp |
|
||||
| Test.java:26:21:26:26 | writer |
|
||||
| Test.java:27:3:27:8 | writer |
|
||||
| Test.java:27:3:27:19 | toString(...) |
|
||||
| Test.java:31:21:31:27 | bufread |
|
||||
| Test.java:31:30:31:35 | writer |
|
||||
| Test.java:32:3:32:8 | writer |
|
||||
| Test.java:32:3:32:19 | toString(...) |
|
||||
| Test.java:37:16:37:18 | inp |
|
||||
| Test.java:37:21:37:23 | tgt |
|
||||
| Test.java:38:3:38:12 | ...=... |
|
||||
| Test.java:38:7:38:9 | tgt |
|
||||
| Test.java:38:7:38:12 | ...[...] |
|
||||
| Test.java:42:21:42:23 | inp |
|
||||
| Test.java:42:26:42:28 | tgt |
|
||||
| Test.java:43:3:43:12 | ...=... |
|
||||
| Test.java:43:7:43:9 | tgt |
|
||||
| Test.java:43:7:43:12 | ...[...] |
|
||||
| Test.java:47:17:47:21 | chars |
|
||||
| Test.java:47:24:47:29 | writer |
|
||||
| Test.java:48:3:48:8 | writer |
|
||||
| Test.java:48:3:48:19 | toString(...) |
|
||||
| Test.java:52:24:52:28 | chars |
|
||||
| Test.java:52:31:52:36 | writer |
|
||||
| Test.java:53:3:53:8 | writer |
|
||||
| Test.java:53:3:53:19 | toString(...) |
|
||||
| Test.java:57:22:57:26 | lines |
|
||||
| Test.java:57:35:57:40 | writer |
|
||||
| Test.java:58:3:58:8 | writer |
|
||||
| Test.java:58:3:58:19 | toString(...) |
|
||||
| Test.java:62:47:62:47 | s |
|
||||
| Test.java:62:50:62:55 | writer |
|
||||
| Test.java:63:3:63:8 | writer |
|
||||
| Test.java:63:3:63:19 | toString(...) |
|
||||
@@ -0,0 +1,15 @@
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:dataflow:ioutils" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof UserInput }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { any() }
|
||||
}
|
||||
|
||||
from UserInput u, DataFlow::Node e, Conf config
|
||||
where config.hasFlow(u, e) and e.getEnclosingCallable().hasName("ioutils")
|
||||
select e
|
||||
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-commons-io-2.6
|
||||
159
java/ql/test/library-tests/dataflow/taint/B.java
Normal file
159
java/ql/test/library-tests/dataflow/taint/B.java
Normal file
@@ -0,0 +1,159 @@
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class B {
|
||||
public static String[] taint() { return new String[] { "tainted" }; }
|
||||
|
||||
public static void sink(Object o) { }
|
||||
|
||||
public static void maintest() {
|
||||
String[] args = taint();
|
||||
// tainted - access to main args
|
||||
String[] aaaargs = args;
|
||||
sink(aaaargs);
|
||||
// tainted - access to tainted array
|
||||
String s = args[0];
|
||||
sink(s);
|
||||
// tainted - concatenation of tainted string
|
||||
String concat = "Look at me " + s + ", I'm tainted!";
|
||||
sink(concat);
|
||||
// tainted - parenthesised
|
||||
String pars = (concat);
|
||||
sink(pars);
|
||||
// tainted method argument, implies tainted return value
|
||||
String method = tainty(pars);
|
||||
sink(method);
|
||||
// tainted - complex
|
||||
String complex = ("Look at me " + args[0]) + ", I'm tainted!";
|
||||
sink(complex);
|
||||
// tainted - data preserving constructors
|
||||
String constructed = new String(complex);
|
||||
sink(constructed);
|
||||
// tainted - unsafe escape
|
||||
String badEscape = constructed.replaceAll("(<script>)", "");
|
||||
sink(badEscape);
|
||||
// tainted - tokenized string
|
||||
String token = new StringTokenizer(badEscape).nextToken();
|
||||
sink(token);
|
||||
|
||||
// not tainted
|
||||
String safe = notTainty(complex);
|
||||
sink(safe);
|
||||
String shouldBeFine = taintyOtherArg(safe, complex);
|
||||
sink(shouldBeFine);
|
||||
// non-whitelisted constructors don't pass taint
|
||||
StringWrapper herring = new StringWrapper(complex);
|
||||
sink(herring);
|
||||
|
||||
// tainted equality check with constant
|
||||
boolean cond = "foo" == s;
|
||||
sink(cond);
|
||||
// tainted logic with tainted operand
|
||||
boolean logic = cond && safe();
|
||||
sink(logic);
|
||||
// tainted condition
|
||||
sink(concat.endsWith("I'm tainted"));
|
||||
// tainted
|
||||
logic = safe() || cond;
|
||||
sink(logic);
|
||||
// tainted, use of equals
|
||||
logic = badEscape.equals("constant");
|
||||
sink(logic);
|
||||
|
||||
// not tainted
|
||||
boolean okay = s == shouldBeFine;
|
||||
sink(okay);
|
||||
|
||||
// methods on string that pass on taint
|
||||
String trimmed = s.trim();
|
||||
sink(trimmed);
|
||||
String[] split = s.split(" ");
|
||||
sink(split);
|
||||
String lower = s.toLowerCase();
|
||||
sink(lower);
|
||||
String upper = s.toUpperCase();
|
||||
sink(upper);
|
||||
byte[] bytes = s.getBytes("UTF-8");
|
||||
sink(bytes);
|
||||
String toString = s.toString();
|
||||
sink(toString);
|
||||
String subs = s.substring(1, 10);
|
||||
sink(subs);
|
||||
String repl = "some constant".replace(" ", s);
|
||||
sink(repl);
|
||||
String replAll = "some constant".replaceAll(" ", s);
|
||||
sink(replAll);
|
||||
String replFirst = "some constant".replaceFirst(" ", s);
|
||||
sink(replFirst);
|
||||
|
||||
ByteArrayOutputStream baos = null;
|
||||
ObjectOutput oos = null;
|
||||
ByteArrayInputStream bais = null;
|
||||
ObjectInputStream ois = null;
|
||||
try
|
||||
{
|
||||
// serialization of tainted string
|
||||
baos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(s);
|
||||
byte[] serializedData = baos.toByteArray(); // tainted
|
||||
sink(serializedData);
|
||||
// serialization of fixed string
|
||||
baos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("not tainted");
|
||||
byte[] serializedData2 = baos.toByteArray(); // *not* tainted
|
||||
sink(serializedData2);
|
||||
|
||||
// de-serialization of tainted string
|
||||
bais = new ByteArrayInputStream(serializedData);
|
||||
ois = new ObjectInputStream(bais);
|
||||
String deserializedData = (String)ois.readObject(); // tainted
|
||||
sink(deserializedData);
|
||||
} catch (IOException e) {
|
||||
// ignored in test code
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignored in test code
|
||||
}
|
||||
|
||||
// tainted array initializers
|
||||
String[] taintedArray = new String[] { s };
|
||||
sink(taintedArray);
|
||||
String[][] taintedArray2 = new String[][] { { s } };
|
||||
sink(taintedArray2);
|
||||
String[][][] taintedArray3 = new String[][][] { { { s } } };
|
||||
sink(taintedArray3);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public static String tainty(String arg) {
|
||||
// tainted return value
|
||||
return arg;
|
||||
}
|
||||
|
||||
public static String taintyOtherArg(String safe, String tainted) {
|
||||
return safe;
|
||||
}
|
||||
|
||||
public static String notTainty(String arg) {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public static class StringWrapper {
|
||||
public String wrapped;
|
||||
|
||||
public StringWrapper(String s) {
|
||||
this.wrapped = s;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean safe() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
38
java/ql/test/library-tests/dataflow/taint/MethodFlow.java
Normal file
38
java/ql/test/library-tests/dataflow/taint/MethodFlow.java
Normal file
@@ -0,0 +1,38 @@
|
||||
public class MethodFlow {
|
||||
public static String taint() { return "tainted"; }
|
||||
|
||||
public static void sink(String s) { }
|
||||
|
||||
public void test() {
|
||||
String tainted = taint();
|
||||
sink(tainted);
|
||||
String tainted2 = notNull(taint());
|
||||
sink(tainted2);
|
||||
String tainted3 = wrapNotNull(taint());
|
||||
sink(tainted3);
|
||||
|
||||
String safe = notNull("a constant");
|
||||
sink(safe);
|
||||
|
||||
String diffString = returnDiffString(taint());
|
||||
sink(diffString);
|
||||
}
|
||||
|
||||
public <T> T notNull(T x) {
|
||||
if (x == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public <T> T wrapNotNull(T x) {
|
||||
T res = notNull(x);
|
||||
sink("Logged: " + res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public String returnDiffString(String x) {
|
||||
sink("Received: " + x);
|
||||
return "OK";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
public class StringBuilderTests {
|
||||
public static String taint() { return "tainted"; }
|
||||
|
||||
public static void sink(String s) { }
|
||||
|
||||
static void stringBuilderBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append(taint());
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderOkay() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append("fred");
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBufferBad() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append(taint());
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderNoVarBad() {
|
||||
sink(new StringBuilder()
|
||||
.append("from preferences select locale where user='")
|
||||
.append(taint())
|
||||
.append("'").toString()
|
||||
);
|
||||
}
|
||||
|
||||
static void stringBuilderConstructorBad() {
|
||||
StringBuilder sb = new StringBuilder(taint());
|
||||
sb.append("from preferences select locale where user='");
|
||||
sb.append("fred");
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderMultipleAppendsBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='").append(taint());
|
||||
sb.append("'");
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderReplaceBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user='placeholder'");
|
||||
sb.replace(45, 57, taint());
|
||||
sink(sb.toString());
|
||||
}
|
||||
|
||||
static void stringBuilderInsertBad() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("from preferences select locale where user=''");
|
||||
sb.insert(45, taint());
|
||||
sink(sb.toString());
|
||||
}
|
||||
}
|
||||
26
java/ql/test/library-tests/dataflow/taint/Varargs.java
Normal file
26
java/ql/test/library-tests/dataflow/taint/Varargs.java
Normal file
@@ -0,0 +1,26 @@
|
||||
public class Varargs {
|
||||
public String taint() { return "tainted"; }
|
||||
|
||||
public void sink(String s) { }
|
||||
|
||||
public void sources() {
|
||||
f1(taint());
|
||||
f2(taint(), taint());
|
||||
f3(new String[] { taint(), "" });
|
||||
}
|
||||
|
||||
public void f1(String... ss) {
|
||||
String s = ss[0];
|
||||
sink(s);
|
||||
}
|
||||
|
||||
public void f2(String... ss) {
|
||||
String s = ss[0];
|
||||
sink(s);
|
||||
}
|
||||
|
||||
public void f3(String... ss) {
|
||||
String s = ss[0];
|
||||
sink(s);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,47 @@
|
||||
| A.java:10:19:10:25 | taint(...) | A.java:15:10:15:11 | b2 |
|
||||
| A.java:20:19:20:25 | taint(...) | A.java:25:10:25:11 | b2 |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:18:10:18:16 | aaaargs |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:21:10:21:10 | s |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:24:10:24:15 | concat |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:27:10:27:13 | pars |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:30:10:30:15 | method |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:33:10:33:16 | complex |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:36:10:36:20 | constructed |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:39:10:39:18 | badEscape |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:42:10:42:14 | token |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:55:10:55:13 | cond |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:58:10:58:14 | logic |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:60:10:60:39 | endsWith(...) |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:63:10:63:14 | logic |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:66:10:66:14 | logic |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:74:10:74:16 | trimmed |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:76:10:76:14 | split |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:78:10:78:14 | lower |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:80:10:80:14 | upper |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:82:10:82:14 | bytes |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:84:10:84:17 | toString |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:86:10:86:13 | subs |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:88:10:88:13 | repl |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:90:10:90:16 | replAll |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:92:10:92:18 | replFirst |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:105:12:105:25 | serializedData |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:117:12:117:27 | deserializedData |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:126:10:126:21 | taintedArray |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:128:10:128:22 | taintedArray2 |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:130:10:130:22 | taintedArray3 |
|
||||
| MethodFlow.java:7:22:7:28 | taint(...) | MethodFlow.java:8:10:8:16 | tainted |
|
||||
| MethodFlow.java:9:31:9:37 | taint(...) | MethodFlow.java:10:10:10:17 | tainted2 |
|
||||
| MethodFlow.java:11:35:11:41 | taint(...) | MethodFlow.java:12:10:12:17 | tainted3 |
|
||||
| MethodFlow.java:11:35:11:41 | taint(...) | MethodFlow.java:30:10:30:25 | ... + ... |
|
||||
| MethodFlow.java:17:42:17:48 | taint(...) | MethodFlow.java:35:10:35:25 | ... + ... |
|
||||
| StringBuilderTests.java:9:15:9:21 | taint(...) | StringBuilderTests.java:11:10:11:22 | toString(...) |
|
||||
| StringBuilderTests.java:25:15:25:21 | taint(...) | StringBuilderTests.java:27:10:27:22 | toString(...) |
|
||||
| StringBuilderTests.java:33:15:33:21 | taint(...) | StringBuilderTests.java:31:10:34:29 | toString(...) |
|
||||
| StringBuilderTests.java:39:42:39:48 | taint(...) | StringBuilderTests.java:43:10:43:22 | toString(...) |
|
||||
| StringBuilderTests.java:48:69:48:75 | taint(...) | StringBuilderTests.java:50:10:50:22 | toString(...) |
|
||||
| StringBuilderTests.java:56:24:56:30 | taint(...) | StringBuilderTests.java:57:10:57:22 | toString(...) |
|
||||
| StringBuilderTests.java:63:19:63:25 | taint(...) | StringBuilderTests.java:64:10:64:22 | toString(...) |
|
||||
| Varargs.java:7:8:7:14 | taint(...) | Varargs.java:14:10:14:10 | s |
|
||||
| Varargs.java:8:8:8:14 | taint(...) | Varargs.java:19:10:19:10 | s |
|
||||
| Varargs.java:8:17:8:23 | taint(...) | Varargs.java:19:10:19:10 | s |
|
||||
| Varargs.java:9:23:9:29 | taint(...) | Varargs.java:24:10:24:10 | s |
|
||||
|
||||
49
java/ql/test/library-tests/dataflow/taintsources/A.java
Normal file
49
java/ql/test/library-tests/dataflow/taintsources/A.java
Normal file
@@ -0,0 +1,49 @@
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class A {
|
||||
public static void main(String[] args) {
|
||||
String[] a = args; // user input
|
||||
String s = args[0]; // user input
|
||||
}
|
||||
|
||||
public static void userInput() throws SQLException, IOException, MalformedURLException {
|
||||
System.getenv("test"); // user input
|
||||
class TestServlet extends HttpServlet {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
req.getParameter("test"); // remote user input
|
||||
req.getHeader("test"); // remote user input
|
||||
req.getQueryString(); // remote user input
|
||||
req.getCookies()[0].getValue(); // remote user input
|
||||
}
|
||||
}
|
||||
new Properties().getProperty("test"); // user input
|
||||
System.getProperty("test"); // user input
|
||||
new Object() {
|
||||
public void test(ResultSet rs) throws SQLException {
|
||||
rs.getString(0); // user input
|
||||
}
|
||||
};
|
||||
new URL("test").openConnection().getInputStream(); // remote user input
|
||||
new Socket("test", 1234).getInputStream(); // remote user input
|
||||
InetAddress.getByName("test").getHostName(); // remote user input
|
||||
|
||||
System.in.read(); // user input
|
||||
new FileInputStream("test").read(); // user input
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package security.library.dataflow;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
public interface RmiFlow extends Remote {
|
||||
String listDirectory(String path);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package security.library.dataflow;
|
||||
|
||||
public class RmiFlowImpl implements RmiFlow {
|
||||
public String listDirectory(String path) {
|
||||
String command = "ls " + path;
|
||||
Runtime.getRuntime().exec(command);
|
||||
return "pretend there are some results here";
|
||||
}
|
||||
|
||||
public String notRemotable(String path) {
|
||||
String command = "ls " + path;
|
||||
Runtime.getRuntime().exec(command);
|
||||
return "pretend there are some results here";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
| A.java:17:27:17:39 | args | A.java:17:27:17:39 | args |
|
||||
| A.java:17:27:17:39 | args | A.java:18:18:18:21 | args |
|
||||
| A.java:17:27:17:39 | args | A.java:19:16:19:19 | args |
|
||||
| A.java:17:27:17:39 | args | A.java:19:16:19:22 | ...[...] |
|
||||
| A.java:23:5:23:25 | getenv(...) | A.java:23:5:23:25 | getenv(...) |
|
||||
| A.java:34:5:34:40 | getProperty(...) | A.java:34:5:34:40 | getProperty(...) |
|
||||
| A.java:35:5:35:30 | getProperty(...) | A.java:35:5:35:30 | getProperty(...) |
|
||||
| A.java:38:9:38:23 | getString(...) | A.java:38:9:38:23 | getString(...) |
|
||||
| A.java:45:5:45:13 | System.in | A.java:45:5:45:13 | System.in |
|
||||
| A.java:46:5:46:31 | new FileInputStream(...) | A.java:46:5:46:31 | new FileInputStream(...) |
|
||||
18
java/ql/test/library-tests/dataflow/taintsources/local.ql
Normal file
18
java/ql/test/library-tests/dataflow/taintsources/local.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "remote taint conf" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n instanceof UserInput and
|
||||
not n instanceof RemoteFlowSource
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node n) { any() }
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink, Conf conf
|
||||
where conf.hasFlow(src, sink)
|
||||
select src, sink
|
||||
1
java/ql/test/library-tests/dataflow/taintsources/options
Normal file
1
java/ql/test/library-tests/dataflow/taintsources/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4
|
||||
@@ -0,0 +1,11 @@
|
||||
| A.java:28:9:28:32 | getParameter(...) | A.java:28:9:28:32 | getParameter(...) |
|
||||
| A.java:29:9:29:29 | getHeader(...) | A.java:29:9:29:29 | getHeader(...) |
|
||||
| A.java:30:9:30:28 | getQueryString(...) | A.java:30:9:30:28 | getQueryString(...) |
|
||||
| A.java:31:9:31:38 | getValue(...) | A.java:31:9:31:38 | getValue(...) |
|
||||
| A.java:41:5:41:53 | getInputStream(...) | A.java:41:5:41:53 | getInputStream(...) |
|
||||
| A.java:42:5:42:45 | getInputStream(...) | A.java:42:5:42:45 | getInputStream(...) |
|
||||
| A.java:43:5:43:47 | getHostName(...) | A.java:43:5:43:47 | getHostName(...) |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:4:30:4:40 | path |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:20:5:31 | ... + ... |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:28:5:31 | path |
|
||||
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:6:29:6:35 | command |
|
||||
15
java/ql/test/library-tests/dataflow/taintsources/remote.ql
Normal file
15
java/ql/test/library-tests/dataflow/taintsources/remote.ql
Normal file
@@ -0,0 +1,15 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "remote taint conf" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) { n instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) { any() }
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink, Conf conf
|
||||
where conf.hasFlow(src, sink)
|
||||
select src, sink
|
||||
14
java/ql/test/stubs/apache-commons-io-2.6/LICENSE.txt
Normal file
14
java/ql/test/stubs/apache-commons-io-2.6/LICENSE.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.apache.commons.io;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class IOUtils {
|
||||
public static BufferedInputStream buffer(InputStream inputStream) { return null; }
|
||||
public static void copy(InputStream input, Writer output, String inputEncoding) throws IOException { }
|
||||
public static long copyLarge(Reader input, Writer output) throws IOException { return 42; }
|
||||
public static int read(InputStream input, byte[] buffer) throws IOException { return 42; }
|
||||
public static void readFully(InputStream input, byte[] buffer) throws IOException { }
|
||||
public static byte[] readFully(InputStream input, int length) throws IOException { return null; }
|
||||
public static List<String> readLines(InputStream input, String encoding) throws IOException { return null; }
|
||||
public static InputStream toBufferedInputStream(InputStream input) throws IOException { return null; }
|
||||
public static BufferedReader toBufferedReader(Reader reader) { return null; }
|
||||
public static byte[] toByteArray(InputStream input, int size) throws IOException { return null; }
|
||||
public static char[] toCharArray(InputStream is, String encoding) throws IOException { return null; }
|
||||
public static InputStream toInputStream(String input, String encoding) throws IOException { return null; }
|
||||
public static String toString(InputStream input, String encoding) throws IOException { return null; }
|
||||
public static void write(char[] data, Writer output) throws IOException { }
|
||||
public static void writeChunked(char[] data, Writer output) throws IOException { }
|
||||
public static void writeLines(Collection<?> lines, String lineEnding, Writer writer) throws IOException { }
|
||||
}
|
||||
@@ -1045,4 +1045,25 @@ module NodeJSLib {
|
||||
i = 0 and result = this.getArgument(i)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides predicates for working with the "path" module and its platform-specific instances as a single module.
|
||||
*/
|
||||
module Path {
|
||||
/**
|
||||
* Gets a node that imports the "path" module, or one of its platform-specific instances.
|
||||
*/
|
||||
DataFlow::SourceNode moduleImport() {
|
||||
result = DataFlow::moduleImport("path") or
|
||||
result = DataFlow::moduleMember("path", "posix") or
|
||||
result = DataFlow::moduleMember("path", "win32")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an access to member `member` of the "path" module, or one of its platform-specific instances.
|
||||
*/
|
||||
DataFlow::SourceNode moduleMember(string member) {
|
||||
result = moduleImport().getAPropertyRead(member)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,4 +401,33 @@ private module ClosureLibraryUri {
|
||||
succ = uri
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes for working with [path](https://nodejs.org/api/path.html) code.
|
||||
*/
|
||||
module path {
|
||||
/**
|
||||
* A taint step in the path module.
|
||||
*/
|
||||
private class Step extends UriLibraryStep, DataFlow::CallNode {
|
||||
DataFlow::Node src;
|
||||
|
||||
Step() {
|
||||
exists(DataFlow::SourceNode ref |
|
||||
ref = NodeJSLib::Path::moduleMember("parse") or
|
||||
// a ponyfill: https://www.npmjs.com/package/path-parse
|
||||
ref = DataFlow::moduleImport("path-parse") or
|
||||
ref = DataFlow::moduleMember("path-parse", "posix") or
|
||||
ref = DataFlow::moduleMember("path-parse", "win32")
|
||||
|
|
||||
this = ref.getACall() and
|
||||
src = getAnArgument()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
pred = src and succ = this
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ module TaintedPath {
|
||||
or
|
||||
// path.join()
|
||||
exists(DataFlow::CallNode join, int n |
|
||||
join = DataFlow::moduleMember("path", "join").getACall()
|
||||
join = NodeJSLib::Path::moduleMember("join").getACall()
|
||||
|
|
||||
src = join.getArgument(n) and
|
||||
dst = join and
|
||||
|
||||
@@ -124,7 +124,7 @@ module TaintedPath {
|
||||
DataFlow::Node output;
|
||||
|
||||
NormalizingPathCall() {
|
||||
this = DataFlow::moduleMember("path", "normalize").getACall() and
|
||||
this = NodeJSLib::Path::moduleMember("normalize").getACall() and
|
||||
input = getArgument(0) and
|
||||
output = this
|
||||
}
|
||||
@@ -148,7 +148,7 @@ module TaintedPath {
|
||||
DataFlow::Node output;
|
||||
|
||||
ResolvingPathCall() {
|
||||
this = DataFlow::moduleMember("path", "resolve").getACall() and
|
||||
this = NodeJSLib::Path::moduleMember("resolve").getACall() and
|
||||
input = getAnArgument() and
|
||||
output = this
|
||||
or
|
||||
@@ -180,7 +180,7 @@ module TaintedPath {
|
||||
DataFlow::Node output;
|
||||
|
||||
NormalizingRelativePathCall() {
|
||||
this = DataFlow::moduleMember("path", "relative").getACall() and
|
||||
this = NodeJSLib::Path::moduleMember("relative").getACall() and
|
||||
input = getAnArgument() and
|
||||
output = this
|
||||
}
|
||||
@@ -205,7 +205,7 @@ module TaintedPath {
|
||||
|
||||
PreservingPathCall() {
|
||||
exists(string name | name = "dirname" or name = "toNamespacedPath" |
|
||||
this = DataFlow::moduleMember("path", name).getACall() and
|
||||
this = NodeJSLib::Path::moduleMember(name).getACall() and
|
||||
input = getAnArgument() and
|
||||
output = this
|
||||
)
|
||||
@@ -244,7 +244,7 @@ module TaintedPath {
|
||||
// ".." + path.sep
|
||||
exists(StringOps::Concatenation conc | node = conc |
|
||||
conc.getOperand(0).getStringValue() = ".." and
|
||||
conc.getOperand(1).getALocalSource() = DataFlow::moduleMember("path", "sep") and
|
||||
conc.getOperand(1).getALocalSource() = NodeJSLib::Path::moduleMember("sep") and
|
||||
conc.getNumOperand() = 2
|
||||
)
|
||||
}
|
||||
@@ -311,7 +311,7 @@ module TaintedPath {
|
||||
|
||||
IsAbsoluteSanitizer() {
|
||||
exists(DataFlow::CallNode call | this = call |
|
||||
call = DataFlow::moduleMember("path", "isAbsolute").getACall() and
|
||||
call = NodeJSLib::Path::moduleMember("isAbsolute").getACall() and
|
||||
operand = call.getArgument(0) and
|
||||
polarity = true and
|
||||
negatable = true
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
| closureUri.js:23:1:23:18 | utils.getPath(uri) | closureUri.js:23:15:23:17 | uri | closureUri.js:23:1:23:18 | utils.getPath(uri) |
|
||||
| closureUri.js:27:1:27:23 | stringU ... code(x) | closureUri.js:27:22:27:22 | x | closureUri.js:27:1:27:23 | stringU ... code(x) |
|
||||
| closureUri.js:28:1:28:23 | stringU ... code(x) | closureUri.js:28:22:28:22 | x | closureUri.js:28:1:28:23 | stringU ... code(x) |
|
||||
| path-parse.js:4:1:4:13 | path.parse(x) | path-parse.js:4:12:4:12 | x | path-parse.js:4:1:4:13 | path.parse(x) |
|
||||
| path-parse.js:5:1:5:13 | path_parse(x) | path-parse.js:5:12:5:12 | x | path-parse.js:5:1:5:13 | path_parse(x) |
|
||||
| path-parse.js:6:1:6:19 | path.posix.parse(x) | path-parse.js:6:18:6:18 | x | path-parse.js:6:1:6:19 | path.posix.parse(x) |
|
||||
| path-parse.js:7:1:7:19 | path_parse.posix(x) | path-parse.js:7:18:7:18 | x | path-parse.js:7:1:7:19 | path_parse.posix(x) |
|
||||
| path-parse.js:8:1:8:19 | path.win32.parse(x) | path-parse.js:8:18:8:18 | x | path-parse.js:8:1:8:19 | path.win32.parse(x) |
|
||||
| path-parse.js:9:1:9:19 | path_parse.win32(x) | path-parse.js:9:18:9:18 | x | path-parse.js:9:1:9:19 | path_parse.win32(x) |
|
||||
| punycode.js:3:9:3:26 | punycode.decode(x) | punycode.js:3:25:3:25 | x | punycode.js:3:9:3:26 | punycode.decode(x) |
|
||||
| punycode.js:5:5:5:22 | punycode.encode(x) | punycode.js:5:21:5:21 | x | punycode.js:5:5:5:22 | punycode.encode(x) |
|
||||
| punycode.js:7:5:7:25 | punycod ... code(x) | punycode.js:7:24:7:24 | x | punycode.js:7:5:7:25 | punycod ... code(x) |
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const path = require('path');
|
||||
const path_parse = require('path-parse');
|
||||
|
||||
path.parse(x);
|
||||
path_parse(x);
|
||||
path.posix.parse(x);
|
||||
path_parse.posix(x);
|
||||
path.win32.parse(x);
|
||||
path_parse.win32(x);
|
||||
Reference in New Issue
Block a user