mirror of
https://github.com/github/codeql.git
synced 2026-07-06 12:05:31 +02:00
Compare commits
84 Commits
codeql-cli
...
rdmarsh2/c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ddacf55a5 | ||
|
|
ba1005f875 | ||
|
|
99b21b3d79 | ||
|
|
5b51fcbd3d | ||
|
|
e13ae70eeb | ||
|
|
9f17bd0d89 | ||
|
|
86bb9c38ce | ||
|
|
dc105b404b | ||
|
|
fac28ccbe0 | ||
|
|
06afe9c0f4 | ||
|
|
2e2621adad | ||
|
|
ba1ad00d2a | ||
|
|
c7aa58252a | ||
|
|
12eab3d7f0 | ||
|
|
014dcd1454 | ||
|
|
5d9b25c75d | ||
|
|
1c0f2251e2 | ||
|
|
4cd90a15d0 | ||
|
|
28d95f4d99 | ||
|
|
f1799ae3d2 | ||
|
|
27fcc90a97 | ||
|
|
a50234adb0 | ||
|
|
5e3cb08ed2 | ||
|
|
1a7d3ee831 | ||
|
|
afadcd9b45 | ||
|
|
d96d6721ba | ||
|
|
de8384d904 | ||
|
|
305a23b952 | ||
|
|
f7846a598e | ||
|
|
7e0bd5bde4 | ||
|
|
df9a9f4a56 | ||
|
|
9b257bfa9e | ||
|
|
ca299b9dc1 | ||
|
|
31e15e27fc | ||
|
|
778879908e | ||
|
|
60908de089 | ||
|
|
20625ae60d | ||
|
|
b5458b2125 | ||
|
|
9cdd8cc8f5 | ||
|
|
9395f156de | ||
|
|
684a987abf | ||
|
|
54268f4424 | ||
|
|
8899c1be04 | ||
|
|
280b101caa | ||
|
|
034d197e01 | ||
|
|
2d0a4c3d83 | ||
|
|
5a0183f1e2 | ||
|
|
151529d08f | ||
|
|
b5f3cd7a55 | ||
|
|
49a3e208d7 | ||
|
|
52171d6733 | ||
|
|
ea11f744e1 | ||
|
|
064c9a6938 | ||
|
|
678e433013 | ||
|
|
ea2777fa3e | ||
|
|
55c8863e92 | ||
|
|
3553f3d9b8 | ||
|
|
39c1832995 | ||
|
|
cc41a83a8d | ||
|
|
b471a401cc | ||
|
|
698ccd8850 | ||
|
|
5a312cd0da | ||
|
|
b1c9843d15 | ||
|
|
594fbc678e | ||
|
|
e52fa9a469 | ||
|
|
049af68bc2 | ||
|
|
0aebc90b61 | ||
|
|
bcf4c57060 | ||
|
|
d052b1e3c9 | ||
|
|
26fcf6b25b | ||
|
|
de3e1c39e4 | ||
|
|
473bc92e2d | ||
|
|
af2c96f344 | ||
|
|
7c4d3800b6 | ||
|
|
5c11062d21 | ||
|
|
83af49c72f | ||
|
|
e0cfbb53dc | ||
|
|
844aabe3d6 | ||
|
|
c09c38c9a8 | ||
|
|
d324969d68 | ||
|
|
4ae218729a | ||
|
|
cc8e65f811 | ||
|
|
76b292da6a | ||
|
|
0b691dd46c |
4
cpp/ql/lib/change-notes/2022-08-01-gvn-functions.md
Normal file
4
cpp/ql/lib/change-notes/2022-08-01-gvn-functions.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Multiple function calls made in the same function may now receive the same global value number when the analysis can show they produce the same results.
|
||||||
@@ -1712,6 +1712,11 @@ class SideEffectInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1723,6 +1728,11 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
|||||||
*/
|
*/
|
||||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
||||||
import semmle.code.cpp.ir.internal.Overlap
|
import semmle.code.cpp.ir.internal.Overlap
|
||||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||||
|
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||||
|
|||||||
@@ -41,8 +41,92 @@ newtype TValueNumber =
|
|||||||
) {
|
) {
|
||||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||||
} or
|
} or
|
||||||
|
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||||
|
|
||||||
|
private class NumberableCallInstruction extends CallInstruction {
|
||||||
|
NumberableCallInstruction() {
|
||||||
|
not this.getResultIRType() instanceof IRVoidType and
|
||||||
|
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||||
|
sideEffectFunc = this.getStaticCallTarget()
|
||||||
|
|
|
||||||
|
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||||
|
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private newtype TCallPartialValueNumber =
|
||||||
|
TNilArgument() or
|
||||||
|
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||||
|
exists(NumberableCallInstruction call, int index |
|
||||||
|
callArgValueNumber(call, index, arg) and
|
||||||
|
callPartialValueNumber(call, index, head)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||||
|
) {
|
||||||
|
index = max(int n | callArgRank(call, n, _) | n) and
|
||||||
|
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||||
|
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||||
|
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||||
|
vn = TArgument(head, arg)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
not exists(int n | callArgRank(call, n, _)) and
|
||||||
|
index = -1 and
|
||||||
|
vn = TNilArgument()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callPartialValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||||
|
) {
|
||||||
|
exists(call) and
|
||||||
|
index = 1 and
|
||||||
|
head = TNilArgument()
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||||
|
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||||
|
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||||
|
head = TArgument(prev, prevVN)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||||
|
exists(Instruction instr |
|
||||||
|
callArgRank(call, index, instr) and
|
||||||
|
arg = tvalueNumber(instr)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||||
|
* argument and side-effect reads.
|
||||||
|
*/
|
||||||
|
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||||
|
arg =
|
||||||
|
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||||
|
// There is no need to include the call's read and write side effects on
|
||||||
|
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||||
|
// to all-aliased-memory.
|
||||||
|
instr = call.getArgument(argIndex) and
|
||||||
|
isEffect = false
|
||||||
|
or
|
||||||
|
exists(ReadSideEffectInstruction read |
|
||||||
|
read.getPrimaryInstruction() = call and
|
||||||
|
read.getSideEffectOperand().getAnyDef() = instr and
|
||||||
|
read.getIndex() = argIndex and
|
||||||
|
isEffect = true
|
||||||
|
)
|
||||||
|
|
|
||||||
|
instr order by argIndex, isEffect
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||||
* operand.
|
* operand.
|
||||||
@@ -93,6 +177,8 @@ private predicate numberableInstruction(Instruction instr) {
|
|||||||
instr instanceof CongruentCopyInstruction
|
instr instanceof CongruentCopyInstruction
|
||||||
or
|
or
|
||||||
instr instanceof LoadTotalOverlapInstruction
|
instr instanceof LoadTotalOverlapInstruction
|
||||||
|
or
|
||||||
|
instr instanceof NumberableCallInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||||
@@ -309,6 +395,11 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
|||||||
or
|
or
|
||||||
// The value number of a copy is just the value number of its source value.
|
// The value number of a copy is just the value number of its source value.
|
||||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber pvn |
|
||||||
|
callValueNumber(instr, _, pvn) and
|
||||||
|
result = TCallValueNumber(pvn)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ private import Imports::RawIR as RawIR
|
|||||||
private import SsaInstructions
|
private import SsaInstructions
|
||||||
private import SsaOperands
|
private import SsaOperands
|
||||||
private import NewIR
|
private import NewIR
|
||||||
|
|
||||||
private class OldBlock = Reachability::ReachableBlock;
|
|
||||||
|
|
||||||
private class OldInstruction = Reachability::ReachableInstruction;
|
|
||||||
|
|
||||||
import Cached
|
import Cached
|
||||||
|
|
||||||
cached
|
cached
|
||||||
@@ -58,7 +53,9 @@ private module Cached {
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
predicate hasInstruction(TStageInstruction instr) {
|
predicate hasInstruction(TStageInstruction instr) {
|
||||||
instr instanceof TRawInstruction and instr instanceof OldInstruction
|
instr instanceof TRawInstruction and
|
||||||
|
instr instanceof OldInstruction and
|
||||||
|
not removedInstruction(instr)
|
||||||
or
|
or
|
||||||
instr = phiInstruction(_, _)
|
instr = phiInstruction(_, _)
|
||||||
or
|
or
|
||||||
@@ -382,7 +379,14 @@ private module Cached {
|
|||||||
(
|
(
|
||||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
||||||
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
||||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
else
|
||||||
|
if removedInstruction(oldInstruction.getSuccessor(kind))
|
||||||
|
then
|
||||||
|
// the only removed nodes are side-effect writes, but those may have Chi nodes
|
||||||
|
// skip to the following instruction in the old IR, which won't be removed
|
||||||
|
// if we start skipping specific side effects, this may no longer hold
|
||||||
|
result = getNewInstruction(oldInstruction.getSuccessor(kind).getSuccessor(kind))
|
||||||
|
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -13,3 +13,15 @@ import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands a
|
|||||||
|
|
||||||
/** DEPRECATED: Alias for SsaOperands */
|
/** DEPRECATED: Alias for SsaOperands */
|
||||||
deprecated module SSAOperands = SsaOperands;
|
deprecated module SSAOperands = SsaOperands;
|
||||||
|
|
||||||
|
private import SideEffectElimination as Elim
|
||||||
|
|
||||||
|
predicate removedInstruction(Reachability::ReachableInstruction instr) {
|
||||||
|
Elim::removeableSideEffect(instr)
|
||||||
|
}
|
||||||
|
|
||||||
|
class OldBlock = Reachability::ReachableBlock;
|
||||||
|
|
||||||
|
class OldInstruction extends Reachability::ReachableInstruction {
|
||||||
|
OldInstruction() { not Elim::removeableSideEffect(this) }
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import cpp as CPP
|
||||||
|
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as Unaliased
|
||||||
|
import AliasAnalysis as Alias
|
||||||
|
import AliasConfiguration as Conf
|
||||||
|
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||||
|
|
||||||
|
private predicate noLocalSideEffectWrite(CPP::Function func) {
|
||||||
|
forall(Unaliased::AddressOperand addr | addr.getUse().getEnclosingFunction() = func |
|
||||||
|
not (
|
||||||
|
Alias::getAddressOperandAllocation(addr) instanceof Conf::VariableAllocation and
|
||||||
|
Alias::getAddressOperandAllocation(addr).(Conf::VariableAllocation).alwaysEscapes()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
language[monotonicAggregates]
|
||||||
|
private predicate noTransitiveSideEffectWrite(CPP::Function func) {
|
||||||
|
exists(Unaliased::IRFunction irFunc | irFunc.getFunction() = func) and
|
||||||
|
noLocalSideEffectWrite(func) and
|
||||||
|
forall(Unaliased::CallInstruction call | call.getEnclosingFunction() = func |
|
||||||
|
exists(call.getStaticCallTarget())
|
||||||
|
) and
|
||||||
|
forall(Unaliased::CallInstruction call, CPP::Function callee |
|
||||||
|
call.getStaticCallTarget() = callee and
|
||||||
|
call.getEnclosingFunction() = func
|
||||||
|
|
|
||||||
|
noTransitiveSideEffectWrite(callee)
|
||||||
|
or
|
||||||
|
callee.(SideEffect::SideEffectFunction).hasOnlySpecificWriteSideEffects()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate removeableSideEffect(Unaliased::SideEffectInstruction instr) {
|
||||||
|
(
|
||||||
|
instr instanceof Unaliased::CallSideEffectInstruction or
|
||||||
|
instr instanceof Unaliased::CallReadSideEffectInstruction
|
||||||
|
) and
|
||||||
|
noTransitiveSideEffectWrite(instr
|
||||||
|
.getPrimaryInstruction()
|
||||||
|
.(Unaliased::CallInstruction)
|
||||||
|
.getStaticCallTarget())
|
||||||
|
}
|
||||||
@@ -34,6 +34,7 @@ newtype TInstruction =
|
|||||||
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||||
} or
|
} or
|
||||||
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
||||||
|
not AliasedSsa::removedInstruction(primaryInstruction) and
|
||||||
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
||||||
} or
|
} or
|
||||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as
|
|||||||
|
|
||||||
/** DEPRECATED: Alias for AliasedSsa */
|
/** DEPRECATED: Alias for AliasedSsa */
|
||||||
deprecated module AliasedSSA = AliasedSsa;
|
deprecated module AliasedSSA = AliasedSsa;
|
||||||
|
|
||||||
|
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SideEffectElimination as Elim
|
||||||
|
|||||||
@@ -1712,6 +1712,11 @@ class SideEffectInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1723,6 +1728,11 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
|||||||
*/
|
*/
|
||||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
||||||
import semmle.code.cpp.ir.internal.Overlap
|
import semmle.code.cpp.ir.internal.Overlap
|
||||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||||
|
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||||
|
|||||||
@@ -41,8 +41,92 @@ newtype TValueNumber =
|
|||||||
) {
|
) {
|
||||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||||
} or
|
} or
|
||||||
|
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||||
|
|
||||||
|
private class NumberableCallInstruction extends CallInstruction {
|
||||||
|
NumberableCallInstruction() {
|
||||||
|
not this.getResultIRType() instanceof IRVoidType and
|
||||||
|
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||||
|
sideEffectFunc = this.getStaticCallTarget()
|
||||||
|
|
|
||||||
|
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||||
|
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private newtype TCallPartialValueNumber =
|
||||||
|
TNilArgument() or
|
||||||
|
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||||
|
exists(NumberableCallInstruction call, int index |
|
||||||
|
callArgValueNumber(call, index, arg) and
|
||||||
|
callPartialValueNumber(call, index, head)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||||
|
) {
|
||||||
|
index = max(int n | callArgRank(call, n, _) | n) and
|
||||||
|
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||||
|
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||||
|
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||||
|
vn = TArgument(head, arg)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
not exists(int n | callArgRank(call, n, _)) and
|
||||||
|
index = -1 and
|
||||||
|
vn = TNilArgument()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callPartialValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||||
|
) {
|
||||||
|
exists(call) and
|
||||||
|
index = 1 and
|
||||||
|
head = TNilArgument()
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||||
|
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||||
|
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||||
|
head = TArgument(prev, prevVN)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||||
|
exists(Instruction instr |
|
||||||
|
callArgRank(call, index, instr) and
|
||||||
|
arg = tvalueNumber(instr)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||||
|
* argument and side-effect reads.
|
||||||
|
*/
|
||||||
|
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||||
|
arg =
|
||||||
|
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||||
|
// There is no need to include the call's read and write side effects on
|
||||||
|
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||||
|
// to all-aliased-memory.
|
||||||
|
instr = call.getArgument(argIndex) and
|
||||||
|
isEffect = false
|
||||||
|
or
|
||||||
|
exists(ReadSideEffectInstruction read |
|
||||||
|
read.getPrimaryInstruction() = call and
|
||||||
|
read.getSideEffectOperand().getAnyDef() = instr and
|
||||||
|
read.getIndex() = argIndex and
|
||||||
|
isEffect = true
|
||||||
|
)
|
||||||
|
|
|
||||||
|
instr order by argIndex, isEffect
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||||
* operand.
|
* operand.
|
||||||
@@ -93,6 +177,8 @@ private predicate numberableInstruction(Instruction instr) {
|
|||||||
instr instanceof CongruentCopyInstruction
|
instr instanceof CongruentCopyInstruction
|
||||||
or
|
or
|
||||||
instr instanceof LoadTotalOverlapInstruction
|
instr instanceof LoadTotalOverlapInstruction
|
||||||
|
or
|
||||||
|
instr instanceof NumberableCallInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||||
@@ -309,6 +395,11 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
|||||||
or
|
or
|
||||||
// The value number of a copy is just the value number of its source value.
|
// The value number of a copy is just the value number of its source value.
|
||||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber pvn |
|
||||||
|
callValueNumber(instr, _, pvn) and
|
||||||
|
result = TCallValueNumber(pvn)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1712,6 +1712,11 @@ class SideEffectInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1723,6 +1728,11 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
|||||||
*/
|
*/
|
||||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
||||||
import semmle.code.cpp.ir.internal.Overlap
|
import semmle.code.cpp.ir.internal.Overlap
|
||||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||||
|
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||||
|
|||||||
@@ -41,8 +41,92 @@ newtype TValueNumber =
|
|||||||
) {
|
) {
|
||||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||||
} or
|
} or
|
||||||
|
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||||
|
|
||||||
|
private class NumberableCallInstruction extends CallInstruction {
|
||||||
|
NumberableCallInstruction() {
|
||||||
|
not this.getResultIRType() instanceof IRVoidType and
|
||||||
|
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||||
|
sideEffectFunc = this.getStaticCallTarget()
|
||||||
|
|
|
||||||
|
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||||
|
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private newtype TCallPartialValueNumber =
|
||||||
|
TNilArgument() or
|
||||||
|
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||||
|
exists(NumberableCallInstruction call, int index |
|
||||||
|
callArgValueNumber(call, index, arg) and
|
||||||
|
callPartialValueNumber(call, index, head)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||||
|
) {
|
||||||
|
index = max(int n | callArgRank(call, n, _) | n) and
|
||||||
|
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||||
|
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||||
|
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||||
|
vn = TArgument(head, arg)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
not exists(int n | callArgRank(call, n, _)) and
|
||||||
|
index = -1 and
|
||||||
|
vn = TNilArgument()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callPartialValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||||
|
) {
|
||||||
|
exists(call) and
|
||||||
|
index = 1 and
|
||||||
|
head = TNilArgument()
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||||
|
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||||
|
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||||
|
head = TArgument(prev, prevVN)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||||
|
exists(Instruction instr |
|
||||||
|
callArgRank(call, index, instr) and
|
||||||
|
arg = tvalueNumber(instr)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||||
|
* argument and side-effect reads.
|
||||||
|
*/
|
||||||
|
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||||
|
arg =
|
||||||
|
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||||
|
// There is no need to include the call's read and write side effects on
|
||||||
|
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||||
|
// to all-aliased-memory.
|
||||||
|
instr = call.getArgument(argIndex) and
|
||||||
|
isEffect = false
|
||||||
|
or
|
||||||
|
exists(ReadSideEffectInstruction read |
|
||||||
|
read.getPrimaryInstruction() = call and
|
||||||
|
read.getSideEffectOperand().getAnyDef() = instr and
|
||||||
|
read.getIndex() = argIndex and
|
||||||
|
isEffect = true
|
||||||
|
)
|
||||||
|
|
|
||||||
|
instr order by argIndex, isEffect
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||||
* operand.
|
* operand.
|
||||||
@@ -93,6 +177,8 @@ private predicate numberableInstruction(Instruction instr) {
|
|||||||
instr instanceof CongruentCopyInstruction
|
instr instanceof CongruentCopyInstruction
|
||||||
or
|
or
|
||||||
instr instanceof LoadTotalOverlapInstruction
|
instr instanceof LoadTotalOverlapInstruction
|
||||||
|
or
|
||||||
|
instr instanceof NumberableCallInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||||
@@ -309,6 +395,11 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
|||||||
or
|
or
|
||||||
// The value number of a copy is just the value number of its source value.
|
// The value number of a copy is just the value number of its source value.
|
||||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber pvn |
|
||||||
|
callValueNumber(instr, _, pvn) and
|
||||||
|
result = TCallValueNumber(pvn)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ private import Imports::RawIR as RawIR
|
|||||||
private import SsaInstructions
|
private import SsaInstructions
|
||||||
private import SsaOperands
|
private import SsaOperands
|
||||||
private import NewIR
|
private import NewIR
|
||||||
|
|
||||||
private class OldBlock = Reachability::ReachableBlock;
|
|
||||||
|
|
||||||
private class OldInstruction = Reachability::ReachableInstruction;
|
|
||||||
|
|
||||||
import Cached
|
import Cached
|
||||||
|
|
||||||
cached
|
cached
|
||||||
@@ -58,7 +53,9 @@ private module Cached {
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
predicate hasInstruction(TStageInstruction instr) {
|
predicate hasInstruction(TStageInstruction instr) {
|
||||||
instr instanceof TRawInstruction and instr instanceof OldInstruction
|
instr instanceof TRawInstruction and
|
||||||
|
instr instanceof OldInstruction and
|
||||||
|
not removedInstruction(instr)
|
||||||
or
|
or
|
||||||
instr = phiInstruction(_, _)
|
instr = phiInstruction(_, _)
|
||||||
or
|
or
|
||||||
@@ -382,7 +379,14 @@ private module Cached {
|
|||||||
(
|
(
|
||||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
||||||
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
||||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
else
|
||||||
|
if removedInstruction(oldInstruction.getSuccessor(kind))
|
||||||
|
then
|
||||||
|
// the only removed nodes are side-effect writes, but those may have Chi nodes
|
||||||
|
// skip to the following instruction in the old IR, which won't be removed
|
||||||
|
// if we start skipping specific side effects, this may no longer hold
|
||||||
|
result = getNewInstruction(oldInstruction.getSuccessor(kind).getSuccessor(kind))
|
||||||
|
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -14,3 +14,9 @@ import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands
|
|||||||
|
|
||||||
/** DEPRECATED: Alias for SsaOperands */
|
/** DEPRECATED: Alias for SsaOperands */
|
||||||
deprecated module SSAOperands = SsaOperands;
|
deprecated module SSAOperands = SsaOperands;
|
||||||
|
|
||||||
|
predicate removedInstruction(Reachability::ReachableInstruction instr) { none() }
|
||||||
|
|
||||||
|
class OldBlock = Reachability::ReachableBlock;
|
||||||
|
|
||||||
|
class OldInstruction = Reachability::ReachableInstruction;
|
||||||
|
|||||||
@@ -29,7 +29,4 @@ where
|
|||||||
n = strictcount(ComplexStmt s | s = b.getAStmt()) and
|
n = strictcount(ComplexStmt s | s = b.getAStmt()) and
|
||||||
n > 3 and
|
n > 3 and
|
||||||
complexStmt = b.getAStmt()
|
complexStmt = b.getAStmt()
|
||||||
select b,
|
select b, "Block with too many statements (" + n.toString() + " complex statements in the block)."
|
||||||
"Block with too many statements (" + n.toString() +
|
|
||||||
" complex statements in the block). Complex statements at: $@", complexStmt,
|
|
||||||
complexStmt.toString()
|
|
||||||
|
|||||||
@@ -110,4 +110,4 @@ where
|
|||||||
emptyBlock(s, eb) and
|
emptyBlock(s, eb) and
|
||||||
not emptyBlockContainsNonchild(eb) and
|
not emptyBlockContainsNonchild(eb) and
|
||||||
not lineComment(eb)
|
not lineComment(eb)
|
||||||
select eb, "Empty block without comment"
|
select eb, "Empty block without comment."
|
||||||
|
|||||||
@@ -12,4 +12,4 @@
|
|||||||
import CommentedOutCode
|
import CommentedOutCode
|
||||||
|
|
||||||
from CommentedOutCode comment
|
from CommentedOutCode comment
|
||||||
select comment, "This comment appears to contain commented-out code"
|
select comment, "This comment appears to contain commented-out code."
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @name Sign check of bitwise operation
|
* @name Sign check of bitwise operation
|
||||||
* @description Checking the sign of a bitwise operation often has surprising
|
* @description Checking the sign of the result of a bitwise operation may yield unexpected results.
|
||||||
* edge cases.
|
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision high
|
* @precision high
|
||||||
@@ -26,4 +25,4 @@ where
|
|||||||
forall(int op | op = lhs.(BitwiseAndExpr).getAnOperand().getValue().toInt() | op < 0) and
|
forall(int op | op = lhs.(BitwiseAndExpr).getAnOperand().getValue().toInt() | op < 0) and
|
||||||
// exception for cases involving macros
|
// exception for cases involving macros
|
||||||
not e.isAffectedByMacro()
|
not e.isAffectedByMacro()
|
||||||
select e, "Potential unsafe sign check of a bitwise operation."
|
select e, "Potentially unsafe sign check of a bitwise operation."
|
||||||
|
|||||||
@@ -21,4 +21,4 @@ where
|
|||||||
FloatingPointType and
|
FloatingPointType and
|
||||||
not ro.getAnOperand().isConstant() and // comparisons to constants generate too many false positives
|
not ro.getAnOperand().isConstant() and // comparisons to constants generate too many false positives
|
||||||
not left.(VariableAccess).getTarget() = right.(VariableAccess).getTarget() // skip self comparison
|
not left.(VariableAccess).getTarget() = right.(VariableAccess).getTarget() // skip self comparison
|
||||||
select ro, "Equality test on floating point values may not behave as expected."
|
select ro, "Equality checks on floating point values can yield unexpected results."
|
||||||
|
|||||||
@@ -13,10 +13,11 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
|
|
||||||
from EnumSwitch es, float missing, float total
|
from EnumSwitch es, float missing, float total, EnumConstant case
|
||||||
where
|
where
|
||||||
not es.hasDefaultCase() and
|
not es.hasDefaultCase() and
|
||||||
missing = count(es.getAMissingCase()) and
|
missing = count(es.getAMissingCase()) and
|
||||||
total = missing + count(es.getASwitchCase()) and
|
total = missing + count(es.getASwitchCase()) and
|
||||||
missing / total < 0.3
|
missing / total < 0.3 and
|
||||||
select es, "Switch statement is missing case for " + es.getAMissingCase().getName()
|
case = es.getAMissingCase()
|
||||||
|
select es, "Switch statement does not have a case for $@.", case, case.getName()
|
||||||
|
|||||||
4
cpp/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
4
cpp/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The alert message of many queries have been changed to make the message consistent with other languages.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1050,46 +1050,36 @@ ssa.cpp:
|
|||||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||||
# 240| r240_4(int) = Constant[1] :
|
# 240| r240_4(int) = Constant[1] :
|
||||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||||
# 240| m240_6(unknown) = ^CallSideEffect : ~m239_4
|
# 240| m240_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||||
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
|
# 240| m240_7(Constructible) = Chi : total:m240_2, partial:m240_6
|
||||||
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
|
||||||
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
|
|
||||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
# 241| v241_4(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_7
|
||||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
# 241| m241_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||||
# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9
|
# 241| m241_6(Constructible) = Chi : total:m240_7, partial:m241_5
|
||||||
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
|
||||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
|
||||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
# 242| v242_4(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_6
|
||||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
# 242| m242_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||||
# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8
|
# 242| m242_6(Constructible) = Chi : total:m241_6, partial:m242_5
|
||||||
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
|
||||||
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
|
||||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||||
# 243| r243_4(int) = Constant[2] :
|
# 243| r243_4(int) = Constant[2] :
|
||||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||||
# 243| m243_6(unknown) = ^CallSideEffect : ~m242_5
|
# 243| m243_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||||
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
|
# 243| m243_7(Constructible) = Chi : total:m243_2, partial:m243_6
|
||||||
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
|
||||||
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
|
|
||||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
# 244| v244_4(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_7
|
||||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
# 244| m244_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||||
# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9
|
# 244| m244_6(Constructible) = Chi : total:m243_7, partial:m244_5
|
||||||
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
|
||||||
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
|
||||||
# 245| v245_1(void) = NoOp :
|
# 245| v245_1(void) = NoOp :
|
||||||
# 239| v239_5(void) = ReturnVoid :
|
# 239| v239_5(void) = ReturnVoid :
|
||||||
# 239| v239_6(void) = AliasedUse : ~m244_5
|
# 239| v239_6(void) = AliasedUse : m239_3
|
||||||
# 239| v239_7(void) = ExitFunction :
|
# 239| v239_7(void) = ExitFunction :
|
||||||
|
|
||||||
# 247| char* VoidStarIndirectParameters(char*, int)
|
# 247| char* VoidStarIndirectParameters(char*, int)
|
||||||
@@ -1391,43 +1381,37 @@ ssa.cpp:
|
|||||||
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
||||||
# 294| r294_19(int) = Load[x] : &:r294_18, m291_6
|
# 294| r294_19(int) = Load[x] : &:r294_18, m291_6
|
||||||
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
||||||
# 294| m294_21(unknown) = ^CallSideEffect : ~m294_14
|
# 294| m294_21(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||||
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
|
# 294| m294_22(unknown) = Chi : total:m294_15, partial:m294_21
|
||||||
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
# 294| v294_23(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||||
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23
|
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_22
|
||||||
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
# 294| m294_25(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||||
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
|
# 294| m294_26(unknown) = Chi : total:m294_7, partial:m294_25
|
||||||
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
|
# 294| m294_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
||||||
# 294| v294_28(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
|
# 294| m294_28(unknown) = Chi : total:m294_22, partial:m294_27
|
||||||
# 294| m294_29(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
# 294| r294_29(glval<int>) = FieldAddress[i] : r294_8
|
||||||
# 294| m294_30(unknown) = Chi : total:m294_7, partial:m294_29
|
# 294| r294_30(int) = Load[?] : &:r294_29, ~m294_26
|
||||||
# 294| m294_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
# 294| m294_31(int) = Store[j] : &:r294_1, r294_30
|
||||||
# 294| m294_32(unknown) = Chi : total:m294_24, partial:m294_31
|
|
||||||
# 294| r294_33(glval<int>) = FieldAddress[i] : r294_8
|
|
||||||
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_30
|
|
||||||
# 294| m294_35(int) = Store[j] : &:r294_1, r294_34
|
|
||||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||||
# 295| r295_3(unsigned long) = Constant[4] :
|
# 295| r295_3(unsigned long) = Constant[4] :
|
||||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_27
|
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_14
|
||||||
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
|
# 295| m295_6(unknown) = Chi : total:m294_14, partial:m295_5
|
||||||
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||||
# 295| r295_8(A *) = Convert : r295_4
|
# 295| r295_8(A *) = Convert : r295_4
|
||||||
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
||||||
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
||||||
# 295| m295_11(unknown) = ^CallSideEffect : ~m295_6
|
# 295| m295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||||
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
|
# 295| m295_12(unknown) = Chi : total:m295_7, partial:m295_11
|
||||||
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
# 295| m295_13(A *) = Store[a] : &:r295_1, r295_8
|
||||||
# 295| m295_14(unknown) = Chi : total:m295_7, partial:m295_13
|
|
||||||
# 295| m295_15(A *) = Store[a] : &:r295_1, r295_8
|
|
||||||
# 296| r296_1(glval<Point *>) = VariableAddress[#return] :
|
# 296| r296_1(glval<Point *>) = VariableAddress[#return] :
|
||||||
# 296| r296_2(glval<Point *>) = VariableAddress[p] :
|
# 296| r296_2(glval<Point *>) = VariableAddress[p] :
|
||||||
# 296| r296_3(Point *) = Load[p] : &:r296_2, m292_9
|
# 296| r296_3(Point *) = Load[p] : &:r296_2, m292_9
|
||||||
# 296| m296_4(Point *) = Store[#return] : &:r296_1, r296_3
|
# 296| m296_4(Point *) = Store[#return] : &:r296_1, r296_3
|
||||||
# 291| r291_7(glval<Point *>) = VariableAddress[#return] :
|
# 291| r291_7(glval<Point *>) = VariableAddress[#return] :
|
||||||
# 291| v291_8(void) = ReturnValue : &:r291_7, m296_4
|
# 291| v291_8(void) = ReturnValue : &:r291_7, m296_4
|
||||||
# 291| v291_9(void) = AliasedUse : ~m295_12
|
# 291| v291_9(void) = AliasedUse : ~m295_6
|
||||||
# 291| v291_10(void) = ExitFunction :
|
# 291| v291_10(void) = ExitFunction :
|
||||||
|
|
||||||
# 301| int main(int, char**)
|
# 301| int main(int, char**)
|
||||||
|
|||||||
@@ -1045,46 +1045,36 @@ ssa.cpp:
|
|||||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||||
# 240| r240_4(int) = Constant[1] :
|
# 240| r240_4(int) = Constant[1] :
|
||||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||||
# 240| m240_6(unknown) = ^CallSideEffect : ~m239_4
|
# 240| m240_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||||
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
|
# 240| m240_7(Constructible) = Chi : total:m240_2, partial:m240_6
|
||||||
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
|
||||||
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
|
|
||||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
# 241| v241_4(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_7
|
||||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
# 241| m241_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||||
# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9
|
# 241| m241_6(Constructible) = Chi : total:m240_7, partial:m241_5
|
||||||
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
|
||||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
|
||||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
# 242| v242_4(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_6
|
||||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
# 242| m242_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||||
# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8
|
# 242| m242_6(Constructible) = Chi : total:m241_6, partial:m242_5
|
||||||
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
|
||||||
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
|
||||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||||
# 243| r243_4(int) = Constant[2] :
|
# 243| r243_4(int) = Constant[2] :
|
||||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||||
# 243| m243_6(unknown) = ^CallSideEffect : ~m242_5
|
# 243| m243_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||||
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
|
# 243| m243_7(Constructible) = Chi : total:m243_2, partial:m243_6
|
||||||
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
|
||||||
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
|
|
||||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
# 244| v244_4(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_7
|
||||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
# 244| m244_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||||
# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9
|
# 244| m244_6(Constructible) = Chi : total:m243_7, partial:m244_5
|
||||||
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
|
||||||
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
|
||||||
# 245| v245_1(void) = NoOp :
|
# 245| v245_1(void) = NoOp :
|
||||||
# 239| v239_5(void) = ReturnVoid :
|
# 239| v239_5(void) = ReturnVoid :
|
||||||
# 239| v239_6(void) = AliasedUse : ~m244_5
|
# 239| v239_6(void) = AliasedUse : m239_3
|
||||||
# 239| v239_7(void) = ExitFunction :
|
# 239| v239_7(void) = ExitFunction :
|
||||||
|
|
||||||
# 247| char* VoidStarIndirectParameters(char*, int)
|
# 247| char* VoidStarIndirectParameters(char*, int)
|
||||||
@@ -1385,43 +1375,37 @@ ssa.cpp:
|
|||||||
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
||||||
# 294| r294_19(int) = Load[x] : &:r294_18, m291_6
|
# 294| r294_19(int) = Load[x] : &:r294_18, m291_6
|
||||||
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
||||||
# 294| m294_21(unknown) = ^CallSideEffect : ~m294_14
|
# 294| m294_21(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||||
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
|
# 294| m294_22(unknown) = Chi : total:m294_15, partial:m294_21
|
||||||
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
# 294| v294_23(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||||
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23
|
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_22
|
||||||
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
# 294| m294_25(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||||
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
|
# 294| m294_26(unknown) = Chi : total:m294_7, partial:m294_25
|
||||||
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
|
# 294| m294_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
||||||
# 294| v294_28(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
|
# 294| m294_28(unknown) = Chi : total:m294_22, partial:m294_27
|
||||||
# 294| m294_29(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
# 294| r294_29(glval<int>) = FieldAddress[i] : r294_8
|
||||||
# 294| m294_30(unknown) = Chi : total:m294_7, partial:m294_29
|
# 294| r294_30(int) = Load[?] : &:r294_29, ~m294_26
|
||||||
# 294| m294_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
# 294| m294_31(int) = Store[j] : &:r294_1, r294_30
|
||||||
# 294| m294_32(unknown) = Chi : total:m294_24, partial:m294_31
|
|
||||||
# 294| r294_33(glval<int>) = FieldAddress[i] : r294_8
|
|
||||||
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_30
|
|
||||||
# 294| m294_35(int) = Store[j] : &:r294_1, r294_34
|
|
||||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||||
# 295| r295_3(unsigned long) = Constant[4] :
|
# 295| r295_3(unsigned long) = Constant[4] :
|
||||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_27
|
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_14
|
||||||
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
|
# 295| m295_6(unknown) = Chi : total:m294_14, partial:m295_5
|
||||||
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||||
# 295| r295_8(A *) = Convert : r295_4
|
# 295| r295_8(A *) = Convert : r295_4
|
||||||
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
||||||
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
||||||
# 295| m295_11(unknown) = ^CallSideEffect : ~m295_6
|
# 295| m295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||||
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
|
# 295| m295_12(unknown) = Chi : total:m295_7, partial:m295_11
|
||||||
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
# 295| m295_13(A *) = Store[a] : &:r295_1, r295_8
|
||||||
# 295| m295_14(unknown) = Chi : total:m295_7, partial:m295_13
|
|
||||||
# 295| m295_15(A *) = Store[a] : &:r295_1, r295_8
|
|
||||||
# 296| r296_1(glval<Point *>) = VariableAddress[#return] :
|
# 296| r296_1(glval<Point *>) = VariableAddress[#return] :
|
||||||
# 296| r296_2(glval<Point *>) = VariableAddress[p] :
|
# 296| r296_2(glval<Point *>) = VariableAddress[p] :
|
||||||
# 296| r296_3(Point *) = Load[p] : &:r296_2, m292_9
|
# 296| r296_3(Point *) = Load[p] : &:r296_2, m292_9
|
||||||
# 296| m296_4(Point *) = Store[#return] : &:r296_1, r296_3
|
# 296| m296_4(Point *) = Store[#return] : &:r296_1, r296_3
|
||||||
# 291| r291_7(glval<Point *>) = VariableAddress[#return] :
|
# 291| r291_7(glval<Point *>) = VariableAddress[#return] :
|
||||||
# 291| v291_8(void) = ReturnValue : &:r291_7, m296_4
|
# 291| v291_8(void) = ReturnValue : &:r291_7, m296_4
|
||||||
# 291| v291_9(void) = AliasedUse : ~m295_12
|
# 291| v291_9(void) = AliasedUse : ~m295_6
|
||||||
# 291| v291_10(void) = ExitFunction :
|
# 291| v291_10(void) = ExitFunction :
|
||||||
|
|
||||||
# 301| int main(int, char**)
|
# 301| int main(int, char**)
|
||||||
|
|||||||
@@ -149,9 +149,6 @@ uniqueNodeLocation
|
|||||||
| conditional_destructors.cpp:29:6:29:7 | EnterFunction | Node should have one location but has 2. |
|
| conditional_destructors.cpp:29:6:29:7 | EnterFunction | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:29:6:29:7 | ExitFunction | Node should have one location but has 2. |
|
| conditional_destructors.cpp:29:6:29:7 | ExitFunction | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:29:6:29:7 | InitializeNonLocal | Node should have one location but has 2. |
|
| conditional_destructors.cpp:29:6:29:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| conditional_destructors.cpp:29:6:29:7 | ReturnVoid | Node should have one location but has 2. |
|
| conditional_destructors.cpp:29:6:29:7 | ReturnVoid | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:29:6:29:7 | SideEffect | Node should have one location but has 2. |
|
| conditional_destructors.cpp:29:6:29:7 | SideEffect | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition | Node should have one location but has 2. |
|
||||||
@@ -162,9 +159,6 @@ uniqueNodeLocation
|
|||||||
| conditional_destructors.cpp:38:6:38:7 | EnterFunction | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | EnterFunction | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:38:6:38:7 | ExitFunction | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | ExitFunction | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:38:6:38:7 | InitializeNonLocal | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| conditional_destructors.cpp:38:6:38:7 | ReturnVoid | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | ReturnVoid | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:38:6:38:7 | SideEffect | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | SideEffect | Node should have one location but has 2. |
|
||||||
| conditional_destructors.cpp:38:6:38:7 | Unreached | Node should have one location but has 2. |
|
| conditional_destructors.cpp:38:6:38:7 | Unreached | Node should have one location but has 2. |
|
||||||
@@ -561,9 +555,6 @@ uniqueNodeLocation
|
|||||||
| forstmt.cpp:1:6:1:7 | EnterFunction | Node should have one location but has 2. |
|
| forstmt.cpp:1:6:1:7 | EnterFunction | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:1:6:1:7 | ExitFunction | Node should have one location but has 2. |
|
| forstmt.cpp:1:6:1:7 | ExitFunction | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:1:6:1:7 | InitializeNonLocal | Node should have one location but has 2. |
|
| forstmt.cpp:1:6:1:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| forstmt.cpp:1:6:1:7 | ReturnVoid | Node should have one location but has 2. |
|
| forstmt.cpp:1:6:1:7 | ReturnVoid | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:1:6:1:7 | SideEffect | Node should have one location but has 2. |
|
| forstmt.cpp:1:6:1:7 | SideEffect | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:8:6:8:7 | AliasedDefinition | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | AliasedDefinition | Node should have one location but has 2. |
|
||||||
@@ -574,9 +565,6 @@ uniqueNodeLocation
|
|||||||
| forstmt.cpp:8:6:8:7 | EnterFunction | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | EnterFunction | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:8:6:8:7 | ExitFunction | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | ExitFunction | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:8:6:8:7 | InitializeNonLocal | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
|
|
||||||
| forstmt.cpp:8:6:8:7 | ReturnVoid | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | ReturnVoid | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:8:6:8:7 | SideEffect | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | SideEffect | Node should have one location but has 2. |
|
||||||
| forstmt.cpp:8:6:8:7 | Unreached | Node should have one location but has 2. |
|
| forstmt.cpp:8:6:8:7 | Unreached | Node should have one location but has 2. |
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 |
|
| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 |
|
||||||
| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 |
|
| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 |
|
||||||
| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 |
|
| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 |
|
||||||
|
| test.cpp:10:16:10:16 | 1 | 10:c16-c16 176:c7-c7 178:c7-c7 |
|
||||||
| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 |
|
| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 |
|
||||||
| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 |
|
| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 |
|
||||||
| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 |
|
| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 |
|
||||||
@@ -38,3 +39,9 @@
|
|||||||
| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 |
|
| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 |
|
||||||
| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
||||||
| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 |
|
| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 |
|
||||||
|
| test.cpp:166:18:166:20 | (const char *)... | 166:c18-c20 167:c18-c20 173:c18-c20 |
|
||||||
|
| test.cpp:166:18:166:20 | dst | 166:c18-c20 167:c18-c20 171:c10-c12 173:c18-c20 |
|
||||||
|
| test.cpp:168:18:168:20 | (const char *)... | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||||
|
| test.cpp:168:18:168:20 | src | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||||
|
| test.cpp:176:10:176:10 | 2 | 176:c10-c10 178:c10-c10 21:c16-c16 |
|
||||||
|
| test.cpp:177:7:177:7 | 3 | 177:c7-c7 35:c16-c16 |
|
||||||
|
|||||||
@@ -44,3 +44,11 @@
|
|||||||
| test.cpp:144:15:144:15 | GVN | 144:c15-c15 149:c15-c15 |
|
| test.cpp:144:15:144:15 | GVN | 144:c15-c15 149:c15-c15 |
|
||||||
| test.cpp:153:11:153:18 | GVN | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
| test.cpp:153:11:153:18 | GVN | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
||||||
| test.cpp:153:21:153:21 | GVN | 153:c21-c21 154:c21-c21 |
|
| test.cpp:153:21:153:21 | GVN | 153:c21-c21 154:c21-c21 |
|
||||||
|
| test.cpp:166:11:166:16 | GVN | 166:c11-c16 167:c11-c16 |
|
||||||
|
| test.cpp:166:18:166:20 | GVN | 166:c18-c20 167:c18-c20 171:c10-c12 173:c18-c20 |
|
||||||
|
| test.cpp:166:18:166:20 | GVN | 166:c18-c20 167:c18-c20 173:c18-c20 |
|
||||||
|
| test.cpp:168:11:168:16 | GVN | 168:c11-c16 169:c11-c16 174:c11-c16 |
|
||||||
|
| test.cpp:168:18:168:20 | GVN | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||||
|
| test.cpp:168:18:168:20 | GVN | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||||
|
| test.cpp:176:7:176:7 | GVN | 176:c7-c7 178:c7-c7 |
|
||||||
|
| test.cpp:176:10:176:10 | GVN | 176:c10-c10 178:c10-c10 |
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
|
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
|
||||||
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
|
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
|
||||||
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |
|
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |
|
||||||
|
| test.cpp:10:16:10:16 | 1 | test.cpp:176:7:176:7 | 1 | AST only |
|
||||||
|
| test.cpp:10:16:10:16 | 1 | test.cpp:178:7:178:7 | 1 | AST only |
|
||||||
| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only |
|
| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only |
|
||||||
| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only |
|
| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only |
|
||||||
| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only |
|
| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only |
|
||||||
|
| test.cpp:21:16:21:16 | 2 | test.cpp:176:10:176:10 | 2 | AST only |
|
||||||
|
| test.cpp:21:16:21:16 | 2 | test.cpp:178:10:178:10 | 2 | AST only |
|
||||||
| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only |
|
| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only |
|
||||||
| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only |
|
| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only |
|
||||||
| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only |
|
| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only |
|
||||||
| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only |
|
| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only |
|
||||||
| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only |
|
| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only |
|
||||||
| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only |
|
| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only |
|
||||||
|
| test.cpp:35:16:35:16 | 3 | test.cpp:177:7:177:7 | 3 | AST only |
|
||||||
| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only |
|
| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only |
|
||||||
| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only |
|
| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only |
|
||||||
| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only |
|
| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only |
|
||||||
@@ -127,3 +132,41 @@
|
|||||||
| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only |
|
| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only |
|
||||||
| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only |
|
| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only |
|
||||||
| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only |
|
| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only |
|
||||||
|
| test.cpp:166:11:166:16 | call to strlen | test.cpp:167:11:167:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:166:18:166:20 | (const char *)... | test.cpp:166:18:166:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:166:18:166:20 | (const char *)... | test.cpp:167:18:167:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:166:18:166:20 | (const char *)... | test.cpp:173:18:173:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:167:11:167:16 | call to strlen | test.cpp:166:11:166:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:167:18:167:20 | (const char *)... | test.cpp:166:18:166:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:167:18:167:20 | (const char *)... | test.cpp:167:18:167:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:167:18:167:20 | (const char *)... | test.cpp:173:18:173:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:168:11:168:16 | call to strlen | test.cpp:169:11:169:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:168:11:168:16 | call to strlen | test.cpp:174:11:174:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||||
|
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:169:11:169:16 | call to strlen | test.cpp:168:11:168:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:169:11:169:16 | call to strlen | test.cpp:174:11:174:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||||
|
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||||
|
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:173:18:173:20 | (const char *)... | test.cpp:166:18:166:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:173:18:173:20 | (const char *)... | test.cpp:167:18:167:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:173:18:173:20 | (const char *)... | test.cpp:173:18:173:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:174:11:174:16 | call to strlen | test.cpp:168:11:168:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:174:11:174:16 | call to strlen | test.cpp:169:11:169:16 | call to strlen | IR only |
|
||||||
|
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||||
|
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||||
|
| test.cpp:176:7:176:7 | 1 | test.cpp:10:16:10:16 | 1 | AST only |
|
||||||
|
| test.cpp:176:10:176:10 | 2 | test.cpp:21:16:21:16 | 2 | AST only |
|
||||||
|
| test.cpp:177:7:177:7 | 3 | test.cpp:35:16:35:16 | 3 | AST only |
|
||||||
|
| test.cpp:178:7:178:7 | 1 | test.cpp:10:16:10:16 | 1 | AST only |
|
||||||
|
| test.cpp:178:10:178:10 | 2 | test.cpp:21:16:21:16 | 2 | AST only |
|
||||||
|
|||||||
@@ -1145,3 +1145,206 @@ test.cpp:
|
|||||||
# 152| v152_7(void) = ReturnVoid :
|
# 152| v152_7(void) = ReturnVoid :
|
||||||
# 152| v152_8(void) = AliasedUse : ~m156_7
|
# 152| v152_8(void) = AliasedUse : ~m156_7
|
||||||
# 152| v152_9(void) = ExitFunction :
|
# 152| v152_9(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 163| int add(int, int)
|
||||||
|
# 163| Block 0
|
||||||
|
# 163| v163_1(void) = EnterFunction :
|
||||||
|
# 163| m163_2(unknown) = AliasedDefinition :
|
||||||
|
# 163| valnum = unique
|
||||||
|
# 163| m163_3(unknown) = InitializeNonLocal :
|
||||||
|
# 163| valnum = unique
|
||||||
|
# 163| m163_4(unknown) = Chi : total:m163_2, partial:m163_3
|
||||||
|
# 163| valnum = unique
|
||||||
|
# 163| r163_5(glval<int>) = VariableAddress[a] :
|
||||||
|
# 163| valnum = r163_10, r163_5
|
||||||
|
# 163| m163_6(int) = InitializeParameter[a] : &:r163_5
|
||||||
|
# 163| valnum = m163_6, r163_11
|
||||||
|
# 163| r163_7(glval<int>) = VariableAddress[b] :
|
||||||
|
# 163| valnum = r163_12, r163_7
|
||||||
|
# 163| m163_8(int) = InitializeParameter[b] : &:r163_7
|
||||||
|
# 163| valnum = m163_8, r163_13
|
||||||
|
# 163| r163_9(glval<int>) = VariableAddress[#return] :
|
||||||
|
# 163| valnum = r163_16, r163_9
|
||||||
|
# 163| r163_10(glval<int>) = VariableAddress[a] :
|
||||||
|
# 163| valnum = r163_10, r163_5
|
||||||
|
# 163| r163_11(int) = Load[a] : &:r163_10, m163_6
|
||||||
|
# 163| valnum = m163_6, r163_11
|
||||||
|
# 163| r163_12(glval<int>) = VariableAddress[b] :
|
||||||
|
# 163| valnum = r163_12, r163_7
|
||||||
|
# 163| r163_13(int) = Load[b] : &:r163_12, m163_8
|
||||||
|
# 163| valnum = m163_8, r163_13
|
||||||
|
# 163| r163_14(int) = Add : r163_11, r163_13
|
||||||
|
# 163| valnum = m163_15, r163_14
|
||||||
|
# 163| m163_15(int) = Store[#return] : &:r163_9, r163_14
|
||||||
|
# 163| valnum = m163_15, r163_14
|
||||||
|
# 163| r163_16(glval<int>) = VariableAddress[#return] :
|
||||||
|
# 163| valnum = r163_16, r163_9
|
||||||
|
# 163| v163_17(void) = ReturnValue : &:r163_16, m163_15
|
||||||
|
# 163| v163_18(void) = AliasedUse : m163_3
|
||||||
|
# 163| v163_19(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 165| void test_func_value_numbering(char*, char*)
|
||||||
|
# 165| Block 0
|
||||||
|
# 165| v165_1(void) = EnterFunction :
|
||||||
|
# 165| m165_2(unknown) = AliasedDefinition :
|
||||||
|
# 165| valnum = unique
|
||||||
|
# 165| m165_3(unknown) = InitializeNonLocal :
|
||||||
|
# 165| valnum = unique
|
||||||
|
# 165| m165_4(unknown) = Chi : total:m165_2, partial:m165_3
|
||||||
|
# 165| valnum = unique
|
||||||
|
# 165| r165_5(glval<char *>) = VariableAddress[dst] :
|
||||||
|
# 165| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||||
|
# 165| m165_6(char *) = InitializeParameter[dst] : &:r165_5
|
||||||
|
# 165| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||||
|
# 165| r165_7(char *) = Load[dst] : &:r165_5, m165_6
|
||||||
|
# 165| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||||
|
# 165| m165_8(unknown) = InitializeIndirection[dst] : &:r165_7
|
||||||
|
# 165| valnum = unique
|
||||||
|
# 165| r165_9(glval<char *>) = VariableAddress[src] :
|
||||||
|
# 165| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||||
|
# 165| m165_10(char *) = InitializeParameter[src] : &:r165_9
|
||||||
|
# 165| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||||
|
# 165| r165_11(char *) = Load[src] : &:r165_9, m165_10
|
||||||
|
# 165| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||||
|
# 165| m165_12(unknown) = InitializeIndirection[src] : &:r165_11
|
||||||
|
# 165| valnum = unique
|
||||||
|
# 166| r166_1(glval<int>) = VariableAddress[a] :
|
||||||
|
# 166| valnum = unique
|
||||||
|
# 166| r166_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||||
|
# 166| valnum = unique
|
||||||
|
# 166| r166_3(glval<char *>) = VariableAddress[dst] :
|
||||||
|
# 166| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||||
|
# 166| r166_4(char *) = Load[dst] : &:r166_3, m165_6
|
||||||
|
# 166| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||||
|
# 166| r166_5(char *) = Convert : r166_4
|
||||||
|
# 166| valnum = r166_5, r167_5, r173_5
|
||||||
|
# 166| r166_6(int) = Call[strlen] : func:r166_2, 0:r166_5
|
||||||
|
# 166| valnum = m166_8, m167_8, r166_6, r167_6
|
||||||
|
# 166| v166_7(void) = ^BufferReadSideEffect[0] : &:r166_5, ~m165_8
|
||||||
|
# 166| m166_8(int) = Store[a] : &:r166_1, r166_6
|
||||||
|
# 166| valnum = m166_8, m167_8, r166_6, r167_6
|
||||||
|
# 167| r167_1(glval<int>) = VariableAddress[b] :
|
||||||
|
# 167| valnum = unique
|
||||||
|
# 167| r167_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||||
|
# 167| valnum = unique
|
||||||
|
# 167| r167_3(glval<char *>) = VariableAddress[dst] :
|
||||||
|
# 167| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||||
|
# 167| r167_4(char *) = Load[dst] : &:r167_3, m165_6
|
||||||
|
# 167| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||||
|
# 167| r167_5(char *) = Convert : r167_4
|
||||||
|
# 167| valnum = r166_5, r167_5, r173_5
|
||||||
|
# 167| r167_6(int) = Call[strlen] : func:r167_2, 0:r167_5
|
||||||
|
# 167| valnum = m166_8, m167_8, r166_6, r167_6
|
||||||
|
# 167| v167_7(void) = ^BufferReadSideEffect[0] : &:r167_5, ~m165_8
|
||||||
|
# 167| m167_8(int) = Store[b] : &:r167_1, r167_6
|
||||||
|
# 167| valnum = m166_8, m167_8, r166_6, r167_6
|
||||||
|
# 168| r168_1(glval<int>) = VariableAddress[c] :
|
||||||
|
# 168| valnum = unique
|
||||||
|
# 168| r168_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||||
|
# 168| valnum = unique
|
||||||
|
# 168| r168_3(glval<char *>) = VariableAddress[src] :
|
||||||
|
# 168| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||||
|
# 168| r168_4(char *) = Load[src] : &:r168_3, m165_10
|
||||||
|
# 168| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||||
|
# 168| r168_5(char *) = Convert : r168_4
|
||||||
|
# 168| valnum = r168_5, r169_5, r171_6, r174_5
|
||||||
|
# 168| r168_6(int) = Call[strlen] : func:r168_2, 0:r168_5
|
||||||
|
# 168| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||||
|
# 168| v168_7(void) = ^BufferReadSideEffect[0] : &:r168_5, ~m165_12
|
||||||
|
# 168| m168_8(int) = Store[c] : &:r168_1, r168_6
|
||||||
|
# 168| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||||
|
# 169| r169_1(glval<int>) = VariableAddress[d] :
|
||||||
|
# 169| valnum = unique
|
||||||
|
# 169| r169_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||||
|
# 169| valnum = unique
|
||||||
|
# 169| r169_3(glval<char *>) = VariableAddress[src] :
|
||||||
|
# 169| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||||
|
# 169| r169_4(char *) = Load[src] : &:r169_3, m165_10
|
||||||
|
# 169| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||||
|
# 169| r169_5(char *) = Convert : r169_4
|
||||||
|
# 169| valnum = r168_5, r169_5, r171_6, r174_5
|
||||||
|
# 169| r169_6(int) = Call[strlen] : func:r169_2, 0:r169_5
|
||||||
|
# 169| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||||
|
# 169| v169_7(void) = ^BufferReadSideEffect[0] : &:r169_5, ~m165_12
|
||||||
|
# 169| m169_8(int) = Store[d] : &:r169_1, r169_6
|
||||||
|
# 169| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||||
|
# 171| r171_1(glval<unknown>) = FunctionAddress[strcat] :
|
||||||
|
# 171| valnum = unique
|
||||||
|
# 171| r171_2(glval<char *>) = VariableAddress[dst] :
|
||||||
|
# 171| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||||
|
# 171| r171_3(char *) = Load[dst] : &:r171_2, m165_6
|
||||||
|
# 171| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||||
|
# 171| r171_4(glval<char *>) = VariableAddress[src] :
|
||||||
|
# 171| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||||
|
# 171| r171_5(char *) = Load[src] : &:r171_4, m165_10
|
||||||
|
# 171| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||||
|
# 171| r171_6(char *) = Convert : r171_5
|
||||||
|
# 171| valnum = r168_5, r169_5, r171_6, r174_5
|
||||||
|
# 171| r171_7(char *) = Call[strcat] : func:r171_1, 0:r171_3, 1:r171_6
|
||||||
|
# 171| valnum = unique
|
||||||
|
# 171| v171_8(void) = ^BufferReadSideEffect[0] : &:r171_3, ~m165_8
|
||||||
|
# 171| v171_9(void) = ^BufferReadSideEffect[1] : &:r171_6, ~m165_12
|
||||||
|
# 171| m171_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r171_3
|
||||||
|
# 171| valnum = unique
|
||||||
|
# 171| m171_11(unknown) = Chi : total:m165_8, partial:m171_10
|
||||||
|
# 171| valnum = unique
|
||||||
|
# 173| r173_1(glval<int>) = VariableAddress[e] :
|
||||||
|
# 173| valnum = unique
|
||||||
|
# 173| r173_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||||
|
# 173| valnum = unique
|
||||||
|
# 173| r173_3(glval<char *>) = VariableAddress[dst] :
|
||||||
|
# 173| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||||
|
# 173| r173_4(char *) = Load[dst] : &:r173_3, m165_6
|
||||||
|
# 173| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||||
|
# 173| r173_5(char *) = Convert : r173_4
|
||||||
|
# 173| valnum = r166_5, r167_5, r173_5
|
||||||
|
# 173| r173_6(int) = Call[strlen] : func:r173_2, 0:r173_5
|
||||||
|
# 173| valnum = m173_8, r173_6
|
||||||
|
# 173| v173_7(void) = ^BufferReadSideEffect[0] : &:r173_5, ~m171_11
|
||||||
|
# 173| m173_8(int) = Store[e] : &:r173_1, r173_6
|
||||||
|
# 173| valnum = m173_8, r173_6
|
||||||
|
# 174| r174_1(glval<int>) = VariableAddress[f] :
|
||||||
|
# 174| valnum = unique
|
||||||
|
# 174| r174_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||||
|
# 174| valnum = unique
|
||||||
|
# 174| r174_3(glval<char *>) = VariableAddress[src] :
|
||||||
|
# 174| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||||
|
# 174| r174_4(char *) = Load[src] : &:r174_3, m165_10
|
||||||
|
# 174| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||||
|
# 174| r174_5(char *) = Convert : r174_4
|
||||||
|
# 174| valnum = r168_5, r169_5, r171_6, r174_5
|
||||||
|
# 174| r174_6(int) = Call[strlen] : func:r174_2, 0:r174_5
|
||||||
|
# 174| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||||
|
# 174| v174_7(void) = ^BufferReadSideEffect[0] : &:r174_5, ~m165_12
|
||||||
|
# 174| m174_8(int) = Store[f] : &:r174_1, r174_6
|
||||||
|
# 174| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||||
|
# 176| r176_1(glval<unknown>) = FunctionAddress[add] :
|
||||||
|
# 176| valnum = unique
|
||||||
|
# 176| r176_2(int) = Constant[1] :
|
||||||
|
# 176| valnum = r176_2, r178_2
|
||||||
|
# 176| r176_3(int) = Constant[2] :
|
||||||
|
# 176| valnum = r176_3, r178_3
|
||||||
|
# 176| r176_4(int) = Call[add] : func:r176_1, 0:r176_2, 1:r176_3
|
||||||
|
# 176| valnum = unique
|
||||||
|
# 177| r177_1(glval<unknown>) = FunctionAddress[add] :
|
||||||
|
# 177| valnum = unique
|
||||||
|
# 177| r177_2(int) = Constant[3] :
|
||||||
|
# 177| valnum = unique
|
||||||
|
# 177| r177_3(int) = Constant[4] :
|
||||||
|
# 177| valnum = unique
|
||||||
|
# 177| r177_4(int) = Call[add] : func:r177_1, 0:r177_2, 1:r177_3
|
||||||
|
# 177| valnum = unique
|
||||||
|
# 178| r178_1(glval<unknown>) = FunctionAddress[add] :
|
||||||
|
# 178| valnum = unique
|
||||||
|
# 178| r178_2(int) = Constant[1] :
|
||||||
|
# 178| valnum = r176_2, r178_2
|
||||||
|
# 178| r178_3(int) = Constant[2] :
|
||||||
|
# 178| valnum = r176_3, r178_3
|
||||||
|
# 178| r178_4(int) = Call[add] : func:r178_1, 0:r178_2, 1:r178_3
|
||||||
|
# 178| valnum = unique
|
||||||
|
# 179| v179_1(void) = NoOp :
|
||||||
|
# 165| v165_13(void) = ReturnIndirection[dst] : &:r165_7, m171_11
|
||||||
|
# 165| v165_14(void) = ReturnIndirection[src] : &:r165_11, m165_12
|
||||||
|
# 165| v165_15(void) = ReturnVoid :
|
||||||
|
# 165| v165_16(void) = AliasedUse : m165_3
|
||||||
|
# 165| v165_17(void) = ExitFunction :
|
||||||
|
|||||||
@@ -157,3 +157,23 @@ void test_read_global_different(int n) {
|
|||||||
|
|
||||||
int d = global_a->x;
|
int d = global_a->x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int strlen(const char *str);
|
||||||
|
char *strcat(char *dst, const char *src);
|
||||||
|
int add(int a, int b) { return a+b; }
|
||||||
|
|
||||||
|
void test_func_value_numbering(char *dst, char *src) {
|
||||||
|
int a = strlen(dst);
|
||||||
|
int b = strlen(dst); // same as previous line
|
||||||
|
int c = strlen(src);
|
||||||
|
int d = strlen(src); // same as previous line
|
||||||
|
|
||||||
|
strcat(dst, src);
|
||||||
|
|
||||||
|
int e = strlen(dst); // different from a and b
|
||||||
|
int f = strlen(src); // same as c and d
|
||||||
|
|
||||||
|
add(1, 2);
|
||||||
|
add(3, 4);
|
||||||
|
add(1, 2); // same as two lines earlier
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
| empty_block.cpp:9:10:9:11 | { ... } | Empty block without comment |
|
| empty_block.cpp:9:10:9:11 | { ... } | Empty block without comment. |
|
||||||
| empty_block.cpp:12:10:13:3 | { ... } | Empty block without comment |
|
| empty_block.cpp:12:10:13:3 | { ... } | Empty block without comment. |
|
||||||
| empty_block.cpp:20:10:21:3 | { ... } | Empty block without comment |
|
| empty_block.cpp:20:10:21:3 | { ... } | Empty block without comment. |
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
| test2.cpp:37:1:37:39 | // int myFunction() { return myValue; } | This comment appears to contain commented-out code |
|
| test2.cpp:37:1:37:39 | // int myFunction() { return myValue; } | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:39:1:39:45 | // int myFunction() const { return myValue; } | This comment appears to contain commented-out code |
|
| test2.cpp:39:1:39:45 | // int myFunction() const { return myValue; } | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:41:1:41:54 | // int myFunction() const noexcept { return myValue; } | This comment appears to contain commented-out code |
|
| test2.cpp:41:1:41:54 | // int myFunction() const noexcept { return myValue; } | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:43:1:43:18 | // #define MYMACRO | This comment appears to contain commented-out code |
|
| test2.cpp:43:1:43:18 | // #define MYMACRO | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:45:1:45:23 | // #include "include.h" | This comment appears to contain commented-out code |
|
| test2.cpp:45:1:45:23 | // #include "include.h" | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:47:1:51:2 | /*\n#ifdef\nvoid myFunction();\n#endif\n*/ | This comment appears to contain commented-out code |
|
| test2.cpp:47:1:51:2 | /*\n#ifdef\nvoid myFunction();\n#endif\n*/ | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:59:1:59:24 | // #if(defined(MYMACRO)) | This comment appears to contain commented-out code |
|
| test2.cpp:59:1:59:24 | // #if(defined(MYMACRO)) | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:63:1:63:15 | // #pragma once | This comment appears to contain commented-out code |
|
| test2.cpp:63:1:63:15 | // #pragma once | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:65:1:65:17 | // # pragma once | This comment appears to contain commented-out code |
|
| test2.cpp:65:1:65:17 | // # pragma once | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:67:1:67:19 | /*#error"myerror"*/ | This comment appears to contain commented-out code |
|
| test2.cpp:67:1:67:19 | /*#error"myerror"*/ | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:91:1:95:2 | /*\n#ifdef MYMACRO\n\t// ...\n#endif // #ifdef MYMACRO\n*/ | This comment appears to contain commented-out code |
|
| test2.cpp:91:1:95:2 | /*\n#ifdef MYMACRO\n\t// ...\n#endif // #ifdef MYMACRO\n*/ | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:107:21:107:43 | // #include "config2.h" | This comment appears to contain commented-out code |
|
| test2.cpp:107:21:107:43 | // #include "config2.h" | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:115:16:115:35 | /* #ifdef MYMACRO */ | This comment appears to contain commented-out code |
|
| test2.cpp:115:16:115:35 | /* #ifdef MYMACRO */ | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:117:1:117:24 | // commented_out_code(); | This comment appears to contain commented-out code |
|
| test2.cpp:117:1:117:24 | // commented_out_code(); | This comment appears to contain commented-out code. |
|
||||||
| test2.cpp:120:2:120:25 | // commented_out_code(); | This comment appears to contain commented-out code |
|
| test2.cpp:120:2:120:25 | // commented_out_code(); | This comment appears to contain commented-out code. |
|
||||||
| test.c:2:1:2:22 | // commented out code; | This comment appears to contain commented-out code |
|
| test.c:2:1:2:22 | // commented out code; | This comment appears to contain commented-out code. |
|
||||||
| test.c:4:1:7:8 | // some; | This comment appears to contain commented-out code |
|
| test.c:4:1:7:8 | // some; | This comment appears to contain commented-out code. |
|
||||||
| test.c:9:1:13:8 | // also; | This comment appears to contain commented-out code |
|
| test.c:9:1:13:8 | // also; | This comment appears to contain commented-out code. |
|
||||||
| test.c:21:1:26:2 | /*\n some;\n commented;\n out;\n code;\n*/ | This comment appears to contain commented-out code |
|
| test.c:21:1:26:2 | /*\n some;\n commented;\n out;\n code;\n*/ | This comment appears to contain commented-out code. |
|
||||||
| test.c:28:1:34:2 | /*\n also;\n this\n is;\n commented-out\n code;\n*/ | This comment appears to contain commented-out code |
|
| test.c:28:1:34:2 | /*\n also;\n this\n is;\n commented-out\n code;\n*/ | This comment appears to contain commented-out code. |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
| bsc.cpp:2:10:2:32 | ... > ... | Potential unsafe sign check of a bitwise operation. |
|
| bsc.cpp:2:10:2:32 | ... > ... | Potentially unsafe sign check of a bitwise operation. |
|
||||||
| bsc.cpp:6:10:6:32 | ... > ... | Potential unsafe sign check of a bitwise operation. |
|
| bsc.cpp:6:10:6:32 | ... > ... | Potentially unsafe sign check of a bitwise operation. |
|
||||||
| bsc.cpp:18:10:18:28 | ... > ... | Potential unsafe sign check of a bitwise operation. |
|
| bsc.cpp:18:10:18:28 | ... > ... | Potentially unsafe sign check of a bitwise operation. |
|
||||||
| bsc.cpp:22:10:22:28 | ... < ... | Potential unsafe sign check of a bitwise operation. |
|
| bsc.cpp:22:10:22:28 | ... < ... | Potentially unsafe sign check of a bitwise operation. |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
| c.c:10:5:10:10 | ... == ... | Equality test on floating point values may not behave as expected. |
|
| c.c:10:5:10:10 | ... == ... | Equality checks on floating point values can yield unexpected results. |
|
||||||
| c.c:14:5:14:14 | ... == ... | Equality test on floating point values may not behave as expected. |
|
| c.c:14:5:14:14 | ... == ... | Equality checks on floating point values can yield unexpected results. |
|
||||||
| c.c:16:5:16:12 | ... == ... | Equality test on floating point values may not behave as expected. |
|
| c.c:16:5:16:12 | ... == ... | Equality checks on floating point values can yield unexpected results. |
|
||||||
| c.c:17:5:17:12 | ... == ... | Equality test on floating point values may not behave as expected. |
|
| c.c:17:5:17:12 | ... == ... | Equality checks on floating point values can yield unexpected results. |
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ import csharp
|
|||||||
|
|
||||||
from CommentLine c
|
from CommentLine c
|
||||||
where c.getText().regexpMatch("(?s).*FIXME.*|.*TODO.*|.*(?<!=)\\s*XXX.*")
|
where c.getText().regexpMatch("(?s).*FIXME.*|.*TODO.*|.*(?<!=)\\s*XXX.*")
|
||||||
select c, "TODO comment."
|
select c, "TODO comments should be addressed."
|
||||||
|
|||||||
@@ -72,5 +72,5 @@ where
|
|||||||
) and
|
) and
|
||||||
m1.fromSource()
|
m1.fromSource()
|
||||||
select m1,
|
select m1,
|
||||||
"confusing to have methods " + m1.getName() + " in " + m1.getDeclaringType().getName() + " and " +
|
"It is confusing to have methods " + m1.getName() + " in " + m1.getDeclaringType().getName() +
|
||||||
m2.getName() + " in " + m2.getDeclaringType().getName() + "."
|
" and " + m2.getName() + " in " + m2.getDeclaringType().getName() + "."
|
||||||
|
|||||||
@@ -64,6 +64,5 @@ where
|
|||||||
validGuard.controls(array, index) and
|
validGuard.controls(array, index) and
|
||||||
validGuard.guards(indexAccess, _)
|
validGuard.guards(indexAccess, _)
|
||||||
)
|
)
|
||||||
select incorrectGuard,
|
select incorrectGuard, "Off-by-one index comparison against length may lead to out-of-bounds $@.",
|
||||||
"Off-by-one index comparison against length leads to possible out of bounds $@.", ea,
|
ea, ea.toString()
|
||||||
ea.toString()
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* @name Equality check on floating point values
|
* @name Equality check on floating point values
|
||||||
* @description Equality checks on floating point values can yield unexpected results.
|
* @description Comparing results of floating-point computations with '==' or
|
||||||
|
* '!=' is likely to yield surprising results since floating-point
|
||||||
|
* computation does not follow the standard rules of algebra.
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ where
|
|||||||
(loopStmtWithEmptyBlock(s) or conditionalWithEmptyBlock(s)) and
|
(loopStmtWithEmptyBlock(s) or conditionalWithEmptyBlock(s)) and
|
||||||
not exists(CommentBlock c | c.getParent() = s) and
|
not exists(CommentBlock c | c.getParent() = s) and
|
||||||
not exists(ForStmt fs | fs.getBody() = s and exists(fs.getAnUpdate()))
|
not exists(ForStmt fs | fs.getBody() = s and exists(fs.getAnUpdate()))
|
||||||
select s, "Empty block."
|
select s, "Empty block without comment."
|
||||||
|
|||||||
@@ -35,4 +35,4 @@ where
|
|||||||
access = cast.getAChild() and
|
access = cast.getAChild() and
|
||||||
access.getTarget().getDeclaringElement() = access.getEnclosingCallable() and
|
access.getTarget().getDeclaringElement() = access.getEnclosingCallable() and
|
||||||
nodeBeforeParameterAccess(access.getAControlFlowNode())
|
nodeBeforeParameterAccess(access.getAControlFlowNode())
|
||||||
select cast, "Missing type-check before casting parameter to 'Equals'."
|
select cast, "Equals() method does not check argument type."
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ where
|
|||||||
c.hasFlowPath(source, sink) and
|
c.hasFlowPath(source, sink) and
|
||||||
// No global timeout set
|
// No global timeout set
|
||||||
not exists(RegexGlobalTimeout r)
|
not exists(RegexGlobalTimeout r)
|
||||||
select sink.getNode(), source, sink, "$@ flows to the construction of a regular expression.",
|
select sink.getNode(), source, sink, "This regular expression is constructed from a $@.",
|
||||||
source.getNode(), "User-provided value"
|
source.getNode(), "user-provided value"
|
||||||
|
|||||||
@@ -18,4 +18,4 @@ from MethodCall mc
|
|||||||
where
|
where
|
||||||
mc instanceof ImplicitToStringExpr and
|
mc instanceof ImplicitToStringExpr and
|
||||||
mc.getTarget() instanceof ToStringMethod
|
mc.getTarget() instanceof ToStringMethod
|
||||||
select mc, "Redundant call to 'ToString'."
|
select mc, "Redundant call to 'ToString' on a String object."
|
||||||
|
|||||||
4
csharp/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
4
csharp/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The alert message of many queries have been changed to make the message consistent with other languages.
|
||||||
@@ -17,3 +17,5 @@ module SSA {
|
|||||||
|
|
||||||
predicate hasUnreachedInstruction(IRFunctionBase irFunc) { none() }
|
predicate hasUnreachedInstruction(IRFunctionBase irFunc) { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predicate removedInstruction(TRawInstruction instr) { none() }
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ newtype TInstruction =
|
|||||||
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||||
} or
|
} or
|
||||||
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
||||||
|
not AliasedSsa::removedInstruction(primaryInstruction) and
|
||||||
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
||||||
} or
|
} or
|
||||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||||
|
|||||||
@@ -1712,6 +1712,11 @@ class SideEffectInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1723,6 +1728,11 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
|||||||
*/
|
*/
|
||||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import experimental.ir.internal.Overlap
|
import experimental.ir.internal.Overlap
|
||||||
import experimental.ir.internal.IRCSharpLanguage as Language
|
import experimental.ir.internal.IRCSharpLanguage as Language
|
||||||
import experimental.ir.implementation.unaliased_ssa.IR
|
import experimental.ir.implementation.unaliased_ssa.IR
|
||||||
|
import experimental.ir.interfaces.SideEffect as SideEffect
|
||||||
|
|||||||
@@ -41,8 +41,92 @@ newtype TValueNumber =
|
|||||||
) {
|
) {
|
||||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||||
} or
|
} or
|
||||||
|
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||||
|
|
||||||
|
private class NumberableCallInstruction extends CallInstruction {
|
||||||
|
NumberableCallInstruction() {
|
||||||
|
not this.getResultIRType() instanceof IRVoidType and
|
||||||
|
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||||
|
sideEffectFunc = this.getStaticCallTarget()
|
||||||
|
|
|
||||||
|
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||||
|
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private newtype TCallPartialValueNumber =
|
||||||
|
TNilArgument() or
|
||||||
|
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||||
|
exists(NumberableCallInstruction call, int index |
|
||||||
|
callArgValueNumber(call, index, arg) and
|
||||||
|
callPartialValueNumber(call, index, head)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||||
|
) {
|
||||||
|
index = max(int n | callArgRank(call, n, _) | n) and
|
||||||
|
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||||
|
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||||
|
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||||
|
vn = TArgument(head, arg)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
not exists(int n | callArgRank(call, n, _)) and
|
||||||
|
index = -1 and
|
||||||
|
vn = TNilArgument()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callPartialValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||||
|
) {
|
||||||
|
exists(call) and
|
||||||
|
index = 1 and
|
||||||
|
head = TNilArgument()
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||||
|
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||||
|
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||||
|
head = TArgument(prev, prevVN)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||||
|
exists(Instruction instr |
|
||||||
|
callArgRank(call, index, instr) and
|
||||||
|
arg = tvalueNumber(instr)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||||
|
* argument and side-effect reads.
|
||||||
|
*/
|
||||||
|
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||||
|
arg =
|
||||||
|
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||||
|
// There is no need to include the call's read and write side effects on
|
||||||
|
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||||
|
// to all-aliased-memory.
|
||||||
|
instr = call.getArgument(argIndex) and
|
||||||
|
isEffect = false
|
||||||
|
or
|
||||||
|
exists(ReadSideEffectInstruction read |
|
||||||
|
read.getPrimaryInstruction() = call and
|
||||||
|
read.getSideEffectOperand().getAnyDef() = instr and
|
||||||
|
read.getIndex() = argIndex and
|
||||||
|
isEffect = true
|
||||||
|
)
|
||||||
|
|
|
||||||
|
instr order by argIndex, isEffect
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||||
* operand.
|
* operand.
|
||||||
@@ -93,6 +177,8 @@ private predicate numberableInstruction(Instruction instr) {
|
|||||||
instr instanceof CongruentCopyInstruction
|
instr instanceof CongruentCopyInstruction
|
||||||
or
|
or
|
||||||
instr instanceof LoadTotalOverlapInstruction
|
instr instanceof LoadTotalOverlapInstruction
|
||||||
|
or
|
||||||
|
instr instanceof NumberableCallInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||||
@@ -309,6 +395,11 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
|||||||
or
|
or
|
||||||
// The value number of a copy is just the value number of its source value.
|
// The value number of a copy is just the value number of its source value.
|
||||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber pvn |
|
||||||
|
callValueNumber(instr, _, pvn) and
|
||||||
|
result = TCallValueNumber(pvn)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1712,6 +1712,11 @@ class SideEffectInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1723,6 +1728,11 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
|||||||
*/
|
*/
|
||||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||||
|
|
||||||
|
/** Gets the operand for the value that will be read by this instruction */
|
||||||
|
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||||
|
|
||||||
|
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import experimental.ir.internal.Overlap
|
import experimental.ir.internal.Overlap
|
||||||
import experimental.ir.internal.IRCSharpLanguage as Language
|
import experimental.ir.internal.IRCSharpLanguage as Language
|
||||||
import experimental.ir.implementation.unaliased_ssa.IR
|
import experimental.ir.implementation.unaliased_ssa.IR
|
||||||
|
import experimental.ir.interfaces.SideEffect as SideEffect
|
||||||
|
|||||||
@@ -41,8 +41,92 @@ newtype TValueNumber =
|
|||||||
) {
|
) {
|
||||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||||
} or
|
} or
|
||||||
|
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||||
|
|
||||||
|
private class NumberableCallInstruction extends CallInstruction {
|
||||||
|
NumberableCallInstruction() {
|
||||||
|
not this.getResultIRType() instanceof IRVoidType and
|
||||||
|
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||||
|
sideEffectFunc = this.getStaticCallTarget()
|
||||||
|
|
|
||||||
|
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||||
|
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private newtype TCallPartialValueNumber =
|
||||||
|
TNilArgument() or
|
||||||
|
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||||
|
exists(NumberableCallInstruction call, int index |
|
||||||
|
callArgValueNumber(call, index, arg) and
|
||||||
|
callPartialValueNumber(call, index, head)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||||
|
) {
|
||||||
|
index = max(int n | callArgRank(call, n, _) | n) and
|
||||||
|
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||||
|
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||||
|
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||||
|
vn = TArgument(head, arg)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
not exists(int n | callArgRank(call, n, _)) and
|
||||||
|
index = -1 and
|
||||||
|
vn = TNilArgument()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate callPartialValueNumber(
|
||||||
|
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||||
|
) {
|
||||||
|
exists(call) and
|
||||||
|
index = 1 and
|
||||||
|
head = TNilArgument()
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||||
|
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||||
|
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||||
|
head = TArgument(prev, prevVN)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||||
|
exists(Instruction instr |
|
||||||
|
callArgRank(call, index, instr) and
|
||||||
|
arg = tvalueNumber(instr)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||||
|
* argument and side-effect reads.
|
||||||
|
*/
|
||||||
|
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||||
|
arg =
|
||||||
|
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||||
|
// There is no need to include the call's read and write side effects on
|
||||||
|
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||||
|
// to all-aliased-memory.
|
||||||
|
instr = call.getArgument(argIndex) and
|
||||||
|
isEffect = false
|
||||||
|
or
|
||||||
|
exists(ReadSideEffectInstruction read |
|
||||||
|
read.getPrimaryInstruction() = call and
|
||||||
|
read.getSideEffectOperand().getAnyDef() = instr and
|
||||||
|
read.getIndex() = argIndex and
|
||||||
|
isEffect = true
|
||||||
|
)
|
||||||
|
|
|
||||||
|
instr order by argIndex, isEffect
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||||
* operand.
|
* operand.
|
||||||
@@ -93,6 +177,8 @@ private predicate numberableInstruction(Instruction instr) {
|
|||||||
instr instanceof CongruentCopyInstruction
|
instr instanceof CongruentCopyInstruction
|
||||||
or
|
or
|
||||||
instr instanceof LoadTotalOverlapInstruction
|
instr instanceof LoadTotalOverlapInstruction
|
||||||
|
or
|
||||||
|
instr instanceof NumberableCallInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||||
@@ -309,6 +395,11 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
|||||||
or
|
or
|
||||||
// The value number of a copy is just the value number of its source value.
|
// The value number of a copy is just the value number of its source value.
|
||||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||||
|
or
|
||||||
|
exists(TCallPartialValueNumber pvn |
|
||||||
|
callValueNumber(instr, _, pvn) and
|
||||||
|
result = TCallValueNumber(pvn)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ private import Imports::RawIR as RawIR
|
|||||||
private import SsaInstructions
|
private import SsaInstructions
|
||||||
private import SsaOperands
|
private import SsaOperands
|
||||||
private import NewIR
|
private import NewIR
|
||||||
|
|
||||||
private class OldBlock = Reachability::ReachableBlock;
|
|
||||||
|
|
||||||
private class OldInstruction = Reachability::ReachableInstruction;
|
|
||||||
|
|
||||||
import Cached
|
import Cached
|
||||||
|
|
||||||
cached
|
cached
|
||||||
@@ -58,7 +53,9 @@ private module Cached {
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
predicate hasInstruction(TStageInstruction instr) {
|
predicate hasInstruction(TStageInstruction instr) {
|
||||||
instr instanceof TRawInstruction and instr instanceof OldInstruction
|
instr instanceof TRawInstruction and
|
||||||
|
instr instanceof OldInstruction and
|
||||||
|
not removedInstruction(instr)
|
||||||
or
|
or
|
||||||
instr = phiInstruction(_, _)
|
instr = phiInstruction(_, _)
|
||||||
or
|
or
|
||||||
@@ -382,7 +379,14 @@ private module Cached {
|
|||||||
(
|
(
|
||||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
||||||
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
||||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
else
|
||||||
|
if removedInstruction(oldInstruction.getSuccessor(kind))
|
||||||
|
then
|
||||||
|
// the only removed nodes are side-effect writes, but those may have Chi nodes
|
||||||
|
// skip to the following instruction in the old IR, which won't be removed
|
||||||
|
// if we start skipping specific side effects, this may no longer hold
|
||||||
|
result = getNewInstruction(oldInstruction.getSuccessor(kind).getSuccessor(kind))
|
||||||
|
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -14,3 +14,9 @@ import experimental.ir.implementation.internal.TOperand::UnaliasedSsaOperands as
|
|||||||
|
|
||||||
/** DEPRECATED: Alias for SsaOperands */
|
/** DEPRECATED: Alias for SsaOperands */
|
||||||
deprecated module SSAOperands = SsaOperands;
|
deprecated module SSAOperands = SsaOperands;
|
||||||
|
|
||||||
|
predicate removedInstruction(Reachability::ReachableInstruction instr) { none() }
|
||||||
|
|
||||||
|
class OldBlock = Reachability::ReachableBlock;
|
||||||
|
|
||||||
|
class OldInstruction = Reachability::ReachableInstruction;
|
||||||
|
|||||||
24
csharp/ql/src/experimental/ir/interfaces/SideEffect.qll
Normal file
24
csharp/ql/src/experimental/ir/interfaces/SideEffect.qll
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
private import csharp as CSharp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that models the side effects of a library function.
|
||||||
|
*/
|
||||||
|
abstract class SideEffectFunction extends CSharp::Callable {
|
||||||
|
/**
|
||||||
|
* Holds if the function never reads from memory that was defined before entry to the function.
|
||||||
|
* This memory could be from global variables, or from other memory that was reachable from a
|
||||||
|
* pointer that was passed into the function. Input side-effects, and reads from memory that
|
||||||
|
* cannot be visible to the caller (for example a buffer inside an I/O library) are not modeled
|
||||||
|
* here.
|
||||||
|
*/
|
||||||
|
abstract predicate hasOnlySpecificReadSideEffects();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the function never writes to memory that remains allocated after the function
|
||||||
|
* returns. This memory could be from global variables, or from other memory that was reachable
|
||||||
|
* from a pointer that was passed into the function. Output side-effects, and writes to memory
|
||||||
|
* that cannot be visible to the caller (for example a buffer inside an I/O library) are not
|
||||||
|
* modeled here.
|
||||||
|
*/
|
||||||
|
abstract predicate hasOnlySpecificWriteSideEffects();
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
| TodoComments.cs:4:5:4:26 | // ... | TODO comment. |
|
| TodoComments.cs:4:5:4:26 | // ... | TODO comments should be addressed. |
|
||||||
| TodoComments.cs:5:5:5:27 | // ... | TODO comment. |
|
| TodoComments.cs:5:5:5:27 | // ... | TODO comments should be addressed. |
|
||||||
| TodoCommentsBad.cs:7:9:7:41 | // ... | TODO comment. |
|
| TodoCommentsBad.cs:7:9:7:41 | // ... | TODO comments should be addressed. |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| EmptyBlock.cs:9:9:10:9 | {...} | Empty block. |
|
| EmptyBlock.cs:9:9:10:9 | {...} | Empty block without comment. |
|
||||||
| EmptyBlock.cs:26:9:27:9 | {...} | Empty block. |
|
| EmptyBlock.cs:26:9:27:9 | {...} | Empty block without comment. |
|
||||||
| EmptyBlock.cs:48:9:49:9 | {...} | Empty block. |
|
| EmptyBlock.cs:48:9:49:9 | {...} | Empty block without comment. |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
| ContainerLengthCmpOffByOne.cs:8:25:8:40 | ... <= ... | Off-by-one index comparison against length leads to possible out of bounds $@. | ContainerLengthCmpOffByOne.cs:10:31:10:37 | access to array element | access to array element |
|
| ContainerLengthCmpOffByOne.cs:8:25:8:40 | ... <= ... | Off-by-one index comparison against length may lead to out-of-bounds $@. | ContainerLengthCmpOffByOne.cs:10:31:10:37 | access to array element | access to array element |
|
||||||
| ContainerLengthCmpOffByOne.cs:14:25:14:40 | ... >= ... | Off-by-one index comparison against length leads to possible out of bounds $@. | ContainerLengthCmpOffByOne.cs:16:31:16:37 | access to array element | access to array element |
|
| ContainerLengthCmpOffByOne.cs:14:25:14:40 | ... >= ... | Off-by-one index comparison against length may lead to out-of-bounds $@. | ContainerLengthCmpOffByOne.cs:16:31:16:37 | access to array element | access to array element |
|
||||||
| ContainerLengthCmpOffByOne.cs:27:13:27:28 | ... <= ... | Off-by-one index comparison against length leads to possible out of bounds $@. | ContainerLengthCmpOffByOne.cs:29:31:29:37 | access to array element | access to array element |
|
| ContainerLengthCmpOffByOne.cs:27:13:27:28 | ... <= ... | Off-by-one index comparison against length may lead to out-of-bounds $@. | ContainerLengthCmpOffByOne.cs:29:31:29:37 | access to array element | access to array element |
|
||||||
| ContainerLengthCmpOffByOne.cs:33:13:33:28 | ... >= ... | Off-by-one index comparison against length leads to possible out of bounds $@. | ContainerLengthCmpOffByOne.cs:35:31:35:37 | access to array element | access to array element |
|
| ContainerLengthCmpOffByOne.cs:33:13:33:28 | ... >= ... | Off-by-one index comparison against length may lead to out-of-bounds $@. | ContainerLengthCmpOffByOne.cs:35:31:35:37 | access to array element | access to array element |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| UncheckedCastInEquals.cs:7:17:7:27 | (...) ... | Missing type-check before casting parameter to 'Equals'. |
|
| UncheckedCastInEquals.cs:7:17:7:27 | (...) ... | Equals() method does not check argument type. |
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ nodes
|
|||||||
| RegexInjection.cs:14:19:14:23 | access to local variable regex | semmle.label | access to local variable regex |
|
| RegexInjection.cs:14:19:14:23 | access to local variable regex | semmle.label | access to local variable regex |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| RegexInjection.cs:14:19:14:23 | access to local variable regex | RegexInjection.cs:10:24:10:46 | access to property QueryString : NameValueCollection | RegexInjection.cs:14:19:14:23 | access to local variable regex | $@ flows to the construction of a regular expression. | RegexInjection.cs:10:24:10:46 | access to property QueryString | User-provided value |
|
| RegexInjection.cs:14:19:14:23 | access to local variable regex | RegexInjection.cs:10:24:10:46 | access to property QueryString : NameValueCollection | RegexInjection.cs:14:19:14:23 | access to local variable regex | This regular expression is constructed from a $@. | RegexInjection.cs:10:24:10:46 | access to property QueryString | user-provided value |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| RedundantToStringCall.cs:7:27:7:38 | call to method ToString | Redundant call to 'ToString'. |
|
| RedundantToStringCall.cs:7:27:7:38 | call to method ToString | Redundant call to 'ToString' on a String object. |
|
||||||
| RedundantToStringCall.cs:10:37:10:48 | call to method ToString | Redundant call to 'ToString'. |
|
| RedundantToStringCall.cs:10:37:10:48 | call to method ToString | Redundant call to 'ToString' on a String object. |
|
||||||
| RedundantToStringCallBad.cs:7:45:7:56 | call to method ToString | Redundant call to 'ToString'. |
|
| RedundantToStringCallBad.cs:7:45:7:56 | call to method ToString | Redundant call to 'ToString' on a String object. |
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ import DataFlow::PathGraph
|
|||||||
|
|
||||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
where cfg.hasFlowPath(source, sink)
|
where cfg.hasFlowPath(source, sink)
|
||||||
select sink.getNode(), source, sink, "This path depends on $@.", source.getNode(),
|
select sink.getNode(), source, sink, "$@ flows to here and is used in a path.", source.getNode(),
|
||||||
"a user-provided value"
|
"User-provided value"
|
||||||
|
|||||||
@@ -76,5 +76,6 @@ class StackTraceExposureConfig extends TaintTracking::Configuration {
|
|||||||
|
|
||||||
from StackTraceExposureConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
from StackTraceExposureConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
where cfg.hasFlowPath(source, sink)
|
where cfg.hasFlowPath(source, sink)
|
||||||
select source.getNode(), source, sink, "This stack trace is exposed to a remote user $@.",
|
select sink.getNode(), source, sink,
|
||||||
sink.getNode(), "here"
|
"Stack trace information from $@ may be exposed to an external user here.", source.getNode(),
|
||||||
|
"here"
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ predicate isStringOrByte(DataFlow::PathNode node) {
|
|||||||
|
|
||||||
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
where config.hasFlowPath(source, sink) and isStringOrByte(sink)
|
where config.hasFlowPath(source, sink) and isStringOrByte(sink)
|
||||||
select sink.getNode(), source, sink, "$@ flows here and is used in an XPath expression.",
|
select sink.getNode(), source, sink, "$@ flows to here and is used in an XPath expression.",
|
||||||
source.getNode(), "A user-provided value"
|
source.getNode(), "User-provided value"
|
||||||
|
|||||||
4
go/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
4
go/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The alert message of many queries have been changed to make the message consistent with other languages.
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Not using `pam.AcctMgmt` after `pam.Authenticate` to check the validity of a login can lead to authorization bypass.
|
* @description Not using `pam.AcctMgmt` after `pam.Authenticate` to check the validity of a login can lead to authorization bypass.
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @id go/unreachable-statement
|
* @id go/pam-auth-bypass
|
||||||
* @tags maintainability
|
* @tags maintainability
|
||||||
* correctness
|
* correctness
|
||||||
* external/cwe/cwe-561
|
* external/cwe/cwe-561
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ nodes
|
|||||||
| test.go:211:35:211:43 | untrusted | semmle.label | untrusted |
|
| test.go:211:35:211:43 | untrusted | semmle.label | untrusted |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.go:209:18:209:26 | untrusted | test.go:208:15:208:26 | call to Data : map type | test.go:209:18:209:26 | untrusted | This path depends on $@. | test.go:208:15:208:26 | call to Data | a user-provided value |
|
| test.go:209:18:209:26 | untrusted | test.go:208:15:208:26 | call to Data : map type | test.go:209:18:209:26 | untrusted | $@ flows to here and is used in a path. | test.go:208:15:208:26 | call to Data | User-provided value |
|
||||||
| test.go:210:10:210:18 | untrusted | test.go:208:15:208:26 | call to Data : map type | test.go:210:10:210:18 | untrusted | This path depends on $@. | test.go:208:15:208:26 | call to Data | a user-provided value |
|
| test.go:210:10:210:18 | untrusted | test.go:208:15:208:26 | call to Data : map type | test.go:210:10:210:18 | untrusted | $@ flows to here and is used in a path. | test.go:208:15:208:26 | call to Data | User-provided value |
|
||||||
| test.go:211:35:211:43 | untrusted | test.go:208:15:208:26 | call to Data : map type | test.go:211:35:211:43 | untrusted | This path depends on $@. | test.go:208:15:208:26 | call to Data | a user-provided value |
|
| test.go:211:35:211:43 | untrusted | test.go:208:15:208:26 | call to Data : map type | test.go:211:35:211:43 | untrusted | $@ flows to here and is used in a path. | test.go:208:15:208:26 | call to Data | User-provided value |
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ nodes
|
|||||||
| EndToEnd.go:64:26:64:55 | call to Get | semmle.label | call to Get |
|
| EndToEnd.go:64:26:64:55 | call to Get | semmle.label | call to Get |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| EndToEnd.go:58:18:58:47 | call to Get | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:47 | call to Get | This path depends on $@. | EndToEnd.go:58:18:58:25 | selection of Params | a user-provided value |
|
| EndToEnd.go:58:18:58:47 | call to Get | EndToEnd.go:58:18:58:25 | selection of Params : pointer type | EndToEnd.go:58:18:58:47 | call to Get | $@ flows to here and is used in a path. | EndToEnd.go:58:18:58:25 | selection of Params | User-provided value |
|
||||||
| EndToEnd.go:64:26:64:55 | call to Get | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:55 | call to Get | This path depends on $@. | EndToEnd.go:64:26:64:33 | selection of Params | a user-provided value |
|
| EndToEnd.go:64:26:64:55 | call to Get | EndToEnd.go:64:26:64:33 | selection of Params : pointer type | EndToEnd.go:64:26:64:55 | call to Get | $@ flows to here and is used in a path. | EndToEnd.go:64:26:64:33 | selection of Params | User-provided value |
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ nodes
|
|||||||
| tst.go:17:41:17:56 | selection of Filename | semmle.label | selection of Filename |
|
| tst.go:17:41:17:56 | selection of Filename | semmle.label | selection of Filename |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| TaintedPath.go:16:29:16:40 | tainted_path | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:16:29:16:40 | tainted_path | This path depends on $@. | TaintedPath.go:13:18:13:22 | selection of URL | a user-provided value |
|
| TaintedPath.go:16:29:16:40 | tainted_path | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:16:29:16:40 | tainted_path | $@ flows to here and is used in a path. | TaintedPath.go:13:18:13:22 | selection of URL | User-provided value |
|
||||||
| TaintedPath.go:20:28:20:69 | call to Join | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:20:28:20:69 | call to Join | This path depends on $@. | TaintedPath.go:13:18:13:22 | selection of URL | a user-provided value |
|
| TaintedPath.go:20:28:20:69 | call to Join | TaintedPath.go:13:18:13:22 | selection of URL : pointer type | TaintedPath.go:20:28:20:69 | call to Join | $@ flows to here and is used in a path. | TaintedPath.go:13:18:13:22 | selection of URL | User-provided value |
|
||||||
| tst.go:17:41:17:56 | selection of Filename | tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:56 | selection of Filename | This path depends on $@. | tst.go:14:2:14:39 | ... := ...[1] | a user-provided value |
|
| tst.go:17:41:17:56 | selection of Filename | tst.go:14:2:14:39 | ... := ...[1] : pointer type | tst.go:17:41:17:56 | selection of Filename | $@ flows to here and is used in a path. | tst.go:14:2:14:39 | ... := ...[1] | User-provided value |
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ nodes
|
|||||||
| test.go:17:10:17:12 | buf | semmle.label | buf |
|
| test.go:17:10:17:12 | buf | semmle.label | buf |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.go:14:2:14:4 | definition of buf | test.go:14:2:14:4 | definition of buf : slice type | test.go:17:10:17:12 | buf | This stack trace is exposed to a remote user $@. | test.go:17:10:17:12 | buf | here |
|
| test.go:17:10:17:12 | buf | test.go:14:2:14:4 | definition of buf : slice type | test.go:17:10:17:12 | buf | Stack trace information from $@ may be exposed to an external user here. | test.go:14:2:14:4 | definition of buf | here |
|
||||||
|
|||||||
@@ -85,43 +85,43 @@ nodes
|
|||||||
| tst.go:180:27:180:122 | ...+... | semmle.label | ...+... |
|
| tst.go:180:27:180:122 | ...+... | semmle.label | ...+... |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| XPathInjection.go:16:29:16:91 | ...+... | XPathInjection.go:13:14:13:19 | selection of Form : Values | XPathInjection.go:16:29:16:91 | ...+... | $@ flows here and is used in an XPath expression. | XPathInjection.go:13:14:13:19 | selection of Form | A user-provided value |
|
| XPathInjection.go:16:29:16:91 | ...+... | XPathInjection.go:13:14:13:19 | selection of Form : Values | XPathInjection.go:16:29:16:91 | ...+... | $@ flows to here and is used in an XPath expression. | XPathInjection.go:13:14:13:19 | selection of Form | User-provided value |
|
||||||
| tst.go:35:23:35:85 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:35:23:35:85 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:32:14:32:19 | selection of Form | A user-provided value |
|
| tst.go:35:23:35:85 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:35:23:35:85 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:32:14:32:19 | selection of Form | User-provided value |
|
||||||
| tst.go:38:24:38:86 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:38:24:38:86 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:32:14:32:19 | selection of Form | A user-provided value |
|
| tst.go:38:24:38:86 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:38:24:38:86 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:32:14:32:19 | selection of Form | User-provided value |
|
||||||
| tst.go:41:24:41:82 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:41:24:41:82 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:32:14:32:19 | selection of Form | A user-provided value |
|
| tst.go:41:24:41:82 | ...+... | tst.go:32:14:32:19 | selection of Form : Values | tst.go:41:24:41:82 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:32:14:32:19 | selection of Form | User-provided value |
|
||||||
| tst.go:49:26:49:84 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:49:26:49:84 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | A user-provided value |
|
| tst.go:49:26:49:84 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:49:26:49:84 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | User-provided value |
|
||||||
| tst.go:52:29:52:87 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:52:29:52:87 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | A user-provided value |
|
| tst.go:52:29:52:87 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:52:29:52:87 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | User-provided value |
|
||||||
| tst.go:55:33:55:91 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:55:33:55:91 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | A user-provided value |
|
| tst.go:55:33:55:91 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:55:33:55:91 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | User-provided value |
|
||||||
| tst.go:58:30:58:88 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:58:30:58:88 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | A user-provided value |
|
| tst.go:58:30:58:88 | ...+... | tst.go:46:14:46:19 | selection of Form : Values | tst.go:58:30:58:88 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:46:14:46:19 | selection of Form | User-provided value |
|
||||||
| tst.go:66:25:66:83 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:66:25:66:83 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:66:25:66:83 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:66:25:66:83 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:69:28:69:86 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:69:28:69:86 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:69:28:69:86 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:69:28:69:86 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:72:25:72:83 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:72:25:72:83 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:72:25:72:83 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:72:25:72:83 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:75:34:75:92 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:75:34:75:92 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:75:34:75:92 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:75:34:75:92 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:78:32:78:90 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:78:32:78:90 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:78:32:78:90 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:78:32:78:90 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:81:29:81:87 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:81:29:81:87 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:81:29:81:87 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:81:29:81:87 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:84:23:84:85 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:84:23:84:85 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:84:23:84:85 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:84:23:84:85 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:87:22:87:84 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:87:22:87:84 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | A user-provided value |
|
| tst.go:87:22:87:84 | ...+... | tst.go:63:14:63:19 | selection of Form : Values | tst.go:87:22:87:84 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:63:14:63:19 | selection of Form | User-provided value |
|
||||||
| tst.go:95:26:95:84 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:95:26:95:84 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | A user-provided value |
|
| tst.go:95:26:95:84 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:95:26:95:84 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | User-provided value |
|
||||||
| tst.go:98:29:98:87 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:98:29:98:87 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | A user-provided value |
|
| tst.go:98:29:98:87 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:98:29:98:87 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | User-provided value |
|
||||||
| tst.go:101:33:101:91 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:101:33:101:91 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | A user-provided value |
|
| tst.go:101:33:101:91 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:101:33:101:91 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | User-provided value |
|
||||||
| tst.go:104:30:104:88 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:104:30:104:88 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | A user-provided value |
|
| tst.go:104:30:104:88 | ...+... | tst.go:92:14:92:19 | selection of Form : Values | tst.go:104:30:104:88 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:92:14:92:19 | selection of Form | User-provided value |
|
||||||
| tst.go:112:25:112:87 | ...+... | tst.go:109:14:109:19 | selection of Form : Values | tst.go:112:25:112:87 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:109:14:109:19 | selection of Form | A user-provided value |
|
| tst.go:112:25:112:87 | ...+... | tst.go:109:14:109:19 | selection of Form : Values | tst.go:112:25:112:87 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:109:14:109:19 | selection of Form | User-provided value |
|
||||||
| tst.go:115:26:115:88 | ...+... | tst.go:109:14:109:19 | selection of Form : Values | tst.go:115:26:115:88 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:109:14:109:19 | selection of Form | A user-provided value |
|
| tst.go:115:26:115:88 | ...+... | tst.go:109:14:109:19 | selection of Form : Values | tst.go:115:26:115:88 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:109:14:109:19 | selection of Form | User-provided value |
|
||||||
| tst.go:124:23:124:126 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:120:14:120:19 | selection of Form | A user-provided value |
|
| tst.go:124:23:124:126 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:120:14:120:19 | selection of Form | User-provided value |
|
||||||
| tst.go:124:23:124:126 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:121:14:121:19 | selection of Form | A user-provided value |
|
| tst.go:124:23:124:126 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:124:23:124:126 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:121:14:121:19 | selection of Form | User-provided value |
|
||||||
| tst.go:127:24:127:127 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:120:14:120:19 | selection of Form | A user-provided value |
|
| tst.go:127:24:127:127 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:120:14:120:19 | selection of Form | User-provided value |
|
||||||
| tst.go:127:24:127:127 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:121:14:121:19 | selection of Form | A user-provided value |
|
| tst.go:127:24:127:127 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:127:24:127:127 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:121:14:121:19 | selection of Form | User-provided value |
|
||||||
| tst.go:130:27:130:122 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:120:14:120:19 | selection of Form | A user-provided value |
|
| tst.go:130:27:130:122 | ...+... | tst.go:120:14:120:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:120:14:120:19 | selection of Form | User-provided value |
|
||||||
| tst.go:130:27:130:122 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:121:14:121:19 | selection of Form | A user-provided value |
|
| tst.go:130:27:130:122 | ...+... | tst.go:121:14:121:19 | selection of Form : Values | tst.go:130:27:130:122 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:121:14:121:19 | selection of Form | User-provided value |
|
||||||
| tst.go:141:27:141:89 | ...+... | tst.go:138:14:138:19 | selection of Form : Values | tst.go:141:27:141:89 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:138:14:138:19 | selection of Form | A user-provided value |
|
| tst.go:141:27:141:89 | ...+... | tst.go:138:14:138:19 | selection of Form : Values | tst.go:141:27:141:89 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:138:14:138:19 | selection of Form | User-provided value |
|
||||||
| tst.go:144:28:144:90 | ...+... | tst.go:138:14:138:19 | selection of Form : Values | tst.go:144:28:144:90 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:138:14:138:19 | selection of Form | A user-provided value |
|
| tst.go:144:28:144:90 | ...+... | tst.go:138:14:138:19 | selection of Form : Values | tst.go:144:28:144:90 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:138:14:138:19 | selection of Form | User-provided value |
|
||||||
| tst.go:153:33:153:136 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | A user-provided value |
|
| tst.go:153:33:153:136 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | User-provided value |
|
||||||
| tst.go:153:33:153:136 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | A user-provided value |
|
| tst.go:153:33:153:136 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:153:33:153:136 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | User-provided value |
|
||||||
| tst.go:156:18:156:121 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | A user-provided value |
|
| tst.go:156:18:156:121 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | User-provided value |
|
||||||
| tst.go:156:18:156:121 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | A user-provided value |
|
| tst.go:156:18:156:121 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:156:18:156:121 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | User-provided value |
|
||||||
| tst.go:162:31:162:126 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | A user-provided value |
|
| tst.go:162:31:162:126 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | User-provided value |
|
||||||
| tst.go:162:31:162:126 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | A user-provided value |
|
| tst.go:162:31:162:126 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:162:31:162:126 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | User-provided value |
|
||||||
| tst.go:171:21:171:116 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | A user-provided value |
|
| tst.go:171:21:171:116 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | User-provided value |
|
||||||
| tst.go:171:21:171:116 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | A user-provided value |
|
| tst.go:171:21:171:116 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:171:21:171:116 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | User-provided value |
|
||||||
| tst.go:180:27:180:122 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | A user-provided value |
|
| tst.go:180:27:180:122 | ...+... | tst.go:149:14:149:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:149:14:149:19 | selection of Form | User-provided value |
|
||||||
| tst.go:180:27:180:122 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | $@ flows here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | A user-provided value |
|
| tst.go:180:27:180:122 | ...+... | tst.go:150:14:150:19 | selection of Form : Values | tst.go:180:27:180:122 | ...+... | $@ flows to here and is used in an XPath expression. | tst.go:150:14:150:19 | selection of Form | User-provided value |
|
||||||
|
|||||||
@@ -1584,7 +1584,7 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
|
private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.findSubType<IrFunction> { it.name.asString() == name }
|
||||||
|
|
||||||
val jvmIntrinsicsClass by lazy {
|
val jvmIntrinsicsClass by lazy {
|
||||||
val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner
|
val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner
|
||||||
@@ -1641,12 +1641,11 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val stringValueOfObjectMethod by lazy {
|
val stringValueOfObjectMethod by lazy {
|
||||||
val result = javaLangString?.declarations?.find {
|
val result = javaLangString?.declarations?.findSubType<IrFunction> {
|
||||||
it is IrFunction &&
|
|
||||||
it.name.asString() == "valueOf" &&
|
it.name.asString() == "valueOf" &&
|
||||||
it.valueParameters.size == 1 &&
|
it.valueParameters.size == 1 &&
|
||||||
it.valueParameters[0].type == pluginContext.irBuiltIns.anyNType
|
it.valueParameters[0].type == pluginContext.irBuiltIns.anyNType
|
||||||
} as IrFunction?
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
logger.error("Couldn't find declaration java.lang.String.valueOf(Object)")
|
logger.error("Couldn't find declaration java.lang.String.valueOf(Object)")
|
||||||
}
|
}
|
||||||
@@ -1654,9 +1653,9 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val objectCloneMethod by lazy {
|
val objectCloneMethod by lazy {
|
||||||
val result = javaLangObject?.declarations?.find {
|
val result = javaLangObject?.declarations?.findSubType<IrFunction> {
|
||||||
it is IrFunction && it.name.asString() == "clone"
|
it.name.asString() == "clone"
|
||||||
} as IrFunction?
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
logger.error("Couldn't find declaration java.lang.Object.clone(...)")
|
logger.error("Couldn't find declaration java.lang.Object.clone(...)")
|
||||||
}
|
}
|
||||||
@@ -1670,10 +1669,9 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val kotlinNoWhenBranchMatchedConstructor by lazy {
|
val kotlinNoWhenBranchMatchedConstructor by lazy {
|
||||||
val result = kotlinNoWhenBranchMatchedExn?.declarations?.find {
|
val result = kotlinNoWhenBranchMatchedExn?.declarations?.findSubType<IrConstructor> {
|
||||||
it is IrConstructor &&
|
|
||||||
it.valueParameters.isEmpty()
|
it.valueParameters.isEmpty()
|
||||||
} as IrConstructor?
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
logger.error("Couldn't find no-arg constructor for kotlin.NoWhenBranchMatchedException")
|
logger.error("Couldn't find no-arg constructor for kotlin.NoWhenBranchMatchedException")
|
||||||
}
|
}
|
||||||
@@ -1798,13 +1796,13 @@ open class KotlinFileExtractor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val func = ((c.getTypeArgument(0) as? IrSimpleType)?.classifier?.owner as? IrClass)?.declarations?.find { it is IrFunction && it.name.asString() == fnName }
|
val func = ((c.getTypeArgument(0) as? IrSimpleType)?.classifier?.owner as? IrClass)?.declarations?.findSubType<IrFunction> { it.name.asString() == fnName }
|
||||||
if (func == null) {
|
if (func == null) {
|
||||||
logger.errorElement("Couldn't find function $fnName on enum type", c)
|
logger.errorElement("Couldn't find function $fnName on enum type", c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
extractMethodAccess(func as IrFunction, false)
|
extractMethodAccess(func, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun binopReceiver(id: Label<out DbExpr>, receiver: IrExpression?, receiverDescription: String) {
|
fun binopReceiver(id: Label<out DbExpr>, receiver: IrExpression?, receiverDescription: String) {
|
||||||
@@ -2273,10 +2271,10 @@ open class KotlinFileExtractor(
|
|||||||
logger.errorElement("Argument to dataClassArrayMemberToString not a class", c)
|
logger.errorElement("Argument to dataClassArrayMemberToString not a class", c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val realCallee = javaUtilArrays?.declarations?.find { decl ->
|
val realCallee = javaUtilArrays?.declarations?.findSubType<IrFunction> { decl ->
|
||||||
decl is IrFunction && decl.name.asString() == "toString" && decl.valueParameters.size == 1 &&
|
decl.name.asString() == "toString" && decl.valueParameters.size == 1 &&
|
||||||
decl.valueParameters[0].type.classOrNull?.let { it == realArrayClass } == true
|
decl.valueParameters[0].type.classOrNull?.let { it == realArrayClass } == true
|
||||||
} as IrFunction?
|
}
|
||||||
if (realCallee == null) {
|
if (realCallee == null) {
|
||||||
logger.errorElement("Couldn't find a java.lang.Arrays.toString method matching class ${realArrayClass.owner.name}", c)
|
logger.errorElement("Couldn't find a java.lang.Arrays.toString method matching class ${realArrayClass.owner.name}", c)
|
||||||
} else {
|
} else {
|
||||||
@@ -2300,10 +2298,10 @@ open class KotlinFileExtractor(
|
|||||||
logger.errorElement("Argument to dataClassArrayMemberHashCode not a class", c)
|
logger.errorElement("Argument to dataClassArrayMemberHashCode not a class", c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val realCallee = javaUtilArrays?.declarations?.find { decl ->
|
val realCallee = javaUtilArrays?.declarations?.findSubType<IrFunction> { decl ->
|
||||||
decl is IrFunction && decl.name.asString() == "hashCode" && decl.valueParameters.size == 1 &&
|
decl.name.asString() == "hashCode" && decl.valueParameters.size == 1 &&
|
||||||
decl.valueParameters[0].type.classOrNull?.let { it == realArrayClass } == true
|
decl.valueParameters[0].type.classOrNull?.let { it == realArrayClass } == true
|
||||||
} as IrFunction?
|
}
|
||||||
if (realCallee == null) {
|
if (realCallee == null) {
|
||||||
logger.errorElement("Couldn't find a java.lang.Arrays.hashCode method matching class ${realArrayClass.owner.name}", c)
|
logger.errorElement("Couldn't find a java.lang.Arrays.hashCode method matching class ${realArrayClass.owner.name}", c)
|
||||||
} else {
|
} else {
|
||||||
@@ -4452,7 +4450,7 @@ open class KotlinFileExtractor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val invokeMethod = functionType.classOrNull?.owner?.declarations?.filterIsInstance<IrFunction>()?.find { it.name.asString() == OperatorNameConventions.INVOKE.asString()}
|
val invokeMethod = functionType.classOrNull?.owner?.declarations?.findSubType<IrFunction> { it.name.asString() == OperatorNameConventions.INVOKE.asString()}
|
||||||
if (invokeMethod == null) {
|
if (invokeMethod == null) {
|
||||||
logger.errorElement("Couldn't find `invoke` method on functional interface.", e)
|
logger.errorElement("Couldn't find `invoke` method on functional interface.", e)
|
||||||
return
|
return
|
||||||
@@ -4463,7 +4461,7 @@ open class KotlinFileExtractor(
|
|||||||
logger.errorElement("Expected to find SAM conversion to IrClass. Found '${typeOwner.javaClass}' instead. Can't implement SAM interface.", e)
|
logger.errorElement("Expected to find SAM conversion to IrClass. Found '${typeOwner.javaClass}' instead. Can't implement SAM interface.", e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val samMember = typeOwner.declarations.filterIsInstance<IrFunction>().find { it is IrOverridableMember && it.modality == Modality.ABSTRACT }
|
val samMember = typeOwner.declarations.findSubType<IrFunction> { it is IrOverridableMember && it.modality == Modality.ABSTRACT }
|
||||||
if (samMember == null) {
|
if (samMember == null) {
|
||||||
logger.errorElement("Couldn't find SAM member in type '${typeOwner.kotlinFqName.asString()}'. Can't implement SAM interface.", e)
|
logger.errorElement("Couldn't find SAM member in type '${typeOwner.kotlinFqName.asString()}'. Can't implement SAM interface.", e)
|
||||||
return
|
return
|
||||||
@@ -4652,7 +4650,7 @@ open class KotlinFileExtractor(
|
|||||||
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
|
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
|
||||||
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.constructor)
|
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.constructor)
|
||||||
|
|
||||||
val baseConstructor = baseClass.owner.declarations.find { it is IrFunction && it.symbol is IrConstructorSymbol }
|
val baseConstructor = baseClass.owner.declarations.findSubType<IrFunction> { it.symbol is IrConstructorSymbol }
|
||||||
val baseConstructorId = useFunction<DbConstructor>(baseConstructor as IrFunction)
|
val baseConstructorId = useFunction<DbConstructor>(baseConstructor as IrFunction)
|
||||||
|
|
||||||
tw.writeHasLocation(superCallId, locId)
|
tw.writeHasLocation(superCallId, locId)
|
||||||
|
|||||||
@@ -326,11 +326,11 @@ open class KotlinUsesExtractor(
|
|||||||
if (replacementClass === parentClass)
|
if (replacementClass === parentClass)
|
||||||
return f
|
return f
|
||||||
return globalExtensionState.syntheticToRealFunctionMap.getOrPut(f) {
|
return globalExtensionState.syntheticToRealFunctionMap.getOrPut(f) {
|
||||||
val result = replacementClass.declarations.find { replacementDecl ->
|
val result = replacementClass.declarations.findSubType<IrSimpleFunction> { replacementDecl ->
|
||||||
replacementDecl is IrSimpleFunction && replacementDecl.name == f.name && replacementDecl.valueParameters.size == f.valueParameters.size && replacementDecl.valueParameters.zip(f.valueParameters).all {
|
replacementDecl is IrSimpleFunction && replacementDecl.name == f.name && replacementDecl.valueParameters.size == f.valueParameters.size && replacementDecl.valueParameters.zip(f.valueParameters).all {
|
||||||
erase(it.first.type) == erase(it.second.type)
|
erase(it.first.type) == erase(it.second.type)
|
||||||
}
|
}
|
||||||
} as IrFunction?
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
logger.warn("Failed to replace synthetic class function ${f.name}")
|
logger.warn("Failed to replace synthetic class function ${f.name}")
|
||||||
} else {
|
} else {
|
||||||
@@ -351,9 +351,9 @@ open class KotlinUsesExtractor(
|
|||||||
if (replacementClass === parentClass)
|
if (replacementClass === parentClass)
|
||||||
return f
|
return f
|
||||||
return globalExtensionState.syntheticToRealFieldMap.getOrPut(f) {
|
return globalExtensionState.syntheticToRealFieldMap.getOrPut(f) {
|
||||||
val result = replacementClass.declarations.find { replacementDecl ->
|
val result = replacementClass.declarations.findSubType<IrField> { replacementDecl ->
|
||||||
replacementDecl is IrField && replacementDecl.name == f.name
|
replacementDecl.name == f.name
|
||||||
} as IrField?
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
logger.warn("Failed to replace synthetic class field ${f.name}")
|
logger.warn("Failed to replace synthetic class field ${f.name}")
|
||||||
} else {
|
} else {
|
||||||
@@ -1097,7 +1097,7 @@ open class KotlinUsesExtractor(
|
|||||||
return f.returnType
|
return f.returnType
|
||||||
}
|
}
|
||||||
|
|
||||||
val otherKeySet = parentClass.declarations.filterIsInstance<IrFunction>().find { it.name.asString() == "keySet" && it.valueParameters.size == 1 }
|
val otherKeySet = parentClass.declarations.findSubType<IrFunction> { it.name.asString() == "keySet" && it.valueParameters.size == 1 }
|
||||||
?: return f.returnType
|
?: return f.returnType
|
||||||
|
|
||||||
return otherKeySet.returnType.codeQlWithHasQuestionMark(false)
|
return otherKeySet.returnType.codeQlWithHasQuestionMark(false)
|
||||||
@@ -1177,8 +1177,7 @@ open class KotlinUsesExtractor(
|
|||||||
getJavaEquivalentClass(parentClass)?.let { javaClass ->
|
getJavaEquivalentClass(parentClass)?.let { javaClass ->
|
||||||
if (javaClass != parentClass)
|
if (javaClass != parentClass)
|
||||||
// Look for an exact type match...
|
// Look for an exact type match...
|
||||||
javaClass.declarations.find { decl ->
|
javaClass.declarations.findSubType<IrFunction> { decl ->
|
||||||
decl is IrFunction &&
|
|
||||||
decl.name == f.name &&
|
decl.name == f.name &&
|
||||||
decl.valueParameters.size == f.valueParameters.size &&
|
decl.valueParameters.size == f.valueParameters.size &&
|
||||||
// Note matching by classifier not the whole type so that generic arguments are allowed to differ,
|
// Note matching by classifier not the whole type so that generic arguments are allowed to differ,
|
||||||
@@ -1194,7 +1193,7 @@ open class KotlinUsesExtractor(
|
|||||||
} ?:
|
} ?:
|
||||||
// Or check property accessors:
|
// Or check property accessors:
|
||||||
if (f.isAccessor) {
|
if (f.isAccessor) {
|
||||||
val prop = javaClass.declarations.filterIsInstance<IrProperty>().find { decl ->
|
val prop = javaClass.declarations.findSubType<IrProperty> { decl ->
|
||||||
decl.name == (f.propertyIfAccessor as IrProperty).name
|
decl.name == (f.propertyIfAccessor as IrProperty).name
|
||||||
}
|
}
|
||||||
if (prop?.getter?.name == f.name)
|
if (prop?.getter?.name == f.name)
|
||||||
|
|||||||
15
java/kotlin-extractor/src/main/kotlin/utils/Iterable.kt
Normal file
15
java/kotlin-extractor/src/main/kotlin/utils/Iterable.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.github.codeql
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This behaves the same as Iterable<IrDeclaration>.find, but requires
|
||||||
|
* that the value found is of the subtype S, and it casts
|
||||||
|
* the result for you appropriately.
|
||||||
|
*/
|
||||||
|
inline fun <reified S: IrDeclaration> Iterable<IrDeclaration>.findSubType(
|
||||||
|
predicate: (S) -> Boolean
|
||||||
|
): S? {
|
||||||
|
return this.find { it is S && predicate(it) } as S?
|
||||||
|
}
|
||||||
|
|
||||||
@@ -93,8 +93,6 @@ class RegExpRoot extends RegExpTerm {
|
|||||||
* Holds if this root term is relevant to the ReDoS analysis.
|
* Holds if this root term is relevant to the ReDoS analysis.
|
||||||
*/
|
*/
|
||||||
predicate isRelevant() {
|
predicate isRelevant() {
|
||||||
// there is at least one repetition
|
|
||||||
getRoot(any(InfiniteRepetitionQuantifier q)) = this and
|
|
||||||
// is actually used as a RegExp
|
// is actually used as a RegExp
|
||||||
this.isUsedAsRegExp() and
|
this.isUsedAsRegExp() and
|
||||||
// not excluded for library specific reasons
|
// not excluded for library specific reasons
|
||||||
@@ -877,6 +875,101 @@ predicate isStartState(State state) {
|
|||||||
*/
|
*/
|
||||||
signature predicate isCandidateSig(State state, string pump);
|
signature predicate isCandidateSig(State state, string pump);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `state` is a candidate for ReDoS.
|
||||||
|
*/
|
||||||
|
signature predicate isCandidateSig(State state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predicates for constructing a prefix string that leads to a given state.
|
||||||
|
*/
|
||||||
|
module PrefixConstruction<isCandidateSig/1 isCandidate> {
|
||||||
|
/**
|
||||||
|
* Holds if `state` is the textually last start state for the regular expression.
|
||||||
|
*/
|
||||||
|
private predicate lastStartState(State state) {
|
||||||
|
exists(RegExpRoot root |
|
||||||
|
state =
|
||||||
|
max(State s, Location l |
|
||||||
|
s = stateInRelevantRegexp() and
|
||||||
|
isStartState(s) and
|
||||||
|
getRoot(s.getRepr()) = root and
|
||||||
|
l = s.getRepr().getLocation()
|
||||||
|
|
|
||||||
|
s
|
||||||
|
order by
|
||||||
|
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
|
||||||
|
l.getEndLine()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
|
||||||
|
*/
|
||||||
|
private predicate existsTransition(State a, State b) { delta(a, _, b) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
|
||||||
|
*/
|
||||||
|
int prefixLength(State start, State state) =
|
||||||
|
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum number of transitions it takes to reach `state` from the start state.
|
||||||
|
*/
|
||||||
|
private int lengthFromStart(State state) { result = prefixLength(_, state) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string for which the regular expression will reach `state`.
|
||||||
|
*
|
||||||
|
* Has at most one result for any given `state`.
|
||||||
|
* This predicate will not always have a result even if there is a ReDoS issue in
|
||||||
|
* the regular expression.
|
||||||
|
*/
|
||||||
|
string prefix(State state) {
|
||||||
|
lastStartState(state) and
|
||||||
|
result = ""
|
||||||
|
or
|
||||||
|
// the search stops past the last redos candidate state.
|
||||||
|
lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and
|
||||||
|
exists(State prev |
|
||||||
|
// select a unique predecessor (by an arbitrary measure)
|
||||||
|
prev =
|
||||||
|
min(State s, Location loc |
|
||||||
|
lengthFromStart(s) = lengthFromStart(state) - 1 and
|
||||||
|
loc = s.getRepr().getLocation() and
|
||||||
|
delta(s, _, state)
|
||||||
|
|
|
||||||
|
s
|
||||||
|
order by
|
||||||
|
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
|
||||||
|
s.getRepr().toString()
|
||||||
|
)
|
||||||
|
|
|
||||||
|
// greedy search for the shortest prefix
|
||||||
|
result = prefix(prev) and delta(prev, Epsilon(), state)
|
||||||
|
or
|
||||||
|
not delta(prev, Epsilon(), state) and
|
||||||
|
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
|
||||||
|
*/
|
||||||
|
private string getCanonicalEdgeChar(State prev, State next) {
|
||||||
|
result =
|
||||||
|
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a state within a regular expression that contains a candidate state. */
|
||||||
|
pragma[noinline]
|
||||||
|
State stateInRelevantRegexp() {
|
||||||
|
exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A module for pruning candidate ReDoS states.
|
* A module for pruning candidate ReDoS states.
|
||||||
* The candidates are specified by the `isCandidate` signature predicate.
|
* The candidates are specified by the `isCandidate` signature predicate.
|
||||||
@@ -910,95 +1003,9 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
/** Gets a state that can reach the `accept-any` state using only epsilon steps. */
|
/** Gets a state that can reach the `accept-any` state using only epsilon steps. */
|
||||||
private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) }
|
private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) }
|
||||||
|
|
||||||
/**
|
predicate isCandidateState(State s) { isReDoSCandidate(s, _) }
|
||||||
* Predicates for constructing a prefix string that leads to a given state.
|
|
||||||
*/
|
|
||||||
private module PrefixConstruction {
|
|
||||||
/**
|
|
||||||
* Holds if `state` is the textually last start state for the regular expression.
|
|
||||||
*/
|
|
||||||
private predicate lastStartState(State state) {
|
|
||||||
exists(RegExpRoot root |
|
|
||||||
state =
|
|
||||||
max(State s, Location l |
|
|
||||||
s = stateInPumpableRegexp() and
|
|
||||||
isStartState(s) and
|
|
||||||
getRoot(s.getRepr()) = root and
|
|
||||||
l = s.getRepr().getLocation()
|
|
||||||
|
|
|
||||||
s
|
|
||||||
order by
|
|
||||||
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
|
|
||||||
l.getEndLine()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
import PrefixConstruction<isCandidateState/1> as Prefix
|
||||||
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
|
|
||||||
*/
|
|
||||||
private predicate existsTransition(State a, State b) { delta(a, _, b) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
|
|
||||||
*/
|
|
||||||
int prefixLength(State start, State state) =
|
|
||||||
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the minimum number of transitions it takes to reach `state` from the start state.
|
|
||||||
*/
|
|
||||||
private int lengthFromStart(State state) { result = prefixLength(_, state) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a string for which the regular expression will reach `state`.
|
|
||||||
*
|
|
||||||
* Has at most one result for any given `state`.
|
|
||||||
* This predicate will not always have a result even if there is a ReDoS issue in
|
|
||||||
* the regular expression.
|
|
||||||
*/
|
|
||||||
string prefix(State state) {
|
|
||||||
lastStartState(state) and
|
|
||||||
result = ""
|
|
||||||
or
|
|
||||||
// the search stops past the last redos candidate state.
|
|
||||||
lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and
|
|
||||||
exists(State prev |
|
|
||||||
// select a unique predecessor (by an arbitrary measure)
|
|
||||||
prev =
|
|
||||||
min(State s, Location loc |
|
|
||||||
lengthFromStart(s) = lengthFromStart(state) - 1 and
|
|
||||||
loc = s.getRepr().getLocation() and
|
|
||||||
delta(s, _, state)
|
|
||||||
|
|
|
||||||
s
|
|
||||||
order by
|
|
||||||
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
|
|
||||||
s.getRepr().toString()
|
|
||||||
)
|
|
||||||
|
|
|
||||||
// greedy search for the shortest prefix
|
|
||||||
result = prefix(prev) and delta(prev, Epsilon(), state)
|
|
||||||
or
|
|
||||||
not delta(prev, Epsilon(), state) and
|
|
||||||
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
|
|
||||||
*/
|
|
||||||
private string getCanonicalEdgeChar(State prev, State next) {
|
|
||||||
result =
|
|
||||||
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a state within a regular expression that has a pumpable state. */
|
|
||||||
pragma[noinline]
|
|
||||||
State stateInPumpableRegexp() {
|
|
||||||
exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predicates for testing the presence of a rejecting suffix.
|
* Predicates for testing the presence of a rejecting suffix.
|
||||||
@@ -1018,8 +1025,6 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
|
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
|
||||||
*/
|
*/
|
||||||
private module SuffixConstruction {
|
private module SuffixConstruction {
|
||||||
import PrefixConstruction
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if all states reachable from `fork` by repeating `w`
|
* Holds if all states reachable from `fork` by repeating `w`
|
||||||
* are likely rejectable by appending some suffix.
|
* are likely rejectable by appending some suffix.
|
||||||
@@ -1036,7 +1041,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
*/
|
*/
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private predicate isLikelyRejectable(State s) {
|
private predicate isLikelyRejectable(State s) {
|
||||||
s = stateInPumpableRegexp() and
|
s = Prefix::stateInRelevantRegexp() and
|
||||||
(
|
(
|
||||||
// exists a reject edge with some char.
|
// exists a reject edge with some char.
|
||||||
hasRejectEdge(s)
|
hasRejectEdge(s)
|
||||||
@@ -1052,7 +1057,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
* Holds if `s` is not an accept state, and there is no epsilon transition to an accept state.
|
* Holds if `s` is not an accept state, and there is no epsilon transition to an accept state.
|
||||||
*/
|
*/
|
||||||
predicate isRejectState(State s) {
|
predicate isRejectState(State s) {
|
||||||
s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_)
|
s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1060,7 +1065,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
*/
|
*/
|
||||||
pragma[noopt]
|
pragma[noopt]
|
||||||
predicate hasEdgeToLikelyRejectable(State s) {
|
predicate hasEdgeToLikelyRejectable(State s) {
|
||||||
s = stateInPumpableRegexp() and
|
s = Prefix::stateInRelevantRegexp() and
|
||||||
// all edges (at least one) with some char leads to another state that is rejectable.
|
// all edges (at least one) with some char leads to another state that is rejectable.
|
||||||
// the `next` states might not share a common suffix, which can cause FPs.
|
// the `next` states might not share a common suffix, which can cause FPs.
|
||||||
exists(string char | char = hasEdgeToLikelyRejectableHelper(s) |
|
exists(string char | char = hasEdgeToLikelyRejectableHelper(s) |
|
||||||
@@ -1076,7 +1081,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
*/
|
*/
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private string hasEdgeToLikelyRejectableHelper(State s) {
|
private string hasEdgeToLikelyRejectableHelper(State s) {
|
||||||
s = stateInPumpableRegexp() and
|
s = Prefix::stateInRelevantRegexp() and
|
||||||
not hasRejectEdge(s) and
|
not hasRejectEdge(s) and
|
||||||
not isRejectState(s) and
|
not isRejectState(s) and
|
||||||
deltaClosedChar(s, result, _)
|
deltaClosedChar(s, result, _)
|
||||||
@@ -1088,8 +1093,8 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
* `prev` to `next` that the character symbol `char`.
|
* `prev` to `next` that the character symbol `char`.
|
||||||
*/
|
*/
|
||||||
predicate deltaClosedChar(State prev, string char, State next) {
|
predicate deltaClosedChar(State prev, string char, State next) {
|
||||||
prev = stateInPumpableRegexp() and
|
prev = Prefix::stateInRelevantRegexp() and
|
||||||
next = stateInPumpableRegexp() and
|
next = Prefix::stateInRelevantRegexp() and
|
||||||
deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next)
|
deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1099,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
result = getAnInputSymbolMatching(char)
|
result = getAnInputSymbolMatching(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
RegExpRoot relevantRoot() {
|
||||||
|
exists(RegExpTerm term, State s |
|
||||||
|
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a char used for finding possible suffixes inside `root`.
|
* Gets a char used for finding possible suffixes inside `root`.
|
||||||
*/
|
*/
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private string relevant(RegExpRoot root) {
|
private string relevant(RegExpRoot root) {
|
||||||
exists(ascii(result)) and exists(root)
|
root = relevantRoot() and
|
||||||
or
|
(
|
||||||
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
|
exists(ascii(result)) and exists(root)
|
||||||
or
|
or
|
||||||
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
|
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
|
||||||
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
|
or
|
||||||
result = ["|", "\n", "Z"] and exists(root)
|
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
|
||||||
|
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
|
||||||
|
result = ["|", "\n", "Z"] and exists(root)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1208,12 +1223,12 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) {
|
predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) {
|
||||||
isReDoSAttackable(t, pump, s) and
|
isReDoSAttackable(t, pump, s) and
|
||||||
(
|
(
|
||||||
prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and
|
prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and
|
||||||
not PrefixConstruction::prefix(s) = ""
|
not Prefix::prefix(s) = ""
|
||||||
or
|
or
|
||||||
PrefixConstruction::prefix(s) = "" and prefixMsg = ""
|
Prefix::prefix(s) = "" and prefixMsg = ""
|
||||||
or
|
or
|
||||||
not exists(PrefixConstruction::prefix(s)) and prefixMsg = ""
|
not exists(Prefix::prefix(s)) and prefixMsg = ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ import semmle.code.java.deadcode.DeadCode
|
|||||||
|
|
||||||
from RootdefCallable c
|
from RootdefCallable c
|
||||||
where not c.whitelisted()
|
where not c.whitelisted()
|
||||||
select c.unusedParameter() as p, "The parameter " + p + " is unused."
|
select c.unusedParameter() as p, "The parameter '" + p + "' is never used."
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ where
|
|||||||
e.isStrict() and
|
e.isStrict() and
|
||||||
e.getGreaterOperand() instanceof BitwiseExpr and
|
e.getGreaterOperand() instanceof BitwiseExpr and
|
||||||
e.getLesserOperand().(IntegerLiteral).getIntValue() = 0
|
e.getLesserOperand().(IntegerLiteral).getIntValue() = 0
|
||||||
select e, "Sign check of a bitwise operation."
|
select e, "Potentially unsafe sign check of a bitwise operation."
|
||||||
|
|||||||
@@ -77,4 +77,4 @@ where
|
|||||||
// Exclude `equals` methods that implement reference-equality.
|
// Exclude `equals` methods that implement reference-equality.
|
||||||
not m instanceof ReferenceEquals and
|
not m instanceof ReferenceEquals and
|
||||||
not m instanceof UnimplementedEquals
|
not m instanceof UnimplementedEquals
|
||||||
select m, "equals() method does not seem to check argument type."
|
select m, "equals() method does not check argument type."
|
||||||
|
|||||||
@@ -19,4 +19,5 @@ import DataFlow::PathGraph
|
|||||||
|
|
||||||
from QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink
|
from QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
where queryTaintedBy(query, source, sink)
|
where queryTaintedBy(query, source, sink)
|
||||||
select query, source, sink, "Query might include code from $@.", source.getNode(), "this user input"
|
select query, source, sink, "This SQL query depends on $@.", source.getNode(),
|
||||||
|
"a user-provided value"
|
||||||
|
|||||||
@@ -51,5 +51,6 @@ class XxeConfig extends TaintTracking::Configuration {
|
|||||||
|
|
||||||
from DataFlow::PathNode source, DataFlow::PathNode sink, XxeConfig conf
|
from DataFlow::PathNode source, DataFlow::PathNode sink, XxeConfig conf
|
||||||
where conf.hasFlowPath(source, sink)
|
where conf.hasFlowPath(source, sink)
|
||||||
select sink.getNode(), source, sink, "Unsafe parsing of XML file from $@.", source.getNode(),
|
select sink.getNode(), source, sink,
|
||||||
"user input"
|
"A $@ is parsed as XML without guarding against external entity expansion.", source.getNode(),
|
||||||
|
"user-provided value"
|
||||||
|
|||||||
@@ -17,4 +17,4 @@ from JavadocText c
|
|||||||
where
|
where
|
||||||
c.getText().matches("%TODO%") or
|
c.getText().matches("%TODO%") or
|
||||||
c.getText().matches("%FIXME%")
|
c.getText().matches("%FIXME%")
|
||||||
select c, "TODO/FIXME comment."
|
select c, "TODO comments should be addressed."
|
||||||
|
|||||||
@@ -21,4 +21,4 @@ where
|
|||||||
read(v) and
|
read(v) and
|
||||||
not def.(AssignExpr).getSource() instanceof NullLiteral and
|
not def.(AssignExpr).getSource() instanceof NullLiteral and
|
||||||
(def instanceof Assignment or def.(UnaryAssignExpr).getParent() instanceof ExprStmt)
|
(def instanceof Assignment or def.(UnaryAssignExpr).getParent() instanceof ExprStmt)
|
||||||
select def, "This assignment to " + v.getName() + " is useless: the value is never read."
|
select def, "This definition of " + v.getName() + " is never used."
|
||||||
|
|||||||
@@ -86,5 +86,6 @@ where
|
|||||||
) and
|
) and
|
||||||
// Exclude special VM classes.
|
// Exclude special VM classes.
|
||||||
not isVMObserver(f.getDeclaringType())
|
not isVMObserver(f.getDeclaringType())
|
||||||
select f, "Field " + f.getName() + " never assigned non-null value, yet it is read at $@.", fr,
|
select f,
|
||||||
fr.getFile().getStem() + ".java:" + fr.getLocation().getStartLine()
|
"The field '" + f.getName() + "' is never explicitly assigned a value, yet it is read $@.", fr,
|
||||||
|
"here"
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ where
|
|||||||
f.getType() instanceof Array and
|
f.getType() instanceof Array and
|
||||||
f.fromSource() and
|
f.fromSource() and
|
||||||
forall(AssignExpr a | a.getDest() = f.getAnAccess() | nonEmptyArrayLiteralOrNull(a.getSource()))
|
forall(AssignExpr a | a.getDest() = f.getAnAccess() | nonEmptyArrayLiteralOrNull(a.getSource()))
|
||||||
select f, "The array constant " + f.getName() + " is vulnerable to mutation."
|
select f, "The array constant '" + f.getName() + "' is vulnerable to mutation."
|
||||||
|
|||||||
@@ -71,4 +71,4 @@ where
|
|||||||
not neededImport(i) and
|
not neededImport(i) and
|
||||||
not i instanceof ImportStaticOnDemand and
|
not i instanceof ImportStaticOnDemand and
|
||||||
not i instanceof ImportStaticTypeMember
|
not i instanceof ImportStaticTypeMember
|
||||||
select i, "The statement '" + i + "' is unnecessary."
|
select i, "Import of '" + i + "' is not used."
|
||||||
|
|||||||
4
java/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
4
java/ql/src/change-notes/2022-08-23-alert-messages.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The alert message of many queries have been changed to make the message consistent with other languages.
|
||||||
@@ -48,4 +48,4 @@ where
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
hasEmbeddedPassword(nameAttr.getValue().trim()) // Attribute value matches password pattern
|
hasEmbeddedPassword(nameAttr.getValue().trim()) // Attribute value matches password pattern
|
||||||
select nameAttr, "Plaintext password in configuration file."
|
select nameAttr, "Avoid plaintext passwords in configuration files."
|
||||||
|
|||||||
@@ -85,5 +85,5 @@ class RegexInjectionConfiguration extends TaintTracking::Configuration {
|
|||||||
|
|
||||||
from DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c
|
from DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c
|
||||||
where c.hasFlowPath(source, sink)
|
where c.hasFlowPath(source, sink)
|
||||||
select sink.getNode(), source, sink, "$@ is user controlled.", source.getNode(),
|
select sink.getNode(), source, sink, "This regular expression is constructed from a $@.",
|
||||||
"This regular expression pattern"
|
source.getNode(), "user-provided value"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| applicationContext.xml:9:3:9:48 | name=password | Plaintext password in configuration file. |
|
| applicationContext.xml:9:3:9:48 | name=password | Avoid plaintext passwords in configuration files. |
|
||||||
| context.xml:4:2:8:50 | password=1234 | Plaintext password in configuration file. |
|
| context.xml:4:2:8:50 | password=1234 | Avoid plaintext passwords in configuration files. |
|
||||||
| custom-config.xml:3:2:3:137 | value=server=myoracle.example.com;port=1521;database=testdb;username=root;password=test1234 | Plaintext password in configuration file. |
|
| custom-config.xml:3:2:3:137 | value=server=myoracle.example.com;port=1521;database=testdb;username=root;password=test1234 | Avoid plaintext passwords in configuration files. |
|
||||||
|
|||||||
@@ -56,18 +56,18 @@ nodes
|
|||||||
subpaths
|
subpaths
|
||||||
| RegexInjection.java:68:36:68:42 | pattern : String | RegexInjection.java:71:14:71:23 | str : String | RegexInjection.java:72:12:72:14 | str : String | RegexInjection.java:68:32:68:43 | foo(...) : String |
|
| RegexInjection.java:68:36:68:42 | pattern : String | RegexInjection.java:71:14:71:23 | str : String | RegexInjection.java:72:12:72:14 | str : String | RegexInjection.java:68:32:68:43 | foo(...) : String |
|
||||||
#select
|
#select
|
||||||
| RegexInjection.java:16:26:16:47 | ... + ... | RegexInjection.java:13:22:13:52 | getParameter(...) : String | RegexInjection.java:16:26:16:47 | ... + ... | $@ is user controlled. | RegexInjection.java:13:22:13:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:16:26:16:47 | ... + ... | RegexInjection.java:13:22:13:52 | getParameter(...) : String | RegexInjection.java:16:26:16:47 | ... + ... | This regular expression is constructed from a $@. | RegexInjection.java:13:22:13:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:23:24:23:30 | pattern | RegexInjection.java:20:22:20:52 | getParameter(...) : String | RegexInjection.java:23:24:23:30 | pattern | $@ is user controlled. | RegexInjection.java:20:22:20:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:23:24:23:30 | pattern | RegexInjection.java:20:22:20:52 | getParameter(...) : String | RegexInjection.java:23:24:23:30 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:20:22:20:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:30:31:30:37 | pattern | RegexInjection.java:27:22:27:52 | getParameter(...) : String | RegexInjection.java:30:31:30:37 | pattern | $@ is user controlled. | RegexInjection.java:27:22:27:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:30:31:30:37 | pattern | RegexInjection.java:27:22:27:52 | getParameter(...) : String | RegexInjection.java:30:31:30:37 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:27:22:27:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:37:29:37:35 | pattern | RegexInjection.java:34:22:34:52 | getParameter(...) : String | RegexInjection.java:37:29:37:35 | pattern | $@ is user controlled. | RegexInjection.java:34:22:34:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:37:29:37:35 | pattern | RegexInjection.java:34:22:34:52 | getParameter(...) : String | RegexInjection.java:37:29:37:35 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:34:22:34:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:44:34:44:40 | pattern | RegexInjection.java:41:22:41:52 | getParameter(...) : String | RegexInjection.java:44:34:44:40 | pattern | $@ is user controlled. | RegexInjection.java:41:22:41:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:44:34:44:40 | pattern | RegexInjection.java:41:22:41:52 | getParameter(...) : String | RegexInjection.java:44:34:44:40 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:41:22:41:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:54:28:54:34 | pattern | RegexInjection.java:51:22:51:52 | getParameter(...) : String | RegexInjection.java:54:28:54:34 | pattern | $@ is user controlled. | RegexInjection.java:51:22:51:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:54:28:54:34 | pattern | RegexInjection.java:51:22:51:52 | getParameter(...) : String | RegexInjection.java:54:28:54:34 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:51:22:51:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:61:28:61:34 | pattern | RegexInjection.java:58:22:58:52 | getParameter(...) : String | RegexInjection.java:61:28:61:34 | pattern | $@ is user controlled. | RegexInjection.java:58:22:58:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:61:28:61:34 | pattern | RegexInjection.java:58:22:58:52 | getParameter(...) : String | RegexInjection.java:61:28:61:34 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:58:22:58:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:68:26:68:52 | ... + ... | RegexInjection.java:65:22:65:52 | getParameter(...) : String | RegexInjection.java:68:26:68:52 | ... + ... | $@ is user controlled. | RegexInjection.java:65:22:65:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:68:26:68:52 | ... + ... | RegexInjection.java:65:22:65:52 | getParameter(...) : String | RegexInjection.java:68:26:68:52 | ... + ... | This regular expression is constructed from a $@. | RegexInjection.java:65:22:65:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:90:26:90:47 | ... + ... | RegexInjection.java:84:22:84:52 | getParameter(...) : String | RegexInjection.java:90:26:90:47 | ... + ... | $@ is user controlled. | RegexInjection.java:84:22:84:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:90:26:90:47 | ... + ... | RegexInjection.java:84:22:84:52 | getParameter(...) : String | RegexInjection.java:90:26:90:47 | ... + ... | This regular expression is constructed from a $@. | RegexInjection.java:84:22:84:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:103:40:103:46 | pattern | RegexInjection.java:100:22:100:52 | getParameter(...) : String | RegexInjection.java:103:40:103:46 | pattern | $@ is user controlled. | RegexInjection.java:100:22:100:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:103:40:103:46 | pattern | RegexInjection.java:100:22:100:52 | getParameter(...) : String | RegexInjection.java:103:40:103:46 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:100:22:100:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:110:42:110:48 | pattern | RegexInjection.java:107:22:107:52 | getParameter(...) : String | RegexInjection.java:110:42:110:48 | pattern | $@ is user controlled. | RegexInjection.java:107:22:107:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:110:42:110:48 | pattern | RegexInjection.java:107:22:107:52 | getParameter(...) : String | RegexInjection.java:110:42:110:48 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:107:22:107:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:117:44:117:50 | pattern | RegexInjection.java:114:22:114:52 | getParameter(...) : String | RegexInjection.java:117:44:117:50 | pattern | $@ is user controlled. | RegexInjection.java:114:22:114:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:117:44:117:50 | pattern | RegexInjection.java:114:22:114:52 | getParameter(...) : String | RegexInjection.java:117:44:117:50 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:114:22:114:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:124:41:124:47 | pattern | RegexInjection.java:121:22:121:52 | getParameter(...) : String | RegexInjection.java:124:41:124:47 | pattern | $@ is user controlled. | RegexInjection.java:121:22:121:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:124:41:124:47 | pattern | RegexInjection.java:121:22:121:52 | getParameter(...) : String | RegexInjection.java:124:41:124:47 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:121:22:121:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:131:43:131:49 | pattern | RegexInjection.java:128:22:128:52 | getParameter(...) : String | RegexInjection.java:131:43:131:49 | pattern | $@ is user controlled. | RegexInjection.java:128:22:128:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:131:43:131:49 | pattern | RegexInjection.java:128:22:128:52 | getParameter(...) : String | RegexInjection.java:131:43:131:49 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:128:22:128:52 | getParameter(...) | user-provided value |
|
||||||
| RegexInjection.java:146:45:146:51 | pattern | RegexInjection.java:143:22:143:52 | getParameter(...) : String | RegexInjection.java:146:45:146:51 | pattern | $@ is user controlled. | RegexInjection.java:143:22:143:52 | getParameter(...) | This regular expression pattern |
|
| RegexInjection.java:146:45:146:51 | pattern | RegexInjection.java:143:22:143:52 | getParameter(...) : String | RegexInjection.java:146:45:146:51 | pattern | This regular expression is constructed from a $@. | RegexInjection.java:143:22:143:52 | getParameter(...) | user-provided value |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| Bad.java:13:17:13:22 | equals | equals() method does not seem to check argument type. |
|
| Bad.java:13:17:13:22 | equals | equals() method does not check argument type. |
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
| StaticArray.java:3:31:3:33 | bad | The array constant bad is vulnerable to mutation. |
|
| StaticArray.java:3:31:3:33 | bad | The array constant 'bad' is vulnerable to mutation. |
|
||||||
| StaticArray.java:14:35:14:54 | bad_multidimensional | The array constant bad_multidimensional is vulnerable to mutation. |
|
| StaticArray.java:14:35:14:54 | bad_multidimensional | The array constant 'bad_multidimensional' is vulnerable to mutation. |
|
||||||
| StaticArray.java:15:35:15:67 | bad_multidimensional_partial_init | The array constant bad_multidimensional_partial_init is vulnerable to mutation. |
|
| StaticArray.java:15:35:15:67 | bad_multidimensional_partial_init | The array constant 'bad_multidimensional_partial_init' is vulnerable to mutation. |
|
||||||
| StaticArray.java:17:31:17:47 | bad_separate_init | The array constant bad_separate_init is vulnerable to mutation. |
|
| StaticArray.java:17:31:17:47 | bad_separate_init | The array constant 'bad_separate_init' is vulnerable to mutation. |
|
||||||
| StaticArray.java:26:33:26:44 | bad_nonempty | The array constant bad_nonempty is vulnerable to mutation. |
|
| StaticArray.java:26:33:26:44 | bad_nonempty | The array constant 'bad_nonempty' is vulnerable to mutation. |
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
| A.java:29:13:29:21 | ...=... | This assignment to x is useless: the value is never read. |
|
| A.java:29:13:29:21 | ...=... | This definition of x is never used. |
|
||||||
| UnreadLocal/ImplicitReads.java:38:5:38:9 | ...=... | This assignment to c is useless: the value is never read. |
|
| UnreadLocal/ImplicitReads.java:38:5:38:9 | ...=... | This definition of c is never used. |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| Test.java:6:11:6:15 | x | The parameter x is unused. |
|
| Test.java:6:11:6:15 | x | The parameter 'x' is never used. |
|
||||||
|
|||||||
@@ -251,101 +251,101 @@ nodes
|
|||||||
| XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | semmle.label | getInputStream(...) |
|
| XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | semmle.label | getInputStream(...) |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:28:19:28:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:35:19:35:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:49:19:49:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:64:19:64:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:71:19:71:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:79:19:79:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:87:19:87:39 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:94:16:94:38 | getInputSource(...) | DocumentBuilderTests.java:93:51:93:71 | getInputStream(...) : InputStream | DocumentBuilderTests.java:94:16:94:38 | getInputSource(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:93:51:93:71 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:94:16:94:38 | getInputSource(...) | DocumentBuilderTests.java:93:51:93:71 | getInputStream(...) : InputStream | DocumentBuilderTests.java:94:16:94:38 | getInputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:93:51:93:71 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:101:16:101:52 | sourceToInputSource(...) | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) : InputStream | DocumentBuilderTests.java:101:16:101:52 | sourceToInputSource(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:101:16:101:52 | sourceToInputSource(...) | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) : InputStream | DocumentBuilderTests.java:101:16:101:52 | sourceToInputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) | user-provided value |
|
||||||
| DocumentBuilderTests.java:102:16:102:38 | getInputStream(...) | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) : InputStream | DocumentBuilderTests.java:102:16:102:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) | user input |
|
| DocumentBuilderTests.java:102:16:102:38 | getInputStream(...) | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) : InputStream | DocumentBuilderTests.java:102:16:102:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | DocumentBuilderTests.java:100:41:100:61 | getInputStream(...) | user-provided value |
|
||||||
| SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | user input |
|
| SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXBuilderTests.java:8:19:8:39 | getInputStream(...) | user-provided value |
|
||||||
| SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | user input |
|
| SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXBuilderTests.java:20:19:20:39 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:13:18:13:38 | getInputStream(...) | SAXParserTests.java:13:18:13:38 | getInputStream(...) | SAXParserTests.java:13:18:13:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:13:18:13:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:13:18:13:38 | getInputStream(...) | SAXParserTests.java:13:18:13:38 | getInputStream(...) | SAXParserTests.java:13:18:13:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:13:18:13:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:30:18:30:38 | getInputStream(...) | SAXParserTests.java:30:18:30:38 | getInputStream(...) | SAXParserTests.java:30:18:30:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:30:18:30:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:30:18:30:38 | getInputStream(...) | SAXParserTests.java:30:18:30:38 | getInputStream(...) | SAXParserTests.java:30:18:30:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:30:18:30:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:38:18:38:38 | getInputStream(...) | SAXParserTests.java:38:18:38:38 | getInputStream(...) | SAXParserTests.java:38:18:38:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:38:18:38:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:38:18:38:38 | getInputStream(...) | SAXParserTests.java:38:18:38:38 | getInputStream(...) | SAXParserTests.java:38:18:38:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:38:18:38:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:46:18:46:38 | getInputStream(...) | SAXParserTests.java:46:18:46:38 | getInputStream(...) | SAXParserTests.java:46:18:46:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:46:18:46:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:46:18:46:38 | getInputStream(...) | SAXParserTests.java:46:18:46:38 | getInputStream(...) | SAXParserTests.java:46:18:46:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:46:18:46:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:55:18:55:38 | getInputStream(...) | SAXParserTests.java:55:18:55:38 | getInputStream(...) | SAXParserTests.java:55:18:55:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:55:18:55:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:55:18:55:38 | getInputStream(...) | SAXParserTests.java:55:18:55:38 | getInputStream(...) | SAXParserTests.java:55:18:55:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:55:18:55:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:64:18:64:38 | getInputStream(...) | SAXParserTests.java:64:18:64:38 | getInputStream(...) | SAXParserTests.java:64:18:64:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:64:18:64:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:64:18:64:38 | getInputStream(...) | SAXParserTests.java:64:18:64:38 | getInputStream(...) | SAXParserTests.java:64:18:64:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:64:18:64:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXParserTests.java:73:18:73:38 | getInputStream(...) | SAXParserTests.java:73:18:73:38 | getInputStream(...) | SAXParserTests.java:73:18:73:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXParserTests.java:73:18:73:38 | getInputStream(...) | user input |
|
| SAXParserTests.java:73:18:73:38 | getInputStream(...) | SAXParserTests.java:73:18:73:38 | getInputStream(...) | SAXParserTests.java:73:18:73:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXParserTests.java:73:18:73:38 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:8:17:8:37 | getInputStream(...) | SAXReaderTests.java:8:17:8:37 | getInputStream(...) | SAXReaderTests.java:8:17:8:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:8:17:8:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:8:17:8:37 | getInputStream(...) | SAXReaderTests.java:8:17:8:37 | getInputStream(...) | SAXReaderTests.java:8:17:8:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:8:17:8:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:23:17:23:37 | getInputStream(...) | SAXReaderTests.java:23:17:23:37 | getInputStream(...) | SAXReaderTests.java:23:17:23:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:23:17:23:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:23:17:23:37 | getInputStream(...) | SAXReaderTests.java:23:17:23:37 | getInputStream(...) | SAXReaderTests.java:23:17:23:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:23:17:23:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:30:17:30:37 | getInputStream(...) | SAXReaderTests.java:30:17:30:37 | getInputStream(...) | SAXReaderTests.java:30:17:30:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:30:17:30:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:30:17:30:37 | getInputStream(...) | SAXReaderTests.java:30:17:30:37 | getInputStream(...) | SAXReaderTests.java:30:17:30:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:30:17:30:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:37:17:37:37 | getInputStream(...) | SAXReaderTests.java:37:17:37:37 | getInputStream(...) | SAXReaderTests.java:37:17:37:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:37:17:37:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:37:17:37:37 | getInputStream(...) | SAXReaderTests.java:37:17:37:37 | getInputStream(...) | SAXReaderTests.java:37:17:37:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:37:17:37:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:45:17:45:37 | getInputStream(...) | SAXReaderTests.java:45:17:45:37 | getInputStream(...) | SAXReaderTests.java:45:17:45:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:45:17:45:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:45:17:45:37 | getInputStream(...) | SAXReaderTests.java:45:17:45:37 | getInputStream(...) | SAXReaderTests.java:45:17:45:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:45:17:45:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:53:17:53:37 | getInputStream(...) | SAXReaderTests.java:53:17:53:37 | getInputStream(...) | SAXReaderTests.java:53:17:53:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:53:17:53:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:53:17:53:37 | getInputStream(...) | SAXReaderTests.java:53:17:53:37 | getInputStream(...) | SAXReaderTests.java:53:17:53:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:53:17:53:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXReaderTests.java:61:17:61:37 | getInputStream(...) | SAXReaderTests.java:61:17:61:37 | getInputStream(...) | SAXReaderTests.java:61:17:61:37 | getInputStream(...) | Unsafe parsing of XML file from $@. | SAXReaderTests.java:61:17:61:37 | getInputStream(...) | user input |
|
| SAXReaderTests.java:61:17:61:37 | getInputStream(...) | SAXReaderTests.java:61:17:61:37 | getInputStream(...) | SAXReaderTests.java:61:17:61:37 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SAXReaderTests.java:61:17:61:37 | getInputStream(...) | user-provided value |
|
||||||
| SAXSourceTests.java:20:18:20:23 | source | SAXSourceTests.java:17:62:17:82 | getInputStream(...) : InputStream | SAXSourceTests.java:20:18:20:23 | source | Unsafe parsing of XML file from $@. | SAXSourceTests.java:17:62:17:82 | getInputStream(...) | user input |
|
| SAXSourceTests.java:20:18:20:23 | source | SAXSourceTests.java:17:62:17:82 | getInputStream(...) : InputStream | SAXSourceTests.java:20:18:20:23 | source | A $@ is parsed as XML without guarding against external entity expansion. | SAXSourceTests.java:17:62:17:82 | getInputStream(...) | user-provided value |
|
||||||
| SchemaTests.java:12:39:12:77 | new StreamSource(...) | SchemaTests.java:12:56:12:76 | getInputStream(...) : InputStream | SchemaTests.java:12:39:12:77 | new StreamSource(...) | Unsafe parsing of XML file from $@. | SchemaTests.java:12:56:12:76 | getInputStream(...) | user input |
|
| SchemaTests.java:12:39:12:77 | new StreamSource(...) | SchemaTests.java:12:56:12:76 | getInputStream(...) : InputStream | SchemaTests.java:12:39:12:77 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | SchemaTests.java:12:56:12:76 | getInputStream(...) | user-provided value |
|
||||||
| SchemaTests.java:25:39:25:77 | new StreamSource(...) | SchemaTests.java:25:56:25:76 | getInputStream(...) : InputStream | SchemaTests.java:25:39:25:77 | new StreamSource(...) | Unsafe parsing of XML file from $@. | SchemaTests.java:25:56:25:76 | getInputStream(...) | user input |
|
| SchemaTests.java:25:39:25:77 | new StreamSource(...) | SchemaTests.java:25:56:25:76 | getInputStream(...) : InputStream | SchemaTests.java:25:39:25:77 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | SchemaTests.java:25:56:25:76 | getInputStream(...) | user-provided value |
|
||||||
| SchemaTests.java:31:39:31:77 | new StreamSource(...) | SchemaTests.java:31:56:31:76 | getInputStream(...) : InputStream | SchemaTests.java:31:39:31:77 | new StreamSource(...) | Unsafe parsing of XML file from $@. | SchemaTests.java:31:56:31:76 | getInputStream(...) | user input |
|
| SchemaTests.java:31:39:31:77 | new StreamSource(...) | SchemaTests.java:31:56:31:76 | getInputStream(...) : InputStream | SchemaTests.java:31:39:31:77 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | SchemaTests.java:31:56:31:76 | getInputStream(...) | user-provided value |
|
||||||
| SchemaTests.java:38:39:38:77 | new StreamSource(...) | SchemaTests.java:38:56:38:76 | getInputStream(...) : InputStream | SchemaTests.java:38:39:38:77 | new StreamSource(...) | Unsafe parsing of XML file from $@. | SchemaTests.java:38:56:38:76 | getInputStream(...) | user input |
|
| SchemaTests.java:38:39:38:77 | new StreamSource(...) | SchemaTests.java:38:56:38:76 | getInputStream(...) : InputStream | SchemaTests.java:38:39:38:77 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | SchemaTests.java:38:56:38:76 | getInputStream(...) | user-provided value |
|
||||||
| SchemaTests.java:45:39:45:77 | new StreamSource(...) | SchemaTests.java:45:56:45:76 | getInputStream(...) : InputStream | SchemaTests.java:45:39:45:77 | new StreamSource(...) | Unsafe parsing of XML file from $@. | SchemaTests.java:45:56:45:76 | getInputStream(...) | user input |
|
| SchemaTests.java:45:39:45:77 | new StreamSource(...) | SchemaTests.java:45:56:45:76 | getInputStream(...) : InputStream | SchemaTests.java:45:39:45:77 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | SchemaTests.java:45:56:45:76 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:14:41:14:61 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:19:41:19:61 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:24:41:24:84 | new InputStreamReader(...) | SimpleXMLTests.java:24:63:24:83 | getInputStream(...) : InputStream | SimpleXMLTests.java:24:41:24:84 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:24:63:24:83 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:24:41:24:84 | new InputStreamReader(...) | SimpleXMLTests.java:24:63:24:83 | getInputStream(...) : InputStream | SimpleXMLTests.java:24:41:24:84 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:24:63:24:83 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:31:41:31:53 | new String(...) | SimpleXMLTests.java:30:5:30:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:31:41:31:53 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:30:5:30:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:31:41:31:53 | new String(...) | SimpleXMLTests.java:30:5:30:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:31:41:31:53 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:30:5:30:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:38:41:38:53 | new String(...) | SimpleXMLTests.java:37:5:37:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:38:41:38:53 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:37:5:37:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:38:41:38:53 | new String(...) | SimpleXMLTests.java:37:5:37:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:38:41:38:53 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:37:5:37:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:43:41:43:84 | new InputStreamReader(...) | SimpleXMLTests.java:43:63:43:83 | getInputStream(...) : InputStream | SimpleXMLTests.java:43:41:43:84 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:43:63:43:83 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:43:41:43:84 | new InputStreamReader(...) | SimpleXMLTests.java:43:63:43:83 | getInputStream(...) : InputStream | SimpleXMLTests.java:43:41:43:84 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:43:63:43:83 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:53:37:53:57 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:58:26:58:46 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:63:26:63:46 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:68:37:68:80 | new InputStreamReader(...) | SimpleXMLTests.java:68:59:68:79 | getInputStream(...) : InputStream | SimpleXMLTests.java:68:37:68:80 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:68:59:68:79 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:68:37:68:80 | new InputStreamReader(...) | SimpleXMLTests.java:68:59:68:79 | getInputStream(...) : InputStream | SimpleXMLTests.java:68:37:68:80 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:68:59:68:79 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:73:37:73:80 | new InputStreamReader(...) | SimpleXMLTests.java:73:59:73:79 | getInputStream(...) : InputStream | SimpleXMLTests.java:73:37:73:80 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:73:59:73:79 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:73:37:73:80 | new InputStreamReader(...) | SimpleXMLTests.java:73:59:73:79 | getInputStream(...) : InputStream | SimpleXMLTests.java:73:37:73:80 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:73:59:73:79 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:78:26:78:69 | new InputStreamReader(...) | SimpleXMLTests.java:78:48:78:68 | getInputStream(...) : InputStream | SimpleXMLTests.java:78:26:78:69 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:78:48:78:68 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:78:26:78:69 | new InputStreamReader(...) | SimpleXMLTests.java:78:48:78:68 | getInputStream(...) : InputStream | SimpleXMLTests.java:78:26:78:69 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:78:48:78:68 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:83:26:83:69 | new InputStreamReader(...) | SimpleXMLTests.java:83:48:83:68 | getInputStream(...) : InputStream | SimpleXMLTests.java:83:26:83:69 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:83:48:83:68 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:83:26:83:69 | new InputStreamReader(...) | SimpleXMLTests.java:83:48:83:68 | getInputStream(...) : InputStream | SimpleXMLTests.java:83:26:83:69 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:83:48:83:68 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:90:37:90:49 | new String(...) | SimpleXMLTests.java:89:5:89:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:90:37:90:49 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:89:5:89:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:90:37:90:49 | new String(...) | SimpleXMLTests.java:89:5:89:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:90:37:90:49 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:89:5:89:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:97:37:97:49 | new String(...) | SimpleXMLTests.java:96:5:96:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:97:37:97:49 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:96:5:96:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:97:37:97:49 | new String(...) | SimpleXMLTests.java:96:5:96:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:97:37:97:49 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:96:5:96:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:104:26:104:38 | new String(...) | SimpleXMLTests.java:103:5:103:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:104:26:104:38 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:103:5:103:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:104:26:104:38 | new String(...) | SimpleXMLTests.java:103:5:103:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:104:26:104:38 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:103:5:103:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:111:26:111:38 | new String(...) | SimpleXMLTests.java:110:5:110:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:111:26:111:38 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:110:5:110:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:111:26:111:38 | new String(...) | SimpleXMLTests.java:110:5:110:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:111:26:111:38 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:110:5:110:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:119:22:119:65 | new InputStreamReader(...) | SimpleXMLTests.java:119:44:119:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:119:22:119:65 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:119:44:119:64 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:119:22:119:65 | new InputStreamReader(...) | SimpleXMLTests.java:119:44:119:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:119:22:119:65 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:119:44:119:64 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:124:22:124:42 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:129:22:129:65 | new InputStreamReader(...) | SimpleXMLTests.java:129:44:129:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:129:22:129:65 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:129:44:129:64 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:129:22:129:65 | new InputStreamReader(...) | SimpleXMLTests.java:129:44:129:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:129:22:129:65 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:129:44:129:64 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:134:22:134:42 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:139:22:139:65 | new InputStreamReader(...) | SimpleXMLTests.java:139:44:139:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:139:22:139:65 | new InputStreamReader(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:139:44:139:64 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:139:22:139:65 | new InputStreamReader(...) | SimpleXMLTests.java:139:44:139:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:139:22:139:65 | new InputStreamReader(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:139:44:139:64 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:146:22:146:34 | new String(...) | SimpleXMLTests.java:145:5:145:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:146:22:146:34 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:145:5:145:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:146:22:146:34 | new String(...) | SimpleXMLTests.java:145:5:145:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:146:22:146:34 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:145:5:145:25 | getInputStream(...) | user-provided value |
|
||||||
| SimpleXMLTests.java:153:22:153:34 | new String(...) | SimpleXMLTests.java:152:5:152:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:153:22:153:34 | new String(...) | Unsafe parsing of XML file from $@. | SimpleXMLTests.java:152:5:152:25 | getInputStream(...) | user input |
|
| SimpleXMLTests.java:153:22:153:34 | new String(...) | SimpleXMLTests.java:152:5:152:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:153:22:153:34 | new String(...) | A $@ is parsed as XML without guarding against external entity expansion. | SimpleXMLTests.java:152:5:152:25 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:20:27:20:65 | new StreamSource(...) | TransformerTests.java:20:44:20:64 | getInputStream(...) : InputStream | TransformerTests.java:20:27:20:65 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:20:44:20:64 | getInputStream(...) | user input |
|
| TransformerTests.java:20:27:20:65 | new StreamSource(...) | TransformerTests.java:20:44:20:64 | getInputStream(...) : InputStream | TransformerTests.java:20:27:20:65 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:20:44:20:64 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:21:23:21:61 | new StreamSource(...) | TransformerTests.java:21:40:21:60 | getInputStream(...) : InputStream | TransformerTests.java:21:23:21:61 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:21:40:21:60 | getInputStream(...) | user input |
|
| TransformerTests.java:21:23:21:61 | new StreamSource(...) | TransformerTests.java:21:40:21:60 | getInputStream(...) : InputStream | TransformerTests.java:21:23:21:61 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:21:40:21:60 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:71:27:71:65 | new StreamSource(...) | TransformerTests.java:71:44:71:64 | getInputStream(...) : InputStream | TransformerTests.java:71:27:71:65 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:71:44:71:64 | getInputStream(...) | user input |
|
| TransformerTests.java:71:27:71:65 | new StreamSource(...) | TransformerTests.java:71:44:71:64 | getInputStream(...) : InputStream | TransformerTests.java:71:27:71:65 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:71:44:71:64 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:72:23:72:61 | new StreamSource(...) | TransformerTests.java:72:40:72:60 | getInputStream(...) : InputStream | TransformerTests.java:72:23:72:61 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:72:40:72:60 | getInputStream(...) | user input |
|
| TransformerTests.java:72:23:72:61 | new StreamSource(...) | TransformerTests.java:72:40:72:60 | getInputStream(...) : InputStream | TransformerTests.java:72:23:72:61 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:72:40:72:60 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:79:27:79:65 | new StreamSource(...) | TransformerTests.java:79:44:79:64 | getInputStream(...) : InputStream | TransformerTests.java:79:27:79:65 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:79:44:79:64 | getInputStream(...) | user input |
|
| TransformerTests.java:79:27:79:65 | new StreamSource(...) | TransformerTests.java:79:44:79:64 | getInputStream(...) : InputStream | TransformerTests.java:79:27:79:65 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:79:44:79:64 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:80:23:80:61 | new StreamSource(...) | TransformerTests.java:80:40:80:60 | getInputStream(...) : InputStream | TransformerTests.java:80:23:80:61 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:80:40:80:60 | getInputStream(...) | user input |
|
| TransformerTests.java:80:23:80:61 | new StreamSource(...) | TransformerTests.java:80:40:80:60 | getInputStream(...) : InputStream | TransformerTests.java:80:23:80:61 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:80:40:80:60 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:88:27:88:65 | new StreamSource(...) | TransformerTests.java:88:44:88:64 | getInputStream(...) : InputStream | TransformerTests.java:88:27:88:65 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:88:44:88:64 | getInputStream(...) | user input |
|
| TransformerTests.java:88:27:88:65 | new StreamSource(...) | TransformerTests.java:88:44:88:64 | getInputStream(...) : InputStream | TransformerTests.java:88:27:88:65 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:88:44:88:64 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:89:23:89:61 | new StreamSource(...) | TransformerTests.java:89:40:89:60 | getInputStream(...) : InputStream | TransformerTests.java:89:23:89:61 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:89:40:89:60 | getInputStream(...) | user input |
|
| TransformerTests.java:89:23:89:61 | new StreamSource(...) | TransformerTests.java:89:40:89:60 | getInputStream(...) : InputStream | TransformerTests.java:89:23:89:61 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:89:40:89:60 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:97:27:97:65 | new StreamSource(...) | TransformerTests.java:97:44:97:64 | getInputStream(...) : InputStream | TransformerTests.java:97:27:97:65 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:97:44:97:64 | getInputStream(...) | user input |
|
| TransformerTests.java:97:27:97:65 | new StreamSource(...) | TransformerTests.java:97:44:97:64 | getInputStream(...) : InputStream | TransformerTests.java:97:27:97:65 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:97:44:97:64 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:98:23:98:61 | new StreamSource(...) | TransformerTests.java:98:40:98:60 | getInputStream(...) : InputStream | TransformerTests.java:98:23:98:61 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:98:40:98:60 | getInputStream(...) | user input |
|
| TransformerTests.java:98:23:98:61 | new StreamSource(...) | TransformerTests.java:98:40:98:60 | getInputStream(...) : InputStream | TransformerTests.java:98:23:98:61 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:98:40:98:60 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:103:21:103:59 | new StreamSource(...) | TransformerTests.java:103:38:103:58 | getInputStream(...) : InputStream | TransformerTests.java:103:21:103:59 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:103:38:103:58 | getInputStream(...) | user input |
|
| TransformerTests.java:103:21:103:59 | new StreamSource(...) | TransformerTests.java:103:38:103:58 | getInputStream(...) : InputStream | TransformerTests.java:103:21:103:59 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:103:38:103:58 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:116:21:116:59 | new StreamSource(...) | TransformerTests.java:116:38:116:58 | getInputStream(...) : InputStream | TransformerTests.java:116:21:116:59 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:116:38:116:58 | getInputStream(...) | user input |
|
| TransformerTests.java:116:21:116:59 | new StreamSource(...) | TransformerTests.java:116:38:116:58 | getInputStream(...) : InputStream | TransformerTests.java:116:21:116:59 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:116:38:116:58 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:122:21:122:59 | new StreamSource(...) | TransformerTests.java:122:38:122:58 | getInputStream(...) : InputStream | TransformerTests.java:122:21:122:59 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:122:38:122:58 | getInputStream(...) | user input |
|
| TransformerTests.java:122:21:122:59 | new StreamSource(...) | TransformerTests.java:122:38:122:58 | getInputStream(...) : InputStream | TransformerTests.java:122:21:122:59 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:122:38:122:58 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:129:21:129:59 | new StreamSource(...) | TransformerTests.java:129:38:129:58 | getInputStream(...) : InputStream | TransformerTests.java:129:21:129:59 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:129:38:129:58 | getInputStream(...) | user input |
|
| TransformerTests.java:129:21:129:59 | new StreamSource(...) | TransformerTests.java:129:38:129:58 | getInputStream(...) : InputStream | TransformerTests.java:129:21:129:59 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:129:38:129:58 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:136:21:136:59 | new StreamSource(...) | TransformerTests.java:136:38:136:58 | getInputStream(...) : InputStream | TransformerTests.java:136:21:136:59 | new StreamSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:136:38:136:58 | getInputStream(...) | user input |
|
| TransformerTests.java:136:21:136:59 | new StreamSource(...) | TransformerTests.java:136:38:136:58 | getInputStream(...) : InputStream | TransformerTests.java:136:21:136:59 | new StreamSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:136:38:136:58 | getInputStream(...) | user-provided value |
|
||||||
| TransformerTests.java:141:18:141:70 | new SAXSource(...) | TransformerTests.java:141:48:141:68 | getInputStream(...) : InputStream | TransformerTests.java:141:18:141:70 | new SAXSource(...) | Unsafe parsing of XML file from $@. | TransformerTests.java:141:48:141:68 | getInputStream(...) | user input |
|
| TransformerTests.java:141:18:141:70 | new SAXSource(...) | TransformerTests.java:141:48:141:68 | getInputStream(...) : InputStream | TransformerTests.java:141:18:141:70 | new SAXSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | TransformerTests.java:141:48:141:68 | getInputStream(...) | user-provided value |
|
||||||
| UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | Unsafe parsing of XML file from $@. | UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | user input |
|
| UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | UnmarshallerTests.java:28:18:28:38 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:16:18:16:55 | new InputSource(...) | XMLReaderTests.java:16:34:16:54 | getInputStream(...) : InputStream | XMLReaderTests.java:16:18:16:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:16:34:16:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:16:18:16:55 | new InputSource(...) | XMLReaderTests.java:16:34:16:54 | getInputStream(...) : InputStream | XMLReaderTests.java:16:18:16:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:16:34:16:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:56:18:56:55 | new InputSource(...) | XMLReaderTests.java:56:34:56:54 | getInputStream(...) : InputStream | XMLReaderTests.java:56:18:56:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:56:34:56:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:56:18:56:55 | new InputSource(...) | XMLReaderTests.java:56:34:56:54 | getInputStream(...) : InputStream | XMLReaderTests.java:56:18:56:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:56:34:56:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:63:18:63:55 | new InputSource(...) | XMLReaderTests.java:63:34:63:54 | getInputStream(...) : InputStream | XMLReaderTests.java:63:18:63:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:63:34:63:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:63:18:63:55 | new InputSource(...) | XMLReaderTests.java:63:34:63:54 | getInputStream(...) : InputStream | XMLReaderTests.java:63:18:63:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:63:34:63:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:70:18:70:55 | new InputSource(...) | XMLReaderTests.java:70:34:70:54 | getInputStream(...) : InputStream | XMLReaderTests.java:70:18:70:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:70:34:70:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:70:18:70:55 | new InputSource(...) | XMLReaderTests.java:70:34:70:54 | getInputStream(...) : InputStream | XMLReaderTests.java:70:18:70:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:70:34:70:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:78:18:78:55 | new InputSource(...) | XMLReaderTests.java:78:34:78:54 | getInputStream(...) : InputStream | XMLReaderTests.java:78:18:78:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:78:34:78:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:78:18:78:55 | new InputSource(...) | XMLReaderTests.java:78:34:78:54 | getInputStream(...) : InputStream | XMLReaderTests.java:78:18:78:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:78:34:78:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:86:18:86:55 | new InputSource(...) | XMLReaderTests.java:86:34:86:54 | getInputStream(...) : InputStream | XMLReaderTests.java:86:18:86:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:86:34:86:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:86:18:86:55 | new InputSource(...) | XMLReaderTests.java:86:34:86:54 | getInputStream(...) : InputStream | XMLReaderTests.java:86:18:86:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:86:34:86:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:94:18:94:55 | new InputSource(...) | XMLReaderTests.java:94:34:94:54 | getInputStream(...) : InputStream | XMLReaderTests.java:94:18:94:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:94:34:94:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:94:18:94:55 | new InputSource(...) | XMLReaderTests.java:94:34:94:54 | getInputStream(...) : InputStream | XMLReaderTests.java:94:18:94:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:94:34:94:54 | getInputStream(...) | user-provided value |
|
||||||
| XMLReaderTests.java:100:18:100:55 | new InputSource(...) | XMLReaderTests.java:100:34:100:54 | getInputStream(...) : InputStream | XMLReaderTests.java:100:18:100:55 | new InputSource(...) | Unsafe parsing of XML file from $@. | XMLReaderTests.java:100:34:100:54 | getInputStream(...) | user input |
|
| XMLReaderTests.java:100:18:100:55 | new InputSource(...) | XMLReaderTests.java:100:34:100:54 | getInputStream(...) : InputStream | XMLReaderTests.java:100:18:100:55 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XMLReaderTests.java:100:34:100:54 | getInputStream(...) | user-provided value |
|
||||||
| XPathExpressionTests.java:27:21:27:58 | new InputSource(...) | XPathExpressionTests.java:27:37:27:57 | getInputStream(...) : InputStream | XPathExpressionTests.java:27:21:27:58 | new InputSource(...) | Unsafe parsing of XML file from $@. | XPathExpressionTests.java:27:37:27:57 | getInputStream(...) | user input |
|
| XPathExpressionTests.java:27:21:27:58 | new InputSource(...) | XPathExpressionTests.java:27:37:27:57 | getInputStream(...) : InputStream | XPathExpressionTests.java:27:21:27:58 | new InputSource(...) | A $@ is parsed as XML without guarding against external entity expansion. | XPathExpressionTests.java:27:37:27:57 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:9:35:9:55 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:10:34:10:54 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:24:35:24:55 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:25:34:25:54 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:31:35:31:55 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:32:34:32:54 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:39:35:39:55 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:40:34:40:54 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:47:35:47:55 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | user-provided value |
|
||||||
| XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | Unsafe parsing of XML file from $@. | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | user input |
|
| XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | A $@ is parsed as XML without guarding against external entity expansion. | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | user-provided value |
|
||||||
|
|||||||
@@ -93,8 +93,6 @@ class RegExpRoot extends RegExpTerm {
|
|||||||
* Holds if this root term is relevant to the ReDoS analysis.
|
* Holds if this root term is relevant to the ReDoS analysis.
|
||||||
*/
|
*/
|
||||||
predicate isRelevant() {
|
predicate isRelevant() {
|
||||||
// there is at least one repetition
|
|
||||||
getRoot(any(InfiniteRepetitionQuantifier q)) = this and
|
|
||||||
// is actually used as a RegExp
|
// is actually used as a RegExp
|
||||||
this.isUsedAsRegExp() and
|
this.isUsedAsRegExp() and
|
||||||
// not excluded for library specific reasons
|
// not excluded for library specific reasons
|
||||||
@@ -877,6 +875,101 @@ predicate isStartState(State state) {
|
|||||||
*/
|
*/
|
||||||
signature predicate isCandidateSig(State state, string pump);
|
signature predicate isCandidateSig(State state, string pump);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `state` is a candidate for ReDoS.
|
||||||
|
*/
|
||||||
|
signature predicate isCandidateSig(State state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predicates for constructing a prefix string that leads to a given state.
|
||||||
|
*/
|
||||||
|
module PrefixConstruction<isCandidateSig/1 isCandidate> {
|
||||||
|
/**
|
||||||
|
* Holds if `state` is the textually last start state for the regular expression.
|
||||||
|
*/
|
||||||
|
private predicate lastStartState(State state) {
|
||||||
|
exists(RegExpRoot root |
|
||||||
|
state =
|
||||||
|
max(State s, Location l |
|
||||||
|
s = stateInRelevantRegexp() and
|
||||||
|
isStartState(s) and
|
||||||
|
getRoot(s.getRepr()) = root and
|
||||||
|
l = s.getRepr().getLocation()
|
||||||
|
|
|
||||||
|
s
|
||||||
|
order by
|
||||||
|
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
|
||||||
|
l.getEndLine()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
|
||||||
|
*/
|
||||||
|
private predicate existsTransition(State a, State b) { delta(a, _, b) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
|
||||||
|
*/
|
||||||
|
int prefixLength(State start, State state) =
|
||||||
|
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum number of transitions it takes to reach `state` from the start state.
|
||||||
|
*/
|
||||||
|
private int lengthFromStart(State state) { result = prefixLength(_, state) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string for which the regular expression will reach `state`.
|
||||||
|
*
|
||||||
|
* Has at most one result for any given `state`.
|
||||||
|
* This predicate will not always have a result even if there is a ReDoS issue in
|
||||||
|
* the regular expression.
|
||||||
|
*/
|
||||||
|
string prefix(State state) {
|
||||||
|
lastStartState(state) and
|
||||||
|
result = ""
|
||||||
|
or
|
||||||
|
// the search stops past the last redos candidate state.
|
||||||
|
lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and
|
||||||
|
exists(State prev |
|
||||||
|
// select a unique predecessor (by an arbitrary measure)
|
||||||
|
prev =
|
||||||
|
min(State s, Location loc |
|
||||||
|
lengthFromStart(s) = lengthFromStart(state) - 1 and
|
||||||
|
loc = s.getRepr().getLocation() and
|
||||||
|
delta(s, _, state)
|
||||||
|
|
|
||||||
|
s
|
||||||
|
order by
|
||||||
|
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
|
||||||
|
s.getRepr().toString()
|
||||||
|
)
|
||||||
|
|
|
||||||
|
// greedy search for the shortest prefix
|
||||||
|
result = prefix(prev) and delta(prev, Epsilon(), state)
|
||||||
|
or
|
||||||
|
not delta(prev, Epsilon(), state) and
|
||||||
|
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
|
||||||
|
*/
|
||||||
|
private string getCanonicalEdgeChar(State prev, State next) {
|
||||||
|
result =
|
||||||
|
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a state within a regular expression that contains a candidate state. */
|
||||||
|
pragma[noinline]
|
||||||
|
State stateInRelevantRegexp() {
|
||||||
|
exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A module for pruning candidate ReDoS states.
|
* A module for pruning candidate ReDoS states.
|
||||||
* The candidates are specified by the `isCandidate` signature predicate.
|
* The candidates are specified by the `isCandidate` signature predicate.
|
||||||
@@ -910,95 +1003,9 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
/** Gets a state that can reach the `accept-any` state using only epsilon steps. */
|
/** Gets a state that can reach the `accept-any` state using only epsilon steps. */
|
||||||
private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) }
|
private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) }
|
||||||
|
|
||||||
/**
|
predicate isCandidateState(State s) { isReDoSCandidate(s, _) }
|
||||||
* Predicates for constructing a prefix string that leads to a given state.
|
|
||||||
*/
|
|
||||||
private module PrefixConstruction {
|
|
||||||
/**
|
|
||||||
* Holds if `state` is the textually last start state for the regular expression.
|
|
||||||
*/
|
|
||||||
private predicate lastStartState(State state) {
|
|
||||||
exists(RegExpRoot root |
|
|
||||||
state =
|
|
||||||
max(State s, Location l |
|
|
||||||
s = stateInPumpableRegexp() and
|
|
||||||
isStartState(s) and
|
|
||||||
getRoot(s.getRepr()) = root and
|
|
||||||
l = s.getRepr().getLocation()
|
|
||||||
|
|
|
||||||
s
|
|
||||||
order by
|
|
||||||
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
|
|
||||||
l.getEndLine()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
import PrefixConstruction<isCandidateState/1> as Prefix
|
||||||
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
|
|
||||||
*/
|
|
||||||
private predicate existsTransition(State a, State b) { delta(a, _, b) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
|
|
||||||
*/
|
|
||||||
int prefixLength(State start, State state) =
|
|
||||||
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the minimum number of transitions it takes to reach `state` from the start state.
|
|
||||||
*/
|
|
||||||
private int lengthFromStart(State state) { result = prefixLength(_, state) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a string for which the regular expression will reach `state`.
|
|
||||||
*
|
|
||||||
* Has at most one result for any given `state`.
|
|
||||||
* This predicate will not always have a result even if there is a ReDoS issue in
|
|
||||||
* the regular expression.
|
|
||||||
*/
|
|
||||||
string prefix(State state) {
|
|
||||||
lastStartState(state) and
|
|
||||||
result = ""
|
|
||||||
or
|
|
||||||
// the search stops past the last redos candidate state.
|
|
||||||
lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and
|
|
||||||
exists(State prev |
|
|
||||||
// select a unique predecessor (by an arbitrary measure)
|
|
||||||
prev =
|
|
||||||
min(State s, Location loc |
|
|
||||||
lengthFromStart(s) = lengthFromStart(state) - 1 and
|
|
||||||
loc = s.getRepr().getLocation() and
|
|
||||||
delta(s, _, state)
|
|
||||||
|
|
|
||||||
s
|
|
||||||
order by
|
|
||||||
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
|
|
||||||
s.getRepr().toString()
|
|
||||||
)
|
|
||||||
|
|
|
||||||
// greedy search for the shortest prefix
|
|
||||||
result = prefix(prev) and delta(prev, Epsilon(), state)
|
|
||||||
or
|
|
||||||
not delta(prev, Epsilon(), state) and
|
|
||||||
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
|
|
||||||
*/
|
|
||||||
private string getCanonicalEdgeChar(State prev, State next) {
|
|
||||||
result =
|
|
||||||
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a state within a regular expression that has a pumpable state. */
|
|
||||||
pragma[noinline]
|
|
||||||
State stateInPumpableRegexp() {
|
|
||||||
exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predicates for testing the presence of a rejecting suffix.
|
* Predicates for testing the presence of a rejecting suffix.
|
||||||
@@ -1018,8 +1025,6 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
|
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
|
||||||
*/
|
*/
|
||||||
private module SuffixConstruction {
|
private module SuffixConstruction {
|
||||||
import PrefixConstruction
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if all states reachable from `fork` by repeating `w`
|
* Holds if all states reachable from `fork` by repeating `w`
|
||||||
* are likely rejectable by appending some suffix.
|
* are likely rejectable by appending some suffix.
|
||||||
@@ -1036,7 +1041,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
*/
|
*/
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private predicate isLikelyRejectable(State s) {
|
private predicate isLikelyRejectable(State s) {
|
||||||
s = stateInPumpableRegexp() and
|
s = Prefix::stateInRelevantRegexp() and
|
||||||
(
|
(
|
||||||
// exists a reject edge with some char.
|
// exists a reject edge with some char.
|
||||||
hasRejectEdge(s)
|
hasRejectEdge(s)
|
||||||
@@ -1052,7 +1057,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
* Holds if `s` is not an accept state, and there is no epsilon transition to an accept state.
|
* Holds if `s` is not an accept state, and there is no epsilon transition to an accept state.
|
||||||
*/
|
*/
|
||||||
predicate isRejectState(State s) {
|
predicate isRejectState(State s) {
|
||||||
s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_)
|
s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1060,7 +1065,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
*/
|
*/
|
||||||
pragma[noopt]
|
pragma[noopt]
|
||||||
predicate hasEdgeToLikelyRejectable(State s) {
|
predicate hasEdgeToLikelyRejectable(State s) {
|
||||||
s = stateInPumpableRegexp() and
|
s = Prefix::stateInRelevantRegexp() and
|
||||||
// all edges (at least one) with some char leads to another state that is rejectable.
|
// all edges (at least one) with some char leads to another state that is rejectable.
|
||||||
// the `next` states might not share a common suffix, which can cause FPs.
|
// the `next` states might not share a common suffix, which can cause FPs.
|
||||||
exists(string char | char = hasEdgeToLikelyRejectableHelper(s) |
|
exists(string char | char = hasEdgeToLikelyRejectableHelper(s) |
|
||||||
@@ -1076,7 +1081,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
*/
|
*/
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private string hasEdgeToLikelyRejectableHelper(State s) {
|
private string hasEdgeToLikelyRejectableHelper(State s) {
|
||||||
s = stateInPumpableRegexp() and
|
s = Prefix::stateInRelevantRegexp() and
|
||||||
not hasRejectEdge(s) and
|
not hasRejectEdge(s) and
|
||||||
not isRejectState(s) and
|
not isRejectState(s) and
|
||||||
deltaClosedChar(s, result, _)
|
deltaClosedChar(s, result, _)
|
||||||
@@ -1088,8 +1093,8 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
* `prev` to `next` that the character symbol `char`.
|
* `prev` to `next` that the character symbol `char`.
|
||||||
*/
|
*/
|
||||||
predicate deltaClosedChar(State prev, string char, State next) {
|
predicate deltaClosedChar(State prev, string char, State next) {
|
||||||
prev = stateInPumpableRegexp() and
|
prev = Prefix::stateInRelevantRegexp() and
|
||||||
next = stateInPumpableRegexp() and
|
next = Prefix::stateInRelevantRegexp() and
|
||||||
deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next)
|
deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1099,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
result = getAnInputSymbolMatching(char)
|
result = getAnInputSymbolMatching(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
RegExpRoot relevantRoot() {
|
||||||
|
exists(RegExpTerm term, State s |
|
||||||
|
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a char used for finding possible suffixes inside `root`.
|
* Gets a char used for finding possible suffixes inside `root`.
|
||||||
*/
|
*/
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private string relevant(RegExpRoot root) {
|
private string relevant(RegExpRoot root) {
|
||||||
exists(ascii(result)) and exists(root)
|
root = relevantRoot() and
|
||||||
or
|
(
|
||||||
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
|
exists(ascii(result)) and exists(root)
|
||||||
or
|
or
|
||||||
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
|
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
|
||||||
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
|
or
|
||||||
result = ["|", "\n", "Z"] and exists(root)
|
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
|
||||||
|
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
|
||||||
|
result = ["|", "\n", "Z"] and exists(root)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1208,12 +1223,12 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
|
|||||||
predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) {
|
predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) {
|
||||||
isReDoSAttackable(t, pump, s) and
|
isReDoSAttackable(t, pump, s) and
|
||||||
(
|
(
|
||||||
prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and
|
prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and
|
||||||
not PrefixConstruction::prefix(s) = ""
|
not Prefix::prefix(s) = ""
|
||||||
or
|
or
|
||||||
PrefixConstruction::prefix(s) = "" and prefixMsg = ""
|
Prefix::prefix(s) = "" and prefixMsg = ""
|
||||||
or
|
or
|
||||||
not exists(PrefixConstruction::prefix(s)) and prefixMsg = ""
|
not exists(Prefix::prefix(s)) and prefixMsg = ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ import UnusedParameter
|
|||||||
|
|
||||||
from Parameter p
|
from Parameter p
|
||||||
where isAnAccidentallyUnusedParameter(p)
|
where isAnAccidentallyUnusedParameter(p)
|
||||||
select p, "Unused parameter " + p.getAVariable().getName() + "."
|
select p, "The parameter '" + p.getVariable().getName() + "' is never used."
|
||||||
|
|||||||
@@ -53,4 +53,4 @@ where
|
|||||||
not e instanceof EqualityTest and
|
not e instanceof EqualityTest and
|
||||||
e.getRightOperand().getIntValue() = 0 and
|
e.getRightOperand().getIntValue() = 0 and
|
||||||
not acceptableSignCheck(b)
|
not acceptableSignCheck(b)
|
||||||
select e, "Sign check of a bitwise operation"
|
select e, "Potentially unsafe sign check of a bitwise operation."
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user