Merge branch 'main' into promote-jexl-injection

This commit is contained in:
Tony Torralba
2021-05-07 12:36:49 +02:00
committed by GitHub
121 changed files with 3948 additions and 548 deletions

View File

@@ -9,6 +9,8 @@
* @id cpp/signed-overflow-check
* @tags correctness
* security
* external/cwe/cwe-128
* external/cwe/cwe-190
*/
import cpp

View File

@@ -7,12 +7,12 @@
* @kind path-problem
* @problem.severity warning
* @precision high
* @id cpp/upcast-array-pointer-arithmetic
* @tags correctness
* reliability
* security
* external/cwe/cwe-119
* external/cwe/cwe-843
* @id cpp/upcast-array-pointer-arithmetic
*/
import cpp

View File

@@ -8,6 +8,8 @@
* @tags reliability
* correctness
* security
* external/cwe/cwe-190
* external/cwe/cwe-253
*/
import cpp

View File

@@ -9,6 +9,7 @@
* @tags reliability
* correctness
* security
* external/cwe/cwe-234
* external/cwe/cwe-685
*/

View File

@@ -8,6 +8,7 @@
* @id cpp/pointer-overflow-check
* @tags reliability
* security
* external/cwe/cwe-758
*/
import cpp

View File

@@ -10,6 +10,7 @@
* @tags correctness
* language-features
* security
* external/cwe/cwe-670
*/
import cpp

View File

@@ -12,6 +12,8 @@
* @tags correctness
* maintainability
* security
* external/cwe/cwe-234
* external/cwe/cwe-685
*/
import cpp

View File

@@ -53,20 +53,27 @@ class WrongCheckErrorOperatorNew extends FunctionCall {
* Holds if results call `operator new` check in `operator if`.
*/
predicate isExistsIfCondition() {
exists(IfCompareWithZero ifc, AssignExpr aex, Initializer it |
exists(IfCompareWithZero ifc |
// call `operator new` directly from the condition of `operator if`.
this = ifc.getCondition().getAChild*()
or
// check results call `operator new` with variable appropriation
postDominates(ifc, this) and
aex.getAChild() = exp and
ifc.getCondition().getAChild().(VariableAccess).getTarget() =
aex.getLValue().(VariableAccess).getTarget()
or
// check results call `operator new` with declaration variable
postDominates(ifc, this) and
exp = it.getExpr() and
it.getDeclaration() = ifc.getCondition().getAChild().(VariableAccess).getTarget()
exists(Variable v |
v = ifc.getCondition().getAChild().(VariableAccess).getTarget() and
(
exists(AssignExpr aex |
// check results call `operator new` with variable appropriation
aex.getAChild() = exp and
v = aex.getLValue().(VariableAccess).getTarget()
)
or
exists(Initializer it |
// check results call `operator new` with declaration variable
exp = it.getExpr() and
it.getDeclaration() = v
)
)
)
)
}

View File

@@ -101,6 +101,7 @@ class Type extends Locatable, @type {
*
* For example, starting with `const i64* const` in the context of `typedef long long i64;`, this predicate will return `long long*`.
*/
pragma[nomagic]
Type getUnspecifiedType() { unspecifiedtype(underlyingElement(this), unresolveElement(result)) }
/**

View File

@@ -297,7 +297,8 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the opcode that specifies the operation performed by this instruction.
*/
final Opcode getOpcode() { result = Construction::getInstructionOpcode(this) }
pragma[inline]
final Opcode getOpcode() { Construction::getInstructionOpcode(result, this) }
/**
* Gets all direct uses of the result of this instruction. The result can be

View File

@@ -338,15 +338,21 @@ private module Cached {
instr = unreachedInstruction(_) and result = Language::getVoidType()
}
/**
* Holds if `opcode` is the opcode that specifies the operation performed by `instr`.
*
* The parameters are ordered such that they produce a clean join (with no need for reordering)
* in the characteristic predicates of the `Instruction` subclasses.
*/
cached
Opcode getInstructionOpcode(Instruction instr) {
result = getOldInstruction(instr).getOpcode()
predicate getInstructionOpcode(Opcode opcode, Instruction instr) {
opcode = getOldInstruction(instr).getOpcode()
or
instr = phiInstruction(_, _) and result instanceof Opcode::Phi
instr = phiInstruction(_, _) and opcode instanceof Opcode::Phi
or
instr = chiInstruction(_) and result instanceof Opcode::Chi
instr = chiInstruction(_) and opcode instanceof Opcode::Chi
or
instr = unreachedInstruction(_) and result instanceof Opcode::Unreached
instr = unreachedInstruction(_) and opcode instanceof Opcode::Unreached
}
cached

View File

@@ -297,7 +297,8 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the opcode that specifies the operation performed by this instruction.
*/
final Opcode getOpcode() { result = Construction::getInstructionOpcode(this) }
pragma[inline]
final Opcode getOpcode() { Construction::getInstructionOpcode(result, this) }
/**
* Gets all direct uses of the result of this instruction. The result can be

View File

@@ -360,8 +360,8 @@ CppType getInstructionResultType(TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(_, getInstructionTag(instr), result)
}
Opcode getInstructionOpcode(TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(result, getInstructionTag(instr), _)
predicate getInstructionOpcode(Opcode opcode, TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(opcode, getInstructionTag(instr), _)
}
IRFunctionBase getInstructionEnclosingIRFunction(TStageInstruction instr) {

View File

@@ -297,7 +297,8 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the opcode that specifies the operation performed by this instruction.
*/
final Opcode getOpcode() { result = Construction::getInstructionOpcode(this) }
pragma[inline]
final Opcode getOpcode() { Construction::getInstructionOpcode(result, this) }
/**
* Gets all direct uses of the result of this instruction. The result can be

View File

@@ -338,15 +338,21 @@ private module Cached {
instr = unreachedInstruction(_) and result = Language::getVoidType()
}
/**
* Holds if `opcode` is the opcode that specifies the operation performed by `instr`.
*
* The parameters are ordered such that they produce a clean join (with no need for reordering)
* in the characteristic predicates of the `Instruction` subclasses.
*/
cached
Opcode getInstructionOpcode(Instruction instr) {
result = getOldInstruction(instr).getOpcode()
predicate getInstructionOpcode(Opcode opcode, Instruction instr) {
opcode = getOldInstruction(instr).getOpcode()
or
instr = phiInstruction(_, _) and result instanceof Opcode::Phi
instr = phiInstruction(_, _) and opcode instanceof Opcode::Phi
or
instr = chiInstruction(_) and result instanceof Opcode::Chi
instr = chiInstruction(_) and opcode instanceof Opcode::Chi
or
instr = unreachedInstruction(_) and result instanceof Opcode::Unreached
instr = unreachedInstruction(_) and opcode instanceof Opcode::Unreached
}
cached

View File

@@ -0,0 +1,14 @@
lgtm,codescanning
* Implicit base constructor calls are now extracted. For example, in
```csharp
class Base
{
public Base() { }
}
class Sub : Base
{
public Sub() { }
}
```
there is an implicit call to the `Base` constructor from the `Sub` constructor.

View File

@@ -7,6 +7,8 @@ namespace Semmle.Extraction.CSharp
{
public static int Main(string[] args)
{
Extractor.SetInvariantCulture();
return (int)Extractor.Run(args);
}
}

View File

@@ -52,6 +52,8 @@ namespace Semmle.Extraction.CSharp.Standalone
{
public static int Main(string[] args)
{
Extractor.SetInvariantCulture();
var options = Options.Create(args);
// options.CIL = true; // To do: Enable this
using var output = new ConsoleLogger(options.Verbosity);

View File

@@ -41,7 +41,38 @@ namespace Semmle.Extraction.CSharp.Entities
var initializer = syntax?.Initializer;
if (initializer is null)
{
if (Symbol.MethodKind is MethodKind.Constructor)
{
var baseType = Symbol.ContainingType.BaseType;
if (baseType is null)
{
Context.ModelError(Symbol, "Unable to resolve base type in implicit constructor initializer");
return;
}
var baseConstructor = baseType.InstanceConstructors.FirstOrDefault(c => c.Arity is 0);
if (baseConstructor is null)
{
Context.ModelError(Symbol, "Unable to resolve implicit constructor initializer call");
return;
}
var baseConstructorTarget = Create(Context, baseConstructor);
var info = new ExpressionInfo(Context,
AnnotatedTypeSymbol.CreateNotAnnotated(baseType),
Location,
Kinds.ExprKind.CONSTRUCTOR_INIT,
this,
-1,
isCompilerGenerated: true,
null);
trapFile.expr_call(new Expression(info), baseConstructorTarget);
}
return;
}
ITypeSymbol initializerType;
var symbolInfo = Context.GetSymbolInfo(initializer);

View File

@@ -11,6 +11,8 @@ using System.Diagnostics;
using System.Threading.Tasks;
using Semmle.Util.Logging;
using System.Collections.Concurrent;
using System.Globalization;
using System.Threading;
namespace Semmle.Extraction.CSharp
{
@@ -52,6 +54,21 @@ namespace Semmle.Extraction.CSharp
public void MissingType(string type) { }
}
/// <summary>
/// Set the application culture to the invariant culture.
///
/// This is required among others to ensure that the invariant culture is used for value formatting during TRAP
/// file writing.
/// </summary>
public static void SetInvariantCulture()
{
var culture = CultureInfo.InvariantCulture;
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
/// <summary>
/// Command-line driver for the extractor.
/// </summary>

View File

@@ -297,7 +297,8 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the opcode that specifies the operation performed by this instruction.
*/
final Opcode getOpcode() { result = Construction::getInstructionOpcode(this) }
pragma[inline]
final Opcode getOpcode() { Construction::getInstructionOpcode(result, this) }
/**
* Gets all direct uses of the result of this instruction. The result can be

View File

@@ -165,10 +165,10 @@ import Cached
cached
private module Cached {
cached
Opcode getInstructionOpcode(TRawInstruction instr) {
predicate getInstructionOpcode(Opcode opcode, TRawInstruction instr) {
exists(TranslatedElement element, InstructionTag tag |
instructionOrigin(instr, element, tag) and
element.hasInstruction(result, tag, _)
element.hasInstruction(opcode, tag, _)
)
}

View File

@@ -297,7 +297,8 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the opcode that specifies the operation performed by this instruction.
*/
final Opcode getOpcode() { result = Construction::getInstructionOpcode(this) }
pragma[inline]
final Opcode getOpcode() { Construction::getInstructionOpcode(result, this) }
/**
* Gets all direct uses of the result of this instruction. The result can be

View File

@@ -338,15 +338,21 @@ private module Cached {
instr = unreachedInstruction(_) and result = Language::getVoidType()
}
/**
* Holds if `opcode` is the opcode that specifies the operation performed by `instr`.
*
* The parameters are ordered such that they produce a clean join (with no need for reordering)
* in the characteristic predicates of the `Instruction` subclasses.
*/
cached
Opcode getInstructionOpcode(Instruction instr) {
result = getOldInstruction(instr).getOpcode()
predicate getInstructionOpcode(Opcode opcode, Instruction instr) {
opcode = getOldInstruction(instr).getOpcode()
or
instr = phiInstruction(_, _) and result instanceof Opcode::Phi
instr = phiInstruction(_, _) and opcode instanceof Opcode::Phi
or
instr = chiInstruction(_) and result instanceof Opcode::Chi
instr = chiInstruction(_) and opcode instanceof Opcode::Chi
or
instr = unreachedInstruction(_) and result instanceof Opcode::Unreached
instr = unreachedInstruction(_) and opcode instanceof Opcode::Unreached
}
cached

View File

@@ -244,18 +244,10 @@ module InitializerSplitting {
* Holds if `c` is a non-static constructor that performs the initialization
* of member `m`.
*/
predicate constructorInitializes(Constructor c, InitializedInstanceMember m) {
predicate constructorInitializes(InstanceConstructor c, InitializedInstanceMember m) {
c.isUnboundDeclaration() and
not c.isStatic() and
c.getDeclaringType().hasMember(m) and
(
not c.hasInitializer()
or
// Members belonging to the base class are initialized via calls to the
// base constructor
c.getInitializer().isBase() and
m.getDeclaringType() = c.getDeclaringType()
)
c.getDeclaringType().getAMember() = m and
not c.getInitializer().isThis()
}
/**

View File

@@ -285,29 +285,37 @@ collections.cs:
constructor_init.cs:
# 5| System.Void BaseClass..ctor()
# 5| Block 0
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| r5_3(glval<BaseClass>) = InitializeThis :
# 6| v6_1(Void) = NoOp :
# 5| v5_4(Void) = ReturnVoid :
# 5| v5_5(Void) = AliasedUse : ~m?
# 5| v5_6(Void) = ExitFunction :
# 5| v5_1(Void) = EnterFunction :
# 5| mu5_2(<unknown>) = AliasedDefinition :
# 5| r5_3(glval<BaseClass>) = InitializeThis :
# 5| r5_4(glval<Object>) = Convert[BaseClass : Object] : r5_3
# 5| r5_5(<funcaddr>) = FunctionAddress[Object] :
# 5| v5_6(Void) = Call[Object] : func:r5_5, this:r5_4
# 5| mu5_7(<unknown>) = ^CallSideEffect : ~m?
# 6| v6_1(Void) = NoOp :
# 5| v5_8(Void) = ReturnVoid :
# 5| v5_9(Void) = AliasedUse : ~m?
# 5| v5_10(Void) = ExitFunction :
# 9| System.Void BaseClass..ctor(System.Int32)
# 9| Block 0
# 9| v9_1(Void) = EnterFunction :
# 9| mu9_2(<unknown>) = AliasedDefinition :
# 9| r9_3(glval<BaseClass>) = InitializeThis :
# 9| r9_4(glval<Int32>) = VariableAddress[i] :
# 9| mu9_5(Int32) = InitializeParameter[i] : &:r9_4
# 11| r11_1(glval<Int32>) = VariableAddress[i] :
# 11| r11_2(Int32) = Load[i] : &:r11_1, ~m?
# 11| r11_3(BaseClass) = CopyValue : r9_3
# 11| r11_4(glval<Int32>) = FieldAddress[num] : r11_3
# 11| mu11_5(Int32) = Store[?] : &:r11_4, r11_2
# 9| v9_6(Void) = ReturnVoid :
# 9| v9_7(Void) = AliasedUse : ~m?
# 9| v9_8(Void) = ExitFunction :
# 9| v9_1(Void) = EnterFunction :
# 9| mu9_2(<unknown>) = AliasedDefinition :
# 9| r9_3(glval<BaseClass>) = InitializeThis :
# 9| r9_4(glval<Int32>) = VariableAddress[i] :
# 9| mu9_5(Int32) = InitializeParameter[i] : &:r9_4
# 9| r9_6(glval<Object>) = Convert[BaseClass : Object] : r9_3
# 9| r9_7(<funcaddr>) = FunctionAddress[Object] :
# 9| v9_8(Void) = Call[Object] : func:r9_7, this:r9_6
# 9| mu9_9(<unknown>) = ^CallSideEffect : ~m?
# 11| r11_1(glval<Int32>) = VariableAddress[i] :
# 11| r11_2(Int32) = Load[i] : &:r11_1, ~m?
# 11| r11_3(BaseClass) = CopyValue : r9_3
# 11| r11_4(glval<Int32>) = FieldAddress[num] : r11_3
# 11| mu11_5(Int32) = Store[?] : &:r11_4, r11_2
# 9| v9_10(Void) = ReturnVoid :
# 9| v9_11(Void) = AliasedUse : ~m?
# 9| v9_12(Void) = ExitFunction :
# 17| System.Void DerivedClass..ctor()
# 17| Block 0
@@ -469,20 +477,24 @@ delegates.cs:
events.cs:
# 8| System.Void Events..ctor()
# 8| Block 0
# 8| v8_1(Void) = EnterFunction :
# 8| mu8_2(<unknown>) = AliasedDefinition :
# 8| r8_3(glval<Events>) = InitializeThis :
# 10| r10_1(MyDel) = NewObj :
# 10| r10_2(<funcaddr>) = FunctionAddress[MyDel] :
# 10| r10_3(glval<MyDel>) = FunctionAddress[Fun] :
# 10| v10_4(Void) = Call[MyDel] : func:r10_2, this:r10_1, 0:r10_3
# 10| mu10_5(<unknown>) = ^CallSideEffect : ~m?
# 10| r10_6(Events) = CopyValue : r8_3
# 10| r10_7(glval<MyDel>) = FieldAddress[Inst] : r10_6
# 10| mu10_8(MyDel) = Store[?] : &:r10_7, r10_1
# 8| v8_4(Void) = ReturnVoid :
# 8| v8_5(Void) = AliasedUse : ~m?
# 8| v8_6(Void) = ExitFunction :
# 8| v8_1(Void) = EnterFunction :
# 8| mu8_2(<unknown>) = AliasedDefinition :
# 8| r8_3(glval<Events>) = InitializeThis :
# 8| r8_4(glval<Object>) = Convert[Events : Object] : r8_3
# 8| r8_5(<funcaddr>) = FunctionAddress[Object] :
# 8| v8_6(Void) = Call[Object] : func:r8_5, this:r8_4
# 8| mu8_7(<unknown>) = ^CallSideEffect : ~m?
# 10| r10_1(MyDel) = NewObj :
# 10| r10_2(<funcaddr>) = FunctionAddress[MyDel] :
# 10| r10_3(glval<MyDel>) = FunctionAddress[Fun] :
# 10| v10_4(Void) = Call[MyDel] : func:r10_2, this:r10_1, 0:r10_3
# 10| mu10_5(<unknown>) = ^CallSideEffect : ~m?
# 10| r10_6(Events) = CopyValue : r8_3
# 10| r10_7(glval<MyDel>) = FieldAddress[Inst] : r10_6
# 10| mu10_8(MyDel) = Store[?] : &:r10_7, r10_1
# 8| v8_8(Void) = ReturnVoid :
# 8| v8_9(Void) = AliasedUse : ~m?
# 8| v8_10(Void) = ExitFunction :
# 13| System.Void Events.AddEvent()
# 13| Block 0
@@ -1237,29 +1249,37 @@ lock.cs:
obj_creation.cs:
# 7| System.Void ObjCreation.MyClass..ctor()
# 7| Block 0
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<MyClass>) = InitializeThis :
# 8| v8_1(Void) = NoOp :
# 7| v7_4(Void) = ReturnVoid :
# 7| v7_5(Void) = AliasedUse : ~m?
# 7| v7_6(Void) = ExitFunction :
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<MyClass>) = InitializeThis :
# 7| r7_4(glval<Object>) = Convert[MyClass : Object] : r7_3
# 7| r7_5(<funcaddr>) = FunctionAddress[Object] :
# 7| v7_6(Void) = Call[Object] : func:r7_5, this:r7_4
# 7| mu7_7(<unknown>) = ^CallSideEffect : ~m?
# 8| v8_1(Void) = NoOp :
# 7| v7_8(Void) = ReturnVoid :
# 7| v7_9(Void) = AliasedUse : ~m?
# 7| v7_10(Void) = ExitFunction :
# 11| System.Void ObjCreation.MyClass..ctor(System.Int32)
# 11| Block 0
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 11| r11_3(glval<MyClass>) = InitializeThis :
# 11| r11_4(glval<Int32>) = VariableAddress[_x] :
# 11| mu11_5(Int32) = InitializeParameter[_x] : &:r11_4
# 13| r13_1(glval<Int32>) = VariableAddress[_x] :
# 13| r13_2(Int32) = Load[_x] : &:r13_1, ~m?
# 13| r13_3(MyClass) = CopyValue : r11_3
# 13| r13_4(glval<Int32>) = FieldAddress[x] : r13_3
# 13| mu13_5(Int32) = Store[?] : &:r13_4, r13_2
# 11| v11_6(Void) = ReturnVoid :
# 11| v11_7(Void) = AliasedUse : ~m?
# 11| v11_8(Void) = ExitFunction :
# 11| v11_1(Void) = EnterFunction :
# 11| mu11_2(<unknown>) = AliasedDefinition :
# 11| r11_3(glval<MyClass>) = InitializeThis :
# 11| r11_4(glval<Int32>) = VariableAddress[_x] :
# 11| mu11_5(Int32) = InitializeParameter[_x] : &:r11_4
# 11| r11_6(glval<Object>) = Convert[MyClass : Object] : r11_3
# 11| r11_7(<funcaddr>) = FunctionAddress[Object] :
# 11| v11_8(Void) = Call[Object] : func:r11_7, this:r11_6
# 11| mu11_9(<unknown>) = ^CallSideEffect : ~m?
# 13| r13_1(glval<Int32>) = VariableAddress[_x] :
# 13| r13_2(Int32) = Load[_x] : &:r13_1, ~m?
# 13| r13_3(MyClass) = CopyValue : r11_3
# 13| r13_4(glval<Int32>) = FieldAddress[x] : r13_3
# 13| mu13_5(Int32) = Store[?] : &:r13_4, r13_2
# 11| v11_10(Void) = ReturnVoid :
# 11| v11_11(Void) = AliasedUse : ~m?
# 11| v11_12(Void) = ExitFunction :
# 17| System.Void ObjCreation.SomeFun(ObjCreation.MyClass)
# 17| Block 0
@@ -1884,13 +1904,17 @@ stmts.cs:
using.cs:
# 7| System.Void UsingStmt.MyDisposable..ctor()
# 7| Block 0
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<MyDisposable>) = InitializeThis :
# 7| v7_4(Void) = NoOp :
# 7| v7_5(Void) = ReturnVoid :
# 7| v7_6(Void) = AliasedUse : ~m?
# 7| v7_7(Void) = ExitFunction :
# 7| v7_1(Void) = EnterFunction :
# 7| mu7_2(<unknown>) = AliasedDefinition :
# 7| r7_3(glval<MyDisposable>) = InitializeThis :
# 7| r7_4(glval<Object>) = Convert[MyDisposable : Object] : r7_3
# 7| r7_5(<funcaddr>) = FunctionAddress[Object] :
# 7| v7_6(Void) = Call[Object] : func:r7_5, this:r7_4
# 7| mu7_7(<unknown>) = ^CallSideEffect : ~m?
# 7| v7_8(Void) = NoOp :
# 7| v7_9(Void) = ReturnVoid :
# 7| v7_10(Void) = AliasedUse : ~m?
# 7| v7_11(Void) = ExitFunction :
# 8| System.Void UsingStmt.MyDisposable.DoSomething()
# 8| Block 0

View File

@@ -674,14 +674,14 @@
| Foreach.cs:36:10:36:11 | exit M6 (normal) | Foreach.cs:36:10:36:11 | exit M6 | 2 |
| Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | 1 |
| Foreach.cs:38:26:38:26 | String x | Foreach.cs:39:11:39:11 | ; | 4 |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | exit Initializers | 15 |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:10:5:10:16 | exit Initializers | 15 |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | exit Initializers | 16 |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:10:5:10:16 | exit Initializers | 16 |
| Initializers.cs:12:10:12:10 | enter M | Initializers.cs:12:10:12:10 | exit M | 22 |
| Initializers.cs:18:20:18:20 | 1 | Initializers.cs:18:16:18:20 | ... = ... | 2 |
| Initializers.cs:20:11:20:23 | enter NoConstructor | Initializers.cs:20:11:20:23 | exit NoConstructor | 9 |
| Initializers.cs:31:9:31:11 | enter Sub | Initializers.cs:31:9:31:11 | exit Sub | 12 |
| Initializers.cs:33:9:33:11 | enter Sub | Initializers.cs:33:9:33:11 | exit Sub | 9 |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:35:9:35:11 | exit Sub | 19 |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:35:9:35:11 | exit Sub | 14 |
| Initializers.cs:51:10:51:13 | enter Test | Initializers.cs:51:10:51:13 | exit Test | 105 |
| LoopUnrolling.cs:7:10:7:11 | enter M1 | LoopUnrolling.cs:9:13:9:28 | ... == ... | 7 |
| LoopUnrolling.cs:7:10:7:11 | exit M1 (normal) | LoopUnrolling.cs:7:10:7:11 | exit M1 | 2 |
@@ -776,6 +776,7 @@
| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | 2 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | 2 |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | exit M2 | 4 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | 1 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 |
@@ -858,6 +859,7 @@
| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 | 2 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | 2 |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | exit M2 | 5 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | 1 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 |
@@ -1231,7 +1233,7 @@
| cflow.cs:127:48:127:49 | "" | cflow.cs:127:48:127:49 | "" | 1 |
| cflow.cs:127:53:127:57 | this access | cflow.cs:127:53:127:57 | access to field Field | 2 |
| cflow.cs:127:62:127:64 | enter set_Prop | cflow.cs:127:62:127:64 | exit set_Prop | 8 |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:129:5:129:15 | exit ControlFlow | 8 |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:129:5:129:15 | exit ControlFlow | 9 |
| cflow.cs:134:5:134:15 | enter ControlFlow | cflow.cs:134:5:134:15 | exit ControlFlow | 9 |
| cflow.cs:136:12:136:22 | enter ControlFlow | cflow.cs:136:12:136:22 | exit ControlFlow | 8 |
| cflow.cs:138:40:138:40 | enter + | cflow.cs:138:40:138:40 | exit + | 9 |
@@ -1330,7 +1332,7 @@
| cflow.cs:284:5:284:18 | enter ControlFlowSub | cflow.cs:284:5:284:18 | exit ControlFlowSub | 5 |
| cflow.cs:286:5:286:18 | enter ControlFlowSub | cflow.cs:286:5:286:18 | exit ControlFlowSub | 7 |
| cflow.cs:291:12:291:12 | enter M | cflow.cs:291:12:291:12 | exit M | 6 |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:5:296:25 | exit NegationInConstructor | 4 |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:5:296:25 | exit NegationInConstructor | 5 |
| cflow.cs:298:10:298:10 | enter M | cflow.cs:300:46:300:50 | ... > ... | 7 |
| cflow.cs:300:44:300:51 | [false] !... | cflow.cs:300:44:300:51 | [false] !... | 1 |
| cflow.cs:300:44:300:51 | [true] !... | cflow.cs:300:44:300:51 | [true] !... | 1 |

View File

@@ -9,6 +9,8 @@ multipleSuccessors
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | successor | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | successor | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | successor | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | successor | MultiImplementationA.cs:20:22:20:31 | {...} |
@@ -19,6 +21,8 @@ multipleSuccessors
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | successor | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | successor | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | successor | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | successor | MultiImplementationA.cs:20:22:20:31 | {...} |

View File

@@ -2475,10 +2475,12 @@ dominance
| Initializers.cs:6:27:6:31 | ... + ... | Initializers.cs:6:9:6:9 | access to property G |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:27:6:31 | ... + ... |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:27:6:31 | ... + ... |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:5:9:5:9 | this access |
| Initializers.cs:8:5:8:16 | call to constructor Object | Initializers.cs:5:9:5:9 | this access |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | call to constructor Object |
| Initializers.cs:8:5:8:16 | exit Initializers (normal) | Initializers.cs:8:5:8:16 | exit Initializers |
| Initializers.cs:8:20:8:22 | {...} | Initializers.cs:8:5:8:16 | exit Initializers (normal) |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:5:9:5:9 | this access |
| Initializers.cs:10:5:10:16 | call to constructor Object | Initializers.cs:5:9:5:9 | this access |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:10:5:10:16 | call to constructor Object |
| Initializers.cs:10:5:10:16 | exit Initializers (normal) | Initializers.cs:10:5:10:16 | exit Initializers |
| Initializers.cs:10:28:10:30 | {...} | Initializers.cs:10:5:10:16 | exit Initializers (normal) |
| Initializers.cs:12:10:12:10 | enter M | Initializers.cs:13:5:16:5 | {...} |
@@ -2506,16 +2508,10 @@ dominance
| Initializers.cs:20:11:20:23 | enter NoConstructor | Initializers.cs:22:23:22:23 | this access |
| Initializers.cs:20:11:20:23 | exit NoConstructor (normal) | Initializers.cs:20:11:20:23 | exit NoConstructor |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:22:27:22:27 | 0 |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:22:27:22:27 | 0 |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:23:23:23:23 | this access |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:23:23:23:23 | this access |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:22:23:22:27 | ... = ... |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:22:23:22:27 | ... = ... |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:23:27:23:27 | 1 |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:23:27:23:27 | 1 |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:20:11:20:23 | exit NoConstructor (normal) |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:28:13:28:13 | this access |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:23:23:23:27 | ... = ... |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:23:23:23:27 | ... = ... |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:28:17:28:17 | 2 |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:28:17:28:17 | 2 |
@@ -2539,7 +2535,8 @@ dominance
| Initializers.cs:33:31:33:35 | ... = ... | Initializers.cs:33:9:33:11 | exit Sub (normal) |
| Initializers.cs:33:31:33:36 | ...; | Initializers.cs:33:31:33:31 | this access |
| Initializers.cs:33:35:33:35 | access to parameter i | Initializers.cs:33:31:33:35 | ... = ... |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:22:23:22:23 | this access |
| Initializers.cs:35:9:35:11 | call to constructor NoConstructor | Initializers.cs:28:13:28:13 | this access |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:35:9:35:11 | call to constructor NoConstructor |
| Initializers.cs:35:9:35:11 | exit Sub (normal) | Initializers.cs:35:9:35:11 | exit Sub |
| Initializers.cs:35:27:35:40 | {...} | Initializers.cs:35:29:35:38 | ...; |
| Initializers.cs:35:29:35:29 | this access | Initializers.cs:35:33:35:33 | access to parameter i |
@@ -2888,8 +2885,8 @@ dominance
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | exit M2 |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:29 | ...; |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:28:20:28 | access to parameter i |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) |
@@ -2973,8 +2970,8 @@ dominance
| MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | exit M2 |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:21:16:30 | throw ... |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:30:18:33 | null |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) |
@@ -3917,7 +3914,8 @@ dominance
| cflow.cs:127:68:127:80 | ... = ... | cflow.cs:127:62:127:64 | exit set_Prop (normal) |
| cflow.cs:127:68:127:81 | ...; | cflow.cs:127:68:127:72 | this access |
| cflow.cs:127:76:127:80 | access to parameter value | cflow.cs:127:68:127:80 | ... = ... |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:130:5:132:5 | {...} |
| cflow.cs:129:5:129:15 | call to constructor Object | cflow.cs:130:5:132:5 | {...} |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:129:5:129:15 | call to constructor Object |
| cflow.cs:129:5:129:15 | exit ControlFlow (normal) | cflow.cs:129:5:129:15 | exit ControlFlow |
| cflow.cs:130:5:132:5 | {...} | cflow.cs:131:9:131:18 | ...; |
| cflow.cs:131:9:131:13 | this access | cflow.cs:131:17:131:17 | access to parameter s |
@@ -4278,7 +4276,8 @@ dominance
| cflow.cs:291:38:291:38 | access to parameter f | cflow.cs:291:40:291:40 | 0 |
| cflow.cs:291:38:291:41 | delegate call | cflow.cs:291:12:291:12 | exit M (normal) |
| cflow.cs:291:40:291:40 | 0 | cflow.cs:291:38:291:41 | delegate call |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:52:296:54 | {...} |
| cflow.cs:296:5:296:25 | call to constructor Object | cflow.cs:296:52:296:54 | {...} |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:5:296:25 | call to constructor Object |
| cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) | cflow.cs:296:5:296:25 | exit NegationInConstructor |
| cflow.cs:296:52:296:54 | {...} | cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) |
| cflow.cs:298:10:298:10 | enter M | cflow.cs:299:5:301:5 | {...} |
@@ -6550,8 +6549,8 @@ postDominance
| Foreach.cs:38:33:38:33 | Int32 y | Foreach.cs:38:26:38:26 | String x |
| Foreach.cs:38:39:38:42 | access to parameter args | Foreach.cs:37:5:40:5 | {...} |
| Foreach.cs:39:11:39:11 | ; | Foreach.cs:38:18:38:34 | (..., ...) |
| Initializers.cs:5:9:5:9 | this access | Initializers.cs:8:5:8:16 | enter Initializers |
| Initializers.cs:5:9:5:9 | this access | Initializers.cs:10:5:10:16 | enter Initializers |
| Initializers.cs:5:9:5:9 | this access | Initializers.cs:8:5:8:16 | call to constructor Object |
| Initializers.cs:5:9:5:9 | this access | Initializers.cs:10:5:10:16 | call to constructor Object |
| Initializers.cs:5:9:5:17 | ... = ... | Initializers.cs:5:13:5:17 | ... + ... |
| Initializers.cs:5:9:5:17 | ... = ... | Initializers.cs:5:13:5:17 | ... + ... |
| Initializers.cs:5:13:5:13 | access to field H | Initializers.cs:5:9:5:9 | this access |
@@ -6572,9 +6571,11 @@ postDominance
| Initializers.cs:6:27:6:31 | ... + ... | Initializers.cs:6:31:6:31 | 2 |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:27:6:27 | access to field H |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:27:6:27 | access to field H |
| Initializers.cs:8:5:8:16 | call to constructor Object | Initializers.cs:8:5:8:16 | enter Initializers |
| Initializers.cs:8:5:8:16 | exit Initializers | Initializers.cs:8:5:8:16 | exit Initializers (normal) |
| Initializers.cs:8:5:8:16 | exit Initializers (normal) | Initializers.cs:8:20:8:22 | {...} |
| Initializers.cs:8:20:8:22 | {...} | Initializers.cs:6:25:6:31 | ... = ... |
| Initializers.cs:10:5:10:16 | call to constructor Object | Initializers.cs:10:5:10:16 | enter Initializers |
| Initializers.cs:10:5:10:16 | exit Initializers | Initializers.cs:10:5:10:16 | exit Initializers (normal) |
| Initializers.cs:10:5:10:16 | exit Initializers (normal) | Initializers.cs:10:28:10:30 | {...} |
| Initializers.cs:10:28:10:30 | {...} | Initializers.cs:6:25:6:31 | ... = ... |
@@ -6603,19 +6604,13 @@ postDominance
| Initializers.cs:20:11:20:23 | exit NoConstructor | Initializers.cs:20:11:20:23 | exit NoConstructor (normal) |
| Initializers.cs:20:11:20:23 | exit NoConstructor (normal) | Initializers.cs:23:23:23:27 | ... = ... |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:20:11:20:23 | enter NoConstructor |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:35:9:35:11 | enter Sub |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:22:27:22:27 | 0 |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:22:27:22:27 | 0 |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:22:23:22:23 | this access |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:22:23:22:23 | this access |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:22:23:22:27 | ... = ... |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:22:23:22:27 | ... = ... |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:23:27:23:27 | 1 |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:23:27:23:27 | 1 |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:23:23:23:23 | this access |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:23:23:23:23 | this access |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:23:23:23:27 | ... = ... |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:31:17:31:20 | call to constructor NoConstructor |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:35:9:35:11 | call to constructor NoConstructor |
| Initializers.cs:28:13:28:17 | ... = ... | Initializers.cs:28:17:28:17 | 2 |
| Initializers.cs:28:13:28:17 | ... = ... | Initializers.cs:28:17:28:17 | 2 |
| Initializers.cs:28:17:28:17 | 2 | Initializers.cs:28:13:28:13 | this access |
@@ -6636,6 +6631,7 @@ postDominance
| Initializers.cs:33:31:33:35 | ... = ... | Initializers.cs:33:35:33:35 | access to parameter i |
| Initializers.cs:33:31:33:36 | ...; | Initializers.cs:33:29:33:38 | {...} |
| Initializers.cs:33:35:33:35 | access to parameter i | Initializers.cs:33:31:33:31 | this access |
| Initializers.cs:35:9:35:11 | call to constructor NoConstructor | Initializers.cs:35:9:35:11 | enter Sub |
| Initializers.cs:35:9:35:11 | exit Sub | Initializers.cs:35:9:35:11 | exit Sub (normal) |
| Initializers.cs:35:9:35:11 | exit Sub (normal) | Initializers.cs:35:29:35:37 | ... = ... |
| Initializers.cs:35:27:35:40 | {...} | Initializers.cs:28:13:28:17 | ... = ... |
@@ -7948,9 +7944,10 @@ postDominance
| cflow.cs:127:68:127:80 | ... = ... | cflow.cs:127:76:127:80 | access to parameter value |
| cflow.cs:127:68:127:81 | ...; | cflow.cs:127:66:127:83 | {...} |
| cflow.cs:127:76:127:80 | access to parameter value | cflow.cs:127:68:127:72 | this access |
| cflow.cs:129:5:129:15 | call to constructor Object | cflow.cs:129:5:129:15 | enter ControlFlow |
| cflow.cs:129:5:129:15 | exit ControlFlow | cflow.cs:129:5:129:15 | exit ControlFlow (normal) |
| cflow.cs:129:5:129:15 | exit ControlFlow (normal) | cflow.cs:131:9:131:17 | ... = ... |
| cflow.cs:130:5:132:5 | {...} | cflow.cs:129:5:129:15 | enter ControlFlow |
| cflow.cs:130:5:132:5 | {...} | cflow.cs:129:5:129:15 | call to constructor Object |
| cflow.cs:131:9:131:13 | this access | cflow.cs:131:9:131:18 | ...; |
| cflow.cs:131:9:131:17 | ... = ... | cflow.cs:131:17:131:17 | access to parameter s |
| cflow.cs:131:9:131:18 | ...; | cflow.cs:130:5:132:5 | {...} |
@@ -8301,9 +8298,10 @@ postDominance
| cflow.cs:291:38:291:38 | access to parameter f | cflow.cs:291:12:291:12 | enter M |
| cflow.cs:291:38:291:41 | delegate call | cflow.cs:291:40:291:40 | 0 |
| cflow.cs:291:40:291:40 | 0 | cflow.cs:291:38:291:38 | access to parameter f |
| cflow.cs:296:5:296:25 | call to constructor Object | cflow.cs:296:5:296:25 | enter NegationInConstructor |
| cflow.cs:296:5:296:25 | exit NegationInConstructor | cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) |
| cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) | cflow.cs:296:52:296:54 | {...} |
| cflow.cs:296:52:296:54 | {...} | cflow.cs:296:5:296:25 | enter NegationInConstructor |
| cflow.cs:296:52:296:54 | {...} | cflow.cs:296:5:296:25 | call to constructor Object |
| cflow.cs:298:10:298:10 | exit M | cflow.cs:298:10:298:10 | exit M (normal) |
| cflow.cs:298:10:298:10 | exit M (normal) | cflow.cs:300:9:300:72 | object creation of type NegationInConstructor |
| cflow.cs:299:5:301:5 | {...} | cflow.cs:298:10:298:10 | enter M |
@@ -11404,12 +11402,15 @@ blockDominance
| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:22:18:36 | {...} |
@@ -11534,12 +11535,15 @@ blockDominance
| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:22:18:36 | {...} |
@@ -14983,15 +14987,18 @@ postBlockDominance
| MultiImplementationA.cs:16:17:16:18 | exit M1 (normal) | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
@@ -15087,6 +15094,7 @@ postBlockDominance
| MultiImplementationB.cs:14:17:14:18 | exit M1 (normal) | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |

View File

@@ -2675,10 +2675,12 @@ nodeEnclosing
| Initializers.cs:6:27:6:31 | ... + ... | Initializers.cs:10:5:10:16 | Initializers |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:8:5:8:16 | Initializers |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:10:5:10:16 | Initializers |
| Initializers.cs:8:5:8:16 | call to constructor Object | Initializers.cs:8:5:8:16 | Initializers |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | Initializers |
| Initializers.cs:8:5:8:16 | exit Initializers | Initializers.cs:8:5:8:16 | Initializers |
| Initializers.cs:8:5:8:16 | exit Initializers (normal) | Initializers.cs:8:5:8:16 | Initializers |
| Initializers.cs:8:20:8:22 | {...} | Initializers.cs:8:5:8:16 | Initializers |
| Initializers.cs:10:5:10:16 | call to constructor Object | Initializers.cs:10:5:10:16 | Initializers |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:10:5:10:16 | Initializers |
| Initializers.cs:10:5:10:16 | exit Initializers | Initializers.cs:10:5:10:16 | Initializers |
| Initializers.cs:10:5:10:16 | exit Initializers (normal) | Initializers.cs:10:5:10:16 | Initializers |
@@ -2709,17 +2711,11 @@ nodeEnclosing
| Initializers.cs:20:11:20:23 | exit NoConstructor | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:20:11:20:23 | exit NoConstructor (normal) | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:20:11:20:23 | NoConstructor |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:31:9:31:11 | Sub |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:28:13:28:17 | ... = ... | Initializers.cs:31:9:31:11 | Sub |
@@ -2744,6 +2740,7 @@ nodeEnclosing
| Initializers.cs:33:31:33:35 | ... = ... | Initializers.cs:33:9:33:11 | Sub |
| Initializers.cs:33:31:33:36 | ...; | Initializers.cs:33:9:33:11 | Sub |
| Initializers.cs:33:35:33:35 | access to parameter i | Initializers.cs:33:9:33:11 | Sub |
| Initializers.cs:35:9:35:11 | call to constructor NoConstructor | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:35:9:35:11 | exit Sub | Initializers.cs:35:9:35:11 | Sub |
| Initializers.cs:35:9:35:11 | exit Sub (normal) | Initializers.cs:35:9:35:11 | Sub |
@@ -3167,6 +3164,8 @@ nodeEnclosing
| MultiImplementationA.cs:18:9:18:22 | exit M2 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
@@ -3354,6 +3353,8 @@ nodeEnclosing
| MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
@@ -4436,6 +4437,7 @@ nodeEnclosing
| cflow.cs:127:68:127:80 | ... = ... | cflow.cs:127:62:127:64 | set_Prop |
| cflow.cs:127:68:127:81 | ...; | cflow.cs:127:62:127:64 | set_Prop |
| cflow.cs:127:76:127:80 | access to parameter value | cflow.cs:127:62:127:64 | set_Prop |
| cflow.cs:129:5:129:15 | call to constructor Object | cflow.cs:129:5:129:15 | ControlFlow |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:129:5:129:15 | ControlFlow |
| cflow.cs:129:5:129:15 | exit ControlFlow | cflow.cs:129:5:129:15 | ControlFlow |
| cflow.cs:129:5:129:15 | exit ControlFlow (normal) | cflow.cs:129:5:129:15 | ControlFlow |
@@ -4826,6 +4828,7 @@ nodeEnclosing
| cflow.cs:291:38:291:38 | access to parameter f | cflow.cs:291:12:291:12 | M |
| cflow.cs:291:38:291:41 | delegate call | cflow.cs:291:12:291:12 | M |
| cflow.cs:291:40:291:40 | 0 | cflow.cs:291:12:291:12 | M |
| cflow.cs:296:5:296:25 | call to constructor Object | cflow.cs:296:5:296:25 | NegationInConstructor |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:5:296:25 | NegationInConstructor |
| cflow.cs:296:5:296:25 | exit NegationInConstructor | cflow.cs:296:5:296:25 | NegationInConstructor |
| cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) | cflow.cs:296:5:296:25 | NegationInConstructor |
@@ -5628,6 +5631,8 @@ blockEnclosing
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
@@ -5716,6 +5721,8 @@ blockEnclosing
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |

View File

@@ -1687,7 +1687,9 @@
| Initializers.cs:6:27:6:27 | access to field H | Initializers.cs:6:27:6:27 | access to field H |
| Initializers.cs:6:27:6:31 | ... + ... | Initializers.cs:6:27:6:27 | access to field H |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:31:6:31 | 2 |
| Initializers.cs:8:5:8:16 | call to constructor Object | Initializers.cs:8:5:8:16 | call to constructor Object |
| Initializers.cs:8:20:8:22 | {...} | Initializers.cs:8:20:8:22 | {...} |
| Initializers.cs:10:5:10:16 | call to constructor Object | Initializers.cs:10:5:10:16 | call to constructor Object |
| Initializers.cs:10:28:10:30 | {...} | Initializers.cs:10:28:10:30 | {...} |
| Initializers.cs:13:5:16:5 | {...} | Initializers.cs:13:5:16:5 | {...} |
| Initializers.cs:14:9:14:54 | ... ...; | Initializers.cs:14:9:14:54 | ... ...; |
@@ -1735,6 +1737,7 @@
| Initializers.cs:33:31:33:35 | ... = ... | Initializers.cs:33:31:33:31 | this access |
| Initializers.cs:33:31:33:36 | ...; | Initializers.cs:33:31:33:36 | ...; |
| Initializers.cs:33:35:33:35 | access to parameter i | Initializers.cs:33:35:33:35 | access to parameter i |
| Initializers.cs:35:9:35:11 | call to constructor NoConstructor | Initializers.cs:35:9:35:11 | call to constructor NoConstructor |
| Initializers.cs:35:27:35:40 | {...} | Initializers.cs:35:27:35:40 | {...} |
| Initializers.cs:35:29:35:29 | access to field I | Initializers.cs:35:29:35:29 | this access |
| Initializers.cs:35:29:35:29 | this access | Initializers.cs:35:29:35:29 | this access |
@@ -2045,6 +2048,7 @@
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:18:9:18:22 | M2(...) |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:24:20:24 | access to field F | MultiImplementationA.cs:20:24:20:24 | this access |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:24:20:24 | this access |
@@ -2089,6 +2093,7 @@
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:16:9:16:31 | M2(...) |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:30:18:33 | null |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:30:18:33 | null |
@@ -2933,6 +2938,7 @@
| cflow.cs:127:68:127:80 | ... = ... | cflow.cs:127:68:127:72 | this access |
| cflow.cs:127:68:127:81 | ...; | cflow.cs:127:68:127:81 | ...; |
| cflow.cs:127:76:127:80 | access to parameter value | cflow.cs:127:76:127:80 | access to parameter value |
| cflow.cs:129:5:129:15 | call to constructor Object | cflow.cs:129:5:129:15 | call to constructor Object |
| cflow.cs:130:5:132:5 | {...} | cflow.cs:130:5:132:5 | {...} |
| cflow.cs:131:9:131:13 | access to field Field | cflow.cs:131:9:131:13 | this access |
| cflow.cs:131:9:131:13 | this access | cflow.cs:131:9:131:13 | this access |
@@ -3267,6 +3273,7 @@
| cflow.cs:291:38:291:38 | access to parameter f | cflow.cs:291:38:291:38 | access to parameter f |
| cflow.cs:291:38:291:41 | delegate call | cflow.cs:291:38:291:38 | access to parameter f |
| cflow.cs:291:40:291:40 | 0 | cflow.cs:291:40:291:40 | 0 |
| cflow.cs:296:5:296:25 | call to constructor Object | cflow.cs:296:5:296:25 | call to constructor Object |
| cflow.cs:296:52:296:54 | {...} | cflow.cs:296:52:296:54 | {...} |
| cflow.cs:299:5:301:5 | {...} | cflow.cs:299:5:301:5 | {...} |
| cflow.cs:300:9:300:72 | object creation of type NegationInConstructor | cflow.cs:300:38:300:38 | 0 |

View File

@@ -2325,7 +2325,9 @@
| Initializers.cs:6:27:6:27 | access to field H | Initializers.cs:6:27:6:27 | access to field H | normal |
| Initializers.cs:6:27:6:31 | ... + ... | Initializers.cs:6:27:6:31 | ... + ... | normal |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:31:6:31 | 2 | normal |
| Initializers.cs:8:5:8:16 | call to constructor Object | Initializers.cs:8:5:8:16 | call to constructor Object | normal |
| Initializers.cs:8:20:8:22 | {...} | Initializers.cs:8:20:8:22 | {...} | normal |
| Initializers.cs:10:5:10:16 | call to constructor Object | Initializers.cs:10:5:10:16 | call to constructor Object | normal |
| Initializers.cs:10:28:10:30 | {...} | Initializers.cs:10:28:10:30 | {...} | normal |
| Initializers.cs:13:5:16:5 | {...} | Initializers.cs:15:13:15:63 | Initializers[] iz = ... | normal |
| Initializers.cs:14:9:14:54 | ... ...; | Initializers.cs:14:13:14:53 | Initializers i = ... | normal |
@@ -2373,6 +2375,7 @@
| Initializers.cs:33:31:33:35 | ... = ... | Initializers.cs:33:31:33:35 | ... = ... | normal |
| Initializers.cs:33:31:33:36 | ...; | Initializers.cs:33:31:33:35 | ... = ... | normal |
| Initializers.cs:33:35:33:35 | access to parameter i | Initializers.cs:33:35:33:35 | access to parameter i | normal |
| Initializers.cs:35:9:35:11 | call to constructor NoConstructor | Initializers.cs:35:9:35:11 | call to constructor NoConstructor | normal |
| Initializers.cs:35:27:35:40 | {...} | Initializers.cs:35:29:35:37 | ... = ... | normal |
| Initializers.cs:35:29:35:29 | access to field I | Initializers.cs:35:29:35:29 | this access | normal |
| Initializers.cs:35:29:35:29 | this access | Initializers.cs:35:29:35:29 | this access | normal |
@@ -2697,6 +2700,7 @@
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | normal |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:18:9:18:22 | M2(...) | normal |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:21:18:21 | 0 | normal |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | normal |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:28 | ... = ... | normal |
| MultiImplementationA.cs:20:24:20:24 | access to field F | MultiImplementationA.cs:20:24:20:24 | this access | normal |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:24:20:24 | this access | normal |
@@ -2741,6 +2745,7 @@
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:16:9:16:31 | M2(...) | normal |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:21:16:30 | throw ... | throw(NullReferenceException) |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:27:16:30 | null | normal |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | normal |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:24:18:34 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:24:18:34 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:30:18:33 | null | normal |
@@ -3868,6 +3873,7 @@
| cflow.cs:127:68:127:80 | ... = ... | cflow.cs:127:68:127:80 | ... = ... | normal |
| cflow.cs:127:68:127:81 | ...; | cflow.cs:127:68:127:80 | ... = ... | normal |
| cflow.cs:127:76:127:80 | access to parameter value | cflow.cs:127:76:127:80 | access to parameter value | normal |
| cflow.cs:129:5:129:15 | call to constructor Object | cflow.cs:129:5:129:15 | call to constructor Object | normal |
| cflow.cs:130:5:132:5 | {...} | cflow.cs:131:9:131:17 | ... = ... | normal |
| cflow.cs:131:9:131:13 | access to field Field | cflow.cs:131:9:131:13 | this access | normal |
| cflow.cs:131:9:131:13 | this access | cflow.cs:131:9:131:13 | this access | normal |
@@ -4272,6 +4278,7 @@
| cflow.cs:291:38:291:38 | access to parameter f | cflow.cs:291:38:291:38 | access to parameter f | normal |
| cflow.cs:291:38:291:41 | delegate call | cflow.cs:291:38:291:41 | delegate call | normal |
| cflow.cs:291:40:291:40 | 0 | cflow.cs:291:40:291:40 | 0 | normal |
| cflow.cs:296:5:296:25 | call to constructor Object | cflow.cs:296:5:296:25 | call to constructor Object | normal |
| cflow.cs:296:52:296:54 | {...} | cflow.cs:296:52:296:54 | {...} | normal |
| cflow.cs:299:5:301:5 | {...} | cflow.cs:300:9:300:72 | object creation of type NegationInConstructor | normal |
| cflow.cs:300:9:300:72 | object creation of type NegationInConstructor | cflow.cs:300:9:300:72 | object creation of type NegationInConstructor | normal |

View File

@@ -2792,10 +2792,12 @@
| Initializers.cs:6:27:6:31 | ... + ... | Initializers.cs:6:9:6:9 | access to property G | semmle.label | successor |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:27:6:31 | ... + ... | semmle.label | successor |
| Initializers.cs:6:31:6:31 | 2 | Initializers.cs:6:27:6:31 | ... + ... | semmle.label | successor |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:5:9:5:9 | this access | semmle.label | successor |
| Initializers.cs:8:5:8:16 | call to constructor Object | Initializers.cs:5:9:5:9 | this access | semmle.label | successor |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | call to constructor Object | semmle.label | successor |
| Initializers.cs:8:5:8:16 | exit Initializers (normal) | Initializers.cs:8:5:8:16 | exit Initializers | semmle.label | successor |
| Initializers.cs:8:20:8:22 | {...} | Initializers.cs:8:5:8:16 | exit Initializers (normal) | semmle.label | successor |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:5:9:5:9 | this access | semmle.label | successor |
| Initializers.cs:10:5:10:16 | call to constructor Object | Initializers.cs:5:9:5:9 | this access | semmle.label | successor |
| Initializers.cs:10:5:10:16 | enter Initializers | Initializers.cs:10:5:10:16 | call to constructor Object | semmle.label | successor |
| Initializers.cs:10:5:10:16 | exit Initializers (normal) | Initializers.cs:10:5:10:16 | exit Initializers | semmle.label | successor |
| Initializers.cs:10:28:10:30 | {...} | Initializers.cs:10:5:10:16 | exit Initializers (normal) | semmle.label | successor |
| Initializers.cs:12:10:12:10 | enter M | Initializers.cs:13:5:16:5 | {...} | semmle.label | successor |
@@ -2823,16 +2825,10 @@
| Initializers.cs:20:11:20:23 | enter NoConstructor | Initializers.cs:22:23:22:23 | this access | semmle.label | successor |
| Initializers.cs:20:11:20:23 | exit NoConstructor (normal) | Initializers.cs:20:11:20:23 | exit NoConstructor | semmle.label | successor |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:22:27:22:27 | 0 | semmle.label | successor |
| Initializers.cs:22:23:22:23 | this access | Initializers.cs:22:27:22:27 | 0 | semmle.label | successor |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:23:23:23:23 | this access | semmle.label | successor |
| Initializers.cs:22:23:22:27 | ... = ... | Initializers.cs:23:23:23:23 | this access | semmle.label | successor |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:22:23:22:27 | ... = ... | semmle.label | successor |
| Initializers.cs:22:27:22:27 | 0 | Initializers.cs:22:23:22:27 | ... = ... | semmle.label | successor |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:23:27:23:27 | 1 | semmle.label | successor |
| Initializers.cs:23:23:23:23 | this access | Initializers.cs:23:27:23:27 | 1 | semmle.label | successor |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:20:11:20:23 | exit NoConstructor (normal) | semmle.label | successor |
| Initializers.cs:23:23:23:27 | ... = ... | Initializers.cs:28:13:28:13 | this access | semmle.label | successor |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:23:23:23:27 | ... = ... | semmle.label | successor |
| Initializers.cs:23:27:23:27 | 1 | Initializers.cs:23:23:23:27 | ... = ... | semmle.label | successor |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:28:17:28:17 | 2 | semmle.label | successor |
| Initializers.cs:28:13:28:13 | this access | Initializers.cs:28:17:28:17 | 2 | semmle.label | successor |
@@ -2856,7 +2852,8 @@
| Initializers.cs:33:31:33:35 | ... = ... | Initializers.cs:33:9:33:11 | exit Sub (normal) | semmle.label | successor |
| Initializers.cs:33:31:33:36 | ...; | Initializers.cs:33:31:33:31 | this access | semmle.label | successor |
| Initializers.cs:33:35:33:35 | access to parameter i | Initializers.cs:33:31:33:35 | ... = ... | semmle.label | successor |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:22:23:22:23 | this access | semmle.label | successor |
| Initializers.cs:35:9:35:11 | call to constructor NoConstructor | Initializers.cs:28:13:28:13 | this access | semmle.label | successor |
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:35:9:35:11 | call to constructor NoConstructor | semmle.label | successor |
| Initializers.cs:35:9:35:11 | exit Sub (normal) | Initializers.cs:35:9:35:11 | exit Sub | semmle.label | successor |
| Initializers.cs:35:27:35:40 | {...} | Initializers.cs:35:29:35:38 | ...; | semmle.label | successor |
| Initializers.cs:35:29:35:29 | this access | Initializers.cs:35:33:35:33 | access to parameter i | semmle.label | successor |
@@ -3253,8 +3250,10 @@
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:21:18:21 | 0 | semmle.label | successor |
| MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | MultiImplementationA.cs:18:9:18:22 | exit M2 | semmle.label | successor |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | exit M2 (normal) | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | call to constructor Object | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationA.cs:20:12:20:13 | exit C2 | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:12:18:13 | exit C2 | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | exit C2 (normal) | MultiImplementationA.cs:20:12:20:13 | exit C2 | semmle.label | successor |
@@ -3394,8 +3393,10 @@
| MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | MultiImplementationB.cs:16:9:16:31 | exit M2 | semmle.label | successor |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | exit M2 (abnormal) | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:21:16:30 | throw ... | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | call to constructor Object | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationA.cs:20:12:20:13 | exit C2 | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | exit C2 (abnormal) | MultiImplementationB.cs:18:12:18:13 | exit C2 | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | exit C2 (normal) | MultiImplementationA.cs:20:12:20:13 | exit C2 | semmle.label | successor |
@@ -4501,7 +4502,8 @@
| cflow.cs:127:68:127:80 | ... = ... | cflow.cs:127:62:127:64 | exit set_Prop (normal) | semmle.label | successor |
| cflow.cs:127:68:127:81 | ...; | cflow.cs:127:68:127:72 | this access | semmle.label | successor |
| cflow.cs:127:76:127:80 | access to parameter value | cflow.cs:127:68:127:80 | ... = ... | semmle.label | successor |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:130:5:132:5 | {...} | semmle.label | successor |
| cflow.cs:129:5:129:15 | call to constructor Object | cflow.cs:130:5:132:5 | {...} | semmle.label | successor |
| cflow.cs:129:5:129:15 | enter ControlFlow | cflow.cs:129:5:129:15 | call to constructor Object | semmle.label | successor |
| cflow.cs:129:5:129:15 | exit ControlFlow (normal) | cflow.cs:129:5:129:15 | exit ControlFlow | semmle.label | successor |
| cflow.cs:130:5:132:5 | {...} | cflow.cs:131:9:131:18 | ...; | semmle.label | successor |
| cflow.cs:131:9:131:13 | this access | cflow.cs:131:17:131:17 | access to parameter s | semmle.label | successor |
@@ -4894,7 +4896,8 @@
| cflow.cs:291:38:291:38 | access to parameter f | cflow.cs:291:40:291:40 | 0 | semmle.label | successor |
| cflow.cs:291:38:291:41 | delegate call | cflow.cs:291:12:291:12 | exit M (normal) | semmle.label | successor |
| cflow.cs:291:40:291:40 | 0 | cflow.cs:291:38:291:41 | delegate call | semmle.label | successor |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:52:296:54 | {...} | semmle.label | successor |
| cflow.cs:296:5:296:25 | call to constructor Object | cflow.cs:296:52:296:54 | {...} | semmle.label | successor |
| cflow.cs:296:5:296:25 | enter NegationInConstructor | cflow.cs:296:5:296:25 | call to constructor Object | semmle.label | successor |
| cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) | cflow.cs:296:5:296:25 | exit NegationInConstructor | semmle.label | successor |
| cflow.cs:296:52:296:54 | {...} | cflow.cs:296:5:296:25 | exit NegationInConstructor (normal) | semmle.label | successor |
| cflow.cs:298:10:298:10 | enter M | cflow.cs:299:5:301:5 | {...} | semmle.label | successor |

View File

@@ -1137,13 +1137,13 @@ entryPoint
| Foreach.cs:24:10:24:11 | M4 | Foreach.cs:25:5:28:5 | {...} |
| Foreach.cs:30:10:30:11 | M5 | Foreach.cs:31:5:34:5 | {...} |
| Foreach.cs:36:10:36:11 | M6 | Foreach.cs:37:5:40:5 | {...} |
| Initializers.cs:8:5:8:16 | Initializers | Initializers.cs:5:9:5:9 | this access |
| Initializers.cs:10:5:10:16 | Initializers | Initializers.cs:5:9:5:9 | this access |
| Initializers.cs:8:5:8:16 | Initializers | Initializers.cs:8:5:8:16 | call to constructor Object |
| Initializers.cs:10:5:10:16 | Initializers | Initializers.cs:10:5:10:16 | call to constructor Object |
| Initializers.cs:12:10:12:10 | M | Initializers.cs:13:5:16:5 | {...} |
| Initializers.cs:20:11:20:23 | NoConstructor | Initializers.cs:22:23:22:23 | this access |
| Initializers.cs:31:9:31:11 | Sub | Initializers.cs:31:17:31:20 | call to constructor NoConstructor |
| Initializers.cs:33:9:33:11 | Sub | Initializers.cs:33:22:33:25 | call to constructor Sub |
| Initializers.cs:35:9:35:11 | Sub | Initializers.cs:22:23:22:23 | this access |
| Initializers.cs:35:9:35:11 | Sub | Initializers.cs:35:9:35:11 | call to constructor NoConstructor |
| Initializers.cs:51:10:51:13 | Test | Initializers.cs:52:5:66:5 | {...} |
| LoopUnrolling.cs:7:10:7:11 | M1 | LoopUnrolling.cs:8:5:13:5 | {...} |
| LoopUnrolling.cs:15:10:15:11 | M2 | LoopUnrolling.cs:16:5:20:5 | {...} |
@@ -1173,8 +1173,8 @@ entryPoint
| MultiImplementationA.cs:16:17:16:18 | M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | M2 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:20:12:20:13 | C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationA.cs:20:12:20:13 | C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationA.cs:21:12:21:13 | C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:12:21:13 | C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationA.cs:22:6:22:7 | ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
@@ -1202,8 +1202,8 @@ entryPoint
| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | M2 | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationA.cs:20:12:20:13 | call to constructor Object |
| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationB.cs:18:12:18:13 | call to constructor Object |
| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
@@ -1265,7 +1265,7 @@ entryPoint
| cflow.cs:119:20:119:21 | M5 | cflow.cs:120:5:124:5 | {...} |
| cflow.cs:127:19:127:21 | get_Prop | cflow.cs:127:23:127:60 | {...} |
| cflow.cs:127:62:127:64 | set_Prop | cflow.cs:127:66:127:83 | {...} |
| cflow.cs:129:5:129:15 | ControlFlow | cflow.cs:130:5:132:5 | {...} |
| cflow.cs:129:5:129:15 | ControlFlow | cflow.cs:129:5:129:15 | call to constructor Object |
| cflow.cs:134:5:134:15 | ControlFlow | cflow.cs:134:31:134:31 | access to parameter i |
| cflow.cs:136:12:136:22 | ControlFlow | cflow.cs:136:33:136:33 | 0 |
| cflow.cs:138:40:138:40 | + | cflow.cs:139:5:142:5 | {...} |
@@ -1285,5 +1285,5 @@ entryPoint
| cflow.cs:284:5:284:18 | ControlFlowSub | cflow.cs:284:32:284:35 | call to constructor ControlFlowSub |
| cflow.cs:286:5:286:18 | ControlFlowSub | cflow.cs:286:34:286:34 | access to parameter i |
| cflow.cs:291:12:291:12 | M | cflow.cs:291:38:291:38 | access to parameter f |
| cflow.cs:296:5:296:25 | NegationInConstructor | cflow.cs:296:52:296:54 | {...} |
| cflow.cs:296:5:296:25 | NegationInConstructor | cflow.cs:296:5:296:25 | call to constructor Object |
| cflow.cs:298:10:298:10 | M | cflow.cs:299:5:301:5 | {...} |

View File

@@ -167,7 +167,9 @@
| Splitting.cs:32:9:32:16 | [b (line 24): false] dynamic call to method Check | normal | Splitting.cs:32:9:32:16 | [b (line 24): false] dynamic call to method Check |
| Splitting.cs:32:9:32:16 | [b (line 24): true] dynamic call to method Check | normal | Splitting.cs:32:9:32:16 | [b (line 24): true] dynamic call to method Check |
| Splitting.cs:34:13:34:20 | dynamic call to method Check | normal | Splitting.cs:34:13:34:20 | dynamic call to method Check |
| This.cs:7:5:7:8 | call to constructor Object | normal | This.cs:7:5:7:8 | call to constructor Object |
| This.cs:17:9:17:18 | object creation of type This | normal | This.cs:17:9:17:18 | object creation of type This |
| This.cs:22:9:22:11 | call to constructor This | normal | This.cs:22:9:22:11 | call to constructor This |
| This.cs:28:13:28:21 | object creation of type Sub | normal | This.cs:28:13:28:21 | object creation of type Sub |
| file://:0:0:0:0 | [summary] call to collectionSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany |
| file://:0:0:0:0 | [summary] call to collectionSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany |

View File

@@ -0,0 +1,8 @@
| expressions.cs:56:9:56:13 | Class | expressions.cs:56:19:56:22 | call to constructor Class | expressions.cs:58:19:58:23 | Class |
| expressions.cs:58:19:58:23 | Class | expressions.cs:58:19:58:23 | call to constructor Object | file://:0:0:0:0 | Object |
| expressions.cs:132:13:132:18 | Nested | expressions.cs:132:13:132:18 | call to constructor Class | expressions.cs:56:9:56:13 | Class |
| expressions.cs:133:13:133:18 | Nested | expressions.cs:133:29:133:32 | call to constructor Class | expressions.cs:58:19:58:23 | Class |
| expressions.cs:249:16:249:26 | LoginDialog | expressions.cs:249:16:249:26 | call to constructor Object | file://:0:0:0:0 | Object |
| expressions.cs:270:16:270:24 | IntVector | expressions.cs:270:16:270:24 | call to constructor Object | file://:0:0:0:0 | Object |
| expressions.cs:310:16:310:20 | Digit | expressions.cs:310:16:310:20 | call to constructor ValueType | file://:0:0:0:0 | ValueType |
| expressions.cs:480:20:480:22 | Num | expressions.cs:480:20:480:22 | call to constructor Object | file://:0:0:0:0 | Object |

View File

@@ -0,0 +1,21 @@
import csharp
private class ConstructorInitializerTarget extends Constructor {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
if this.fromSource()
then this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
else (
filepath = "" and
startline = 0 and
startcolumn = 0 and
endline = 0 and
endcolumn = 0
)
}
}
from Constructor c, ConstructorInitializer i, ConstructorInitializerTarget target
where c.getInitializer() = i and target = i.getTarget()
select c, i, target

View File

@@ -835,7 +835,14 @@ expressions.cs:
# 129| 21: [Class] Nested
#-----| 3: (Base types)
# 129| 0: [TypeMention] Class
# 133| 4: [InstanceConstructor] Nested
# 131| 4: [StaticConstructor] Nested
# 131| 4: [BlockStmt] {...}
# 132| 5: [InstanceConstructor] Nested
#-----| 2: (Parameters)
# 132| 0: [Parameter] b
# 132| -1: [TypeMention] bool
# 132| 4: [BlockStmt] {...}
# 133| 6: [InstanceConstructor] Nested
#-----| 2: (Parameters)
# 133| 0: [Parameter] i
# 133| -1: [TypeMention] int
@@ -844,7 +851,7 @@ expressions.cs:
# 133| 0: [ParameterAccess] access to parameter i
# 133| 1: [IntLiteral] 1
# 133| 4: [BlockStmt] {...}
# 135| 5: [Method] OtherAccesses
# 135| 7: [Method] OtherAccesses
# 135| -1: [TypeMention] Void
# 136| 4: [BlockStmt] {...}
# 137| 0: [ExprStmt] ...;

View File

@@ -128,8 +128,8 @@ namespace Expressions
class Nested : Class
{
static Nested() { }
Nested(bool b) { }
Nested(int i) : base(i + 1) { }
void OtherAccesses()

View File

@@ -132,6 +132,7 @@ JavaScript and TypeScript built-in support
postgres, Database
ramda, Utility library
react, HTML framework
react native, HTML framework
request, Network communicator
sequelize, Database
socket.io, Network communicator

View File

@@ -3,7 +3,7 @@
## Introduction
This document describes how to format the code you contribute to this repository. It covers aspects such as layout, white-space, naming, and documentation. Adhering to consistent standards makes code easier to read and maintain. Of course, these are only guidelines, and can be overridden as the need arises on a case-by-case basis. Where existing code deviates from these guidelines, prefer consistency with the surrounding code.
Note, if you use [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode/procedures/about-codeql-for-vscode.html), you can autoformat your query in the editor.
Note, if you use [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/about-codeql-for-visual-studio-code/), you can autoformat your query in the editor.
Words in *italic* are defined in the [Glossary](#glossary).
@@ -166,7 +166,7 @@ private predicate foo(Expr e, Expr p) {
```
## Naming
1. Use [PascalCase](http://wiki.c2.com/?PascalCase) for:
1. Use [PascalCase](https://wiki.c2.com/?PascalCase) for:
- `class` names
- `module` names
- `newtype` names
@@ -249,7 +249,7 @@ For more information about documenting the code that you contribute to this repo
1. The `and` and `else` keywords *may* be placed on the same line as the closing parenthesis.
1. The `and` and `else` keywords *may* be "cuddled": `) else (`
1. *Always* qualify *calls* to predicates of the same class with `this`.
2. *Prefer* postfix casts `a.(Expr)` to prefix casts `(Expr)a`.
1. *Prefer* postfix casts `a.(Expr)` to prefix casts `(Expr)a`.
### Examples
@@ -350,16 +350,16 @@ For more information about documenting the code that you contribute to this repo
| Phrase | Meaning |
|-------------|----------|
| *[annotation](https://help.semmle.com/QL/ql-handbook/language.html#annotations)* | An additional specifier used to modify a declaration, such as `private`, `override`, `deprecated`, `pragma`, `bindingset`, or `cached`. |
| *[annotation](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#annotations)* | An additional specifier used to modify a declaration, such as `private`, `override`, `deprecated`, `pragma`, `bindingset`, or `cached`. |
| *body* | The text inside `{ }`, `( )`, or each section of an `if`-`then`-`else` or `from`-`where`-`select`. |
| *binary operator* | An operator with two operands, such as comparison operators, `and`, `or`, `implies`, or arithmetic operators. |
| *call* | A *formula* that invokes a predicate, e.g. `this.isStatic()` or `calls(a,b)`. |
| *[conjunct](https://help.semmle.com/QL/ql-handbook/language.html#conjunctions)* | A formula that is an operand to an `and`. |
| *[conjunct](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#conjunctions)* | A formula that is an operand to an `and`. |
| *declaration* | A class, module, predicate, field or newtype. |
| *[disjunct](https://help.semmle.com/QL/ql-handbook/language.html#disjunctions)* | A formula that is an operand to an `or`. |
| *[formula](https://help.semmle.com/QL/ql-handbook/language.html#formulas)* | A logical expression, such as `A = B`, a *call*, a *quantifier*, `and`, `or`, `not`, `in` or `instanceof`. |
| *[disjunct](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#disjunctions)* | A formula that is an operand to an `or`. |
| *[formula](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#formulas)* | A logical expression, such as `A = B`, a *call*, a *quantifier*, `and`, `or`, `not`, `in` or `instanceof`. |
| *should/should not/avoid/prefer* | Adhere to this rule wherever possible, where it makes sense. |
| *may/can* | This is a reasonable alternative, to be used with discretion. |
| *must/always/do not* | Always adhere to this rule. |
| *[quantifier/aggregation](https://help.semmle.com/QL/ql-handbook/language.html#aggregations)* | `exists`, `count`, `strictcount`, `any`, `forall`, `forex` and so on. |
| *[quantifier/aggregation](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#aggregations)* | `exists`, `count`, `strictcount`, `any`, `forall`, `forex` and so on. |
| *variable* | A parameter to a predicate, a field, a from variable, or a variable introduced by a *quantifier* or *aggregation*. |

View File

@@ -124,11 +124,12 @@ Certain special predicates should be documented consistently.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/locations.html).
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) { ... }
```
## QLDoc for classes
1. Document classes using a noun phrase of the form `A <domain element> that <has property>.`

View File

@@ -4,11 +4,12 @@
When you contribute a new [supported query](supported-queries.md) to this repository, or add a custom query for analysis in LGTM, you should also write a query help file. This file provides detailed information about the purpose and use of the query, which is available to users in LGTM (for example [here](https://lgtm.com/rules/1506093386171/)) and on the query homepages:
* [C/C++ queries](https://help.semmle.com/wiki/display/CCPPOBJ/)
* [C# queries](https://help.semmle.com/wiki/display/CSHARP/)
* [Java queries](https://help.semmle.com/wiki/display/JAVA/)
* [JavaScript queries](https://help.semmle.com/wiki/display/JS/)
* [Python queries](https://help.semmle.com/wiki/display/PYTHON/)
* [C/C++ queries](https://codeql.github.com/codeql-query-help/cpp/)
* [C# queries](https://codeql.github.com/codeql-query-help/csharp/)
* [Go queries](https://codeql.github.com/codeql-query-help/go/)
* [Java queries](https://codeql.github.com/codeql-query-help/java/)
* [JavaScript queries](https://codeql.github.com/codeql-query-help/javascript/)
* [Python queries](https://codeql.github.com/codeql-query-help/python/)
### Location and file name
@@ -18,57 +19,57 @@ Query help files must have the same base name as the query they describe and mus
Query help files are written using a custom XML format, and stored in a file with a `.qhelp` extension. The basic structure is as follows:
```
```xml
<!DOCTYPE qhelp SYSTEM "qhelp.dtd">
<qhelp>
CONTAINS one or more section-level elements
</qhelp>
```
The header and single top-level `<qhelp>` element are both mandatory.
The header and single top-level `<qhelp>` element are both mandatory.
### Section-level elements
Section-level elements are used to group the information within the query help file. All query help files should include at least the following section elements, in the order specified:
1. `overview`—a short summary of the issue that the query identifies, including an explanation of how it could affect the behavior of the program.
2. `recommendation`—information on how to fix the issue highlighted by the query.
3. `example`—an example of code showing the problem. Where possible, this section should also include a solution to the issue.
4. `references`—relevant references, such as authoritative sources on language semantics and best practice.
1. `overview`—a short summary of the issue that the query identifies, including an explanation of how it could affect the behavior of the program.
2. `recommendation`—information on how to fix the issue highlighted by the query.
3. `example`—an example of code showing the problem. Where possible, this section should also include a solution to the issue.
4. `references`—relevant references, such as authoritative sources on language semantics and best practice.
For further information about the other section-level, block, list and table elements supported by query help files, see [Query help files](https://help.semmle.com/QL/learn-ql/ql/writing-queries/query-help.html) on help.semmle.com.
For further information about the other section-level, block, list and table elements supported by query help files, see [Query help files](https://codeql.github.com/docs/writing-codeql-queries/query-help-files/) on codeql.github.com.
## English style
You should write the overview and recommendation elements in simple English that is easy to follow. You should:
* Use simple sentence structures and avoid complex or academic language.
* Avoid colloquialisms and contractions.
* Use US English spelling throughout.
* Use words that are in common usage.
* Use simple sentence structures and avoid complex or academic language.
* Avoid colloquialisms and contractions.
* Use US English spelling throughout.
* Use words that are in common usage.
## Code examples
Whenever possible, you should include a code example that helps to explain the issue you are highlighting. Any code examples that you include should adhere to the following guidelines:
* The example should be less than 20 lines, but it should still clearly illustrate the issue that the query identifies. If appropriate, then the example may also be runnable.
* Put the code example after the recommendation element where possible. Only include an example in the description element if absolutely necessary.
* If you are using an example to illustrate the solution to a problem, and the change required is minor, avoid repeating the whole example. It is preferable to either describe the change required or to include a smaller snippet of the corrected code.
* Clearly indicate which of the samples is an example of bad coding practice and which is recommended practice.
* Define the code examples in `src` files. The language is inferred from the file extension:
* The example should be less than 20 lines, but it should still clearly illustrate the issue that the query identifies. If appropriate, then the example may also be runnable.
* Put the code example after the recommendation element where possible. Only include an example in the description element if absolutely necessary.
* If you are using an example to illustrate the solution to a problem, and the change required is minor, avoid repeating the whole example. It is preferable to either describe the change required or to include a smaller snippet of the corrected code.
* Clearly indicate which of the samples is an example of bad coding practice and which is recommended practice.
* Define the code examples in `src` files. The language is inferred from the file extension:
```
<example>
<p>This example highlights poor coding practice</p>
```xml
<example>
<p>This example highlights poor coding practice</p>
<sample src = "example-code-bad.java" />
<sample src = "example-code-bad.java" />
<p>This example shows how to fix the code</p>
<p>This example shows how to fix the code</p>
<sample src = "example-code-fixed.java" />
</example>
```
<sample src = "example-code-fixed.java" />
</example>
```
Note, if any code words are included in the `overview` and `recommendation` sections, they should be formatted with `<code> ... </code>` for emphasis.
@@ -90,7 +91,7 @@ Note, & symbols need to be replaced by \&amp;. The symbol will be displayed corr
### Academic papers
If you are citing an academic paper, we recommend adopting the reference style of the journal that you are citing. For example:
If you are citing an academic paper, we recommend adopting the reference style of the journal that you are citing. For example:
>S. R. Chidamber and C. F. Kemerer, _A metrics suite for object-oriented design_. IEEE Transactions on Software Engineering, 20(6):476-493, 1994.
@@ -109,11 +110,11 @@ For example:
If your query checks code for a CWE weakness, you should use the `@tags` element in the query file to reference the associated CWEs, as explained [here](query-metadata-style-guide.md). When you use these tags, a link to the appropriate entry from the [MITRE.org](https://cwe.mitre.org/scoring/index.html) site will automatically appear as a reference in the output HTML file.
## Query help example
## Query help example
The following example is a query help file for a query from the standard query suite for Java:
The following example is a query help file for a query from the standard query suite for Java:
```
```xml
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">

View File

@@ -8,27 +8,27 @@ This document outlines the structure of CodeQL query files. You should adopt thi
Query files have the extension `.ql`. Each file has two distinct areas:
* Metadata areadisplayed at the top of the file, contains the metadata that defines how results for the query are interpreted and gives a brief description of the purpose of the query.
* Query definitiondefined using QL. The query includes a select statement, which defines the content and format of the results. For further information about writing QL, see the following topics:
* [Learning CodeQL](https://help.semmle.com/QL/learn-ql/index.html)
* [QL language reference](https://help.semmle.com/QL/ql-handbook/index.html)
* [CodeQL style guide](https://github.com/github/codeql/blob/main/docs/ql-style-guide.md)
* Metadata areadisplayed at the top of the file, contains the metadata that defines how results for the query are interpreted and gives a brief description of the purpose of the query.
* Query definitiondefined using QL. The query includes a select statement, which defines the content and format of the results. For further information about writing QL, see the following topics:
* [CodeQL documentation](https://codeql.github.com/docs/)
* [QL language reference](https://codeql.github.com/docs/ql-language-reference/)
* [CodeQL style guide](ql-style-guide.md)
For examples of query files for the languages supported by CodeQL, visit the following links:
For examples of query files for the languages supported by CodeQL, visit the following links:
* [C/C++ queries](https://help.semmle.com/wiki/display/CCPPOBJ/)
* [C# queries](https://help.semmle.com/wiki/display/CSHARP/)
* [Go queries](https://help.semmle.com/wiki/display/GO/)
* [Java queries](https://help.semmle.com/wiki/display/JAVA/)
* [JavaScript queries](https://help.semmle.com/wiki/display/JS/)
* [Python queries](https://help.semmle.com/wiki/display/PYTHON/)
* [C/C++ queries](https://codeql.github.com/codeql-query-help/cpp/)
* [C# queries](https://codeql.github.com/codeql-query-help/csharp/)
* [Go queries](https://codeql.github.com/codeql-query-help/go/)
* [Java queries](https://codeql.github.com/codeql-query-help/java/)
* [JavaScript queries](https://codeql.github.com/codeql-query-help/javascript/)
* [Python queries](https://codeql.github.com/codeql-query-help/python/)
## Metadata area
Query file metadata contains important information that defines the identifier and purpose of the query. The metadata is included as the content of a valid [QLDoc](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#qldoc) comment, on lines with leading whitespace followed by `*`, between an initial `/**` and a trailing `*/`. For example:
```
```ql
/**
* @name Useless assignment to local variable
* @description An assignment to a local variable that is not used later on, or whose value is always
@@ -42,7 +42,7 @@ Query file metadata contains important information that defines the identifier a
*/
```
To help others use your query, and to ensure that the query works correctly on LGTM, you should include all of the required information outlined below in the metadata, and as much of the optional information as possible. For further information on query metadata see [Metadata for CodeQL queries](https://help.semmle.com/QL/learn-ql/ql/writing-queries/query-metadata.html) on help.semmle.com.
To help others use your query, and to ensure that the query works correctly on LGTM, you should include all of the required information outlined below in the metadata, and as much of the optional information as possible. For further information on query metadata see [Metadata for CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/metadata-for-codeql-queries/) on codeql.github.com.
@@ -51,10 +51,10 @@ To help others use your query, and to ensure that the query works correctly on L
You must specify an `@name` property for your query. This property defines the display name for the query. Query names should use sentence capitalization, but not include a full stop. For example:
* `@name Access to variable in enclosing class`
* `@name Array argument size mismatch`
* `@name Reference equality test on strings`
* `@name Return statement outside function`
* `@name Access to variable in enclosing class`
* `@name Array argument size mismatch`
* `@name Reference equality test on strings`
* `@name Return statement outside function`
### Query descriptions `@description`
@@ -62,38 +62,38 @@ You must specify an `@name` property for your query. This property defines the d
You must define an `@description` property for your query. This property defines a short help message. Query descriptions should be written as a sentence or short-paragraph of plain prose, with sentence capitalization and full stop. The preferred pattern for alert queries is "Syntax X causes behavior Y." Any code elements included in the description should be enclosed in single quotes. For example:
* `@description Using a format string with an incorrect format causes a 'System.FormatException'.`
* `@description Commented-out code makes the remaining code more difficult to read.`
* `@description Using a format string with an incorrect format causes a 'System.FormatException'.`
* `@description Commented-out code makes the remaining code more difficult to read.`
### Query ID `@id`
You must specify an `@id` property for your query. It must be unique and should follow the standard CodeQL convention. That is, it should begin with the 'language code' for the language that the query analyzes followed by a forward slash. The following language codes are supported:
* C and C++: `cpp`
* C#: `cs`
* Go: `go`
* Java: `java`
* JavaScript and TypeScript: `js`
* Python: `py`
* C and C++: `cpp`
* C#: `cs`
* Go: `go`
* Java: `java`
* JavaScript and TypeScript: `js`
* Python: `py`
The `@id` should consist of a short noun phrase that identifies the issue that the query highlights. For example:
* `@id cs/command-line-injection`
* `@id java/string-concatenation-in-loop`
* `@id cs/command-line-injection`
* `@id java/string-concatenation-in-loop`
Further terms can be added to the `@id` to group queries that, for example, highlight similar issues or are of particular relevance to a certain framework. For example:
* `@id js/angular-js/missing-explicit-injection`
* `@id js/angular-js/duplicate-dependency`
* `@id js/angular-js/missing-explicit-injection`
* `@id js/angular-js/duplicate-dependency`
Note, `@id` properties should be consistent for queries that highlight the same issue for different languages. For example, the following queries identify format strings that contain unsanitized input in Java and C++ code respectively:
* `@id java/tainted-format-string`
* `@id cpp/tainted-format-string`
* `@id java/tainted-format-string`
* `@id cpp/tainted-format-string`
### Query type `@kind`
@@ -102,48 +102,48 @@ Note, `@id` properties should be consistent for queries that highlight the same
* alerts (`@kind problem`)
* alerts containing path information (`@kind path-problem`)
* alerts (`@kind problem`)
* alerts containing path information (`@kind path-problem`)
Alert queries (`@kind problem` or `path-problem`) support two further properties. These are added by GitHub staff after the query has been tested, prior to deployment to LGTM. The following information is for reference:
* `@precision`broadly indicates the proportion of query results that are true positives, while also considering their context and relevance:
* `low `
* `medium `
* `high `
* `very-high`
* `@problem.severity`defines the level of severity of the alert:
* `error`an issue that is likely to cause incorrect program behavior, for example a crash or vulnerability.
* `warning`an issue that indicates a potential problem in the code, or makes the code fragile if another (unrelated) part of code is changed.
* `recommendation`an issue where the code behaves correctly, but it could be improved.
* `@precision`broadly indicates the proportion of query results that are true positives, while also considering their context and relevance:
* `low`
* `medium`
* `high`
* `very-high`
* `@problem.severity`defines the level of severity of the alert:
* `error`an issue that is likely to cause incorrect program behavior, for example a crash or vulnerability.
* `warning`an issue that indicates a potential problem in the code, or makes the code fragile if another (unrelated) part of code is changed.
* `recommendation`an issue where the code behaves correctly, but it could be improved.
The values of `@precision` and `@problem.severity` assigned to a query that is part of the standard set determine how the results are displayed by LGTM. See [About alerts](https://help.semmle.com/lgtm-enterprise/user/help/about-alerts.html) and [Alert interest](https://lgtm.com/help/lgtm/alert-interest) for further information. For information about using custom queries in LGTM on a 'per-project' basis, see [Writing custom queries to include in LGTM analysis](https://lgtm.com/help/lgtm/writing-custom-queries) and [About adding custom queries](https://help.semmle.com/lgtm-enterprise/admin/help/about-adding-custom-queries.html).
The values of `@precision` and `@problem.severity` assigned to a query that is part of the standard set determine how the results are displayed by LGTM. See [About alerts](https://help.semmle.com/lgtm-enterprise/user/help/about-alerts.html) and [Alert interest](https://lgtm.com/help/lgtm/alert-interest) for further information. For information about using custom queries in LGTM on a 'per-project' basis, see [Writing custom queries to include in LGTM analysis](https://lgtm.com/help/lgtm/writing-custom-queries) and [About adding custom queries](https://help.semmle.com/lgtm-enterprise/admin/help/about-adding-custom-queries.html).
## Query tags `@tags`
The `@tags` property is used to define categories that the query relates to. Each query should belong to one (or more, if necessary) of the following four top-level categories:
* `@tags correctness`for queries that detect incorrect program behavior.
* `@tags maintainability`for queries that detect patterns that make it harder for developers to make changes to the code.
* `@tags readability`for queries that detect confusing patterns that make it harder for developers to read the code.
* `@tags security`for queries that detect security weaknesses. See below for further information.
* `@tags correctness`for queries that detect incorrect program behavior.
* `@tags maintainability`for queries that detect patterns that make it harder for developers to make changes to the code.
* `@tags readability`for queries that detect confusing patterns that make it harder for developers to read the code.
* `@tags security`for queries that detect security weaknesses. See below for further information.
There are also more specific `@tags` that can be added. See, the following pages for examples of the low-level tags:
* [C/C++ queries](https://help.semmle.com/wiki/display/CCPPOBJ/)
* [C# queries](https://help.semmle.com/wiki/display/CSHARP/)
* [Go queries](https://help.semmle.com/wiki/display/GO/)
* [Java queries](https://help.semmle.com/wiki/display/JAVA/)
* [JavaScript queries](https://help.semmle.com/wiki/display/JS/)
* [Python queries](https://help.semmle.com/wiki/display/PYTHON/)
* [C/C++ queries](https://codeql.github.com/codeql-query-help/cpp/)
* [C# queries](https://codeql.github.com/codeql-query-help/csharp/)
* [Go queries](https://codeql.github.com/codeql-query-help/go/)
* [Java queries](https://codeql.github.com/codeql-query-help/java/)
* [JavaScript queries](https://codeql.github.com/codeql-query-help/javascript/)
* [Python queries](https://codeql.github.com/codeql-query-help/python/)
If necessary, you can also define your own low-level tags to categorize the queries specific to your project or organization. When creating your own tags, you should:
* Use all lower-case letters, including for acronyms and proper nouns, with no spaces. All characters apart from * and @ are accepted.
* Use a forward slash / to indicate a hierarchical relationship between tags if necessary. For example, a query with tag `foo/bar` is also interpreted as also having tag `foo`, but not `bar`.
* Use a single-word `@tags` name. Multiple words, separated with hyphens, can be used for clarity if necessary.
* Use all lower-case letters, including for acronyms and proper nouns, with no spaces. All characters apart from * and @ are accepted.
* Use a forward slash / to indicate a hierarchical relationship between tags if necessary. For example, a query with tag `foo/bar` is also interpreted as also having tag `foo`, but not `bar`.
* Use a single-word `@tags` name. Multiple words, separated with hyphens, can be used for clarity if necessary.
#### Security query `@tags`
@@ -155,7 +155,7 @@ If your query is a security query, use one or more `@tags` to associate it with
||`external/cwe/cwe-036` |
||`external/cwe/cwe-073` |
When you tag a query like this, the associated CWE pages from [MITRE.org](http://cwe.mitre.org/index.html) will automatically appear in the reference section of its associated qhelp file.
When you tag a query like this, the associated CWE pages from [MITRE.org](https://cwe.mitre.org/index.html) will automatically appear in the reference section of its associated qhelp file.
## QL area
@@ -163,20 +163,20 @@ When you tag a query like this, the associated CWE pages from [MITRE.org](http:/
The select clause of each alert query defines the alert message that is displayed for each result found by the query. Alert messages are strings that concisely describe the problem that the alert is highlighting and, if possible, also provide some context. For consistency, alert messages should adhere to the following guidelines:
* Each message should be a complete, standalone sentence. That is, it should be capitalized and have proper punctuation, including a full stop.
* The message should factually describe the problem that is being highlightedit should not contain recommendations about how to fix the problem or value judgements.
* Program element references should be in 'single quotes' to distinguish them from ordinary words. Quotes are not needed around substitutions ($@).
* Avoid constant alert message strings and include some context, if possible. For example, `The class 'Foo' is duplicated as 'Bar'.` is preferable to `This class is duplicated here.`
* Where you reference another program element, link to it if possible using a substitution (`$@`). Links should be used inline in the sentence, rather than as parenthesised lists or appositions.
* When a message contains multiple links, construct a sentence that has the most variable link (that is, the link with most targets) last. For further information, see [Defining the results of a query](https://help.semmle.com/QL/learn-ql/ql/writing-queries/select-statement.html).
* Each message should be a complete, standalone sentence. That is, it should be capitalized and have proper punctuation, including a full stop.
* The message should factually describe the problem that is being highlightedit should not contain recommendations about how to fix the problem or value judgements.
* Program element references should be in 'single quotes' to distinguish them from ordinary words. Quotes are not needed around substitutions (`$@`).
* Avoid constant alert message strings and include some context, if possible. For example, `The class 'Foo' is duplicated as 'Bar'.` is preferable to `This class is duplicated here.`
* Where you reference another program element, link to it if possible using a substitution (`$@`). Links should be used inline in the sentence, rather than as parenthesised lists or appositions.
* When a message contains multiple links, construct a sentence that has the most variable link (that is, the link with most targets) last. For further information, see [Defining the results of a query](https://codeql.github.com/docs/writing-codeql-queries/defining-the-results-of-a-query/).
For examples of select clauses and alert messages, see the query source files at the following pages:
* [C/C++ queries](https://help.semmle.com/wiki/display/CCPPOBJ/)
* [C# queries](https://help.semmle.com/wiki/display/CSHARP/)
* [Go queries](https://help.semmle.com/wiki/display/GO/)
* [Java queries](https://help.semmle.com/wiki/display/JAVA/)
* [JavaScript queries](https://help.semmle.com/wiki/display/JS/)
* [Python queries](https://help.semmle.com/wiki/display/PYTHON/)
* [C/C++ queries](https://codeql.github.com/codeql-query-help/cpp/)
* [C# queries](https://codeql.github.com/codeql-query-help/csharp/)
* [Go queries](https://codeql.github.com/codeql-query-help/go/)
* [Java queries](https://codeql.github.com/codeql-query-help/java/)
* [JavaScript queries](https://codeql.github.com/codeql-query-help/javascript/)
* [Python queries](https://codeql.github.com/codeql-query-help/python/)
For further information on query writing, see [CodeQL queries](https://help.semmle.com/QL/learn-ql/ql/writing-queries/writing-queries.html). For more information on learning CodeQL, see [Learning CodeQL](https://help.semmle.com/QL/learn-ql/index.html).
For further information on query writing, see [CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/codeql-queries/). For more information on learning CodeQL, see [CodeQL documentation](https://codeql.github.com/docs/).

View File

@@ -27,8 +27,8 @@ The process must begin with the first step and must conclude with the final step
Add one or more unit tests for the query (and for any library changes you make) to the `ql/<language>/ql/test/experimental` directory. Tests for library changes go into the `library-tests` subdirectory, and tests for queries go into `query-tests` with their relative path mirroring the query's location under `ql/<language>/ql/src/experimental`.
- See the section on [Testing custom queries](https://help.semmle.com/codeql/codeql-cli/procedures/test-queries.html) in the [CodeQL documentation](https://help.semmle.com/codeql/) for more information.
- See [C/C++ CodeQL tests](/cpp/ql/test/README.md) for more information about contributing tests for C/C++ queries in particular.
- See the section on [Testing custom queries](https://help.semmle.com/codeql/codeql-cli/procedures/test-queries.html) in the [CodeQL documentation](https://codeql.github.com/docs/) for more information.
- See [C/C++ CodeQL tests](/cpp/ql/test/README.md) for more information about contributing tests for C/C++ queries in particular.
4. **Test for correctness on real-world code**
@@ -46,10 +46,10 @@ The process must begin with the first step and must conclude with the final step
QL performance profiling and tuning is an advanced topic, and some tasks will require assistance from GitHub employees. With that said, there are several things you can do.
- Understand [the evaluation model of QL](https://help.semmle.com/QL/ql-handbook/evaluation.html). It's more similar to SQL than to any mainstream programming language.
- Understand [the evaluation model of QL](https://codeql.github.com/docs/ql-language-reference/evaluation-of-ql-programs/). It's more similar to SQL than to any mainstream programming language.
- Most performance tuning in QL boils down to computing as few tuples (rows of data) as possible. As a mental model, think of predicate evaluation as enumerating all combinations of parameters that satisfy the predicate body. This includes the implicit parameters `this` and `result`.
- The major libraries in CodeQL are _cached_ and will only be computed once for the entire suite of queries. The first query that needs a cached _stage_ will trigger its evaluation. This means that query authors should usually only look at the run time of the last stage of evaluation.
- In [the settings for the VSCode extension](https://help.semmle.com/codeql/codeql-for-vscode/reference/settings.html), check the box "Running Queries: Debug" (`codeQL.runningQueries.debug`). Then find "CodeQL Query Server" in the VSCode Output panel (View -> Output) and capture the output when running the query. That output contains timing and tuple counts for all computed predicates.
- In [the settings for the VSCode extension](https://codeql.github.com/docs/codeql-for-visual-studio-code/customizing-settings/), check the box "Running Queries: Debug" (`codeQL.runningQueries.debug`). Then find "CodeQL Query Server" in the VSCode Output panel (View -> Output) and capture the output when running the query. That output contains timing and tuple counts for all computed predicates.
- To clear the entire cache, invoke "CodeQL: Clear Cache" from the VSCode command palette.
6. **Make sure your query has the correct metadata**
@@ -78,4 +78,4 @@ The process must begin with the first step and must conclude with the final step
- The structure of an `experimental` subdirectory mirrors the structure of its parent directory, so this step may just be a matter of removing the `experimental/` prefix of the query and test paths. Be sure to also edit any references to the query path in tests.
- Add the query to one of the legacy suite files in `ql/<language>/config/suites/<language>/` if it exists. Note that there are separate suite directories for C and C++, `c` and `cpp` respectively, and the query should be added to one or both as appropriate.
- Add a release note to `change-notes/<next-version>/analysis-<language>.md`.
- Your pull request will be flagged automatically for a review by the documentation team to ensure that the query help file is ready for wider use.
- Your pull request will be flagged automatically for a review by the documentation team to ensure that the query help file is ready for wider use.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The query "XPath injection" (`java/xml/xpath-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @SpaceWhite](https://github.com/github/codeql/pull/2800)

View File

@@ -51,12 +51,26 @@ private predicate unknownErrors(@diagnostic d, string msg, int sev) {
/**
* Holds if an extraction error or warning occurred that should be reported to end users,
* with the error message `msg` and SARIF severity `sev`.
* with the message `msg` and SARIF severity `sev`.
*/
predicate reportableDiagnostics(@diagnostic d, string msg, int sev) {
knownWarnings(d, msg, sev) or knownErrors(d, msg, sev) or unknownErrors(d, msg, sev)
reportableWarnings(d, msg, sev) or reportableErrors(d, msg, sev)
}
/**
* Holds if an extraction error occurred that should be reported to end users,
* with the message `msg` and SARIF severity `sev`.
*/
predicate reportableErrors(@diagnostic d, string msg, int sev) {
knownErrors(d, msg, sev) or unknownErrors(d, msg, sev)
}
/**
* Holds if an extraction warning occurred that should be reported to end users,
* with the message `msg` and SARIF severity `sev`.
*/
predicate reportableWarnings(@diagnostic d, string msg, int sev) { knownWarnings(d, msg, sev) }
/**
* Holds if compilation unit `f` is a source file that has
* no relevant extraction diagnostics associated with it.

View File

@@ -9,5 +9,5 @@ import java
import DiagnosticsReporting
from string msg, int sev
where reportableDiagnostics(_, msg, sev)
where reportableErrors(_, msg, sev)
select msg, sev

View File

@@ -0,0 +1,13 @@
/**
* @name Extraction warnings
* @description A list of extraction warnings for files in the source code directory.
* @kind diagnostic
* @id java/diagnostics/extraction-warnings
*/
import java
import DiagnosticsReporting
from string msg, int sev
where reportableWarnings(_, msg, sev)
select msg, sev

View File

@@ -58,9 +58,19 @@ try {
// Bad Dom4j
org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
org.dom4j.Document document = reader.read(new InputSource(new StringReader(xmlStr)));
isExist = document.selectSingleNode("/users/user[@name='" + user + "' and @pass='" + pass + "']").hasContent();
isExist = document.selectSingleNode("/users/user[@name='" + user + "' and @pass='" + pass + "']") != null;
// or document.selectNodes
System.out.println(isExist);
// Good Dom4j
org.jaxen.SimpleVariableContext svc = new org.jaxen.SimpleVariableContext();
svc.setVariableValue("user", user);
svc.setVariableValue("pass", pass);
String xpathString = "/users/user[@name=$user and @pass=$pass]";
org.dom4j.XPath safeXPath = document.createXPath(xpathString);
safeXPath.setVariableContext(svc);
isExist = safeXPath.selectSingleNode(document) != null;
System.out.println(isExist);
}
} catch (ParserConfigurationException e) {

View File

@@ -5,14 +5,14 @@
<overview>
<p>
If an XPath expression is built using string concatenation, and the components of the concatenation
include user input, a user is likely to be able to create a malicious XPath expression.
include user input, it makes it very easy for a user to create a malicious XPath expression.
</p>
</overview>
<recommendation>
<p>
If user input must be included in an XPath expression, pre-compile the query and use variable
references to include the user input.
If user input must be included in an XPath expression, either sanitize the data or pre-compile the query
and use variable references to include the user input.
</p>
<p>
XPath injection can also be prevented by using XQuery.
@@ -22,23 +22,23 @@ XPath injection can also be prevented by using XQuery.
<example>
<p>
In the first, second, and third example, the code accepts a name and password specified by the user, and uses this
In the first three examples, the code accepts a name and password specified by the user, and uses this
unvalidated and unsanitized value in an XPath expression. This is vulnerable to the user providing
special characters or string sequences that change the meaning of the XPath expression to search
for different values.
</p>
<p>
In the fourth example, the code utilizes setXPathVariableResolver which prevents XPath Injection.
In the fourth example, the code uses <code>setXPathVariableResolver</code> which prevents XPath injection.
</p>
<p>
The fifth example is a dom4j XPath injection example.
The final two examples are for dom4j. They show an example of XPath injection and one method of preventing it.
</p>
<sample src="XPathInjection.java" />
</example>
<references>
<li>OWASP: <a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/09-Testing_for_XPath_Injection">Testing for XPath Injection</a>.</li>
<li>OWASP: <a href="https://www.owasp.org/index.php/XPATH_Injection">XPath Injection</a>.</li>
<li>OWASP: <a href="https://owasp.org/www-community/attacks/XPATH_Injection">XPath Injection</a>.</li>
</references>
</qhelp>

View File

@@ -13,7 +13,7 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.XmlParsers
import semmle.code.java.security.XPath
import DataFlow::PathGraph
class XPathInjectionConfiguration extends TaintTracking::Configuration {
@@ -24,20 +24,6 @@ class XPathInjectionConfiguration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof XPathInjectionSink }
}
class XPathInjectionSink extends DataFlow::ExprNode {
XPathInjectionSink() {
exists(Method m, MethodAccess ma | ma.getMethod() = m |
m.getDeclaringType().hasQualifiedName("javax.xml.xpath", "XPath") and
(m.hasName("evaluate") or m.hasName("compile")) and
ma.getArgument(0) = this.getExpr()
or
m.getDeclaringType().hasQualifiedName("org.dom4j", "Node") and
(m.hasName("selectNodes") or m.hasName("selectSingleNode")) and
ma.getArgument(0) = this.getExpr()
)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, XPathInjectionConfiguration c
where c.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to here and is used in an XPath expression.",

View File

@@ -0,0 +1,49 @@
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ClientSuppliedIpUsedInSecurityCheck {
@Autowired
private HttpServletRequest request;
@GetMapping(value = "bad1")
public void bad1(HttpServletRequest request) {
String ip = getClientIP();
if (!StringUtils.startsWith(ip, "192.168.")) {
new Exception("ip illegal");
}
}
@GetMapping(value = "bad2")
public void bad2(HttpServletRequest request) {
String ip = getClientIP();
if (!"127.0.0.1".equals(ip)) {
new Exception("ip illegal");
}
}
@GetMapping(value = "good1")
@ResponseBody
public String good1(HttpServletRequest request) {
String ip = request.getHeader("X-FORWARDED-FOR");
// Good: if this application runs behind a reverse proxy it may append the real remote IP to the end of any client-supplied X-Forwarded-For header.
ip = ip.split(",")[ip.split(",").length - 1];
if (!StringUtils.startsWith(ip, "192.168.")) {
new Exception("ip illegal");
}
return ip;
}
protected String getClientIP() {
String xfHeader = request.getHeader("X-Forwarded-For");
if (xfHeader == null) {
return request.getRemoteAddr();
}
return xfHeader.split(",")[0];
}
}

View File

@@ -0,0 +1,35 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>An original client IP address is retrieved from an http header (<code>X-Forwarded-For</code> or <code>X-Real-IP</code> or <code>Proxy-Client-IP</code>
etc.), which is used to ensure security. Attackers can forge the value of these identifiers to
bypass a ban-list, for example.</p>
</overview>
<recommendation>
<p>Do not trust the values of HTTP headers allegedly identifying the originating IP. If you are aware your application will run behind some reverse proxies then the last entry of a <code>X-Forwarded-For</code> header value may be more trustworthy than the rest of it because some reverse proxies append the IP address they observed to the end of any remote-supplied header.</p>
</recommendation>
<example>
<p>The following examples show the bad case and the good case respectively.
In <code>bad1</code> method and <code>bad2</code> method, the client ip the <code>X-Forwarded-For</code> is split into comma-separated values, but the less-trustworthy first one is used. Both of these examples could be deceived by providing a forged HTTP header. The method
<code>good1</code> similarly splits an <code>X-Forwarded-For</code> value, but uses the last, more-trustworthy entry.</p>
<sample src="ClientSuppliedIpUsedInSecurityCheck.java" />
</example>
<references>
<li>Dennis Schneider: <a href="https://www.dennis-schneider.com/blog/prevent-ip-address-spoofing-with-x-forwarded-for-header-and-aws-elb-in-clojure-ring/">
Prevent IP address spoofing with X-Forwarded-For header when using AWS ELB and Clojure Ring</a>
</li>
<li>Security Rule Zero: <a href="https://www.f5.com/company/blog/security-rule-zero-a-warning-about-x-forwarded-for">A Warning about X-Forwarded-For</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,53 @@
/**
* @name IP address spoofing
* @description A remote endpoint identifier is read from an HTTP header. Attackers can modify the value
* of the identifier to forge the client ip.
* @kind path-problem
* @problem.severity error
* @precision high
* @id java/ip-address-spoofing
* @tags security
* external/cwe/cwe-348
*/
import java
import ClientSuppliedIpUsedInSecurityCheckLib
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
/**
* Taint-tracking configuration tracing flow from obtaining a client ip from an HTTP header to a sensitive use.
*/
class ClientSuppliedIpUsedInSecurityCheckConfig extends TaintTracking::Configuration {
ClientSuppliedIpUsedInSecurityCheckConfig() { this = "ClientSuppliedIpUsedInSecurityCheckConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof ClientSuppliedIpUsedInSecurityCheck
}
override predicate isSink(DataFlow::Node sink) {
sink instanceof ClientSuppliedIpUsedInSecurityCheckSink
}
/**
* Splitting a header value by `,` and taking an entry other than the first is sanitizing, because
* later entries may originate from more-trustworthy intermediate proxies, not the original client.
*/
override predicate isSanitizer(DataFlow::Node node) {
exists(ArrayAccess aa, MethodAccess ma | aa.getArray() = ma |
ma.getQualifier() = node.asExpr() and
ma.getMethod() instanceof SplitMethod and
not aa.getIndexExpr().(CompileTimeConstantExpr).getIntValue() = 0
)
or
node.getType() instanceof PrimitiveType
or
node.getType() instanceof BoxedType
}
}
from
DataFlow::PathNode source, DataFlow::PathNode sink, ClientSuppliedIpUsedInSecurityCheckConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "IP address spoofing might include code from $@.",
source.getNode(), "this user input"

View File

@@ -0,0 +1,100 @@
import java
import DataFlow
import semmle.code.java.frameworks.Networking
import semmle.code.java.security.QueryInjection
import experimental.semmle.code.java.Logging
/**
* A data flow source of the client ip obtained according to the remote endpoint identifier specified
* (`X-Forwarded-For`, `X-Real-IP`, `Proxy-Client-IP`, etc.) in the header.
*
* For example: `ServletRequest.getHeader("X-Forwarded-For")`.
*/
class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::Node {
ClientSuppliedIpUsedInSecurityCheck() {
exists(MethodAccess ma |
ma.getMethod().hasName("getHeader") and
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue().toLowerCase() in [
"x-forwarded-for", "x-real-ip", "proxy-client-ip", "wl-proxy-client-ip",
"http_x_forwarded_for", "http_x_forwarded", "http_x_cluster_client_ip", "http_client_ip",
"http_forwarded_for", "http_forwarded", "http_via", "remote_addr"
] and
ma = this.asExpr()
)
}
}
/** A data flow sink for ip address forgery vulnerabilities. */
abstract class ClientSuppliedIpUsedInSecurityCheckSink extends DataFlow::Node { }
/**
* A data flow sink for remote client ip comparison.
*
* For example: `if (!StringUtils.startsWith(ipAddr, "192.168.")){...` determine whether the client ip starts
* with `192.168.`, and the program can be deceived by forging the ip address.
*/
private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink {
CompareSink() {
exists(MethodAccess ma |
ma.getMethod().getName() in ["equals", "equalsIgnoreCase"] and
ma.getMethod().getDeclaringType() instanceof TypeString and
ma.getMethod().getNumberOfParameters() = 1 and
(
ma.getArgument(0) = this.asExpr() and
ma.getQualifier().(CompileTimeConstantExpr).getStringValue() instanceof PrivateHostName and
not ma.getQualifier().(CompileTimeConstantExpr).getStringValue() = "0:0:0:0:0:0:0:1"
or
ma.getQualifier() = this.asExpr() and
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() instanceof PrivateHostName and
not ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "0:0:0:0:0:0:0:1"
)
)
or
exists(MethodAccess ma |
ma.getMethod().getName() in ["contains", "startsWith"] and
ma.getMethod().getDeclaringType() instanceof TypeString and
ma.getMethod().getNumberOfParameters() = 1 and
ma.getQualifier() = this.asExpr() and
ma.getAnArgument().(CompileTimeConstantExpr).getStringValue().regexpMatch(getIpAddressRegex()) // Matches IP-address-like strings
)
or
exists(MethodAccess ma |
ma.getMethod().hasName("startsWith") and
ma.getMethod()
.getDeclaringType()
.hasQualifiedName(["org.apache.commons.lang3", "org.apache.commons.lang"], "StringUtils") and
ma.getMethod().getNumberOfParameters() = 2 and
ma.getAnArgument() = this.asExpr() and
ma.getAnArgument().(CompileTimeConstantExpr).getStringValue().regexpMatch(getIpAddressRegex())
)
or
exists(MethodAccess ma |
ma.getMethod().getName() in ["equals", "equalsIgnoreCase"] and
ma.getMethod()
.getDeclaringType()
.hasQualifiedName(["org.apache.commons.lang3", "org.apache.commons.lang"], "StringUtils") and
ma.getMethod().getNumberOfParameters() = 2 and
ma.getAnArgument() = this.asExpr() and
ma.getAnArgument().(CompileTimeConstantExpr).getStringValue() instanceof PrivateHostName and
not ma.getAnArgument().(CompileTimeConstantExpr).getStringValue() = "0:0:0:0:0:0:0:1"
)
}
}
/** A data flow sink for sql operation. */
private class SqlOperationSink extends ClientSuppliedIpUsedInSecurityCheckSink {
SqlOperationSink() { this instanceof QueryInjectionSink }
}
/** A method that split string. */
class SplitMethod extends Method {
SplitMethod() {
this.getNumberOfParameters() = 1 and
this.hasQualifiedName("java.lang", "String", "split")
}
}
string getIpAddressRegex() {
result =
"^((10\\.((1\\d{2})?|(2[0-4]\\d)?|(25[0-5])?|([1-9]\\d|[0-9])?)(\\.)?)|(192\\.168\\.)|172\\.(1[6789]|2[0-9]|3[01])\\.)((1\\d{2})?|(2[0-4]\\d)?|(25[0-5])?|([1-9]\\d|[0-9])?)(\\.)?((1\\d{2})?|(2[0-4]\\d)?|(25[0-5])?|([1-9]\\d|[0-9])?)$"
}

View File

@@ -2,7 +2,7 @@
<qhelp>
<overview>
<p>
Even though the request-handling methods of <code>Servlet</code> are declared <code>throws IOException, ServletException</code>, it's a bad idea to let such exceptions be thrown. Failure to catch exceptions in a servlet could leave a system in an unexpected state, possibly resulting in denial-of-service attacks, or could lead to exposure of sensitive information because when a servlet throws an exception, the servlet container typically sends debugging information back to the user. That information could be valuable to an attacker.
Even though the request-handling methods of <code>Servlet</code> are declared <code>throws IOException, ServletException</code>, it's a bad idea to let such exceptions be thrown. Failure to catch exceptions in a servlet could lead to exposure of sensitive information because when a servlet throws an exception, the servlet container typically sends debugging information back to the user. That information could be valuable to an attacker.
</p>
</overview>

View File

@@ -80,6 +80,7 @@ private module Frameworks {
private import semmle.code.java.security.ResponseSplitting
private import semmle.code.java.security.XSS
private import semmle.code.java.security.LdapInjection
private import semmle.code.java.security.XPath
private import semmle.code.java.security.JexlInjection
}

View File

@@ -0,0 +1,58 @@
/** Provides classes to reason about XPath vulnerabilities. */
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.ExternalFlow
/**
* A sink that represents a method that interprets XPath expressions.
* Extend this class to add your own XPath Injection sinks.
*/
abstract class XPathInjectionSink extends DataFlow::Node { }
/** CSV sink models representing methods susceptible to XPath Injection attacks. */
private class DefaultXPathInjectionSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
"javax.xml.xpath;XPath;true;evaluate;;;Argument[0];xpath",
"javax.xml.xpath;XPath;true;evaluateExpression;;;Argument[0];xpath",
"javax.xml.xpath;XPath;true;compile;;;Argument[0];xpath",
"org.dom4j;Node;true;selectObject;;;Argument[0];xpath",
"org.dom4j;Node;true;selectNodes;;;Argument[0..1];xpath",
"org.dom4j;Node;true;selectSingleNode;;;Argument[0];xpath",
"org.dom4j;Node;true;numberValueOf;;;Argument[0];xpath",
"org.dom4j;Node;true;valueOf;;;Argument[0];xpath",
"org.dom4j;Node;true;matches;;;Argument[0];xpath",
"org.dom4j;Node;true;createXPath;;;Argument[0];xpath",
"org.dom4j;DocumentFactory;true;createPattern;;;Argument[0];xpath",
"org.dom4j;DocumentFactory;true;createXPath;;;Argument[0];xpath",
"org.dom4j;DocumentFactory;true;createXPathFilter;;;Argument[0];xpath",
"org.dom4j;DocumentHelper;false;createPattern;;;Argument[0];xpath",
"org.dom4j;DocumentHelper;false;createXPath;;;Argument[0];xpath",
"org.dom4j;DocumentHelper;false;createXPathFilter;;;Argument[0];xpath",
"org.dom4j;DocumentHelper;false;selectNodes;;;Argument[0];xpath",
"org.dom4j;DocumentHelper;false;sort;;;Argument[1];xpath",
"org.dom4j.tree;AbstractNode;true;createXPathFilter;;;Argument[0];xpath",
"org.dom4j.tree;AbstractNode;true;createPattern;;;Argument[0];xpath",
"org.dom4j.util;ProxyDocumentFactory;true;createPattern;;;Argument[0];xpath",
"org.dom4j.util;ProxyDocumentFactory;true;createXPath;;;Argument[0];xpath",
"org.dom4j.util;ProxyDocumentFactory;true;createXPathFilter;;;Argument[0];xpath"
]
}
}
/** A default sink representing methods susceptible to XPath Injection attacks. */
private class DefaultXPathInjectionSink extends XPathInjectionSink {
DefaultXPathInjectionSink() {
sinkNode(this, "xpath")
or
exists(ClassInstanceExpr constructor |
constructor.getConstructedType().getASourceSupertype*().hasQualifiedName("org.dom4j", "XPath")
or
constructor.getConstructedType().hasQualifiedName("org.dom4j.xpath", "XPathPattern")
|
this.asExpr() = constructor.getArgument(0)
)
}
}

View File

@@ -0,0 +1,16 @@
edges
| ClientSuppliedIpUsedInSecurityCheck.java:16:21:16:33 | getClientIP(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip |
| ClientSuppliedIpUsedInSecurityCheck.java:24:21:24:33 | getClientIP(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:25:33:25:34 | ip |
| ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String |
| ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | ClientSuppliedIpUsedInSecurityCheck.java:16:21:16:33 | getClientIP(...) : String |
| ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | ClientSuppliedIpUsedInSecurityCheck.java:24:21:24:33 | getClientIP(...) : String |
nodes
| ClientSuppliedIpUsedInSecurityCheck.java:16:21:16:33 | getClientIP(...) : String | semmle.label | getClientIP(...) : String |
| ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip | semmle.label | ip |
| ClientSuppliedIpUsedInSecurityCheck.java:24:21:24:33 | getClientIP(...) : String | semmle.label | getClientIP(...) : String |
| ClientSuppliedIpUsedInSecurityCheck.java:25:33:25:34 | ip | semmle.label | ip |
| ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | semmle.label | getHeader(...) : String |
| ClientSuppliedIpUsedInSecurityCheck.java:47:16:47:37 | ...[...] : String | semmle.label | ...[...] : String |
#select
| ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:17:37:17:38 | ip | IP address spoofing might include code from $@. | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) | this user input |
| ClientSuppliedIpUsedInSecurityCheck.java:25:33:25:34 | ip | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) : String | ClientSuppliedIpUsedInSecurityCheck.java:25:33:25:34 | ip | IP address spoofing might include code from $@. | ClientSuppliedIpUsedInSecurityCheck.java:43:27:43:62 | getHeader(...) | this user input |

View File

@@ -0,0 +1,49 @@
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ClientSuppliedIpUsedInSecurityCheck {
@Autowired
private HttpServletRequest request;
@GetMapping(value = "bad1")
public void bad1(HttpServletRequest request) {
String ip = getClientIP();
if (!StringUtils.startsWith(ip, "192.168.")) {
new Exception("ip illegal");
}
}
@GetMapping(value = "bad2")
public void bad2(HttpServletRequest request) {
String ip = getClientIP();
if (!"127.0.0.1".equals(ip)) {
new Exception("ip illegal");
}
}
@GetMapping(value = "good1")
@ResponseBody
public String good1(HttpServletRequest request) {
String ip = request.getHeader("X-FORWARDED-FOR");
// Good: if this application runs behind a reverse proxy it may append the real remote IP to the end of any client-supplied X-Forwarded-For header.
ip = ip.split(",")[ip.split(",").length - 1];
if (!StringUtils.startsWith(ip, "192.168.")) {
new Exception("ip illegal");
}
return ip;
}
protected String getClientIP() {
String xfHeader = request.getHeader("X-Forwarded-For");
if (xfHeader == null) {
return request.getRemoteAddr();
}
return xfHeader.split(",")[0];
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.2.3/:${testdir}/../../../../stubs/apache-commons-lang3-3.7/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jdom-1.1.3:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/simple-xml-2.7.1:${testdir}/../../../stubs/jaxb-api-2.3.1
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jdom-1.1.3:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/simple-xml-2.7.1:${testdir}/../../../stubs/jaxb-api-2.3.1:${testdir}/../../../stubs/jaxen-1.2.0

View File

@@ -0,0 +1,166 @@
import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.jaxen.pattern.Pattern;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Namespace;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.dom4j.util.ProxyDocumentFactory;
import org.dom4j.xpath.DefaultXPath;
import org.dom4j.xpath.XPathPattern;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class XPathInjectionTest {
private static abstract class XPathImplStub implements XPath {
public static XPathImplStub getInstance() {
return null;
}
@Override
public XPathExpression compile(String expression) throws XPathExpressionException {
return null;
}
@Override
public Object evaluate(String expression, Object item, QName returnType) throws XPathExpressionException {
return null;
}
@Override
public String evaluate(String expression, Object item) throws XPathExpressionException {
return null;
}
@Override
public Object evaluate(String expression, InputSource source, QName returnType)
throws XPathExpressionException {
return null;
}
@Override
public String evaluate(String expression, InputSource source) throws XPathExpressionException {
return null;
}
}
private static class ProxyDocumentFactoryStub extends ProxyDocumentFactory {
}
private static class PatternStub extends Pattern {
private String text;
PatternStub(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
public void handle(HttpServletRequest request) throws Exception {
String user = request.getParameter("user");
String pass = request.getParameter("pass");
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']";
final String xmlStr = "<users>" + " <user name=\"aaa\" pass=\"pass1\"></user>"
+ " <user name=\"bbb\" pass=\"pass2\"></user>" + "</users>";
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
InputSource xmlSource = new InputSource(new StringReader(xmlStr));
Document doc = builder.parse(xmlSource);
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.evaluate(expression, doc, XPathConstants.BOOLEAN); // $hasXPathInjection
xpath.evaluateExpression(expression, xmlSource); // $hasXPathInjection
xpath.compile("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
XPathImplStub xpathStub = XPathImplStub.getInstance();
xpathStub.evaluate(expression, doc, XPathConstants.BOOLEAN); // $hasXPathInjection
xpathStub.evaluateExpression(expression, xmlSource); // $hasXPathInjection
xpathStub.compile("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
StringBuffer sb = new StringBuffer("/users/user[@name=");
sb.append(user);
sb.append("' and @pass='");
sb.append(pass);
sb.append("']");
String query = sb.toString();
xpath.compile(query); // $hasXPathInjection
xpathStub.compile(query); // $hasXPathInjection
String expression4 = "/users/user[@name=$user and @pass=$pass]";
xpath.setXPathVariableResolver(v -> {
switch (v.getLocalPart()) {
case "user":
return user;
case "pass":
return pass;
default:
throw new IllegalArgumentException();
}
});
xpath.evaluate(expression4, doc, XPathConstants.BOOLEAN); // Safe
SAXReader reader = new SAXReader();
org.dom4j.Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes()));
document.selectObject("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
document.selectNodes("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
document.selectNodes("/users/user[@name='test']", "/users/user[@pass='" + pass + "']"); // $hasXPathInjection
document.selectSingleNode("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
document.valueOf("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
document.numberValueOf("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
document.matches("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
document.createXPath("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
new DefaultXPath("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
new XPathPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
new XPathPattern(new PatternStub(user)); // $ MISSING: hasXPathInjection // Jaxen is not modeled yet
DocumentFactory docFactory = DocumentFactory.getInstance();
docFactory.createPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
docFactory.createXPath("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
docFactory.createXPathFilter("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
DocumentHelper.createPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
DocumentHelper.createXPath("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
DocumentHelper.createXPathFilter("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
DocumentHelper.selectNodes("/users/user[@name='" + user + "' and @pass='" + pass + "']", new ArrayList<Node>()); // $hasXPathInjection
DocumentHelper.sort(new ArrayList<Node>(), "/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
ProxyDocumentFactoryStub proxyDocFactory = new ProxyDocumentFactoryStub();
proxyDocFactory.createPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
proxyDocFactory.createXPath("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
proxyDocFactory.createXPathFilter("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
Namespace namespace = new Namespace("prefix", "http://some.uri.io");
namespace.createPattern("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
namespace.createXPathFilter("/users/user[@name='" + user + "' and @pass='" + pass + "']"); // $hasXPathInjection
org.jaxen.SimpleVariableContext svc = new org.jaxen.SimpleVariableContext();
svc.setVariableValue("user", user);
svc.setVariableValue("pass", pass);
String xpathString = "/users/user[@name=$user and @pass=$pass]";
org.dom4j.XPath safeXPath = document.createXPath(xpathString); // Safe
safeXPath.setVariableContext(svc);
safeXPath.selectSingleNode(document); // Safe
}
}

View File

@@ -0,0 +1,28 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.XPath
import TestUtilities.InlineExpectationsTest
class Conf extends TaintTracking::Configuration {
Conf() { this = "test:xml:xpathinjection" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof XPathInjectionSink }
}
class HasXPathInjectionTest extends InlineExpectationsTest {
HasXPathInjectionTest() { this = "HasXPathInjectionTest" }
override string getARelevantTag() { result = "hasXPathInjection" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasXPathInjection" and
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jaxen-1.2.0

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
public interface Branch extends Node {
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -13,7 +13,8 @@
package org.dom4j;
public interface Document {
public interface Document extends Branch {
}
/*

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
import java.io.Serializable;
import java.util.Map;
import org.dom4j.rule.Pattern;
import org.jaxen.VariableContext;
public class DocumentFactory implements Serializable {
public DocumentFactory() {
}
public static synchronized DocumentFactory getInstance() {
return null;
}
public Document createDocument() {
return null;
}
public Document createDocument(String encoding) {
return null;
}
public Document createDocument(Element rootElement) {
return null;
}
public Element createElement(String name) {
return null;
}
public Element createElement(String qualifiedName, String namespaceURI) {
return null;
}
public Namespace createNamespace(String prefix, String uri) {
return null;
}
public XPath createXPath(String xpathExpression) throws InvalidXPathException {
return null;
}
public XPath createXPath(String xpathExpression, VariableContext variableContext) {
return null;
}
public NodeFilter createXPathFilter(String xpathFilterExpression, VariableContext variableContext) {
return null;
}
public NodeFilter createXPathFilter(String xpathFilterExpression) {
return null;
}
public Pattern createPattern(String xpathPattern) {
return null;
}
public Map<String, String> getXPathNamespaceURIs() {
return null;
}
public void setXPathNamespaceURIs(Map<String, String> namespaceURIs) {
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,109 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
import java.util.List;
import org.dom4j.rule.Pattern;
import org.jaxen.VariableContext;
public final class DocumentHelper {
public static Document createDocument() {
return null;
}
public static Document createDocument(Element rootElement) {
return null;
}
public static Element createElement(String name) {
return null;
}
public static Namespace createNamespace(String prefix, String uri) {
return null;
}
public static XPath createXPath(String xpathExpression) throws InvalidXPathException {
return null;
}
public static XPath createXPath(String xpathExpression, VariableContext context) throws InvalidXPathException {
return null;
}
public static NodeFilter createXPathFilter(String xpathFilterExpression) {
return null;
}
public static Pattern createPattern(String xpathPattern) {
return null;
}
public static List<Node> selectNodes(String xpathFilterExpression, List<Node> nodes) {
return null;
}
public static List<Node> selectNodes(String xpathFilterExpression, Node node) {
return null;
}
public static void sort(List<Node> list, String xpathExpression) {
}
public static void sort(List<Node> list, String expression, boolean distinct) {
}
public static Element makeElement(Branch source, String path) {
return null;
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,140 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public interface Element extends Branch {
Namespace getNamespace();
Namespace getNamespaceForPrefix(String prefix);
Namespace getNamespaceForURI(String uri);
List<Namespace> getNamespacesForURI(String uri);
String getNamespacePrefix();
String getNamespaceURI();
String getQualifiedName();
List<Namespace> additionalNamespaces();
List<Namespace> declaredNamespaces();
Element addAttribute(String name, String value);
Element addComment(String comment);
Element addCDATA(String cdata);
Element addEntity(String name, String text);
Element addNamespace(String prefix, String uri);
Element addProcessingInstruction(String target, String text);
Element addProcessingInstruction(String target, Map<String, String> data);
Element addText(String text);
void add(Namespace namespace);
String getText();
String getTextTrim();
String getStringValue();
Object getData();
void setData(Object data);
int attributeCount();
String attributeValue(String name);
String attributeValue(String name, String defaultValue);
void setAttributeValue(String name, String value);
Element element(String name);
List<Element> elements();
List<Element> elements(String name);
Iterator<Element> elementIterator();
Iterator<Element> elementIterator(String name);
boolean isRootElement();
boolean hasMixedContent();
boolean isTextOnly();
void appendAttributes(Element element);
Element createCopy();
Element createCopy(String name);
String elementText(String name);
String elementTextTrim(String name);
Node getXPathResult(int index);
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
public class InvalidXPathException extends IllegalArgumentException {
public InvalidXPathException(String xpath) {
}
public InvalidXPathException(String xpath, String reason) {
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,119 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
import org.dom4j.tree.AbstractNode;
public class Namespace extends AbstractNode {
public Namespace(String prefix, String uri) {
}
public static Namespace get(String prefix, String uri) {
return null;
}
public static Namespace get(String uri) {
return null;
}
public short getNodeType() {
return 0;
}
public int hashCode() {
return 0;
}
public boolean equals(Object object) {
return false;
}
public String getText() {
return null;
}
public String getStringValue() {
return null;
}
public String getPrefix() {
return null;
}
public String getURI() {
return null;
}
public String getXPathNameStep() {
return null;
}
public String getPath(Element context) {
return null;
}
public String getUniquePath(Element context) {
return null;
}
public String toString() {
return null;
}
public String asXML() {
return null;
}
public void accept(Visitor visitor) {
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
import java.util.List;
public interface Node extends Cloneable {
List<Node> selectNodes(String xpathExpression);
Object selectObject(String xpathExpression);
List<Node> selectNodes(String xpathExpression, String comparisonXPathExpression);
List<Node> selectNodes(String xpathExpression, String comparisonXPathExpression, boolean removeDuplicates);
Node selectSingleNode(String xpathExpression);
String valueOf(String xpathExpression);
Number numberValueOf(String xpathExpression);
boolean matches(String xpathExpression);
XPath createXPath(String xpathExpression) throws InvalidXPathException;
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
public interface NodeFilter {
boolean matches(Node node);
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
public interface Visitor {
void visit(Document document);
void visit(Element node);
void visit(Namespace namespace);
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j;
import java.util.List;
import java.util.Map;
public interface XPath extends NodeFilter {
String getText();
boolean matches(Node node);
Object evaluate(Object context);
Object selectObject(Object context);
List<Node> selectNodes(Object context);
List<Node> selectNodes(Object context, XPath sortXPath);
List<Node> selectNodes(Object context, XPath sortXPath, boolean distinct);
Node selectSingleNode(Object context);
String valueOf(Object context);
Number numberValueOf(Object context);
boolean booleanValueOf(Object context);
void sort(List<Node> list);
void sort(List<Node> list, boolean distinct);
void setNamespaceURIs(Map<String, String> map);
void setVariableContext(org.jaxen.VariableContext variableContext);
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j.rule;
import org.dom4j.Node;
import org.dom4j.NodeFilter;
public interface Pattern extends NodeFilter {
boolean matches(Node node);
double getPriority();
Pattern[] getUnionPatterns();
short getMatchType();
String getMatchesNodeName();
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,183 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j.tree;
import org.dom4j.*;
import org.dom4j.rule.Pattern;
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.util.List;
public abstract class AbstractNode implements Node, Cloneable, Serializable {
public AbstractNode() {
}
public short getNodeType() {
return 0;
}
public String getNodeTypeName() {
return null;
}
public Document getDocument() {
return null;
}
public void setDocument(Document document) {
}
public Element getParent() {
return null;
}
public void setParent(Element parent) {
}
public boolean supportsParent() {
return false;
}
public boolean isReadOnly() {
return false;
}
public boolean hasContent() {
return false;
}
public String getPath() {
return null;
}
public String getUniquePath() {
return null;
}
public Object clone() {
return null;
}
public Node detach() {
return null;
}
public String getName() {
return null;
}
public void setName(String name) {
}
public String getText() {
return null;
}
public String getStringValue() {
return null;
}
public void setText(String text) {
}
public void write(Writer writer) throws IOException {
}
public Object selectObject(String xpathExpression) {
return null;
}
public List<Node> selectNodes(String xpathExpression) {
return null;
}
public List<Node> selectNodes(String xpathExpression, String comparisonXPathExpression) {
return null;
}
public List<Node> selectNodes(String xpathExpression, String comparisonXPathExpression, boolean removeDuplicates) {
return null;
}
public Node selectSingleNode(String xpathExpression) {
return null;
}
public String valueOf(String xpathExpression) {
return null;
}
public Number numberValueOf(String xpathExpression) {
return null;
}
public boolean matches(String patternText) {
return false;
}
public XPath createXPath(String xpathExpression) {
return null;
}
public NodeFilter createXPathFilter(String patternText) {
return null;
}
public Pattern createPattern(String patternText) {
return null;
}
public Node asXPathResult(Element parent) {
return null;
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j.util;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.NodeFilter;
import org.dom4j.XPath;
import org.dom4j.rule.Pattern;
import org.jaxen.VariableContext;
public abstract class ProxyDocumentFactory {
public ProxyDocumentFactory() {
}
public ProxyDocumentFactory(DocumentFactory proxy) {
}
public Document createDocument() {
return null;
}
public Document createDocument(Element rootElement) {
return null;
}
public Element createElement(String name) {
return null;
}
public XPath createXPath(String xpathExpression) {
return null;
}
public XPath createXPath(String xpathExpression, VariableContext variableContext) {
return null;
}
public NodeFilter createXPathFilter(String xpathFilterExpression, VariableContext variableContext) {
return null;
}
public NodeFilter createXPathFilter(String xpathFilterExpression) {
return null;
}
public Pattern createPattern(String xpathPattern) {
return null;
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,135 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j.xpath;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.dom4j.InvalidXPathException;
import org.dom4j.Node;
import org.dom4j.XPath;
public class DefaultXPath implements org.dom4j.XPath, Serializable {
public DefaultXPath(String text) throws InvalidXPathException {
}
@Override
public String getText() {
return null;
}
@Override
public boolean matches(Node node) {
return false;
}
@Override
public Object evaluate(Object context) {
return null;
}
@Override
public Object selectObject(Object context) {
return null;
}
@Override
public List<Node> selectNodes(Object context) {
return null;
}
@Override
public List<Node> selectNodes(Object context, XPath sortXPath) {
return null;
}
@Override
public List<Node> selectNodes(Object context, XPath sortXPath, boolean distinct) {
return null;
}
@Override
public Node selectSingleNode(Object context) {
return null;
}
@Override
public String valueOf(Object context) {
return null;
}
@Override
public Number numberValueOf(Object context) {
return null;
}
@Override
public boolean booleanValueOf(Object context) {
return false;
}
@Override
public void sort(List<Node> list) {
}
@Override
public void sort(List<Node> list, boolean distinct) {
}
@Override
public void setNamespaceURIs(Map<String, String> map) {
}
@Override
public void setVariableContext(org.jaxen.VariableContext variableContext) {
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
/*
* Adapted from DOM4J version 2.1.1 as available at
* https://search.maven.org/remotecontent?filepath=org/dom4j/dom4j/2.1.1/dom4j-2.1.1-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.dom4j.xpath;
import org.dom4j.Node;
public class XPathPattern implements org.dom4j.rule.Pattern {
public XPathPattern(String text) {
}
public XPathPattern(org.jaxen.pattern.Pattern pattern) {
}
public boolean matches(Node node) {
return false;
}
public String getText() {
return null;
}
public double getPriority() {
return 0;
}
public org.dom4j.rule.Pattern[] getUnionPatterns() {
return null;
}
public short getMatchType() {
return 0;
}
public String getMatchesNodeName() {
return null;
}
public String toString() {
return null;
}
}
/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/

View File

@@ -0,0 +1,66 @@
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* Copyright 2000-2002 bob mcwhirter & James Strachan.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the Jaxen Project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
* This software consists of voluntary contributions made by many
* individuals on behalf of the Jaxen Project and was originally
* created by bob mcwhirter <bob@werken.com> and
* James Strachan <jstrachan@apache.org>. For more information on the
* Jaxen Project, please see <http://www.jaxen.org/>.
*
* $Id$
*/
package org.jaxen;
import java.io.Serializable;
public class SimpleVariableContext implements VariableContext, Serializable {
public SimpleVariableContext() {
}
public void setVariableValue(String namespaceURI, String localName, Object value) {
}
public void setVariableValue(String localName, Object value) {
}
public Object getVariableValue(String namespaceURI, String prefix, String localName) {
return null;
}
}

View File

@@ -0,0 +1,59 @@
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* Copyright 2000-2002 bob mcwhirter & James Strachan.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the Jaxen Project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
* This software consists of voluntary contributions made by many
* individuals on behalf of the Jaxen Project and was originally
* created by bob mcwhirter <bob@werken.com> and
* James Strachan <jstrachan@apache.org>. For more information on the
* Jaxen Project, please see <http://www.jaxen.org/>.
*
* $Id$
*/
/*
* Adapted from Jaxen version 1.2.0 as available at
* https://repo1.maven.org/maven2/jaxen/jaxen/1.2.0/jaxen-1.2.0-sources.jar
* Only relevant stubs of this file have been retained for test purposes.
*/
package org.jaxen;
public interface VariableContext {
public Object getVariableValue(String namespaceURI, String prefix, String localName);
}

View File

@@ -0,0 +1,73 @@
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* Copyright 2000-2002 bob mcwhirter & James Strachan.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the Jaxen Project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
* This software consists of voluntary contributions made by many
* individuals on behalf of the Jaxen Project and was originally
* created by bob mcwhirter <bob@werken.com> and
* James Strachan <jstrachan@apache.org>. For more information on the
* Jaxen Project, please see <http://www.jaxen.org/>.
*
* $Id$
*/
package org.jaxen.pattern;
public abstract class Pattern {
public double getPriority() {
return 0;
}
public Pattern[] getUnionPatterns() {
return null;
}
public short getMatchType() {
return 0;
}
public String getMatchesNodeName() {
return null;
}
public Pattern simplify() {
return null;
}
public abstract String getText();
}

View File

@@ -0,0 +1,14 @@
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}

View File

@@ -0,0 +1,25 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Cookies without <code>HttpOnly</code> flag are accessible to JavaScript running in the same origin. In case of
Cross-Site Scripting (XSS) vulnerability the cookie can be stolen by malicious script.</p>
</overview>
<recommendation>
<p>Protect sensitive cookies, such as those related to authentication, by setting <code>HttpOnly</code> to <code>true</code> to make
them not accessible to JavaScript.</p>
</recommendation>
<references>
<li>Production Best Practices: Security:<a href="https://expressjs.com/en/advanced/best-practice-security.html#use-cookies-securely">Use cookies securely</a>.</li>
<li>NodeJS security cheat sheet:<a href="https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#set-cookie-flags-appropriately">Set cookie flags appropriately</a>.</li>
<li>express-session:<a href="https://github.com/expressjs/session#cookiehttponly">cookie.httpOnly</a>.</li>
<li>cookie-session:<a href="https://github.com/expressjs/cookie-session#cookie-options">Cookie Options</a>.</li>
<li><a href="https://expressjs.com/en/api.html#res.cookie">express response.cookie</a>.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,20 @@
/**
* @name 'HttpOnly' attribute is not set to true
* @description Omitting the 'HttpOnly' attribute for security sensitive cookie data allows
* malicious JavaScript to steal it in case of XSS vulnerabilities. Always set
* 'HttpOnly' to 'true' for authentication related cookies to make them
* inaccessible from JavaScript.
* @kind problem
* @problem.severity warning
* @precision high
* @id js/cookie-httponly-not-set
* @tags security
* external/cwe/cwe-1004
*/
import javascript
import experimental.semmle.javascript.security.InsecureCookie::Cookie
from Cookie cookie
where cookie.isAuthNotHttpOnly()
select cookie, "Cookie attribute 'HttpOnly' is not set to true for this sensitive cookie."

View File

@@ -11,7 +11,7 @@
*/
import javascript
import InsecureCookie::Cookie
import experimental.semmle.javascript.security.InsecureCookie::Cookie
from Cookie cookie
where not cookie.isSecure()

View File

@@ -1,148 +0,0 @@
/**
* Provides classes for reasoning about cookies added to response without the 'secure' flag being set.
* A cookie without the 'secure' flag being set can be intercepted and read by a malicious user.
*/
import javascript
module Cookie {
/**
* `secure` property of the cookie options.
*/
string flag() { result = "secure" }
/**
* Abstract class to represent different cases of insecure cookie settings.
*/
abstract class Cookie extends DataFlow::Node {
/**
* Gets the name of the middleware/library used to set the cookie.
*/
abstract string getKind();
/**
* Gets the options used to set this cookie, if any.
*/
abstract DataFlow::Node getCookieOptionsArgument();
/**
* Holds if this cookie is secure.
*/
abstract predicate isSecure();
}
/**
* A cookie set using the `express` module `cookie-session` (https://github.com/expressjs/cookie-session).
*/
class InsecureCookieSession extends ExpressLibraries::CookieSession::MiddlewareInstance, Cookie {
override string getKind() { result = "cookie-session" }
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// The flag `secure` is set to `false` by default for HTTP, `true` by default for HTTPS (https://github.com/expressjs/cookie-session#cookie-options).
// A cookie is secure if the `secure` flag is not explicitly set to `false`.
not getCookieFlagValue(flag()).mayHaveBooleanValue(false)
}
}
/**
* A cookie set using the `express` module `express-session` (https://github.com/expressjs/session).
*/
class InsecureExpressSessionCookie extends ExpressLibraries::ExpressSession::MiddlewareInstance,
Cookie {
override string getKind() { result = "express-session" }
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// The flag `secure` is not set by default (https://github.com/expressjs/session#Cookieecure).
// The default value for cookie options is { path: '/', httpOnly: true, secure: false, maxAge: null }.
// A cookie is secure if there are the cookie options with the `secure` flag set to `true` or to `auto`.
getCookieFlagValue(flag()).mayHaveBooleanValue(true) or
getCookieFlagValue(flag()).mayHaveStringValue("auto")
}
}
/**
* A cookie set using `response.cookie` from `express` module (https://expressjs.com/en/api.html#res.cookie).
*/
class InsecureExpressCookieResponse extends Cookie, DataFlow::MethodCallNode {
InsecureExpressCookieResponse() { this.calls(any(Express::ResponseExpr r).flow(), "cookie") }
override string getKind() { result = "response.cookie" }
override DataFlow::SourceNode getCookieOptionsArgument() {
result = this.getLastArgument().getALocalSource()
}
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
getCookieFlagValue(flag()).mayHaveBooleanValue(true)
}
}
/**
* A cookie set using `Set-Cookie` header of an `HTTP` response (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie).
*/
class InsecureSetCookieHeader extends Cookie {
InsecureSetCookieHeader() {
this.asExpr() = any(HTTP::SetCookieHeader setCookie).getHeaderArgument()
}
override string getKind() { result = "set-cookie header" }
override DataFlow::Node getCookieOptionsArgument() {
result.asExpr() = this.asExpr().(ArrayExpr).getAnElement()
}
override predicate isSecure() {
// A cookie is secure if the 'secure' flag is specified in the cookie definition.
exists(string s |
getCookieOptionsArgument().mayHaveStringValue(s) and
s.regexpMatch("(.*;)?\\s*secure.*")
)
}
}
/**
* A cookie set using `js-cookie` library (https://github.com/js-cookie/js-cookie).
*/
class InsecureJsCookie extends Cookie {
InsecureJsCookie() {
this =
[
DataFlow::globalVarRef("Cookie"),
DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict"),
DataFlow::moduleImport("js-cookie")
].getAMemberCall("set")
}
override string getKind() { result = "js-cookie" }
override DataFlow::SourceNode getCookieOptionsArgument() {
result = this.(DataFlow::CallNode).getAnArgument().getALocalSource()
}
DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
getCookieFlagValue(flag()).mayHaveBooleanValue(true)
}
}
}

View File

@@ -0,0 +1,323 @@
/**
* Provides classes for reasoning about cookies added to response without the 'secure' or 'httponly' flag being set.
* - A cookie without the 'secure' flag being set can be intercepted and read by a malicious user.
* - A cookie without the 'httponly' flag being set can be read by maliciously injected JavaScript.
*/
import javascript
module Cookie {
/**
* `secure` property of the cookie options.
*/
string secureFlag() { result = "secure" }
/**
* `httpOnly` property of the cookie options.
*/
string httpOnlyFlag() { result = "httpOnly" }
/**
* Abstract class to represent different cases of insecure cookie settings.
*/
abstract class Cookie extends DataFlow::Node {
/**
* Gets the name of the middleware/library used to set the cookie.
*/
abstract string getKind();
/**
* Gets the options used to set this cookie, if any.
*/
abstract DataFlow::Node getCookieOptionsArgument();
/**
* Holds if this cookie is secure.
*/
abstract predicate isSecure();
/**
* Holds if this cookie is HttpOnly.
*/
abstract predicate isHttpOnly();
/**
* Holds if the cookie is authentication sensitive and lacks HttpOnly.
*/
abstract predicate isAuthNotHttpOnly();
}
/**
* Holds if the expression is a variable with a sensitive name.
*/
private predicate isAuthVariable(DataFlow::Node expr) {
exists(string val |
(
val = expr.getStringValue() or
val = expr.asExpr().(VarAccess).getName() or
val = expr.(DataFlow::PropRead).getPropertyName()
) and
regexpMatchAuth(val)
)
or
isAuthVariable(expr.getAPredecessor())
}
/**
* Holds if `val` looks related to authentication, without being an anti-forgery token.
*/
bindingset[val]
private predicate regexpMatchAuth(string val) {
val.regexpMatch("(?i).*(session|login|token|user|auth|credential).*") and
not val.regexpMatch("(?i).*(xsrf|csrf|forgery).*")
}
/**
* A cookie set using the `express` module `cookie-session` (https://github.com/expressjs/cookie-session).
*/
class InsecureCookieSession extends ExpressLibraries::CookieSession::MiddlewareInstance, Cookie {
override string getKind() { result = "cookie-session" }
override DataFlow::SourceNode getCookieOptionsArgument() { result.flowsTo(getArgument(0)) }
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// The flag `secure` is set to `false` by default for HTTP, `true` by default for HTTPS (https://github.com/expressjs/cookie-session#cookie-options).
// A cookie is secure if the `secure` flag is not explicitly set to `false`.
not getCookieFlagValue(secureFlag()).mayHaveBooleanValue(false)
}
override predicate isAuthNotHttpOnly() {
not isHttpOnly() // It is a session cookie, likely auth sensitive
}
override predicate isHttpOnly() {
// The flag `httpOnly` is set to `true` by default (https://github.com/expressjs/cookie-session#cookie-options).
// A cookie is httpOnly if the `httpOnly` flag is not explicitly set to `false`.
not getCookieFlagValue(httpOnlyFlag()).mayHaveBooleanValue(false)
}
}
/**
* A cookie set using the `express` module `express-session` (https://github.com/expressjs/session).
*/
class InsecureExpressSessionCookie extends ExpressLibraries::ExpressSession::MiddlewareInstance,
Cookie {
override string getKind() { result = "express-session" }
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// The flag `secure` is not set by default (https://github.com/expressjs/session#Cookiesecure).
// The default value for cookie options is { path: '/', httpOnly: true, secure: false, maxAge: null }.
// A cookie is secure if there are the cookie options with the `secure` flag set to `true` or to `auto`.
getCookieFlagValue(secureFlag()).mayHaveBooleanValue(true) or
getCookieFlagValue(secureFlag()).mayHaveStringValue("auto")
}
override predicate isAuthNotHttpOnly() {
not isHttpOnly() // It is a session cookie, likely auth sensitive
}
override predicate isHttpOnly() {
// The flag `httpOnly` is set by default (https://github.com/expressjs/session#Cookiesecure).
// The default value for cookie options is { path: '/', httpOnly: true, secure: false, maxAge: null }.
// A cookie is httpOnly if the `httpOnly` flag is not explicitly set to `false`.
not getCookieFlagValue(httpOnlyFlag()).mayHaveBooleanValue(false)
}
}
/**
* A cookie set using `response.cookie` from `express` module (https://expressjs.com/en/api.html#res.cookie).
*/
class InsecureExpressCookieResponse extends Cookie, DataFlow::MethodCallNode {
InsecureExpressCookieResponse() { this.calls(any(Express::ResponseExpr r).flow(), "cookie") }
override string getKind() { result = "response.cookie" }
override DataFlow::SourceNode getCookieOptionsArgument() {
result = this.getLastArgument().getALocalSource()
}
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
// The default is `false`.
getCookieFlagValue(secureFlag()).mayHaveBooleanValue(true)
}
override predicate isAuthNotHttpOnly() {
isAuthVariable(this.getArgument(0)) and
not isHttpOnly()
}
override predicate isHttpOnly() {
// A cookie is httpOnly if there are cookie options with the `httpOnly` flag set to `true`.
// The default is `false`.
getCookieFlagValue(httpOnlyFlag()).mayHaveBooleanValue(true)
}
}
private class AttributeToSetCookieHeaderTrackingConfig extends TaintTracking::Configuration {
AttributeToSetCookieHeaderTrackingConfig() { this = "AttributeToSetCookieHeaderTrackingConfig" }
override predicate isSource(DataFlow::Node source) {
exists(string s | source.mayHaveStringValue(s))
}
override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof TemplateLiteral }
}
private class SensitiveNameToSetCookieHeaderTrackingConfig extends TaintTracking::Configuration {
SensitiveNameToSetCookieHeaderTrackingConfig() {
this = "SensitiveNameToSetCookieHeaderTrackingConfig"
}
override predicate isSource(DataFlow::Node source) { isAuthVariable(source) }
override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof TemplateLiteral }
}
/**
* A cookie set using `Set-Cookie` header of an `HTTP` response.
* (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie).
* In case an array is passed `setHeader("Set-Cookie", [...]` it sets multiple cookies.
* Each array element has its own attributes.
*/
class InsecureSetCookieHeader extends Cookie {
InsecureSetCookieHeader() {
this.asExpr() = any(HTTP::SetCookieHeader setCookie).getHeaderArgument()
}
override string getKind() { result = "set-cookie header" }
override DataFlow::Node getCookieOptionsArgument() {
if this.asExpr() instanceof ArrayExpr
then result.asExpr() = this.asExpr().(ArrayExpr).getAnElement()
else result.asExpr() = this.asExpr()
}
/**
* A cookie is secure if the `secure` flag is specified in the cookie definition.
* The default is `false`.
*/
override predicate isSecure() { allHaveCookieAttribute("secure") }
/**
* A cookie is httpOnly if the `httpOnly` flag is specified in the cookie definition.
* The default is `false`.
*/
override predicate isHttpOnly() { allHaveCookieAttribute(httpOnlyFlag()) }
/**
* The predicate holds only if all elements have the specified attribute.
*/
bindingset[attribute]
private predicate allHaveCookieAttribute(string attribute) {
forall(DataFlow::Node n | n = getCookieOptionsArgument() |
exists(string s |
n.mayHaveStringValue(s) and
hasCookieAttribute(s, attribute)
)
or
exists(AttributeToSetCookieHeaderTrackingConfig cfg, DataFlow::Node source |
cfg.hasFlow(source, n) and
exists(string attr |
source.mayHaveStringValue(attr) and
attr.regexpMatch("(?i).*\\b" + attribute + "\\b.*")
)
)
)
}
/**
* The predicate holds only if any element has a sensitive name and
* doesn't have the `httpOnly` flag.
*/
override predicate isAuthNotHttpOnly() {
exists(DataFlow::Node n | n = getCookieOptionsArgument() |
exists(string s |
n.mayHaveStringValue(s) and
(
not hasCookieAttribute(s, httpOnlyFlag()) and
regexpMatchAuth(getCookieName(s))
)
)
or
not exists(AttributeToSetCookieHeaderTrackingConfig cfg, DataFlow::Node source |
cfg.hasFlow(source, n) and
exists(string attr |
source.mayHaveStringValue(attr) and
attr.regexpMatch("(?i).*\\b" + httpOnlyFlag() + "\\b.*")
)
) and
exists(SensitiveNameToSetCookieHeaderTrackingConfig cfg | cfg.hasFlow(_, n))
)
}
/**
* Gets cookie name from a `Set-Cookie` header value.
* The header value always starts with `<cookie-name>=<cookie-value>` optionally followed by attributes:
* `<cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly`
*/
bindingset[s]
private string getCookieName(string s) { result = s.regexpCapture("\\s*([^=\\s]*)\\s*=.*", 1) }
/**
* Holds if the `Set-Cookie` header value contains the specified attribute
* 1. The attribute is case insensitive
* 2. It always starts with a pair `<cookie-name>=<cookie-value>`.
* If the attribute is present there must be `;` after the pair.
* Other attributes like `Domain=`, `Path=`, etc. may come after the pair:
* `<cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly`
* See `https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie`
*/
bindingset[s, attribute]
private predicate hasCookieAttribute(string s, string attribute) {
s.regexpMatch("(?i).*;\\s*" + attribute + "\\s*;?.*$")
}
}
/**
* A cookie set using `js-cookie` library (https://github.com/js-cookie/js-cookie).
*/
class InsecureJsCookie extends Cookie {
InsecureJsCookie() {
this =
[
DataFlow::globalVarRef("Cookie"),
DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict"),
DataFlow::moduleImport("js-cookie")
].getAMemberCall("set")
}
override string getKind() { result = "js-cookie" }
override DataFlow::SourceNode getCookieOptionsArgument() {
result = this.(DataFlow::CallNode).getAnArgument().getALocalSource()
}
DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
getCookieFlagValue(secureFlag()).mayHaveBooleanValue(true)
}
override predicate isAuthNotHttpOnly() { none() }
override predicate isHttpOnly() { none() } // js-cookie is browser side library and doesn't support HttpOnly
}
}

View File

@@ -36,6 +36,14 @@ module ArrayTaintTracking {
succ = call
)
or
// `array.filter(x => x)` keeps the taint
call.(DataFlow::MethodCallNode).getMethodName() = "filter" and
pred = call.getReceiver() and
succ = call and
exists(DataFlow::FunctionNode callback | callback = call.getArgument(0).getAFunctionValue() |
callback.getParameter(0).getALocalUse() = callback.getAReturn()
)
or
// `array.reduce` with tainted value in callback
call.(DataFlow::MethodCallNode).getMethodName() = "reduce" and
pred = call.getArgument(0).(DataFlow::FunctionNode).getAReturn() and // Require the argument to be a closure to avoid spurious call/return flow

View File

@@ -5,27 +5,37 @@
*/
import javascript
private import semmle.javascript.internal.CachedStages
/**
* Gets a parameter that is a library input to a top-level package.
*/
cached
DataFlow::ParameterNode getALibraryInputParameter() {
Stages::Taint::ref() and
exists(int bound, DataFlow::FunctionNode func |
func = getAValueExportedByPackage().getABoundFunctionValue(bound) and
result = func.getParameter(any(int arg | arg >= bound))
)
}
private import NodeModuleResolutionImpl as NodeModule
/**
* Gets a value exported by the main module from a named `package.json` file.
* The value is either directly the `module.exports` value, a nested property of `module.exports`, or a method on an exported class.
*/
private DataFlow::Node getAValueExportedByPackage() {
// The base case, an export from a named `package.json` file.
result =
getAnExportFromModule(any(PackageJSON pack | exists(pack.getPackageName())).getMainModule())
or
// module.exports.bar.baz = result;
result = getAValueExportedByPackage().(DataFlow::PropWrite).getRhs()
or
// class Foo {
// bar() {} // <- result
// };
// module.exports = new Foo();
exists(DataFlow::SourceNode callee |
callee = getAValueExportedByPackage().(DataFlow::NewNode).getCalleeNode().getALocalSource()
|
@@ -36,20 +46,67 @@ private DataFlow::Node getAValueExportedByPackage() {
or
result = getAValueExportedByPackage().getALocalSource()
or
// Nested property reads.
result = getAValueExportedByPackage().(DataFlow::SourceNode).getAPropertyReference()
or
// module.exports.foo = require("./other-module.js");
exists(Module mod |
mod = getAValueExportedByPackage().getEnclosingExpr().(Import).getImportedModule()
|
result = getAnExportFromModule(mod)
)
or
// module.exports = class Foo {
// bar() {} // <- result
// static baz() {} // <- result
// constructor() {} // <- result
// };
exists(DataFlow::ClassNode cla | cla = getAValueExportedByPackage() |
result = cla.getAnInstanceMethod() or
result = cla.getAStaticMethod() or
result = cla.getConstructor()
)
or
// One shot closures that define a "factory" function.
// Recognizes the following pattern:
// ```Javascript
// (function (root, factory) {
// if (typeof define === 'function' && define.amd) {
// define('library-name', factory);
// } else if (typeof exports === 'object') {
// module.exports = factory();
// } else {
// root.libraryName = factory();
// }
// }(this, function () {
// ....
// }));
// ```
// Such files are not recognized as modules, so we manually use `NodeModule::resolveMainModule` to resolve the file against a `package.json` file.
exists(ImmediatelyInvokedFunctionExpr func, DataFlow::ParameterNode prev, int i |
prev.getName() = "factory" and
func.getParameter(i) = prev.getParameter() and
result = func.getInvocation().getArgument(i).flow().getAFunctionValue().getAReturn() and
DataFlow::globalVarRef("define").getACall().getArgument(1) = prev.getALocalUse() and
func.getFile() =
min(int j, File f |
f = NodeModule::resolveMainModule(any(PackageJSON pack | exists(pack.getPackageName())), j)
|
f order by j
)
)
or
// the exported value is a call to a unique callee
// ```JavaScript
// module.exports = foo();
// function foo() {
// return result;
// }
// ```
exists(DataFlow::CallNode call | call = getAValueExportedByPackage() |
result = unique( | | call.getCalleeNode().getAFunctionValue()).getAReturn()
)
or
// *****
// Common styles of transforming exported objects.
// *****

View File

@@ -255,7 +255,9 @@ module DataFlow {
* Holds if this node is annotated with the given named type,
* or is declared as a subtype thereof, or is a union or intersection containing such a type.
*/
cached
predicate hasUnderlyingType(string globalName) {
Stages::TypeTracking::ref() and
getType().hasUnderlyingType(globalName)
or
getFallbackTypeAnnotation().getAnUnderlyingType().hasQualifiedName(globalName)
@@ -265,7 +267,9 @@ module DataFlow {
* Holds if this node is annotated with the given named type,
* or is declared as a subtype thereof, or is a union or intersection containing such a type.
*/
cached
predicate hasUnderlyingType(string moduleName, string typeName) {
Stages::TypeTracking::ref() and
getType().hasUnderlyingType(moduleName, typeName)
or
getFallbackTypeAnnotation().getAnUnderlyingType().hasQualifiedName(moduleName, typeName)

View File

@@ -53,49 +53,11 @@ private module Cached {
predicate step(DataFlow::SourceNode pred, DataFlow::SourceNode succ, StepSummary summary) {
exists(DataFlow::Node mid | pred.flowsTo(mid) | StepSummary::smallstep(mid, succ, summary))
}
}
import Cached::Public
class OptionalPropertyName extends string {
OptionalPropertyName() { this instanceof PropertyName or this = "" }
}
/**
* INTERNAL: Use `TypeTracker` or `TypeBackTracker` instead.
*
* A description of a step on an inter-procedural data flow path.
*/
class StepSummary extends TStepSummary {
/** Gets a textual representation of this step summary. */
string toString() {
this instanceof LevelStep and result = "level"
or
this instanceof CallStep and result = "call"
or
this instanceof ReturnStep and result = "return"
or
exists(string prop | this = StoreStep(prop) | result = "store " + prop)
or
exists(string prop | this = LoadStep(prop) | result = "load " + prop)
or
exists(string prop | this = CopyStep(prop) | result = "copy " + prop)
or
exists(string fromProp, string toProp | this = LoadStoreStep(fromProp, toProp) |
result = "load " + fromProp + " and store to " + toProp
)
}
}
module StepSummary {
/**
* INTERNAL: Use `SourceNode.track()` or `SourceNode.backtrack()` instead.
*/
predicate step = Cached::step/3;
/**
* INTERNAL: Use `TypeBackTracker.smallstep()` instead.
*/
cached
predicate smallstep(DataFlow::Node pred, DataFlow::Node succ, StepSummary summary) {
// Flow through properties of objects
propertyFlowStep(pred, succ) and
@@ -194,3 +156,47 @@ module StepSummary {
)
}
}
import Cached::Public
class OptionalPropertyName extends string {
OptionalPropertyName() { this instanceof PropertyName or this = "" }
}
/**
* INTERNAL: Use `TypeTracker` or `TypeBackTracker` instead.
*
* A description of a step on an inter-procedural data flow path.
*/
class StepSummary extends TStepSummary {
/** Gets a textual representation of this step summary. */
string toString() {
this instanceof LevelStep and result = "level"
or
this instanceof CallStep and result = "call"
or
this instanceof ReturnStep and result = "return"
or
exists(string prop | this = StoreStep(prop) | result = "store " + prop)
or
exists(string prop | this = LoadStep(prop) | result = "load " + prop)
or
exists(string prop | this = CopyStep(prop) | result = "copy " + prop)
or
exists(string fromProp, string toProp | this = LoadStoreStep(fromProp, toProp) |
result = "load " + fromProp + " and store to " + toProp
)
}
}
module StepSummary {
/**
* INTERNAL: Use `SourceNode.track()` or `SourceNode.backtrack()` instead.
*/
predicate step = Cached::step/3;
/**
* INTERNAL: Use `TypeBackTracker.smallstep()` instead.
*/
predicate smallstep = Cached::smallstep/3;
}

View File

@@ -198,6 +198,10 @@ module Stages {
exists(any(DataFlow::TypeBackTracker t).prepend(_))
or
DataFlow::functionForwardingStep(_, _)
or
any(DataFlow::Node node).hasUnderlyingType(_)
or
any(DataFlow::Node node).hasUnderlyingType(_, _)
}
}
@@ -232,6 +236,8 @@ module Stages {
*/
cached
module Taint {
private import semmle.javascript.PackageExports as Exports
/**
* Always holds.
* Ensures that a predicate is evaluated as part of the Taint stage.
@@ -250,6 +256,8 @@ module Stages {
TaintTracking::heapStep(_, _)
or
exists(RemoteFlowSource r)
or
exists(Exports::getALibraryInputParameter())
}
}
}

View File

@@ -30,6 +30,7 @@
| lib/closure.js:4:6:4:7 | u* | Strings with many repetitions of 'u' can start matching anywhere after the start of the preceeding u*o |
| lib/lib.js:1:15:1:16 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
| lib/lib.js:8:3:8:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
| lib/sublib/factory.js:13:14:13:15 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
| polynomial-redos.js:7:24:7:26 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ |
| polynomial-redos.js:8:17:8:18 | * | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding *, * |
| polynomial-redos.js:9:19:9:21 | \\s* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s*\\n\\s* |

View File

@@ -11,6 +11,10 @@ nodes
| lib/lib.js:7:19:7:22 | name |
| lib/lib.js:8:13:8:16 | name |
| lib/lib.js:8:13:8:16 | name |
| lib/sublib/factory.js:12:26:12:29 | name |
| lib/sublib/factory.js:12:26:12:29 | name |
| lib/sublib/factory.js:13:24:13:27 | name |
| lib/sublib/factory.js:13:24:13:27 | name |
| polynomial-redos.js:5:6:5:32 | tainted |
| polynomial-redos.js:5:16:5:32 | req.query.tainted |
| polynomial-redos.js:5:16:5:32 | req.query.tainted |
@@ -166,6 +170,10 @@ edges
| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name |
| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name |
| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name |
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted |
@@ -307,6 +315,7 @@ edges
| lib/closure.js:4:5:4:17 | /u*o/.test(x) | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | This $@ that depends on $@ may run slow on strings with many repetitions of 'u'. | lib/closure.js:4:6:4:7 | u* | regular expression | lib/closure.js:3:21:3:21 | x | library input |
| lib/lib.js:4:2:4:18 | regexp.test(name) | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/lib.js:1:15:1:16 | a* | regular expression | lib/lib.js:3:28:3:31 | name | library input |
| lib/lib.js:8:2:8:17 | /f*g/.test(name) | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:8:3:8:4 | f* | regular expression | lib/lib.js:7:19:7:22 | name | library input |
| lib/sublib/factory.js:13:13:13:28 | /f*g/.test(name) | lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/sublib/factory.js:13:14:13:15 | f* | regular expression | lib/sublib/factory.js:12:26:12:29 | name | library input |
| polynomial-redos.js:7:2:7:34 | tainted ... /g, '') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:7:2:7:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:7:24:7:26 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:8:2:8:23 | tainted ... *, */) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:8:2:8:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:8:17:8:18 | * | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:9:2:9:34 | tainted ... g, ' ') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:9:2:9:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:9:19:9:21 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |

Some files were not shown because too many files have changed in this diff Show More