From b2571c8d638ff8fddf6acc887a874c4b675e4e9b Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Tue, 11 Sep 2018 11:28:50 +0200 Subject: [PATCH 01/29] C++: IR: Fix performance of value-init ranges On a snapshot of Postgres, evaluation of `getNextExplicitlyInitializedElementAfter#fff#antijoin_rhs#1` took forever, preventing the computation of the IR. I haven't been able to reproduce it with a small test case, but the implementation of `getNextExplicitlyInitializedElementAfter` was fragile because it called the inline predicate `ArrayAggregateLiteral.isInitialized`. It also seemed inefficient that `getNextExplicitlyInitializedElementAfter` was computed for many values of its parameters that were never needed by the caller. This commit replaces `getNextExplicitlyInitializedElementAfter` with a new predicate named `getEndOfValueInitializedRange`, which should have the same behavior but a more efficient implementation. It uses a helper predicate `getNextExplicitlyInitializedElementAfter`, which shares its name with the now-deleted predicate but has behavior that I think matches the name. --- .../raw/internal/TranslatedElement.qll | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 380efb6e924..f0bced00b59 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -270,7 +270,7 @@ newtype TTranslatedElement = not ignoreExpr(initList) and isFirstValueInitializedElementInRange(initList, elementIndex) and elementCount = - getNextExplicitlyInitializedElementAfter(initList, elementIndex) - + getEndOfValueInitializedRange(initList, elementIndex) - elementIndex } or // The initialization of a base class from within a constructor. @@ -322,23 +322,28 @@ newtype TTranslatedElement = /** * Gets the index of the first explicitly initialized element in `initList` - * whose index is greater than `afterElementIndex`. If there are no remaining - * explicitly initialized elements in `initList`, the result is the total number - * of elements in the array being initialized. + * whose index is greater than `afterElementIndex`, where `afterElementIndex` + * is a first value-initialized element in a value-initialized range in + * `initList`. If there are no remaining explicitly initialized elements in + * `initList`, the result is the total number of elements in the array being + * initialized. */ - private int getNextExplicitlyInitializedElementAfter( - ArrayAggregateLiteral initList, int afterElementIndex) { - if exists(int x | - x > afterElementIndex and - exists(initList.getElementExpr(x))) - then ( - if exists(initList.getElementExpr(afterElementIndex + 1)) - then result = afterElementIndex + 1 - else result = getNextExplicitlyInitializedElementAfter(initList, afterElementIndex+1)) - else - result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize() and - // required for binding - initList.isInitialized(afterElementIndex) +private int getEndOfValueInitializedRange(ArrayAggregateLiteral initList, int afterElementIndex) { + isFirstValueInitializedElementInRange(initList, afterElementIndex) and + not exists(getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)) and + result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize() +} + +/** + * Gets the index of the first explicitly initialized element in `initList` + * whose index is greater than `afterElementIndex`, where `afterElementIndex` + * is a first value-initialized element in a value-initialized range in + * `initList`. + */ +private int getNextExplicitlyInitializedElementAfter( + ArrayAggregateLiteral initList, int afterElementIndex) { + isFirstValueInitializedElementInRange(initList, afterElementIndex) and + result = min(int i | exists(initList.getElementExpr(i)) and i > afterElementIndex) } /** From bb499663954c54b617bc374c3175fb17f098f378 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Tue, 11 Sep 2018 15:19:18 +0200 Subject: [PATCH 02/29] C++: Fixup getEndOfValueInitializedRange --- .../cpp/ir/implementation/raw/internal/TranslatedElement.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index f0bced00b59..580dbe0f725 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -329,6 +329,8 @@ newtype TTranslatedElement = * initialized. */ private int getEndOfValueInitializedRange(ArrayAggregateLiteral initList, int afterElementIndex) { + result = getNextExplicitlyInitializedElementAfter(initList, afterElementIndex) + or isFirstValueInitializedElementInRange(initList, afterElementIndex) and not exists(getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)) and result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize() From df948ecbbc111d4e9bf7180b671af509b6d46824 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Tue, 11 Sep 2018 19:34:20 +0200 Subject: [PATCH 03/29] C++: IR: designated initializer test --- .../library-tests/ir/ir/PrintAST.expected | 32 +++++++++++++ .../ir/ir/aliased_ssa_ir.expected | 46 +++++++++++++++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 5 ++ .../test/library-tests/ir/ir/raw_ir.expected | 46 +++++++++++++++++++ .../ir/ir/ssa_block_count.expected | 1 + .../ir/ir/unaliased_ssa_ir.expected | 46 +++++++++++++++++++ 6 files changed, 176 insertions(+) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index a7da38c6d97..884abe554a6 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -6303,3 +6303,35 @@ ir.cpp: # 958| Type = int # 958| ValueCategory = prvalue(load) # 959| 8: return ... +# 961| designatedInit() -> int +# 961| params: +# 961| body: { ... } +# 962| 0: declaration +# 962| 0: definition of a1 +# 962| Type = int[1000] +# 962| init: initializer for a1 +# 962| expr: {...} +# 962| Type = int[1000] +# 962| ValueCategory = prvalue +# 962| 0: 10002 +# 962| Type = int +# 962| Value = 10002 +# 962| ValueCategory = prvalue +# 962| 1: 10900 +# 962| Type = int +# 962| Value = 10900 +# 962| ValueCategory = prvalue +# 963| 1: return ... +# 963| 0: access to array +# 963| Type = int +# 963| ValueCategory = prvalue(load) +# 963| 0: array to pointer conversion +# 963| Type = int * +# 963| ValueCategory = prvalue +# 963| expr: a1 +# 963| Type = int[1000] +# 963| ValueCategory = lvalue +# 963| 1: 900 +# 963| Type = int +# 963| Value = 900 +# 963| ValueCategory = prvalue diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected index b9a7b4f2403..5fbbec2afb7 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected @@ -3906,3 +3906,49 @@ ir.cpp: # 950| v0_65(void) = ReturnVoid : # 950| v0_66(void) = UnmodeledUse : mu* # 950| v0_67(void) = ExitFunction : + +# 961| designatedInit() -> int +# 961| Block 0 +# 961| v0_0(void) = EnterFunction : +# 961| mu0_1(unknown) = UnmodeledDefinition : +# 962| r0_2(glval) = VariableAddress[a1] : +# 962| r0_3(int) = Constant[0] : +# 962| r0_4(glval) = PointerAdd : r0_2, r0_3 +# 962| r0_5(unknown[8]) = Constant[0] : +# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5 +#-----| Goto -> Block 2 + +# 962| Block 1 +# 962| r1_0(int) = Constant[900] : +# 962| r1_1(glval) = PointerAdd : r0_2, r1_0 +# 962| r1_2(int) = Constant[10900] : +# 962| mu1_3(int) = Store : r1_1, r1_2 +# 962| r1_4(int) = Constant[901] : +# 962| r1_5(glval) = PointerAdd : r0_2, r1_4 +# 962| r1_6(unknown[396]) = Constant[0] : +# 962| mu1_7(unknown[396]) = Store : r1_5, r1_6 +#-----| Goto -> Block 2 + +# 963| Block 2 +# 963| r2_0(glval) = VariableAddress[#return] : +# 963| r2_1(glval) = VariableAddress[a1] : +# 963| r2_2(int *) = Convert : r2_1 +# 963| r2_3(int) = Constant[900] : +# 963| r2_4(int *) = PointerAdd[4] : r2_2, r2_3 +# 963| r2_5(int) = Load : r2_4, mu0_1 +# 963| m2_6(int) = Store : r2_0, r2_5 +# 961| r2_7(glval) = VariableAddress[#return] : +# 961| v2_8(void) = ReturnValue : r2_7, m2_6 +# 961| v2_9(void) = UnmodeledUse : mu* +# 961| v2_10(void) = ExitFunction : + +# 962| Block 3 +# 962| r3_0(int) = Constant[2] : +# 962| r3_1(glval) = PointerAdd : r0_2, r3_0 +# 962| r3_2(int) = Constant[10002] : +# 962| mu3_3(int) = Store : r3_1, r3_2 +# 962| r3_4(int) = Constant[3] : +# 962| r3_5(glval) = PointerAdd : r0_2, r3_4 +# 962| r3_6(unknown[3588]) = Constant[0] : +# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6 +#-----| Goto -> Block 2 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 05682c61db2..5490cd0f2d9 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -958,6 +958,11 @@ void OperatorNewArray(int n) { new int[n] { 0, 1, 2 }; } +int designatedInit() { + int a1[1000] = { [2] = 10002, [900] = 10900 }; + return a1[900]; +} + #if 0 void OperatorDelete() { delete static_cast(nullptr); // No destructor diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 0c361cfb374..5f5dc4d3f5d 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -3885,3 +3885,49 @@ ir.cpp: # 950| v0_65(void) = ReturnVoid : # 950| v0_66(void) = UnmodeledUse : mu* # 950| v0_67(void) = ExitFunction : + +# 961| designatedInit() -> int +# 961| Block 0 +# 961| v0_0(void) = EnterFunction : +# 961| mu0_1(unknown) = UnmodeledDefinition : +# 962| r0_2(glval) = VariableAddress[a1] : +# 962| r0_3(int) = Constant[0] : +# 962| r0_4(glval) = PointerAdd : r0_2, r0_3 +# 962| r0_5(unknown[8]) = Constant[0] : +# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5 +#-----| Goto -> Block 2 + +# 962| Block 1 +# 962| r1_0(int) = Constant[900] : +# 962| r1_1(glval) = PointerAdd : r0_2, r1_0 +# 962| r1_2(int) = Constant[10900] : +# 962| mu1_3(int) = Store : r1_1, r1_2 +# 962| r1_4(int) = Constant[901] : +# 962| r1_5(glval) = PointerAdd : r0_2, r1_4 +# 962| r1_6(unknown[396]) = Constant[0] : +# 962| mu1_7(unknown[396]) = Store : r1_5, r1_6 +#-----| Goto -> Block 2 + +# 963| Block 2 +# 963| r2_0(glval) = VariableAddress[#return] : +# 963| r2_1(glval) = VariableAddress[a1] : +# 963| r2_2(int *) = Convert : r2_1 +# 963| r2_3(int) = Constant[900] : +# 963| r2_4(int *) = PointerAdd[4] : r2_2, r2_3 +# 963| r2_5(int) = Load : r2_4, mu0_1 +# 963| mu2_6(int) = Store : r2_0, r2_5 +# 961| r2_7(glval) = VariableAddress[#return] : +# 961| v2_8(void) = ReturnValue : r2_7, mu0_1 +# 961| v2_9(void) = UnmodeledUse : mu* +# 961| v2_10(void) = ExitFunction : + +# 962| Block 3 +# 962| r3_0(int) = Constant[2] : +# 962| r3_1(glval) = PointerAdd : r0_2, r3_0 +# 962| r3_2(int) = Constant[10002] : +# 962| mu3_3(int) = Store : r3_1, r3_2 +# 962| r3_4(int) = Constant[3] : +# 962| r3_5(glval) = PointerAdd : r0_2, r3_4 +# 962| r3_6(unknown[3588]) = Constant[0] : +# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6 +#-----| Goto -> Block 2 diff --git a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected index 4bd31c2a64f..0ef298fee3d 100644 --- a/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected +++ b/cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected @@ -92,6 +92,7 @@ | IR: VarArgs | 1 | | IR: VirtualMemberFunction | 1 | | IR: WhileStatements | 4 | +| IR: designatedInit | 4 | | IR: min | 4 | | IR: operator= | 1 | | IR: ~Base | 1 | diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected index c26bcce5810..af2385fb03d 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected @@ -3906,3 +3906,49 @@ ir.cpp: # 950| v0_65(void) = ReturnVoid : # 950| v0_66(void) = UnmodeledUse : mu* # 950| v0_67(void) = ExitFunction : + +# 961| designatedInit() -> int +# 961| Block 0 +# 961| v0_0(void) = EnterFunction : +# 961| mu0_1(unknown) = UnmodeledDefinition : +# 962| r0_2(glval) = VariableAddress[a1] : +# 962| r0_3(int) = Constant[0] : +# 962| r0_4(glval) = PointerAdd : r0_2, r0_3 +# 962| r0_5(unknown[8]) = Constant[0] : +# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5 +#-----| Goto -> Block 2 + +# 962| Block 1 +# 962| r1_0(int) = Constant[900] : +# 962| r1_1(glval) = PointerAdd : r0_2, r1_0 +# 962| r1_2(int) = Constant[10900] : +# 962| mu1_3(int) = Store : r1_1, r1_2 +# 962| r1_4(int) = Constant[901] : +# 962| r1_5(glval) = PointerAdd : r0_2, r1_4 +# 962| r1_6(unknown[396]) = Constant[0] : +# 962| mu1_7(unknown[396]) = Store : r1_5, r1_6 +#-----| Goto -> Block 2 + +# 963| Block 2 +# 963| r2_0(glval) = VariableAddress[#return] : +# 963| r2_1(glval) = VariableAddress[a1] : +# 963| r2_2(int *) = Convert : r2_1 +# 963| r2_3(int) = Constant[900] : +# 963| r2_4(int *) = PointerAdd[4] : r2_2, r2_3 +# 963| r2_5(int) = Load : r2_4, mu0_1 +# 963| m2_6(int) = Store : r2_0, r2_5 +# 961| r2_7(glval) = VariableAddress[#return] : +# 961| v2_8(void) = ReturnValue : r2_7, m2_6 +# 961| v2_9(void) = UnmodeledUse : mu* +# 961| v2_10(void) = ExitFunction : + +# 962| Block 3 +# 962| r3_0(int) = Constant[2] : +# 962| r3_1(glval) = PointerAdd : r0_2, r3_0 +# 962| r3_2(int) = Constant[10002] : +# 962| mu3_3(int) = Store : r3_1, r3_2 +# 962| r3_4(int) = Constant[3] : +# 962| r3_5(glval) = PointerAdd : r0_2, r3_4 +# 962| r3_6(unknown[3588]) = Constant[0] : +# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6 +#-----| Goto -> Block 2 From 2b4da8d6a723d0b3a2515b9368e1aba61945c5ce Mon Sep 17 00:00:00 2001 From: Pavel Avgustinov Date: Fri, 14 Sep 2018 12:22:01 +0100 Subject: [PATCH 04/29] Parameter.qll: Tweak how effective declaration entries are computed With the new formulation, we can join on function and index at the same time, leading to significant performance gains on large code bases that use templates extensively. --- cpp/ql/src/semmle/code/cpp/Parameter.qll | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/Parameter.qll b/cpp/ql/src/semmle/code/cpp/Parameter.qll index 971a2f33f61..c6fc33b9355 100644 --- a/cpp/ql/src/semmle/code/cpp/Parameter.qll +++ b/cpp/ql/src/semmle/code/cpp/Parameter.qll @@ -68,10 +68,9 @@ class Parameter extends LocalScopeVariable, @parameter { */ private VariableDeclarationEntry getAnEffectiveDeclarationEntry() { if getFunction().isConstructedFrom(_) - then exists (Parameter prototype - | prototype = result.getVariable() and - prototype.getIndex() = getIndex() and - getFunction().isConstructedFrom(prototype.getFunction())) + then exists (Function prototypeInstantiation + | prototypeInstantiation.getParameter(getIndex()) = result.getVariable() and + getFunction().isConstructedFrom(prototypeInstantiation)) else result = getADeclarationEntry() } From b20fd3c0843c96dfabbd62f9a7659237bcc88cb0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 17 Sep 2018 11:31:10 +0100 Subject: [PATCH 05/29] JS: recognize res.sendfile as alias for res.sendFile in Express --- javascript/ql/src/semmle/javascript/frameworks/Express.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Express.qll b/javascript/ql/src/semmle/javascript/frameworks/Express.qll index 9e9b52d050e..c0163a143fe 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Express.qll @@ -785,7 +785,8 @@ module Express { override MethodCallExpr astNode; ResponseSendFileAsFileSystemAccess() { - asExpr().(MethodCallExpr).calls(any(ResponseExpr res), "sendFile") + exists (string name | name = "sendFile" or name = "sendfile" | + asExpr().(MethodCallExpr).calls(any(ResponseExpr res), name)) } override DataFlow::Node getAPathArgument() { From b633ee1bc4f6a4d8fface8e49c0ae30a6ed990e4 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Fri, 14 Sep 2018 14:23:31 +0200 Subject: [PATCH 06/29] C++: Add more tests of resolveClass These tests exercise the problematic cases where a variable can appear to have multiple types because of how we fail to account for qualified names when comparing type names. --- .../structs/compatible_cpp/b1.cpp | 6 ++++ .../compatible_cpp/compatible.expected | 3 ++ .../compatible_cpp/compatible_types.expected | 1 + .../pointerbasetype.expected | 9 ++++++ .../structs/incomplete_definition/x.cpp | 28 ++++++++++++++++++ .../structs/qualified_names/c1.cpp | 9 ++++++ .../structs/qualified_names/c2.cpp | 6 ++++ .../structs/qualified_names/decls.cpp | 5 ++++ .../structs/qualified_names/defs.cpp | 29 +++++++++++++++++++ .../structs/qualified_names/header.h | 3 ++ .../qualified_names/pointerBaseType.expected | 6 ++++ .../qualified_names/pointerBaseType.ql | 5 ++++ 12 files changed, 110 insertions(+) create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/c1.cpp create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/c2.cpp create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/decls.cpp create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/defs.cpp create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/header.h create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected create mode 100644 cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.ql diff --git a/cpp/ql/test/library-tests/structs/compatible_cpp/b1.cpp b/cpp/ql/test/library-tests/structs/compatible_cpp/b1.cpp index c7d839b4874..760147d60ff 100644 --- a/cpp/ql/test/library-tests/structs/compatible_cpp/b1.cpp +++ b/cpp/ql/test/library-tests/structs/compatible_cpp/b1.cpp @@ -24,3 +24,9 @@ class Damson { int damson_x; void foo(); }; + +namespace unrelated { + class AppleCompatible { + long apple_x; + }; +} diff --git a/cpp/ql/test/library-tests/structs/compatible_cpp/compatible.expected b/cpp/ql/test/library-tests/structs/compatible_cpp/compatible.expected index 4b631dde98b..326fea4210f 100644 --- a/cpp/ql/test/library-tests/structs/compatible_cpp/compatible.expected +++ b/cpp/ql/test/library-tests/structs/compatible_cpp/compatible.expected @@ -32,6 +32,9 @@ | b1.cpp:23:7:23:12 | Damson | 5 members | 2 locations | 1 | foo | | b1.cpp:23:7:23:12 | Damson | 5 members | 2 locations | 2 | operator= | | b1.cpp:23:7:23:12 | Damson | 5 members | 2 locations | 3 | operator= | +| b1.cpp:29:9:29:23 | AppleCompatible | 3 members | 1 locations | 0 | apple_x | +| b1.cpp:29:9:29:23 | AppleCompatible | 3 members | 1 locations | 1 | operator= | +| b1.cpp:29:9:29:23 | AppleCompatible | 3 members | 1 locations | 2 | operator= | | b2.cpp:2:7:2:21 | AppleCompatible | 3 members | 2 locations | 0 | apple_x | | b2.cpp:2:7:2:21 | AppleCompatible | 3 members | 2 locations | 1 | operator= | | b2.cpp:2:7:2:21 | AppleCompatible | 3 members | 2 locations | 2 | operator= | diff --git a/cpp/ql/test/library-tests/structs/compatible_cpp/compatible_types.expected b/cpp/ql/test/library-tests/structs/compatible_cpp/compatible_types.expected index df2a178f667..f9446f1b19a 100644 --- a/cpp/ql/test/library-tests/structs/compatible_cpp/compatible_types.expected +++ b/cpp/ql/test/library-tests/structs/compatible_cpp/compatible_types.expected @@ -10,6 +10,7 @@ | b1.cpp:11:7:11:22 | BananaCompatible | 0 | file://:0:0:0:0 | int | 1 types | | b1.cpp:16:7:16:12 | Cherry | 0 | file://:0:0:0:0 | int | 1 types | | b1.cpp:23:7:23:12 | Damson | 0 | file://:0:0:0:0 | int | 1 types | +| b1.cpp:29:9:29:23 | AppleCompatible | 0 | file://:0:0:0:0 | long | 1 types | | b2.cpp:2:7:2:21 | AppleCompatible | 0 | file://:0:0:0:0 | int | 1 types | | b2.cpp:9:7:9:22 | BananaCompatible | 0 | file://:0:0:0:0 | int | 1 types | | b2.cpp:14:7:14:12 | Cherry | 0 | file://:0:0:0:0 | short | 1 types | diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected b/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected index 98a672ad435..3efebf1a927 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected @@ -1,2 +1,11 @@ +| a.h:5:8:5:13 | cheese | x.cpp:6:10:6:12 | Foo | 3 | +| a.h:5:8:5:13 | cheese | x.cpp:12:9:12:11 | Foo | 3 | | a.h:5:8:5:13 | cheese | y.cpp:4:8:4:10 | Foo | 3 | | x.cpp:3:6:3:10 | bar_x | a.h:4:8:4:10 | Bar | 3 | +| x.cpp:19:6:19:10 | foo_x | x.cpp:6:10:6:12 | Foo | 3 | +| x.cpp:19:6:19:10 | foo_x | x.cpp:12:9:12:11 | Foo | 3 | +| x.cpp:19:6:19:10 | foo_x | y.cpp:4:8:4:10 | Foo | 3 | +| x.cpp:23:5:23:17 | templateField | x.cpp:6:10:6:12 | Foo | 3 | +| x.cpp:23:5:23:17 | templateField | x.cpp:12:9:12:11 | Foo | 3 | +| x.cpp:26:18:26:29 | template_foo | x.cpp:22:7:22:14 | Template | 3 | +| x.cpp:26:18:26:29 | template_foo | x.cpp:22:7:22:14 | Template | 3 | diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp b/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp index 5b2a352e3dd..ab5eb947455 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp @@ -1,3 +1,31 @@ #include "a.h" Bar *bar_x; + +namespace unrelated { + struct Foo { + short val; + }; +} + +struct ContainsAnotherFoo { + class Foo { + long val; + }; +}; + +// The type of `foo_x` should not refer to any of the above classes, none of +// which are named `Foo` in the global scope. +Foo *foo_x; + +template +class Template { + T templateField; +}; + +Template *template_foo; + +// Instantiation of the template with unrelated classes named `Foo` should not +// get mixed up with the instantiation above. +template class Template; +template class Template; diff --git a/cpp/ql/test/library-tests/structs/qualified_names/c1.cpp b/cpp/ql/test/library-tests/structs/qualified_names/c1.cpp new file mode 100644 index 00000000000..f7230370121 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/c1.cpp @@ -0,0 +1,9 @@ +#include "header.h" + +struct MultipleDefsButSameHeader { + int i; +}; + +struct OneDefInDifferentFile { + int i; +}; diff --git a/cpp/ql/test/library-tests/structs/qualified_names/c2.cpp b/cpp/ql/test/library-tests/structs/qualified_names/c2.cpp new file mode 100644 index 00000000000..be538056615 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/c2.cpp @@ -0,0 +1,6 @@ +#include "header.h" + +struct MultipleDefsButSameHeader { + char char1; + char char2; +}; diff --git a/cpp/ql/test/library-tests/structs/qualified_names/decls.cpp b/cpp/ql/test/library-tests/structs/qualified_names/decls.cpp new file mode 100644 index 00000000000..c6cde7b00b9 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/decls.cpp @@ -0,0 +1,5 @@ +namespace foo { + class C; + + C *x; +} diff --git a/cpp/ql/test/library-tests/structs/qualified_names/defs.cpp b/cpp/ql/test/library-tests/structs/qualified_names/defs.cpp new file mode 100644 index 00000000000..095f8412604 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/defs.cpp @@ -0,0 +1,29 @@ +namespace foo { + class C { + }; +} + +namespace bar { + class C { + }; +} + +class DefinedAndDeclared { +}; + +// Despite this declaration being present, the variable below is associated +// with the definition above rather than this declaration. +class DefinedAndDeclared; + +DefinedAndDeclared *definedAndDeclared; + +#include "header.h" + +// Because there are multiple definitions of `MultipleDefsButSameHeader`, the +// type of this variable will refer to the declaration in `header.h` rather +// than any of the definitions. +MultipleDefsButSameHeader *mdbsh; + +// Because there is only one definition of `OneDefInDifferentFile`, the type of +// this variable will refer to that definition. +OneDefInDifferentFile *odidf; diff --git a/cpp/ql/test/library-tests/structs/qualified_names/header.h b/cpp/ql/test/library-tests/structs/qualified_names/header.h new file mode 100644 index 00000000000..d410b0d3533 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/header.h @@ -0,0 +1,3 @@ +struct MultipleDefsButSameHeader; + +struct OneDefInDifferentFile; diff --git a/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected b/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected new file mode 100644 index 00000000000..6e86c7f5f12 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected @@ -0,0 +1,6 @@ +| decls.cpp:4:6:4:6 | x | defs.cpp:2:9:2:9 | C | +| decls.cpp:4:6:4:6 | x | defs.cpp:7:9:7:9 | C | +| defs.cpp:18:21:18:38 | definedAndDeclared | defs.cpp:11:7:11:24 | DefinedAndDeclared | +| defs.cpp:25:28:25:32 | mdbsh | c1.cpp:3:8:3:32 | MultipleDefsButSameHeader | +| defs.cpp:25:28:25:32 | mdbsh | c2.cpp:3:8:3:32 | MultipleDefsButSameHeader | +| defs.cpp:29:24:29:28 | odidf | c1.cpp:7:8:7:28 | OneDefInDifferentFile | diff --git a/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.ql b/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.ql new file mode 100644 index 00000000000..b2aeaee6348 --- /dev/null +++ b/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.ql @@ -0,0 +1,5 @@ +import cpp + +from Variable x +where exists(x.getFile().getRelativePath()) +select x, x.getType().(PointerType).getBaseType() From d7f442b0428ea119e2e70aa92c9361ab36e2eb8b Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Fri, 14 Sep 2018 14:21:44 +0200 Subject: [PATCH 07/29] C++: Force unique resolveClass results --- .../semmle/code/cpp/internal/ResolveClass.qll | 23 +++++++++++-------- .../pointerbasetype.expected | 10 +++----- .../qualified_names/pointerBaseType.expected | 6 ++--- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll b/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll index c3cde4c4346..76c5b473e43 100644 --- a/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll +++ b/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll @@ -1,23 +1,28 @@ import semmle.code.cpp.Type -/** Holds if `d` is a complete class named `name`. */ +pragma[noinline] +private string getTopLevelClassName(@usertype c) { + isClass(c) and + usertypes(c, result, _) +} + +/** Holds if `d` is a unique complete class named `name`. */ pragma[noinline] private predicate existsCompleteWithName(string name, @usertype d) { - isClass(d) and is_complete(d) and - usertypes(d, name, _) + name = getTopLevelClassName(d) and + strictcount(@usertype other | is_complete(other) and getTopLevelClassName(other) = name) = 1 } /** Holds if `c` is an incomplete class named `name`. */ pragma[noinline] private predicate existsIncompleteWithName(string name, @usertype c) { - isClass(c) and not is_complete(c) and - usertypes(c, name, _) + name = getTopLevelClassName(c) } /** - * Holds if `c` is an imcomplete class, and there exists a complete class `d` + * Holds if `c` is an imcomplete class, and there exists a unique complete class `d` * with the same name. */ private predicate hasCompleteTwin(@usertype c, @usertype d) { @@ -30,10 +35,8 @@ private predicate hasCompleteTwin(@usertype c, @usertype d) { import Cached cached private module Cached { /** - * If `c` is incomplete, and there exists a complete class with the same name, - * then the result is that complete class. Otherwise, the result is `c`. If - * multiple complete classes have the same name, this predicate may have - * multiple results. + * If `c` is incomplete, and there exists a unique complete class with the same name, + * then the result is that complete class. Otherwise, the result is `c`. */ cached @usertype resolveClass(@usertype c) { hasCompleteTwin(c, result) diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected b/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected index 3efebf1a927..3e8c8fd34c6 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected @@ -1,11 +1,7 @@ -| a.h:5:8:5:13 | cheese | x.cpp:6:10:6:12 | Foo | 3 | -| a.h:5:8:5:13 | cheese | x.cpp:12:9:12:11 | Foo | 3 | +| a.h:5:8:5:13 | cheese | a.h:2:8:2:10 | Foo | 0 | | a.h:5:8:5:13 | cheese | y.cpp:4:8:4:10 | Foo | 3 | | x.cpp:3:6:3:10 | bar_x | a.h:4:8:4:10 | Bar | 3 | -| x.cpp:19:6:19:10 | foo_x | x.cpp:6:10:6:12 | Foo | 3 | -| x.cpp:19:6:19:10 | foo_x | x.cpp:12:9:12:11 | Foo | 3 | -| x.cpp:19:6:19:10 | foo_x | y.cpp:4:8:4:10 | Foo | 3 | +| x.cpp:19:6:19:10 | foo_x | a.h:2:8:2:10 | Foo | 0 | | x.cpp:23:5:23:17 | templateField | x.cpp:6:10:6:12 | Foo | 3 | | x.cpp:23:5:23:17 | templateField | x.cpp:12:9:12:11 | Foo | 3 | -| x.cpp:26:18:26:29 | template_foo | x.cpp:22:7:22:14 | Template | 3 | -| x.cpp:26:18:26:29 | template_foo | x.cpp:22:7:22:14 | Template | 3 | +| x.cpp:26:18:26:29 | template_foo | x.cpp:22:7:22:14 | Template | 0 | diff --git a/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected b/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected index 6e86c7f5f12..1573f1c446e 100644 --- a/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected +++ b/cpp/ql/test/library-tests/structs/qualified_names/pointerBaseType.expected @@ -1,6 +1,4 @@ -| decls.cpp:4:6:4:6 | x | defs.cpp:2:9:2:9 | C | -| decls.cpp:4:6:4:6 | x | defs.cpp:7:9:7:9 | C | +| decls.cpp:4:6:4:6 | x | decls.cpp:2:9:2:9 | C | | defs.cpp:18:21:18:38 | definedAndDeclared | defs.cpp:11:7:11:24 | DefinedAndDeclared | -| defs.cpp:25:28:25:32 | mdbsh | c1.cpp:3:8:3:32 | MultipleDefsButSameHeader | -| defs.cpp:25:28:25:32 | mdbsh | c2.cpp:3:8:3:32 | MultipleDefsButSameHeader | +| defs.cpp:25:28:25:32 | mdbsh | header.h:1:8:1:32 | MultipleDefsButSameHeader | | defs.cpp:29:24:29:28 | odidf | c1.cpp:7:8:7:28 | OneDefInDifferentFile | From a7d897108ada5123a6447493085b9f5608fd90db Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Fri, 14 Sep 2018 15:07:25 +0200 Subject: [PATCH 08/29] C++: Exclude non-toplevel items from resolveClass Also exclude templates as their names are not canonical. The test changes in `isfromtemplateinstantiation/` are the inverses of what we got in 34c9892f7, which should be a good thing. --- .../semmle/code/cpp/internal/ResolveClass.qll | 5 ++++- .../pointerbasetype.expected | 3 +-- .../isfromtemplateinstantiation.expected | 19 ------------------- .../isfromuninstantiatedtemplate.expected | 11 ++++++----- 4 files changed, 11 insertions(+), 27 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll b/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll index 76c5b473e43..eaefc8196cc 100644 --- a/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll +++ b/cpp/ql/src/semmle/code/cpp/internal/ResolveClass.qll @@ -3,7 +3,10 @@ import semmle.code.cpp.Type pragma[noinline] private string getTopLevelClassName(@usertype c) { isClass(c) and - usertypes(c, result, _) + usertypes(c, result, _) and + not namespacembrs(_, c) and // not in a namespace + not member(_, _, c) and // not in some structure + not class_instantiation(c, _) // not a template instantiation } /** Holds if `d` is a unique complete class named `name`. */ diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected b/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected index 3e8c8fd34c6..801306a572a 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/pointerbasetype.expected @@ -1,7 +1,6 @@ -| a.h:5:8:5:13 | cheese | a.h:2:8:2:10 | Foo | 0 | | a.h:5:8:5:13 | cheese | y.cpp:4:8:4:10 | Foo | 3 | | x.cpp:3:6:3:10 | bar_x | a.h:4:8:4:10 | Bar | 3 | -| x.cpp:19:6:19:10 | foo_x | a.h:2:8:2:10 | Foo | 0 | +| x.cpp:19:6:19:10 | foo_x | y.cpp:4:8:4:10 | Foo | 3 | | x.cpp:23:5:23:17 | templateField | x.cpp:6:10:6:12 | Foo | 3 | | x.cpp:23:5:23:17 | templateField | x.cpp:12:9:12:11 | Foo | 3 | | x.cpp:26:18:26:29 | template_foo | x.cpp:22:7:22:14 | Template | 0 | diff --git a/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromtemplateinstantiation.expected b/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromtemplateinstantiation.expected index 4d2706e2e95..dc73e749a4c 100644 --- a/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromtemplateinstantiation.expected +++ b/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromtemplateinstantiation.expected @@ -116,32 +116,13 @@ | isfromtemplateinstantiation.cpp:134:29:134:29 | Outer::operator=(const Outer &) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:134:29:134:29 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:134:29:134:29 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(Inner &&) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(Inner &&) | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(const Inner &) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(const Inner &) | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(Inner &&) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(Inner &&) | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(const Inner &) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer::Inner::operator=(const Inner &) | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | | isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:135:31:135:35 | definition of Inner | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:136:7:136:7 | x | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:136:7:136:7 | x | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:136:7:136:7 | x | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | -| isfromtemplateinstantiation.cpp:137:7:137:7 | y | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | -| isfromtemplateinstantiation.cpp:137:7:137:7 | y | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | isfromtemplateinstantiation.cpp:137:7:137:7 | y | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | | load.cpp:13:7:13:7 | basic_text_iprimitive::basic_text_iprimitive(basic_text_iprimitive &&) | load.cpp:13:7:13:27 | basic_text_iprimitive | | load.cpp:13:7:13:7 | basic_text_iprimitive::basic_text_iprimitive(const basic_text_iprimitive &) | load.cpp:13:7:13:27 | basic_text_iprimitive | diff --git a/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected b/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected index 38fda5364ee..74a096dff1a 100644 --- a/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected +++ b/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected @@ -3,6 +3,7 @@ isFromUninstantiatedTemplate | file://:0:0:0:0 | 0 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass | | file://:0:0:0:0 | (int)... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass | | file://:0:0:0:0 | (int)... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass | +| file://:0:0:0:0 | Inner | file://:0:0:0:0 | Inner | | file://:0:0:0:0 | declaration of 1st parameter | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | file://:0:0:0:0 | declaration of 1st parameter | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer | | file://:0:0:0:0 | initializer for MyClassEnumConst | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass | @@ -433,15 +434,15 @@ isFromUninstantiatedTemplate | isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | I | T | DeclarationEntry | | | isfromtemplateinstantiation.cpp:135:31:135:31 | operator= | I | T | Declaration | | | isfromtemplateinstantiation.cpp:135:31:135:31 | operator= | I | T | Declaration | | -| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | I | T | Declaration | | +| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | | T | Declaration | | | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner | I | T | Declaration | | +| isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | | T | Definition | | | isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | I | T | Definition | | -| isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | I | T | Definition | | -| isfromtemplateinstantiation.cpp:136:7:136:7 | x | I | T | Declaration | | +| isfromtemplateinstantiation.cpp:136:7:136:7 | x | | T | Declaration | | | isfromtemplateinstantiation.cpp:136:7:136:7 | x | I | T | Declaration | | +| isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | | T | Definition | | | isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | I | T | Definition | | -| isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | I | T | Definition | | -| isfromtemplateinstantiation.cpp:137:7:137:7 | y | I | T | Declaration | | +| isfromtemplateinstantiation.cpp:137:7:137:7 | y | | T | Declaration | | | isfromtemplateinstantiation.cpp:137:7:137:7 | y | I | T | Declaration | | | isfromtemplateinstantiation.cpp:144:28:144:56 | incomplete_never_instantiated | | T | Declaration | | | isfromtemplateinstantiation.cpp:146:28:146:45 | never_instantiated | | T | Declaration | | From 7d69c8445371fff1effcb69f09c4c1bdf33d5a4b Mon Sep 17 00:00:00 2001 From: yh-semmle Date: Wed, 19 Sep 2018 11:04:21 -0400 Subject: [PATCH 09/29] Java: tweak some query metadata The severity of four queries is reduced to `warning`. --- java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql | 2 +- java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql | 2 +- java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql | 2 +- java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql b/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql index ffbe8f34429..eca0dc5f041 100644 --- a/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql +++ b/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql @@ -3,7 +3,7 @@ * @description If a synchronized method is overridden in a subclass, and the overriding method is * not synchronized, the thread-safety of the subclass may be broken. * @kind problem - * @problem.severity error + * @problem.severity warning * @precision very-high * @id java/non-sync-override * @tags reliability diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql index 5da821a7626..1fd9bddc7bf 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql @@ -3,7 +3,7 @@ * @description A resource that is opened for reading but not closed may cause a resource * leak. * @kind problem - * @problem.severity error + * @problem.severity warning * @precision high * @id java/input-resource-leak * @tags efficiency diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql index d2681cbb6d1..a2803d7525e 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql @@ -2,7 +2,7 @@ * @name Potential database resource leak * @description A database resource that is opened but not closed may cause a resource leak. * @kind problem - * @problem.severity error + * @problem.severity warning * @precision high * @id java/database-resource-leak * @tags correctness diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql index f0ce36cc821..f854c6c7ab6 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql @@ -3,7 +3,7 @@ * @description A resource that is opened for writing but not closed may cause a resource * leak. * @kind problem - * @problem.severity error + * @problem.severity warning * @precision high * @id java/output-resource-leak * @tags efficiency From b0ec929aaddf9e72b1380c0759ddfb1aefffff84 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 20 Sep 2018 16:16:32 -0700 Subject: [PATCH 10/29] Cast between semantically different integer types: HRESULT to/from a Boolean type. Closing the gap between Semmle and PreFast. Covers C6214, C6215, C6216, C6217, C6230 --- .gitignore | 4 + .../CWE/CWE-704/IncorrectTypeConversion.cpp | 7 ++ .../CWE/CWE-704/IncorrectTypeConversion.qhelp | 26 +++++++ .../CWE/CWE-704/IncorrectTypeConversion.ql | 30 ++++++++ .../CWE/CWE-704/IncorrectTypeConversion.cpp | 76 +++++++++++++++++++ .../CWE-704/IncorrectTypeConversion.expected | 6 ++ .../CWE/CWE-704/IncorrectTypeConversion.qlref | 1 + 7 files changed, 150 insertions(+) create mode 100644 cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp create mode 100644 cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.qhelp create mode 100644 cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref diff --git a/.gitignore b/.gitignore index 31f8ccd9abf..5fa8568d5b6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,7 @@ # qltest projects and artifacts */ql/test/**/*.testproj */ql/test/**/*.actual +/.vs/slnx.sqlite +/.vs/ql2/v15/Browse.VC.opendb +/.vs/ql2/v15/Browse.VC.db +/.vs/ProjectSettings.json diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp new file mode 100644 index 00000000000..bf711c9b288 --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp @@ -0,0 +1,7 @@ +LPMALLOC pMalloc; +HRESULT hr = CoGetMalloc(1, &pMalloc); + +if (!hr) +{ + // code ... +} diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.qhelp b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.qhelp new file mode 100644 index 00000000000..d441e368b20 --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.qhelp @@ -0,0 +1,26 @@ + + + + +

This query indicates that an HRESULT is being cast to a boolean type or vice versa.

+

The typical success value (S_OK) of an HRESULT equals 0. However, 0 indicates failure for a boolean type.

+

Casting an HRESULT to a boolean type and then using it in a test expression will yield an incorrect result.

+
+ + +

To check if a call that returns an HRESULT succeeded use the FAILED macro.

+
+ + +

In the following example, HRESULT is used in a test expression incorrectly as it may yield an incorrect result.

+ + +

To fix this issue, use the FAILED macro in the test expression.

+
+ + + + +
diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql new file mode 100644 index 00000000000..900ee6ace2f --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql @@ -0,0 +1,30 @@ +/** + * @name Cast between semantically different integer types: HRESULT to/from a Boolean type + * @description Cast between semantically different integer types: HRESULT to/from a Boolean type. + * Boolean types indicate success by a non-zero value, whereas success (S_OK) in HRESULT is indicated by a value of 0. + * Casting an HRESULT to/from a Boolean type and then using it in a test expression will yield an incorrect result. + * @kind problem + * @id cpp/incorrect-type-conversion + * @problem.severity error + * @precision high + * @tags security + * external/cwe/cwe-704 + * external/microsoft/C6214 + * external/microsoft/C6215 + * external/microsoft/C6216 + * external/microsoft/C6217 + * external/microsoft/C6230 + */ +import cpp + +from Expr e1, Cast e2, string msg +where e2 = e1.getConversion() and + exists ( Type t1, Type t2 | + t1 = e1.getType() and + t2 = e2.getType() and + ((t1.hasName("bool") or t1.hasName("BOOL")) and t2.hasName("HRESULT") or + (t2.hasName("bool") or t2.hasName("BOOL")) and t1.hasName("HRESULT") + )) + and if e2.isImplicit() then ( msg = "Implicit" ) + else ( msg = "Explicit" ) +select e1, msg + " conversion from " + e1.getType().toString() + " to " + e2.getType().toString() \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp new file mode 100644 index 00000000000..cb29d8cd742 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp @@ -0,0 +1,76 @@ +// winnt.h +typedef long HRESULT; +#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) +#define FAILED(hr) (((HRESULT)(hr)) < 0) + +// minwindef.h +typedef int BOOL; +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +// winerror.h +#define S_OK ((HRESULT)0L) +#define S_FALSE ((HRESULT)1L) +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL) + +HRESULT HresultFunction() +{ + return S_OK; +} + +BOOL BoolFunction() +{ + return FALSE; +} + +HRESULT IncorrectHresultFunction() +{ + return BoolFunction(); // BUG +} + +void IncorrectTypeConversionTest() { + HRESULT hr = HresultFunction(); + if ((BOOL)hr) // BUG + { + // ... + } + if (SUCCEEDED(hr)) // Correct Usage + { + // ... + } + + if (SUCCEEDED(BoolFunction())) // BUG + { + // ... + } + if (BoolFunction()) // Correct Usage + { + // ... + } + BOOL b = IncorrectHresultFunction(); // BUG + + hr = E_UNEXPECTED; + if (!hr) // BUG + { + // ... + } + if (!FAILED(hr)) // Correct Usage + { + // ... + } + + hr = S_FALSE; + if (hr) // Should fail + { + // ... + } + if (SUCCEEDED(hr)) // Correct Usage + { + // ... + } +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected new file mode 100644 index 00000000000..35c40158a77 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected @@ -0,0 +1,6 @@ +| IncorrectTypeConversion.cpp:33:9:33:20 | call to BoolFunction | Implicit conversion from BOOL to HRESULT | +| IncorrectTypeConversion.cpp:38:12:38:13 | hr | Explicit conversion from HRESULT to BOOL | +| IncorrectTypeConversion.cpp:47:6:47:30 | (...) | Explicit conversion from BOOL to HRESULT | +| IncorrectTypeConversion.cpp:55:11:55:34 | call to IncorrectHresultFunction | Implicit conversion from HRESULT to BOOL | +| IncorrectTypeConversion.cpp:58:7:58:8 | hr | Implicit conversion from HRESULT to bool | +| IncorrectTypeConversion.cpp:68:6:68:7 | hr | Implicit conversion from HRESULT to bool | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref new file mode 100644 index 00000000000..cd59f148bd0 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-704/incorrectTypeConversion.ql \ No newline at end of file From c7aa5c169be733ac28e8ba64b5655782d9e5ab7c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 21 Sep 2018 10:47:00 +0100 Subject: [PATCH 11/29] CPP: Add a test of placement new for AV Rule 79.ql. --- .../AV Rule 79/AV Rule 79.expected | 3 ++ .../4.10 Classes/AV Rule 79/PlacementNew.cpp | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected index 85f71ce6446..e50f3497697 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected @@ -11,5 +11,8 @@ | ExternalOwners.cpp:49:3:49:20 | ... = ... | Resource a is acquired by class MyScreen but not released anywhere in this class. | | ListDelete.cpp:21:3:21:21 | ... = ... | Resource first is acquired by class MyThingColection but not released anywhere in this class. | | NoDestructor.cpp:23:3:23:20 | ... = ... | Resource n is acquired by class MyClass5 but not released anywhere in this class. | +| PlacementNew.cpp:36:3:36:36 | ... = ... | Resource p1 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | +| PlacementNew.cpp:37:3:37:51 | ... = ... | Resource p2 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | +| PlacementNew.cpp:38:3:38:49 | ... = ... | Resource p3 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | | SelfRegistering.cpp:25:3:25:24 | ... = ... | Resource side is acquired by class MyOwner but not released anywhere in this class. | | Variants.cpp:23:3:23:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp new file mode 100644 index 00000000000..46704715498 --- /dev/null +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp @@ -0,0 +1,47 @@ + +typedef unsigned long size_t; + +namespace std +{ + using ::size_t; + struct nothrow_t {}; + extern const nothrow_t nothrow; +} + +// nothrow new +void* operator new(std::size_t size, const std::nothrow_t&) throw(); + +// placement new +void* operator new (std::size_t size, void* ptr) throw(); + +// --- + +class MyClassForPlacementNew +{ +public: + MyClassForPlacementNew(int _v) : v(_v) {} + ~MyClassForPlacementNew() {} + +private: + int v; +}; + +class MyTestForPlacementNew +{ +public: + MyTestForPlacementNew() + { + void *buffer_ptr = buffer; + + p1 = new MyClassForPlacementNew(1); // BAD: not released + p2 = new (std::nothrow) MyClassForPlacementNew(2); // BAD: not released + p3 = new (buffer_ptr) MyClassForPlacementNew(3); // GOOD: placement new, not an allocation [FALSE POSITIVE] + } + + ~MyTestForPlacementNew() + { + } + + MyClassForPlacementNew *p1, *p2, *p3; + char buffer[sizeof(MyClassForPlacementNew)]; +}; From 84f9900c8c0cf4224718a6f6563993d4623fd65a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 21 Sep 2018 10:53:42 +0100 Subject: [PATCH 12/29] CPP: Exclude placement new. --- cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql | 16 +++++++++++++++- .../4.10 Classes/AV Rule 79/AV Rule 79.expected | 2 -- .../jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql index 22ee7204b91..3e9c6b1cccf 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql @@ -125,7 +125,21 @@ class Resource extends MemberVariable { private Assignment getANew() { result.getLValue() = this.getAnAccess() and - (result.getRValue() instanceof NewExpr or result.getRValue() instanceof NewArrayExpr) and + ( + ( + result.getRValue() instanceof NewExpr and + + // exclude placement new and custom overloads as they + // may not conform to assumptions + not result.getRValue().(NewExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1 + ) or ( + result.getRValue() instanceof NewArrayExpr and + + // exclude placement new and custom overloads as they + // may not conform to assumptions + not result.getRValue().(NewArrayExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1 + ) + ) and this.inSameClass(result) } diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected index e50f3497697..2aad28d2c4e 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected @@ -12,7 +12,5 @@ | ListDelete.cpp:21:3:21:21 | ... = ... | Resource first is acquired by class MyThingColection but not released anywhere in this class. | | NoDestructor.cpp:23:3:23:20 | ... = ... | Resource n is acquired by class MyClass5 but not released anywhere in this class. | | PlacementNew.cpp:36:3:36:36 | ... = ... | Resource p1 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | -| PlacementNew.cpp:37:3:37:51 | ... = ... | Resource p2 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | -| PlacementNew.cpp:38:3:38:49 | ... = ... | Resource p3 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | | SelfRegistering.cpp:25:3:25:24 | ... = ... | Resource side is acquired by class MyOwner but not released anywhere in this class. | | Variants.cpp:23:3:23:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp index 46704715498..c7794857cb9 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/PlacementNew.cpp @@ -34,8 +34,8 @@ public: void *buffer_ptr = buffer; p1 = new MyClassForPlacementNew(1); // BAD: not released - p2 = new (std::nothrow) MyClassForPlacementNew(2); // BAD: not released - p3 = new (buffer_ptr) MyClassForPlacementNew(3); // GOOD: placement new, not an allocation [FALSE POSITIVE] + p2 = new (std::nothrow) MyClassForPlacementNew(2); // BAD: not released [NOT DETECTED] + p3 = new (buffer_ptr) MyClassForPlacementNew(3); // GOOD: placement new, not an allocation } ~MyTestForPlacementNew() From 6f109a742f8f120165914c198e37892038c2b6b1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 21 Sep 2018 11:04:33 +0100 Subject: [PATCH 13/29] JS: add a test case for res.sendfile --- .../ql/test/query-tests/Security/CWE-022/TaintedPath.expected | 1 + .../ql/test/query-tests/Security/CWE-022/tainted-sendFile.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index 5abd47e9abb..418873e5c6f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -25,4 +25,5 @@ | tainted-array-steps.js:15:29:15:43 | parts.join('/') | This path depends on $@. | tainted-array-steps.js:9:24:9:30 | req.url | a user-provided value | | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | a user-provided value | +| tainted-sendFile.js:9:16:9:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | a user-provided value | | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js b/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js index be465c8d5ef..e925f6c566b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js @@ -5,4 +5,6 @@ var app = express(); app.get('/some/path', function(req, res) { // BAD: sending a file based on un-sanitized query parameters res.sendFile(req.param("gimme")); + // BAD: same as above + res.sendfile(req.param("gimme")); }); From 5f467d2fc518034ebdd08b81813fc7c86f981c70 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 21 Sep 2018 13:15:17 +0100 Subject: [PATCH 14/29] JS: recognize CSRF middleware from lusca package --- .../Security/CWE-352/MissingCsrfMiddleware.ql | 11 ++++--- .../CWE-352/MissingCsrfMiddleware.expected | 3 ++ .../Security/CWE-352/lusca_example.js | 33 +++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js diff --git a/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql b/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql index 9aec09aa6b6..554f0f31095 100644 --- a/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql +++ b/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql @@ -38,12 +38,15 @@ predicate hasCookieMiddleware(Express::RouteHandlerExpr expr, Express::RouteHand * // protected from CSRF * }) * ``` - * - * Currently the predicate only detects `csurf`-based protectors. */ DataFlow::CallNode csrfMiddlewareCreation() { - exists (DataFlow::ModuleImportNode mod | result = mod.getACall() | - mod.getPath() = "csurf" + exists (DataFlow::SourceNode callee | result = callee.getACall() | + callee = DataFlow::moduleImport("csurf") + or + callee = DataFlow::moduleImport("lusca") and + result.getOptionArgument(0, "csrf").analyze().getABooleanValue() = true // any truthy value will enable CSRF + or + callee = DataFlow::moduleMember("lusca", "csrf") ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected b/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected index 974dd70fc55..dcdbcc9d4b5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected +++ b/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected @@ -1,3 +1,6 @@ | MissingCsrfMiddlewareBad.js:7:9:7:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | MissingCsrfMiddlewareBad.js:10:26:11:1 | functio ... es) {\\n} | here | | csurf_api_example.js:39:37:39:50 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | csurf_api_example.js:39:53:41:3 | functio ... e')\\n } | here | | csurf_example.js:18:9:18:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | csurf_example.js:29:40:31:1 | functio ... sed')\\n} | here | +| lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:23:42:25:1 | functio ... sed')\\n} | here | +| lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:27:55:29:1 | functio ... sed')\\n} | here | +| lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:31:40:33:1 | functio ... sed')\\n} | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js b/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js new file mode 100644 index 00000000000..51d963ed6af --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js @@ -0,0 +1,33 @@ +var express = require('express') +var cookieParser = require('cookie-parser') +var bodyParser = require('body-parser') + +var parseForm = bodyParser.urlencoded({ extended: false }) +var lusca = require('lusca'); + +var app = express() +app.use(cookieParser()) + +app.post('/process', parseForm, lusca.csrf(), function (req, res) { // OK + res.send('data is being processed') +}) + +app.post('/process', parseForm, lusca({csrf:true}), function (req, res) { // OK + res.send('data is being processed') +}) + +app.post('/process', parseForm, lusca({csrf:{}}), function (req, res) { // OK + res.send('data is being processed') +}) + +app.post('/process', parseForm, lusca(), function (req, res) { // NOT OK - missing csrf option + res.send('data is being processed') +}) + +app.post('/process', parseForm, lusca({csrf: false}), function (req, res) { // NOT OK - csrf disabled + res.send('data is being processed') +}) + +app.post('/process_unsafe', parseForm, function (req, res) { // NOT OK + res.send('data is being processed') +}) From d2a04d32be953f2806abca0279e632978c8ac6e6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 21 Sep 2018 13:20:02 +0100 Subject: [PATCH 15/29] JS: add change note --- change-notes/1.19/analysis-javascript.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index 4415af95d30..d86866c78d3 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -22,5 +22,6 @@ | Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. | | Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. | | Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. | +| Missing CSRF middleware | Fewer false-positive results | This rule now recognizes CSRF middleware from the [lusca](https://www.npmjs.com/package/lusca) package. | ## Changes to QL libraries From 4797924bea1731b637a9b8c78f646e5f4fe9036f Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 21 Sep 2018 14:41:00 +0100 Subject: [PATCH 16/29] JS: review comments --- change-notes/1.19/analysis-javascript.md | 2 +- javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql | 2 +- .../Security/CWE-352/MissingCsrfMiddleware.expected | 3 +-- .../ql/test/query-tests/Security/CWE-352/lusca_example.js | 4 ---- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index d86866c78d3..82077d8a8e4 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -22,6 +22,6 @@ | Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. | | Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. | | Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. | -| Missing CSRF middleware | Fewer false-positive results | This rule now recognizes CSRF middleware from the [lusca](https://www.npmjs.com/package/lusca) package. | +| Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. | ## Changes to QL libraries diff --git a/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql b/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql index 554f0f31095..9a1a3e1aa88 100644 --- a/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql +++ b/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql @@ -44,7 +44,7 @@ DataFlow::CallNode csrfMiddlewareCreation() { callee = DataFlow::moduleImport("csurf") or callee = DataFlow::moduleImport("lusca") and - result.getOptionArgument(0, "csrf").analyze().getABooleanValue() = true // any truthy value will enable CSRF + exists(result.getOptionArgument(0, "csrf")) or callee = DataFlow::moduleMember("lusca", "csrf") ) diff --git a/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected b/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected index dcdbcc9d4b5..6e063b6454b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected +++ b/javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddleware.expected @@ -2,5 +2,4 @@ | csurf_api_example.js:39:37:39:50 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | csurf_api_example.js:39:53:41:3 | functio ... e')\\n } | here | | csurf_example.js:18:9:18:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | csurf_example.js:29:40:31:1 | functio ... sed')\\n} | here | | lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:23:42:25:1 | functio ... sed')\\n} | here | -| lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:27:55:29:1 | functio ... sed')\\n} | here | -| lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:31:40:33:1 | functio ... sed')\\n} | here | +| lusca_example.js:9:9:9:22 | cookieParser() | This cookie middleware is serving a request handler $@ without CSRF protection. | lusca_example.js:27:40:29:1 | functio ... sed')\\n} | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js b/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js index 51d963ed6af..ee91d060dd1 100644 --- a/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js +++ b/javascript/ql/test/query-tests/Security/CWE-352/lusca_example.js @@ -24,10 +24,6 @@ app.post('/process', parseForm, lusca(), function (req, res) { // NOT OK - missi res.send('data is being processed') }) -app.post('/process', parseForm, lusca({csrf: false}), function (req, res) { // NOT OK - csrf disabled - res.send('data is being processed') -}) - app.post('/process_unsafe', parseForm, function (req, res) { // NOT OK res.send('data is being processed') }) From d5a48ad63e8462df70bb4471455de1cb40896a2c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 21 Sep 2018 15:45:21 +0100 Subject: [PATCH 17/29] CPP: Additional test cases. --- .../AV Rule 79/AV Rule 79.expected | 4 +- .../jsf/4.10 Classes/AV Rule 79/Variants.cpp | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected index 2aad28d2c4e..6c8715afb56 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected @@ -13,4 +13,6 @@ | NoDestructor.cpp:23:3:23:20 | ... = ... | Resource n is acquired by class MyClass5 but not released anywhere in this class. | | PlacementNew.cpp:36:3:36:36 | ... = ... | Resource p1 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | | SelfRegistering.cpp:25:3:25:24 | ... = ... | Resource side is acquired by class MyOwner but not released anywhere in this class. | -| Variants.cpp:23:3:23:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | +| Variants.cpp:25:3:25:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | +| Variants.cpp:65:3:65:17 | ... = ... | Resource a is acquired by class MyClass6 but not released anywhere in this class. | +| Variants.cpp:66:3:66:36 | ... = ... | Resource b is acquired by class MyClass6 but not released anywhere in this class. | diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp index bbbfab1fc92..5f4cc89da54 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp @@ -2,6 +2,8 @@ // library typedef unsigned int size_t; void *malloc(size_t size); +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); void free(void* ptr); int *ID(int *x) @@ -34,3 +36,40 @@ public: int *a, *b, *c, *d, *e, *f, *g; }; + +class MyClass5 +{ +public: + MyClass5() + { + a = new int[10]; // GOOD + b = (int *)calloc(10, sizeof(int)); // GOOD + c = (int *)realloc(0, 10 * sizeof(int)); // GOOD + } + + ~MyClass5() + { + delete [] a; + free(b); + free(c); + } + + int *a, *b, *c; +}; + +class MyClass6 +{ +public: + MyClass6() + { + a = new int[10]; // BAD + b = (int *)calloc(10, sizeof(int)); // BAD + c = (int *)realloc(0, 10 * sizeof(int)); // BAD [NOT DETECTED] + } + + ~MyClass6() + { + } + + int *a, *b, *c; +}; From 783be15a45939dd04c825dc723b40ac9e2494730 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 21 Sep 2018 11:14:14 -0700 Subject: [PATCH 18/29] Fixing typos & ID. NOTE: There is an ongoing discussion on the proper CWE we should use --- cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql | 2 +- .../Security/CWE/CWE-704/IncorrectTypeConversion.cpp | 2 +- .../Security/CWE/CWE-704/IncorrectTypeConversion.qlref | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql index 900ee6ace2f..0ff7502d9a9 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql @@ -4,7 +4,7 @@ * Boolean types indicate success by a non-zero value, whereas success (S_OK) in HRESULT is indicated by a value of 0. * Casting an HRESULT to/from a Boolean type and then using it in a test expression will yield an incorrect result. * @kind problem - * @id cpp/incorrect-type-conversion + * @id cpp/hresult-to-boolean-conversion * @problem.severity error * @precision high * @tags security diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp index cb29d8cd742..8ecab54b4df 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp @@ -65,7 +65,7 @@ void IncorrectTypeConversionTest() { } hr = S_FALSE; - if (hr) // Should fail + if (hr) // BUG { // ... } diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref index cd59f148bd0..56b47b192d7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref @@ -1 +1 @@ -Security/CWE/CWE-704/incorrectTypeConversion.ql \ No newline at end of file +Security/CWE/CWE-704/IncorrectTypeConversion.ql \ No newline at end of file From 3922082e7dbb02e109ffb4d94d1fa2c1eb4c65ba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 21 Sep 2018 13:08:49 +0100 Subject: [PATCH 19/29] CPP: Tidy and simplify AV Rule 79.ql. --- cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql | 147 +++++++++--------- .../AV Rule 79/AV Rule 79.expected | 1 + .../jsf/4.10 Classes/AV Rule 79/Variants.cpp | 2 +- 3 files changed, 75 insertions(+), 75 deletions(-) diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql index 3e9c6b1cccf..853285050a4 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql @@ -10,33 +10,69 @@ * external/cwe/cwe-404 */ import cpp +import Critical.NewDelete -// List pairs of functions that do resource acquisition/release -// Extend this to add custom function pairs. As written the query -// will only apply if the resource is the *return value* of the -// first call and a *parameter* to the second. Other cases should -// be handled differently. -predicate resourceManagementPair(string acquire, string release) { - - (acquire = "fopen" and release = "fclose") - or - (acquire = "open" and release = "close") - or - (acquire = "socket" and release = "close") - +/** + * An expression that acquires a resource, and the kind of resource that is acquired. The + * kind of a resource indicates which acquisition/release expressions can be paired. + */ +predicate acquireExpr(Expr acquire, string kind) { + exists(FunctionCall fc, Function f, string name | + fc = acquire and + f = fc.getTarget() and + name = f.getName() and + ( + ( + name = "fopen" and + kind = "file" + ) or ( + name = "open" and + kind = "file descriptor" + ) or ( + name = "socket" and + kind = "file descriptor" + ) + ) + ) or ( + allocExpr(acquire, kind) + ) } -// List functions that return malloc-allocated memory. Customize -// to list your own functions there -predicate mallocFunction(Function malloc) { - malloc.hasName("malloc") or malloc.hasName("calloc") or // Not realloc: doesn't acquire it, really - malloc.hasName("strdup") -} - -private predicate isRelease(string release) { - resourceManagementPair(_, release) or - release = "free" or - release = "delete" +/** + * An expression that releases a resource, and the kind of resource that is released. The + * kind of a resource indicates which acquisition/release expressions can be paired. + */ +predicate releaseExpr(Expr release, Expr resource, string kind) { + exists(FunctionCall fc, Function f, string name | + fc = release and + f = fc.getTarget() and + name = f.getName() and + ( + ( + name = "fclose" and + resource = fc.getArgument(0) and + kind = "file" + ) or ( + name = "close" and + resource = fc.getArgument(0) and + kind = "file descriptor" + ) + ) + ) or exists(string releaseKind | + freeExpr(release, resource, releaseKind) and + ( + ( + kind = "malloc" and + releaseKind = "free" + ) or ( + kind = "new" and + releaseKind = "delete" + ) or ( + kind = "new[]" and + releaseKind = "delete[]" + ) + ) + ) } /** @@ -52,35 +88,23 @@ Expr exprOrDereference(Expr e) { * Holds if the expression `e` releases expression `released`, whether directly * or via one or more function call(s). */ -private predicate exprReleases(Expr e, Expr released, string releaseType) { +private predicate exprReleases(Expr e, Expr released, string kind) { ( - // `e` is a call to a release function and `released` is any argument - e.(FunctionCall).getTarget().getName() = releaseType and - isRelease(releaseType) and - e.(FunctionCall).getAnArgument() = released - ) or ( - // `e` is a call to `delete` and `released` is the target - e.(DeleteExpr).getExpr() = released and - releaseType = "delete" - ) or ( - // `e` is a call to `delete[]` and `released` is the target - e.(DeleteArrayExpr).getExpr() = released and - releaseType = "delete" + // `e` is a call to a release function and `released` is the released argument + releaseExpr(e, released, kind) ) or exists(Function f, int arg | // `e` is a call to a function that releases one of it's parameters, // and `released` is the corresponding argument e.(FunctionCall).getTarget() = f and e.(FunctionCall).getArgument(arg) = released and - exprReleases(_, exprOrDereference(f.getParameter(arg).getAnAccess()), releaseType) - ) or exists(Function f, Expr innerThis | + exprReleases(_, exprOrDereference(f.getParameter(arg).getAnAccess()), kind) + ) or exists(Function f, ThisExpr innerThis | // `e` is a call to a method that releases `this`, and `released` // is the object that is called e.(FunctionCall).getTarget() = f and e.(FunctionCall).getQualifier() = exprOrDereference(released) and innerThis.getEnclosingFunction() = f and - exprReleases(_, innerThis, releaseType) and - innerThis instanceof ThisExpr and - releaseType = "delete" + exprReleases(_, innerThis, kind) ) } @@ -109,42 +133,17 @@ class Resource extends MemberVariable { ) } - predicate acquisitionWithRequiredRelease(Expr acquire, string releaseName) { - acquire.(Assignment).getLValue() = this.getAnAccess() and + predicate acquisitionWithRequiredRelease(Assignment acquireAssign, string kind) { + // acquireAssign is an assignment to this resource + acquireAssign.(Assignment).getLValue() = this.getAnAccess() and // Should be in this class, but *any* member method will do - this.inSameClass(acquire) and + this.inSameClass(acquireAssign) and // Check that it is an acquisition function and return the corresponding free - ( - exists(Function f | f = acquire.(Assignment).getRValue().(FunctionCall).getTarget() and - (resourceManagementPair(f.getName(), releaseName) or (mallocFunction(f) and (releaseName = "free" or releaseName = "delete"))) - ) - or - (acquire = this.getANew() and releaseName = "delete") - ) + acquireExpr(acquireAssign.getRValue(), kind) } - private Assignment getANew() { - result.getLValue() = this.getAnAccess() and - ( - ( - result.getRValue() instanceof NewExpr and - - // exclude placement new and custom overloads as they - // may not conform to assumptions - not result.getRValue().(NewExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1 - ) or ( - result.getRValue() instanceof NewArrayExpr and - - // exclude placement new and custom overloads as they - // may not conform to assumptions - not result.getRValue().(NewArrayExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1 - ) - ) and - this.inSameClass(result) - } - - Expr getAReleaseExpr(string releaseName) { - exprReleases(result, this.getAnAccess(), releaseName) + Expr getAReleaseExpr(string kind) { + exprReleases(result, this.getAnAccess(), kind) } } diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected index 6c8715afb56..eed2f14a99f 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected @@ -16,3 +16,4 @@ | Variants.cpp:25:3:25:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | | Variants.cpp:65:3:65:17 | ... = ... | Resource a is acquired by class MyClass6 but not released anywhere in this class. | | Variants.cpp:66:3:66:36 | ... = ... | Resource b is acquired by class MyClass6 but not released anywhere in this class. | +| Variants.cpp:67:3:67:41 | ... = ... | Resource c is acquired by class MyClass6 but not released anywhere in this class. | diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp index 5f4cc89da54..dbeee230de4 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp @@ -64,7 +64,7 @@ public: { a = new int[10]; // BAD b = (int *)calloc(10, sizeof(int)); // BAD - c = (int *)realloc(0, 10 * sizeof(int)); // BAD [NOT DETECTED] + c = (int *)realloc(0, 10 * sizeof(int)); // BAD } ~MyClass6() From 492d79ea53cc972983fb8316e24a11247e104e70 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 21 Sep 2018 21:13:37 +0100 Subject: [PATCH 20/29] CPP: Change note. --- change-notes/1.19/analysis-cpp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index 17a165e5928..7fcf1fd234c 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -12,7 +12,7 @@ | **Query** | **Expected impact** | **Change** | |----------------------------|------------------------|------------------------------------------------------------------| -| *@name of query (Query ID)*| *Impact on results* | *How/why the query has changed* | +| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. | ## Changes to QL libraries From 242ee108064707f05250b15667f719ca286fa109 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 21 Sep 2018 16:47:31 -0700 Subject: [PATCH 21/29] Major change in order to support the rule for C as well as cpp --- .gitignore | 3 + .../HResultBooleanConversion.cpp} | 2 +- .../HResultBooleanConversion.qhelp} | 0 .../CWE/CWE-253/HResultBooleanConversion.ql | 71 +++++++++++++ .../CWE/CWE-704/IncorrectTypeConversion.ql | 30 ------ .../CWE/CWE-253/HResultBooleanConversion.c | 100 ++++++++++++++++++ .../CWE/CWE-253/HResultBooleanConversion.cpp | 97 +++++++++++++++++ .../CWE-253/HResultBooleanConversion.expected | 20 ++++ .../CWE-253/HResultBooleanConversion.qlref | 1 + .../CWE/CWE-704/IncorrectTypeConversion.cpp | 76 ------------- .../CWE-704/IncorrectTypeConversion.expected | 6 -- .../CWE/CWE-704/IncorrectTypeConversion.qlref | 1 - 12 files changed, 293 insertions(+), 114 deletions(-) rename cpp/ql/src/Security/CWE/{CWE-704/IncorrectTypeConversion.cpp => CWE-253/HResultBooleanConversion.cpp} (81%) rename cpp/ql/src/Security/CWE/{CWE-704/IncorrectTypeConversion.qhelp => CWE-253/HResultBooleanConversion.qhelp} (100%) create mode 100644 cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql delete mode 100644 cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.c create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.cpp create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.expected create mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.qlref delete mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp delete mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected delete mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref diff --git a/.gitignore b/.gitignore index 4b055e55a09..fdcd174a97c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ /.vs/ql/v15/Browse.VC.opendb /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json +/.vs/slnx.sqlite-journal +/.vs/ql2/v15/Browse.VC.opendb +/.vs/ql2/v15/Browse.VC.db diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.cpp similarity index 81% rename from cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp rename to cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.cpp index bf711c9b288..44896e89e15 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.cpp +++ b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.cpp @@ -3,5 +3,5 @@ HRESULT hr = CoGetMalloc(1, &pMalloc); if (!hr) { - // code ... + // code ... } diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.qhelp b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp similarity index 100% rename from cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.qhelp rename to cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp diff --git a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql new file mode 100644 index 00000000000..7678cff23f0 --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql @@ -0,0 +1,71 @@ +/** + * @name Cast between semantically different integer types: HRESULT to/from a Boolean type + * @description Cast between semantically different integer types: HRESULT to/from a Boolean type. + * Boolean types indicate success by a non-zero value, whereas success (S_OK) in HRESULT is indicated by a value of 0. + * Casting an HRESULT to/from a Boolean type and then using it in a test expression will yield an incorrect result. + * @kind problem + * @id cpp/hresult-boolean-conversion + * @problem.severity error + * @precision high + * @tags security + * external/cwe/cwe-253 + * external/microsoft/C6214 + * external/microsoft/C6215 + * external/microsoft/C6216 + * external/microsoft/C6217 + * external/microsoft/C6230 + */ +import cpp + +predicate isHresultBooleanConverted( Expr e1, Cast e2 ) +{ + exists ( Type t1, Type t2 | + t1 = e1.getType() and + t2 = e2.getType() and + ((t1.hasName("bool") or t1.hasName("BOOL") or t1.hasName("_Bool")) and t2.hasName("HRESULT") or + (t2.hasName("bool") or t2.hasName("BOOL") or t2.hasName("_Bool")) and t1.hasName("HRESULT") + )) +} + +predicate isHresultBooleanConverted( Expr e1 ) +{ + exists( Cast e2 | + e2 = e1.getConversion() and + isHresultBooleanConverted(e1, e2) + ) +} + +from Expr e1, string msg +where exists + ( + Cast e2 | + e2 = e1.getConversion() | + isHresultBooleanConverted( e1, e2 ) + and if e2.isImplicit() then ( msg = "Implicit conversion from " + e1.getType().toString() + " to " + e2.getType().toString()) + else ( msg = "Explicit conversion from " + e1.getType().toString() + " to " + e2.getType().toString()) + ) + or exists + ( + ControlStructure ctls | + ctls.getControllingExpr() = e1 + and e1.getType().(TypedefType).hasName("HRESULT") + and not isHresultBooleanConverted(e1) + and msg = "Direct usage of a type " + e1.getType().toString() + " as a conditional expression" + ) + or + ( + exists( BinaryLogicalOperation blop | + blop.getAnOperand() = e1 | + e1.getType().(TypedefType).hasName("HRESULT") + and msg = "Usage of a type " + e1.getType().toString() + " as an argument of a binary logical operation" + ) + or exists + ( + UnaryLogicalOperation ulop | + ulop.getAnOperand() = e1 | + e1.getType().(TypedefType).hasName("HRESULT") + and msg = "Usage of a type " + e1.getType().toString() + " as an argument of a unary logical operation" + ) + and not isHresultBooleanConverted(e1) + ) +select e1, msg \ No newline at end of file diff --git a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql deleted file mode 100644 index 0ff7502d9a9..00000000000 --- a/cpp/ql/src/Security/CWE/CWE-704/IncorrectTypeConversion.ql +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @name Cast between semantically different integer types: HRESULT to/from a Boolean type - * @description Cast between semantically different integer types: HRESULT to/from a Boolean type. - * Boolean types indicate success by a non-zero value, whereas success (S_OK) in HRESULT is indicated by a value of 0. - * Casting an HRESULT to/from a Boolean type and then using it in a test expression will yield an incorrect result. - * @kind problem - * @id cpp/hresult-to-boolean-conversion - * @problem.severity error - * @precision high - * @tags security - * external/cwe/cwe-704 - * external/microsoft/C6214 - * external/microsoft/C6215 - * external/microsoft/C6216 - * external/microsoft/C6217 - * external/microsoft/C6230 - */ -import cpp - -from Expr e1, Cast e2, string msg -where e2 = e1.getConversion() and - exists ( Type t1, Type t2 | - t1 = e1.getType() and - t2 = e2.getType() and - ((t1.hasName("bool") or t1.hasName("BOOL")) and t2.hasName("HRESULT") or - (t2.hasName("bool") or t2.hasName("BOOL")) and t1.hasName("HRESULT") - )) - and if e2.isImplicit() then ( msg = "Implicit" ) - else ( msg = "Explicit" ) -select e1, msg + " conversion from " + e1.getType().toString() + " to " + e2.getType().toString() \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.c b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.c new file mode 100644 index 00000000000..9edcd34a8df --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.c @@ -0,0 +1,100 @@ +// semmle-extractor-options: --microsoft +// winnt.h +typedef long HRESULT; +#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) +#define FAILED(hr) (((HRESULT)(hr)) < 0) + +typedef _Bool bool; +#define FALSE 0 + +// minwindef.h +typedef int BOOL; +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +// winerror.h +#define S_OK ((HRESULT)0L) +#define S_FALSE ((HRESULT)1L) +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL) + +HRESULT HresultFunction() +{ + return S_OK; +} + +BOOL BoolFunction() +{ + return FALSE; +} + +bool BoolFunction2() +{ + return FALSE; +} + +HRESULT IncorrectHresultFunction() +{ + return BoolFunction(); // BUG +} + +HRESULT IncorrectHresultFunction2() +{ + return BoolFunction2(); // BUG +} + +void IncorrectTypeConversionTest() { + + HRESULT hr = HresultFunction(); + if ((BOOL)hr) // BUG + { + // ... + } + if ((bool)hr) // BUG + { + // ... + } + if (SUCCEEDED(hr)) // Correct Usage + { + // ... + } + + if (SUCCEEDED(BoolFunction())) // BUG + { + // ... + } + if (SUCCEEDED(BoolFunction2())) // BUG + { + // ... + } + if (BoolFunction()) // Correct Usage + { + // ... + } + BOOL b = IncorrectHresultFunction(); // BUG + bool b2 = IncorrectHresultFunction(); // BUG + + hr = E_UNEXPECTED; + if (!hr) // BUG + { + // ... + } + if (!FAILED(hr)) // Correct Usage + { + // ... + } + + hr = S_FALSE; + if (hr) // BUG + { + // ... + } + if (SUCCEEDED(hr)) // Correct Usage + { + // ... + } +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.cpp new file mode 100644 index 00000000000..04588c24264 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.cpp @@ -0,0 +1,97 @@ +// semmle-extractor-options: --microsoft +// winnt.h +typedef long HRESULT; +#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) +#define FAILED(hr) (((HRESULT)(hr)) < 0) + +// minwindef.h +typedef int BOOL; +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +// winerror.h +#define S_OK ((HRESULT)0L) +#define S_FALSE ((HRESULT)1L) +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL) + +HRESULT HresultFunction() +{ + return S_OK; +} + +BOOL BoolFunction() +{ + return FALSE; +} + +bool BoolFunction2() +{ + return FALSE; +} + +HRESULT IncorrectHresultFunction() +{ + return BoolFunction(); // BUG +} + +HRESULT IncorrectHresultFunction2() +{ + return BoolFunction2(); // BUG +} + +void IncorrectTypeConversionTest() { + + HRESULT hr = HresultFunction(); + if ((BOOL)hr) // BUG + { + // ... + } + if ((bool)hr) // BUG + { + // ... + } + if (SUCCEEDED(hr)) // Correct Usage + { + // ... + } + + if (SUCCEEDED(BoolFunction())) // BUG + { + // ... + } + if (SUCCEEDED(BoolFunction2())) // BUG + { + // ... + } + if (BoolFunction()) // Correct Usage + { + // ... + } + BOOL b = IncorrectHresultFunction(); // BUG + bool b2 = IncorrectHresultFunction(); // BUG + + hr = E_UNEXPECTED; + if (!hr) // BUG + { + // ... + } + if (!FAILED(hr)) // Correct Usage + { + // ... + } + + hr = S_FALSE; + if (hr) // BUG + { + // ... + } + if (SUCCEEDED(hr)) // Correct Usage + { + // ... + } +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.expected new file mode 100644 index 00000000000..15996702920 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.expected @@ -0,0 +1,20 @@ +| HResultBooleanConversion.c:42:12:42:23 | call to BoolFunction | Implicit conversion from BOOL to HRESULT | +| HResultBooleanConversion.c:47:12:47:24 | call to BoolFunction2 | Implicit conversion from bool to HRESULT | +| HResultBooleanConversion.c:53:15:53:16 | hr | Explicit conversion from HRESULT to BOOL | +| HResultBooleanConversion.c:57:15:57:16 | hr | Explicit conversion from HRESULT to bool | +| HResultBooleanConversion.c:66:9:66:33 | (...) | Explicit conversion from BOOL to HRESULT | +| HResultBooleanConversion.c:70:9:70:34 | (...) | Explicit conversion from bool to HRESULT | +| HResultBooleanConversion.c:78:14:78:37 | call to IncorrectHresultFunction | Implicit conversion from HRESULT to BOOL | +| HResultBooleanConversion.c:79:15:79:38 | call to IncorrectHresultFunction | Implicit conversion from HRESULT to bool | +| HResultBooleanConversion.c:82:10:82:11 | hr | Usage of a type HRESULT as an argument of a unary logical operation | +| HResultBooleanConversion.c:92:9:92:10 | hr | Direct usage of a type HRESULT as a conditional expression | +| HResultBooleanConversion.cpp:39:12:39:23 | call to BoolFunction | Implicit conversion from BOOL to HRESULT | +| HResultBooleanConversion.cpp:44:12:44:24 | call to BoolFunction2 | Implicit conversion from bool to HRESULT | +| HResultBooleanConversion.cpp:50:15:50:16 | hr | Explicit conversion from HRESULT to BOOL | +| HResultBooleanConversion.cpp:54:15:54:16 | hr | Explicit conversion from HRESULT to bool | +| HResultBooleanConversion.cpp:63:9:63:33 | (...) | Explicit conversion from BOOL to HRESULT | +| HResultBooleanConversion.cpp:67:9:67:34 | (...) | Explicit conversion from bool to HRESULT | +| HResultBooleanConversion.cpp:75:14:75:37 | call to IncorrectHresultFunction | Implicit conversion from HRESULT to BOOL | +| HResultBooleanConversion.cpp:76:15:76:38 | call to IncorrectHresultFunction | Implicit conversion from HRESULT to bool | +| HResultBooleanConversion.cpp:79:10:79:11 | hr | Implicit conversion from HRESULT to bool | +| HResultBooleanConversion.cpp:89:9:89:10 | hr | Implicit conversion from HRESULT to bool | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.qlref new file mode 100644 index 00000000000..a345e5c6dfb --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-253/HResultBooleanConversion.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-253/HResultBooleanConversion.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp deleted file mode 100644 index 8ecab54b4df..00000000000 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// winnt.h -typedef long HRESULT; -#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) -#define FAILED(hr) (((HRESULT)(hr)) < 0) - -// minwindef.h -typedef int BOOL; -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -// winerror.h -#define S_OK ((HRESULT)0L) -#define S_FALSE ((HRESULT)1L) -#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) -#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL) - -HRESULT HresultFunction() -{ - return S_OK; -} - -BOOL BoolFunction() -{ - return FALSE; -} - -HRESULT IncorrectHresultFunction() -{ - return BoolFunction(); // BUG -} - -void IncorrectTypeConversionTest() { - HRESULT hr = HresultFunction(); - if ((BOOL)hr) // BUG - { - // ... - } - if (SUCCEEDED(hr)) // Correct Usage - { - // ... - } - - if (SUCCEEDED(BoolFunction())) // BUG - { - // ... - } - if (BoolFunction()) // Correct Usage - { - // ... - } - BOOL b = IncorrectHresultFunction(); // BUG - - hr = E_UNEXPECTED; - if (!hr) // BUG - { - // ... - } - if (!FAILED(hr)) // Correct Usage - { - // ... - } - - hr = S_FALSE; - if (hr) // BUG - { - // ... - } - if (SUCCEEDED(hr)) // Correct Usage - { - // ... - } -} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected deleted file mode 100644 index 35c40158a77..00000000000 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.expected +++ /dev/null @@ -1,6 +0,0 @@ -| IncorrectTypeConversion.cpp:33:9:33:20 | call to BoolFunction | Implicit conversion from BOOL to HRESULT | -| IncorrectTypeConversion.cpp:38:12:38:13 | hr | Explicit conversion from HRESULT to BOOL | -| IncorrectTypeConversion.cpp:47:6:47:30 | (...) | Explicit conversion from BOOL to HRESULT | -| IncorrectTypeConversion.cpp:55:11:55:34 | call to IncorrectHresultFunction | Implicit conversion from HRESULT to BOOL | -| IncorrectTypeConversion.cpp:58:7:58:8 | hr | Implicit conversion from HRESULT to bool | -| IncorrectTypeConversion.cpp:68:6:68:7 | hr | Implicit conversion from HRESULT to bool | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref deleted file mode 100644 index 56b47b192d7..00000000000 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-704/IncorrectTypeConversion.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-704/IncorrectTypeConversion.ql \ No newline at end of file From aa267c83027a8216cfaf4e4b7fbe33e5c9ebcc02 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Thu, 20 Sep 2018 11:38:56 -0700 Subject: [PATCH 22/29] C++: Force LF for .c,.cpp,.h,.hpp --- .editorconfig | 2 +- .gitattributes | 4 + .../ClassesWithManyDependencies.cpp | 34 +- .../ClassesWithManyFields.cpp | 40 +- .../FunctionsWithManyParameters.cpp | 16 +- .../src/Best Practices/ComplexCondition.cpp | 24 +- .../Hiding/DeclarationHidesParameter.cpp | 12 +- .../Hiding/DeclarationHidesVariable.cpp | 24 +- .../LocalVariableHidesGlobalVariable.cpp | 24 +- .../Likely Errors/EmptyBlock.cpp | 18 +- .../Best Practices/Likely Errors/Slicing.cpp | 86 +- .../Magic Constants/MagicConstantsNumbers.cpp | 32 +- cpp/ql/src/Best Practices/RuleOfTwo.cpp | 52 +- cpp/ql/src/Best Practices/SwitchLongCase.cpp | 62 +- .../Unused Entities/UnusedLocals.cpp | 10 +- .../Unused Entities/UnusedStaticFunctions.cpp | 28 +- .../Unused Entities/UnusedStaticVariables.cpp | 10 +- cpp/ql/src/Critical/DeadCodeCondition.cpp | 38 +- cpp/ql/src/Critical/DeadCodeFunction.cpp | 24 +- .../src/Critical/DescriptorMayNotBeClosed.cpp | 18 +- cpp/ql/src/Critical/DescriptorNeverClosed.cpp | 12 +- cpp/ql/src/Critical/GlobalUseBeforeInit.cpp | 22 +- cpp/ql/src/Critical/InitialisationNotRun.cpp | 24 +- cpp/ql/src/Critical/LargeParameter.cpp | 26 +- cpp/ql/src/Critical/MissingNullTest.cpp | 22 +- .../src/Critical/NewArrayDeleteMismatch.cpp | 10 +- .../src/Critical/NewDeleteArrayMismatch.cpp | 10 +- cpp/ql/src/Critical/NewFreeMismatch.cpp | 10 +- cpp/ql/src/Critical/NotInitialised.cpp | 12 +- cpp/ql/src/Critical/OverflowDestination.cpp | 26 +- cpp/ql/src/Critical/ReturnValueIgnored.cpp | 46 +- cpp/ql/src/Critical/SizeCheck.cpp | 20 +- cpp/ql/src/Critical/Unused.cpp | 8 +- cpp/ql/src/Critical/UseAfterFree.cpp | 18 +- cpp/ql/src/Documentation/TodoComments.cpp | 6 +- .../Cleanup-DuplicateIncludeGuard.cpp | 14 +- .../Cleanup-DuplicateIncludeGuard2.cpp | 14 +- .../Arithmetic/ComparisonPrecedence.cpp | 12 +- .../Conversion/ArrayArgSizeMismatch.cpp | 24 +- .../Conversion/ConversionChangesSign.cpp | 8 +- .../Conversion/LossyPointerCast.cpp | 10 +- .../InconsistentCheckReturnNull.cpp | 60 +- .../Likely Typos/BoolValueInBitOp.cpp | 26 +- .../LogicalExprCouldBeSimplified.cpp | 22 +- .../Likely Typos/MissingEnumCaseInSwitch.cpp | 60 +- .../PotentialBufferOverflow.cpp | 24 +- .../SuspiciousCallToStrncat.cpp | 8 +- .../Memory Management/SuspiciousSizeof.cpp | 8 +- cpp/ql/src/Likely Bugs/NestedLoopSameVar.cpp | 32 +- .../Likely Bugs/OO/NonVirtualDestructor.cpp | 62 +- .../src/Likely Bugs/OO/ThrowInDestructor.cpp | 38 +- cpp/ql/src/Likely Bugs/ShortLoopVarName.cpp | 26 +- .../CWE/CWE-190/ComparisonWithWiderType.c | 56 +- cpp/ql/src/jsf/4.10 Classes/AV Rule 95.cpp | 40 +- .../multi-target-includes/common.h | 8 +- .../multi-target-includes/defines_issue.h | 4 +- .../multi-target-includes/main2.cpp | 14 +- .../multi-target-includes/nameclash.h | 4 +- .../multi-target-includes/subdir1/nameclash.h | 4 +- .../multi-target-includes/subdir2/nameclash.h | 4 +- .../library-tests/allocators/allocators.cpp | 222 +- cpp/ql/test/library-tests/calls/calls1.cpp | 16 +- cpp/ql/test/library-tests/calls/calls1.h | 4 +- cpp/ql/test/library-tests/calls/calls2.cpp | 40 +- .../classes/classes/Classes.ms.cpp | 82 +- .../classes/derivations/offsets/offsets.cpp | 168 +- .../loopentrycondition/forstmt.cpp | 202 +- .../loopentrycondition/whilestmt.cpp | 126 +- .../library-tests/conversions/conversions.cpp | 500 ++--- .../library-tests/ctorinits/ctorinits.cpp | 88 +- .../declarationEntry/template/src5.cpp | 20 +- .../declarationEntry/template/src5.fwd.hpp | 16 +- .../declarationEntry/template/src6.cpp | 10 +- .../depends_addressable/addressable.cpp | 56 +- .../library-tests/depends_friends/friends.cpp | 56 +- .../depends_initializers/initializers.cpp | 62 +- .../depends_initializers/template_static.cpp | 178 +- .../template_static_instantiated.cpp | 148 +- .../derived_types/derivedtype.cpp | 18 +- .../test/library-tests/enums/enums/enums.cpp | 30 +- .../exprs/comparison_operation/test.cpp | 28 +- .../exprs/unary_operation/test.cpp | 30 +- .../value_categories/value_categories.cpp | 310 +-- .../exprs_basic/exprs_basic1.cpp | 66 +- .../library-tests/fields/fields/fields.cpp | 66 +- cpp/ql/test/library-tests/files/files1.cpp | 18 +- cpp/ql/test/library-tests/files/files1.h | 4 +- cpp/ql/test/library-tests/files/files2.cpp | 14 +- .../functions/functions/functions.cpp | 66 +- .../ir/constant_func/constant_func.cpp | 64 +- .../test/library-tests/ir/escape/escape.cpp | 196 +- cpp/ql/test/library-tests/ir/ir/ir.cpp | 1968 ++++++++--------- .../aggregate_literals/aggregate_literals.c | 204 +- .../aggregate_literals_cpp.cpp | 56 +- cpp/ql/test/library-tests/loops/loops.cpp | 72 +- .../namespaces/namespaces/namespaces.cpp | 88 +- .../namespaces/same_name/same_name.cpp | 32 +- .../library-tests/operators/operators.cpp | 54 +- .../test/library-tests/padding/size_asserts.h | 92 +- .../parameters/parameters/parameters.cpp | 56 +- .../preprocessor/include/guarded.h | 14 +- .../preprocessor/include/unguarded.h | 6 +- .../preprocessor/linedirective/header.h | 6 +- .../preprocessor/linedirective/line.h | 28 +- .../preprocessor/linedirective/system.h | 28 +- .../library-tests/scopes/scopes/scopes.cpp | 206 +- .../library-tests/sideEffects/exprs/exprs.cpp | 80 +- .../library-tests/specifiers/specifiers.cpp | 44 +- .../string_analysis/string_analysis.cpp | 88 +- .../structs/compatible_variables/a.c | 28 +- .../structs/compatible_variables/b.c | 34 +- .../structs/compatible_variables/h.h | 20 +- .../structs/incomplete_definition/a.h | 12 +- .../structs/incomplete_definition/x.cpp | 62 +- .../structs/incomplete_definition/y.cpp | 16 +- .../structs/mutual_recursion/a.c | 122 +- .../structs/mutual_recursion/b.c | 114 +- .../test/library-tests/typedefs/typedefs.cpp | 62 +- .../integral_types_ms/integral_types.cpp | 10 +- .../types/pointertypes/pointertypes.c | 80 +- .../library-tests/types/refersTo/refersTo.cpp | 40 +- .../test/library-tests/types/scope/scope.cpp | 54 +- .../test/library-tests/types/types/types.cpp | 164 +- .../library-tests/types/wchar_t_typedef/ms.c | 8 +- cpp/ql/test/library-tests/unions/unions.cpp | 46 +- .../GlobalValueNumbering/test.cpp | 6 +- .../variables/variables/variables.cpp | 106 +- .../virtual_functions/virtual_functions.cpp | 96 +- .../AlertSuppression/.gitattributes | 1 + .../query-tests/AlertSuppression/tstWindows.c | 56 +- .../MagicConstantsNumbers/functions.h | 66 +- .../MagicConstantsNumbers/test.cpp | 26 +- .../Unused Entities/UnusedIncludes/a.h | 6 +- .../Unused Entities/UnusedIncludes/b.h | 6 +- .../Unused Entities/UnusedIncludes/c.h | 6 +- .../Unused Entities/UnusedIncludes/d.hpp | 6 +- .../Unused Entities/UnusedIncludes/e.hpp | 6 +- .../Unused Entities/UnusedIncludes/f.fwd.hpp | 6 +- .../Cleanup-DuplicateIncludeGuard/header1.h | 16 +- .../Cleanup-DuplicateIncludeGuard/header2.h | 16 +- .../Cleanup-DuplicateIncludeGuard/header3.h | 24 +- .../Cleanup-DuplicateIncludeGuard/header4.h | 16 +- .../Cleanup-DuplicateIncludeGuard/header6.h | 16 +- .../Cleanup-DuplicateIncludeGuard/header7.h | 16 +- .../Cleanup-DuplicateIncludeGuard/main.c | 26 +- .../subfolder/header4.h | 16 +- .../subfolder/header5.h | 16 +- .../Linux_signed_chars/common.h | 40 +- .../Linux_unsigned_chars/common.h | 40 +- .../Microsoft/common.h | 40 +- .../Microsoft_no_wchar/common.h | 40 +- .../StackAddressEscapes/manager.cpp | 108 +- .../jsf/4.09 Style/AV Rule 53 54/test.CPP | 4 +- .../jsf/4.09 Style/AV Rule 53 54/test.c | 8 +- .../jsf/4.10 Classes/AV Rule 73/original.cpp | 320 +-- .../4.10 Classes/AV Rule 78/AV Rule 78.cpp | 216 +- .../successor-tests/assignexpr/assignexpr.cpp | 22 +- .../block/dummyblock/dummyblock.c | 8 +- .../block/emptyblock/emptyblock.c | 10 +- .../args/membercallexpr/membercallexpr.cpp | 22 +- .../staticmembercallexpr.cpp | 22 +- .../noargs/membercallexpr/membercallexpr.cpp | 20 +- .../nonmembercallexpr/nonmembercallexpr.c | 12 +- .../nonmemberfp2callexpr.c | 12 +- .../nonmemberfpcallexpr/nonmemberfpcallexpr.c | 10 +- .../callexpr/noargs/pmcallexpr/pmcallexpr.cpp | 20 +- .../staticmembercallexpr.cpp | 20 +- .../defdestructordeleteexpr.cpp | 12 +- .../deleteexpr/deleteexpr/deleteexpr.cpp | 18 +- cpp/ql/test/successor-tests/dostmt/dostmt.c | 76 +- cpp/ql/test/successor-tests/enum/enum.c | 14 +- .../ellipsisexceptionhandler.cpp | 34 +- .../exceptionhandler/exceptionhandler.cpp | 44 +- .../test/successor-tests/exprstmt/exprstmt.c | 8 +- .../constmemberaccess/constmemberaccess.cpp | 18 +- .../fieldaccess/fieldaccess.cpp | 18 +- .../forstmt/forstmt/forstmt.cpp | 40 +- .../forstmt/shortforstmt/shortforstmt.cpp | 76 +- .../forstmt/tinyforstmt/tinyforstmt.c | 10 +- .../test/successor-tests/gotostmt/gotostmt.c | 10 +- .../ifstmt/ifelsestmt/ifelsestmt.c | 90 +- .../successor-tests/ifstmt/ifstmt/ifstmt.c | 64 +- .../aggregateinitializer.c | 8 +- .../constructorinitializer.cpp | 18 +- .../initializer/initializer/initializer.c | 6 +- .../parameterinitializer.cpp | 62 +- .../test/successor-tests/landexpr/landexpr.c | 10 +- cpp/ql/test/successor-tests/lorexpr/lorexpr.c | 10 +- .../ltrbinopexpr/ltrbinopexpr.c | 86 +- .../defconstructornewexpr.cpp | 10 +- .../newexpr/newexpr/newexpr.cpp | 18 +- .../questionexpr/questionexpr.c | 6 +- .../successor-tests/returnstmt/returnstmt.c | 20 +- .../staticlocals/staticlocals.cpp | 26 +- .../subscriptexpr/revsubscriptexpr.c | 10 +- .../subscriptexpr/subscriptexpr.c | 10 +- .../nodefaultswitchstmt/nodefaultswitchstmt.c | 14 +- .../switchstmt/switchstmt/switchstmt.c | 16 +- .../successor-tests/unaryopexpr/unaryopexpr.c | 28 +- .../successor-tests/whilestmt/whilestmt.c | 90 +- 200 files changed, 5422 insertions(+), 5417 deletions(-) create mode 100644 cpp/ql/test/query-tests/AlertSuppression/.gitattributes diff --git a/.editorconfig b/.editorconfig index decc2081a24..413e18ca658 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,2 @@ -[*.{ql,qll,qlref,dbscheme,qhelp,html,js,mjs,ts,json,yml}] +[*.{ql,qll,qlref,dbscheme,qhelp,html,js,mjs,ts,json,yml,c,cpp,h,hpp}] end_of_line = lf diff --git a/.gitattributes b/.gitattributes index ec825a38b57..d945c85a015 100644 --- a/.gitattributes +++ b/.gitattributes @@ -21,3 +21,7 @@ *.ts eol=lf *.json eol=lf *.yml eol=lf +*.c eol=lf +*.cpp eol=lf +*.h eol=lf +*.hpp eol=lf diff --git a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.cpp b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.cpp index fea666c554d..4a056489271 100644 --- a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.cpp +++ b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.cpp @@ -1,17 +1,17 @@ -// an include declaration just adds one source dependency, it does not automatically -// add a dependency from this file to all the declarations in stdio.h -#include -#include // contains non-static global myfile_err - -extern int myfile_err; // this external declaration adds a dependency on myfile.h - -class C { -public: - C() { - // one dependency for printf: - printf("Hello world!"); - // one dependency for FILE type, and one for NULL macro: - FILE fp = NULL; - } -}; - +// an include declaration just adds one source dependency, it does not automatically +// add a dependency from this file to all the declarations in stdio.h +#include +#include // contains non-static global myfile_err + +extern int myfile_err; // this external declaration adds a dependency on myfile.h + +class C { +public: + C() { + // one dependency for printf: + printf("Hello world!"); + // one dependency for FILE type, and one for NULL macro: + FILE fp = NULL; + } +}; + diff --git a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.cpp b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.cpp index 0b576cc29b0..987255a46d6 100644 --- a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.cpp +++ b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.cpp @@ -1,20 +1,20 @@ -//This struct contains 30 fields. -struct MyParticle { - bool isActive; - int priority; - - float x, y, z; - float dx, dy, dz; - float ddx, ddy, ddz; - bool isCollider; - - int age, maxAge; - float size1, size2; - - bool hasColor; - unsigned char r1, g1, b1, a1; - unsigned char r2, g2, b2, a2; - - class texture *tex; - float u1, v1, u2, v2; -}; +//This struct contains 30 fields. +struct MyParticle { + bool isActive; + int priority; + + float x, y, z; + float dx, dy, dz; + float ddx, ddy, ddz; + bool isCollider; + + int age, maxAge; + float size1, size2; + + bool hasColor; + unsigned char r1, g1, b1, a1; + unsigned char r2, g2, b2, a2; + + class texture *tex; + float u1, v1, u2, v2; +}; diff --git a/cpp/ql/src/Architecture/Refactoring Opportunities/FunctionsWithManyParameters.cpp b/cpp/ql/src/Architecture/Refactoring Opportunities/FunctionsWithManyParameters.cpp index 624226bff6a..80d2c503feb 100644 --- a/cpp/ql/src/Architecture/Refactoring Opportunities/FunctionsWithManyParameters.cpp +++ b/cpp/ql/src/Architecture/Refactoring Opportunities/FunctionsWithManyParameters.cpp @@ -1,8 +1,8 @@ -// this example has 15 parameters. -void fillRect(int x, int y, int w, int h, - int r1, int g1, int b1, int a1, - int r2, int g2, int b2, int a2, - gradient_type grad, unsigned int flags, bool border) -{ - // ... -} +// this example has 15 parameters. +void fillRect(int x, int y, int w, int h, + int r1, int g1, int b1, int a1, + int r2, int g2, int b2, int a2, + gradient_type grad, unsigned int flags, bool border) +{ + // ... +} diff --git a/cpp/ql/src/Best Practices/ComplexCondition.cpp b/cpp/ql/src/Best Practices/ComplexCondition.cpp index 8a8638c5bbe..fba51491990 100644 --- a/cpp/ql/src/Best Practices/ComplexCondition.cpp +++ b/cpp/ql/src/Best Practices/ComplexCondition.cpp @@ -1,13 +1,13 @@ -//This condition is too complex and can be improved by using local variables -bool accept_message = - (message_type == CONNECT && _state != CONNECTED) || - (message_type == DISCONNECT && _state == CONNECTED) || - (message_type == DATA && _state == CONNECTED); - -//This condition is acceptable, as all the logical operators are of the same type (&&) -bool valid_connect = - message_type == CONNECT && - _state != CONNECTED && - time_since_prev_connect > MAX_CONNECT_INTERVAL && - message_length <= MAX_PACKET_SIZE && +//This condition is too complex and can be improved by using local variables +bool accept_message = + (message_type == CONNECT && _state != CONNECTED) || + (message_type == DISCONNECT && _state == CONNECTED) || + (message_type == DATA && _state == CONNECTED); + +//This condition is acceptable, as all the logical operators are of the same type (&&) +bool valid_connect = + message_type == CONNECT && + _state != CONNECTED && + time_since_prev_connect > MAX_CONNECT_INTERVAL && + message_length <= MAX_PACKET_SIZE && checksum(message) == get_checksum_field(message); \ No newline at end of file diff --git a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.cpp b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.cpp index 687129d8815..374a3290ec7 100644 --- a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.cpp +++ b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.cpp @@ -1,6 +1,6 @@ -void f(int i) { - for (int i = 0; i < 10; ++i) { //the loop variable hides the parameter to f() - ... - } -} - +void f(int i) { + for (int i = 0; i < 10; ++i) { //the loop variable hides the parameter to f() + ... + } +} + diff --git a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.cpp b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.cpp index bc96def17df..7cfe4617035 100644 --- a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.cpp +++ b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.cpp @@ -1,12 +1,12 @@ -void f() { - int i = 10; - - for (int i = 0; i < 10; i++) { //the loop counter hides the variable - ... - } - - { - int i = 12; //this variable hides the variable in the outer block - ... - } -} +void f() { + int i = 10; + + for (int i = 0; i < 10; i++) { //the loop counter hides the variable + ... + } + + { + int i = 12; //this variable hides the variable in the outer block + ... + } +} diff --git a/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.cpp b/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.cpp index 61590c86011..89c473561a8 100644 --- a/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.cpp +++ b/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.cpp @@ -1,12 +1,12 @@ -int i = 10; - -void f() { - for (int i = 0; i < 10; i++) { //the loop counter hides the global variable i - ... - } - - { - int i = 12; //this variable hides the global variable i - ... - } -} +int i = 10; + +void f() { + for (int i = 0; i < 10; i++) { //the loop counter hides the global variable i + ... + } + + { + int i = 12; //this variable hides the global variable i + ... + } +} diff --git a/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.cpp b/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.cpp index 547810752ec..a0a4c2d64ac 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.cpp +++ b/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.cpp @@ -1,9 +1,9 @@ -void f(int i) { - if (i == 10); //empty then block - ... //won't be part of the if statement - - if (i == 12) { - ... - } else { //empty else block, most likely a mistake - } -} +void f(int i) { + if (i == 10); //empty then block + ... //won't be part of the if statement + + if (i == 12) { + ... + } else { //empty else block, most likely a mistake + } +} diff --git a/cpp/ql/src/Best Practices/Likely Errors/Slicing.cpp b/cpp/ql/src/Best Practices/Likely Errors/Slicing.cpp index 09d1f414e5d..538516964a7 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/Slicing.cpp +++ b/cpp/ql/src/Best Practices/Likely Errors/Slicing.cpp @@ -1,43 +1,43 @@ -static int idctr = 0; -//Basic connection with id -class Connection { -public: - int connId; - virtual void print_info() { - cout << "id: " << connId << "\n"; - } - Connection() { - connId = idctr++; - } -}; - -//Adds counters, and an overriding print_info -class MeteredConnection : public Connection { -public: - int txCtr; - int rxCtr; - MeteredConnection() { - txCtr = 0; - rxCtr = 0; - } - virtual void print_info() { - cout << "id: " << connId << "\n" << "tx/rx: " << txCtr << "/" << rxCtr << "\n"; - } -}; - -int main(int argc, char* argv[]) { - Connection conn; - MeteredConnection m_conn; - - Connection curr_conn = conn; - curr_conn.print_info(); - curr_conn = m_conn; //Wrong: Derived MetricConnection assigned to Connection - //variable, will slice off the counters and the overriding print_info - curr_conn.print_info(); //Will not print the counters. - - Connection* curr_pconn = &conn; - curr_pconn->print_info(); - curr_pconn = &m_conn; //Correct: Pointer assigned to address of the MetricConnection. - //Counters and virtual functions remain intact. - curr_pconn->print_info(); //Will call the correct method MeteredConnection::print_info -} +static int idctr = 0; +//Basic connection with id +class Connection { +public: + int connId; + virtual void print_info() { + cout << "id: " << connId << "\n"; + } + Connection() { + connId = idctr++; + } +}; + +//Adds counters, and an overriding print_info +class MeteredConnection : public Connection { +public: + int txCtr; + int rxCtr; + MeteredConnection() { + txCtr = 0; + rxCtr = 0; + } + virtual void print_info() { + cout << "id: " << connId << "\n" << "tx/rx: " << txCtr << "/" << rxCtr << "\n"; + } +}; + +int main(int argc, char* argv[]) { + Connection conn; + MeteredConnection m_conn; + + Connection curr_conn = conn; + curr_conn.print_info(); + curr_conn = m_conn; //Wrong: Derived MetricConnection assigned to Connection + //variable, will slice off the counters and the overriding print_info + curr_conn.print_info(); //Will not print the counters. + + Connection* curr_pconn = &conn; + curr_pconn->print_info(); + curr_pconn = &m_conn; //Correct: Pointer assigned to address of the MetricConnection. + //Counters and virtual functions remain intact. + curr_pconn->print_info(); //Will call the correct method MeteredConnection::print_info +} diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.cpp b/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.cpp index f637c8d68e5..98f830132eb 100644 --- a/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.cpp +++ b/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.cpp @@ -1,16 +1,16 @@ -void sanitize(Fields[] record) { - //The number of fields here can be put in a const - for (fieldCtr = 0; field < 7; field++) { - sanitize(fields[fieldCtr]); - } -} - -#define NUM_FIELDS 7 - -void process(Fields[] record) { - //This avoids using a magic constant by using the macro instead - for (fieldCtr = 0; field < NUM_FIELDS; field++) { - process(fields[fieldCtr]); - } -} - +void sanitize(Fields[] record) { + //The number of fields here can be put in a const + for (fieldCtr = 0; field < 7; field++) { + sanitize(fields[fieldCtr]); + } +} + +#define NUM_FIELDS 7 + +void process(Fields[] record) { + //This avoids using a magic constant by using the macro instead + for (fieldCtr = 0; field < NUM_FIELDS; field++) { + process(fields[fieldCtr]); + } +} + diff --git a/cpp/ql/src/Best Practices/RuleOfTwo.cpp b/cpp/ql/src/Best Practices/RuleOfTwo.cpp index 4e602c10543..d633f9db980 100644 --- a/cpp/ql/src/Best Practices/RuleOfTwo.cpp +++ b/cpp/ql/src/Best Practices/RuleOfTwo.cpp @@ -1,26 +1,26 @@ -class C { -private: - Other* other = NULL; -public: - C(const C& copyFrom) { - Other* newOther = new Other(); - *newOther = copyFrom.other; - this->other = newOther; - } - - //No operator=, by default will just copy the pointer other, will not create a new object -}; - -class D { - Other* other = NULL; -public: - D& operator=(D& rhs) { - Other* newOther = new Other(); - *newOther = rhs.other; - this->other = newOther; - return *this; - } - - //No copy constructor, will just copy the pointer other and not create a new object -}; - +class C { +private: + Other* other = NULL; +public: + C(const C& copyFrom) { + Other* newOther = new Other(); + *newOther = copyFrom.other; + this->other = newOther; + } + + //No operator=, by default will just copy the pointer other, will not create a new object +}; + +class D { + Other* other = NULL; +public: + D& operator=(D& rhs) { + Other* newOther = new Other(); + *newOther = rhs.other; + this->other = newOther; + return *this; + } + + //No copy constructor, will just copy the pointer other and not create a new object +}; + diff --git a/cpp/ql/src/Best Practices/SwitchLongCase.cpp b/cpp/ql/src/Best Practices/SwitchLongCase.cpp index 422c3fdbf56..7b8a0e66808 100644 --- a/cpp/ql/src/Best Practices/SwitchLongCase.cpp +++ b/cpp/ql/src/Best Practices/SwitchLongCase.cpp @@ -1,32 +1,32 @@ -//This switch statement has long case statements, and can become difficult to -//read as the processing for each message type becomes more complex -switch (message_type) { - case CONNECT: - _state = CONNECTING; - int message_id = message_get_id(message); - int source = connect_get_source(message); - //More code here... - send(connect_response); - break; - case DISCONNECT: - _state = DISCONNECTING; - int message_id = message_get_id(message); - int source = disconnect_get_source(message); - //More code here... - send(disconnect_response); - break; - default: - log("Invalid message, id : %d", message_get_id(message)); -} - -//This is better, as each case is split out to a separate function -switch (packet_type) { - case STREAM: - process_stream_packet(packet); - break; - case DATAGRAM: - process_datagram_packet(packet); - break; - default: - log("Invalid packet type: %d", packet_type); +//This switch statement has long case statements, and can become difficult to +//read as the processing for each message type becomes more complex +switch (message_type) { + case CONNECT: + _state = CONNECTING; + int message_id = message_get_id(message); + int source = connect_get_source(message); + //More code here... + send(connect_response); + break; + case DISCONNECT: + _state = DISCONNECTING; + int message_id = message_get_id(message); + int source = disconnect_get_source(message); + //More code here... + send(disconnect_response); + break; + default: + log("Invalid message, id : %d", message_get_id(message)); +} + +//This is better, as each case is split out to a separate function +switch (packet_type) { + case STREAM: + process_stream_packet(packet); + break; + case DATAGRAM: + process_datagram_packet(packet); + break; + default: + log("Invalid packet type: %d", packet_type); } \ No newline at end of file diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.cpp b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.cpp index 0f20fd9d529..277e753b06b 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.cpp +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.cpp @@ -1,5 +1,5 @@ -{ - int x = 0; //x is unused - int y = 0; - cout << y; -} +{ + int x = 0; //x is unused + int y = 0; + cout << y; +} diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticFunctions.cpp b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticFunctions.cpp index 9e2685ea7c4..a1b259e2c47 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticFunctions.cpp +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticFunctions.cpp @@ -1,14 +1,14 @@ -//start of file -static void f() { //static function f() is unused in the file - //... -} -static void g() { - //... -} -void public_func() { //non-static function public_func is not called in file, - //but could be visible in other files - //... - g(); //call to g() - //... -} -//end of file +//start of file +static void f() { //static function f() is unused in the file + //... +} +static void g() { + //... +} +void public_func() { //non-static function public_func is not called in file, + //but could be visible in other files + //... + g(); //call to g() + //... +} +//end of file diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.cpp b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.cpp index 4627aab67b3..c5d92cc6eef 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.cpp +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.cpp @@ -1,5 +1,5 @@ -void f() { - static int i = 0; //i is unused - ... - return; -} +void f() { + static int i = 0; //i is unused + ... + return; +} diff --git a/cpp/ql/src/Critical/DeadCodeCondition.cpp b/cpp/ql/src/Critical/DeadCodeCondition.cpp index 743dc39c1b3..1a0eec18bca 100644 --- a/cpp/ql/src/Critical/DeadCodeCondition.cpp +++ b/cpp/ql/src/Critical/DeadCodeCondition.cpp @@ -1,19 +1,19 @@ -while(result) { - if ( ... ) - ... - else if (result //wrong: this test is redundant - && result->flags != 0) - ... - result = next(queue); -} - - -fp = fopen(log, "r"); -if (fp) { - /* - * large block of code - */ - if (!fp) { //wrong: always false - ... /* dead code */ - } -} +while(result) { + if ( ... ) + ... + else if (result //wrong: this test is redundant + && result->flags != 0) + ... + result = next(queue); +} + + +fp = fopen(log, "r"); +if (fp) { + /* + * large block of code + */ + if (!fp) { //wrong: always false + ... /* dead code */ + } +} diff --git a/cpp/ql/src/Critical/DeadCodeFunction.cpp b/cpp/ql/src/Critical/DeadCodeFunction.cpp index e16dc9c3bf5..1cdcc652d97 100644 --- a/cpp/ql/src/Critical/DeadCodeFunction.cpp +++ b/cpp/ql/src/Critical/DeadCodeFunction.cpp @@ -1,12 +1,12 @@ -class C { -public: - void g() { - ... - //f() was previously used but is now commented, orphaning f() - //f(); - ... - } -private: - void f() { //is now unused, and can be removed - } -}; +class C { +public: + void g() { + ... + //f() was previously used but is now commented, orphaning f() + //f(); + ... + } +private: + void f() { //is now unused, and can be removed + } +}; diff --git a/cpp/ql/src/Critical/DescriptorMayNotBeClosed.cpp b/cpp/ql/src/Critical/DescriptorMayNotBeClosed.cpp index 69b83a9a490..a29e0d634d7 100644 --- a/cpp/ql/src/Critical/DescriptorMayNotBeClosed.cpp +++ b/cpp/ql/src/Critical/DescriptorMayNotBeClosed.cpp @@ -1,9 +1,9 @@ -int f() { - try { - int sockfd = socket(AF_INET, SOCK_STREAM, 0); - do_stuff(sockfd); - return sockfd; //if there are no exceptions, the socket is returned - } catch (int do_stuff_exception) { - return -1; //return error value, but sockfd may still be open - } -} +int f() { + try { + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + do_stuff(sockfd); + return sockfd; //if there are no exceptions, the socket is returned + } catch (int do_stuff_exception) { + return -1; //return error value, but sockfd may still be open + } +} diff --git a/cpp/ql/src/Critical/DescriptorNeverClosed.cpp b/cpp/ql/src/Critical/DescriptorNeverClosed.cpp index d791a7024bf..137e962ac64 100644 --- a/cpp/ql/src/Critical/DescriptorNeverClosed.cpp +++ b/cpp/ql/src/Critical/DescriptorNeverClosed.cpp @@ -1,6 +1,6 @@ -int main(int argc, char* argv[]) { - int sockfd = socket(AF_INET, SOCK_STREAM, 0); - int status = 0; - ... //code that does not close sockfd - return status; //sockfd is never closed -} +int main(int argc, char* argv[]) { + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + int status = 0; + ... //code that does not close sockfd + return status; //sockfd is never closed +} diff --git a/cpp/ql/src/Critical/GlobalUseBeforeInit.cpp b/cpp/ql/src/Critical/GlobalUseBeforeInit.cpp index 30fb4ca1cee..dc3a35c8aae 100644 --- a/cpp/ql/src/Critical/GlobalUseBeforeInit.cpp +++ b/cpp/ql/src/Critical/GlobalUseBeforeInit.cpp @@ -1,11 +1,11 @@ -int g_callCtr; - -void initGlobals() { - g_callCtr = 0; -} - -int main(int argc, char* argv[]) { - ... - cout << g_callCtr; //callCtr used before it is initialized - initGlobals(); -} +int g_callCtr; + +void initGlobals() { + g_callCtr = 0; +} + +int main(int argc, char* argv[]) { + ... + cout << g_callCtr; //callCtr used before it is initialized + initGlobals(); +} diff --git a/cpp/ql/src/Critical/InitialisationNotRun.cpp b/cpp/ql/src/Critical/InitialisationNotRun.cpp index 2c937d4b9b9..ab67945e636 100644 --- a/cpp/ql/src/Critical/InitialisationNotRun.cpp +++ b/cpp/ql/src/Critical/InitialisationNotRun.cpp @@ -1,12 +1,12 @@ -GlobalStorage *g_storage; - -void init() { //initializes g_storage, but is never run from main - g_storage = new GlobalStorage(); - ... -} - -int main(int argc, char *argv[]) { - ... //init not called - strcpy(g_storage->name, argv[1]); // g_storage is used before init() is called - ... -} +GlobalStorage *g_storage; + +void init() { //initializes g_storage, but is never run from main + g_storage = new GlobalStorage(); + ... +} + +int main(int argc, char *argv[]) { + ... //init not called + strcpy(g_storage->name, argv[1]); // g_storage is used before init() is called + ... +} diff --git a/cpp/ql/src/Critical/LargeParameter.cpp b/cpp/ql/src/Critical/LargeParameter.cpp index 5e829636132..64a05b85df9 100644 --- a/cpp/ql/src/Critical/LargeParameter.cpp +++ b/cpp/ql/src/Critical/LargeParameter.cpp @@ -1,13 +1,13 @@ -typedef struct Names { - char first[100]; - char last[100]; -} Names; - -int doFoo(Names n) { //wrong: n is passed by value (meaning the entire structure - //is copied onto the stack, instead of just a pointer) - ... -} - -int doBar(Names &n) { //better, only a reference is passed - ... -} +typedef struct Names { + char first[100]; + char last[100]; +} Names; + +int doFoo(Names n) { //wrong: n is passed by value (meaning the entire structure + //is copied onto the stack, instead of just a pointer) + ... +} + +int doBar(Names &n) { //better, only a reference is passed + ... +} diff --git a/cpp/ql/src/Critical/MissingNullTest.cpp b/cpp/ql/src/Critical/MissingNullTest.cpp index 074f9d285e9..05f2ba2278a 100644 --- a/cpp/ql/src/Critical/MissingNullTest.cpp +++ b/cpp/ql/src/Critical/MissingNullTest.cpp @@ -1,11 +1,11 @@ -typedef struct { - char name[100]; - int status; -} person; - -void f() { - person* buf = NULL; - buf = malloc(sizeof(person)); - - (*buf).status = 0; //access to buf before it was checked for NULL -} +typedef struct { + char name[100]; + int status; +} person; + +void f() { + person* buf = NULL; + buf = malloc(sizeof(person)); + + (*buf).status = 0; //access to buf before it was checked for NULL +} diff --git a/cpp/ql/src/Critical/NewArrayDeleteMismatch.cpp b/cpp/ql/src/Critical/NewArrayDeleteMismatch.cpp index 2ee7ed26732..94265b6262b 100644 --- a/cpp/ql/src/Critical/NewArrayDeleteMismatch.cpp +++ b/cpp/ql/src/Critical/NewArrayDeleteMismatch.cpp @@ -1,5 +1,5 @@ -Record* record = new Record[SIZE]; - -... - -delete record; //record was created using 'new[]', but was freed using 'delete' +Record* record = new Record[SIZE]; + +... + +delete record; //record was created using 'new[]', but was freed using 'delete' diff --git a/cpp/ql/src/Critical/NewDeleteArrayMismatch.cpp b/cpp/ql/src/Critical/NewDeleteArrayMismatch.cpp index 31aaa24a832..4ee57b7e20e 100644 --- a/cpp/ql/src/Critical/NewDeleteArrayMismatch.cpp +++ b/cpp/ql/src/Critical/NewDeleteArrayMismatch.cpp @@ -1,5 +1,5 @@ -Record *ptr = new Record(...); - -... - -delete [] ptr; // ptr was created using 'new', but was freed using 'delete[]' +Record *ptr = new Record(...); + +... + +delete [] ptr; // ptr was created using 'new', but was freed using 'delete[]' diff --git a/cpp/ql/src/Critical/NewFreeMismatch.cpp b/cpp/ql/src/Critical/NewFreeMismatch.cpp index 4a359c0ffa5..14ae95415de 100644 --- a/cpp/ql/src/Critical/NewFreeMismatch.cpp +++ b/cpp/ql/src/Critical/NewFreeMismatch.cpp @@ -1,5 +1,5 @@ -Record *ptr = new Record(...); - -... - -free(ptr); // BAD: ptr was created using 'new', but is being freed using 'free' +Record *ptr = new Record(...); + +... + +free(ptr); // BAD: ptr was created using 'new', but is being freed using 'free' diff --git a/cpp/ql/src/Critical/NotInitialised.cpp b/cpp/ql/src/Critical/NotInitialised.cpp index 7d0e6b8f9be..af9b733e962 100644 --- a/cpp/ql/src/Critical/NotInitialised.cpp +++ b/cpp/ql/src/Critical/NotInitialised.cpp @@ -1,6 +1,6 @@ -{ - int i; - - ... - int g = COEFF * i; //i is used before it is initialized -} +{ + int i; + + ... + int g = COEFF * i; //i is used before it is initialized +} diff --git a/cpp/ql/src/Critical/OverflowDestination.cpp b/cpp/ql/src/Critical/OverflowDestination.cpp index d6413231bbf..1a758430bf4 100644 --- a/cpp/ql/src/Critical/OverflowDestination.cpp +++ b/cpp/ql/src/Critical/OverflowDestination.cpp @@ -1,13 +1,13 @@ - -int main(int argc, char* argv[]) { - char param[SIZE]; - - char arg1[10]; - char arg2[20]; - - //wrong: only uses the size of the source (argv[1]) when using strncpy - strncpy(param, argv[1], strlen(arg1)); - - //correct: uses the size of the destination array as well - strncpy(param, argv[1], min(strlen(arg1, sizeof(param) -1))); -} + +int main(int argc, char* argv[]) { + char param[SIZE]; + + char arg1[10]; + char arg2[20]; + + //wrong: only uses the size of the source (argv[1]) when using strncpy + strncpy(param, argv[1], strlen(arg1)); + + //correct: uses the size of the destination array as well + strncpy(param, argv[1], min(strlen(arg1, sizeof(param) -1))); +} diff --git a/cpp/ql/src/Critical/ReturnValueIgnored.cpp b/cpp/ql/src/Critical/ReturnValueIgnored.cpp index d68d5021bba..5e11e765eb0 100644 --- a/cpp/ql/src/Critical/ReturnValueIgnored.cpp +++ b/cpp/ql/src/Critical/ReturnValueIgnored.cpp @@ -1,23 +1,23 @@ -int doFoo() { - ... - return status; -} - -void f() { - if (doFoo() == OK) { - ... - } -} - -void g() { - int status = doFoo(); - if (status == OK) { - ... - } -} - -void err() { - doFoo(); //doFoo is called but its return value is not checked, and - //the value is checked in other locations - ... -} +int doFoo() { + ... + return status; +} + +void f() { + if (doFoo() == OK) { + ... + } +} + +void g() { + int status = doFoo(); + if (status == OK) { + ... + } +} + +void err() { + doFoo(); //doFoo is called but its return value is not checked, and + //the value is checked in other locations + ... +} diff --git a/cpp/ql/src/Critical/SizeCheck.cpp b/cpp/ql/src/Critical/SizeCheck.cpp index 6400e9d4fb5..5f3ec91ad1e 100644 --- a/cpp/ql/src/Critical/SizeCheck.cpp +++ b/cpp/ql/src/Critical/SizeCheck.cpp @@ -1,10 +1,10 @@ -#define RECORD_SIZE 30 //incorrect or outdated size for record -typedef struct { - char name[30]; - int status; -} Record; - -void f() { - Record* p = malloc(RECORD_SIZE); //not of sufficient size to hold a Record - ... -} +#define RECORD_SIZE 30 //incorrect or outdated size for record +typedef struct { + char name[30]; + int status; +} Record; + +void f() { + Record* p = malloc(RECORD_SIZE); //not of sufficient size to hold a Record + ... +} diff --git a/cpp/ql/src/Critical/Unused.cpp b/cpp/ql/src/Critical/Unused.cpp index 01c60357397..bda3329d7c0 100644 --- a/cpp/ql/src/Critical/Unused.cpp +++ b/cpp/ql/src/Critical/Unused.cpp @@ -1,4 +1,4 @@ -{ - int foo = 1; - ... //foo is unused -} +{ + int foo = 1; + ... //foo is unused +} diff --git a/cpp/ql/src/Critical/UseAfterFree.cpp b/cpp/ql/src/Critical/UseAfterFree.cpp index 448696b4bb7..da921a6a31a 100644 --- a/cpp/ql/src/Critical/UseAfterFree.cpp +++ b/cpp/ql/src/Critical/UseAfterFree.cpp @@ -1,9 +1,9 @@ -int f() { - char* buf = new char[SIZE]; - .... - if (error) { - free(buf); //error handling has freed the buffer - } - ... - log_contents(buf); //but it is still used here for logging -} +int f() { + char* buf = new char[SIZE]; + .... + if (error) { + free(buf); //error handling has freed the buffer + } + ... + log_contents(buf); //but it is still used here for logging +} diff --git a/cpp/ql/src/Documentation/TodoComments.cpp b/cpp/ql/src/Documentation/TodoComments.cpp index 2404ca2b2e9..15cfb35b4e9 100644 --- a/cpp/ql/src/Documentation/TodoComments.cpp +++ b/cpp/ql/src/Documentation/TodoComments.cpp @@ -1,4 +1,4 @@ -int isOdd(int n) { - //TODO: Works only for positive n. Need to check if negative n is valid input - return (n % 2) == 1; +int isOdd(int n) { + //TODO: Works only for positive n. Need to check if negative n is valid input + return (n % 2) == 1; } \ No newline at end of file diff --git a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.cpp b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.cpp index 2b4e70c98ab..30904384a3a 100644 --- a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.cpp +++ b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.cpp @@ -1,8 +1,8 @@ -// header_file.h - -#ifndef HEADER_FILE_H -#define HEADER_FILE_H - - // ... - +// header_file.h + +#ifndef HEADER_FILE_H +#define HEADER_FILE_H + + // ... + #endif // HEADER_FILE_H \ No newline at end of file diff --git a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard2.cpp b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard2.cpp index 3a5d7afd9c2..5057800dcf6 100644 --- a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard2.cpp +++ b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard2.cpp @@ -1,8 +1,8 @@ -// another_header_file.h - -#ifndef HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H -#define HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H - - // ... - +// another_header_file.h + +#ifndef HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H +#define HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H + + // ... + #endif // HEADER_FILE_H \ No newline at end of file diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.cpp index 07f1a0529e9..34b7239ba41 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.cpp +++ b/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.cpp @@ -1,6 +1,6 @@ -void h() { - int a, b, c; - - a < b != c; //parenthesize to explicitly define order of operators - (a < b) < c; //correct: parenthesized to specify order -} +void h() { + int a, b, c; + + a < b != c; //parenthesize to explicitly define order of operators + (a < b) < c; //correct: parenthesized to specify order +} diff --git a/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.cpp b/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.cpp index eff2e167c1d..20c8b031d78 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.cpp +++ b/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.cpp @@ -1,13 +1,13 @@ - -//Function foo's array parameter has a specified size -void foo(int a[10]) { - int i = 0; - for (i = 0; i <10; i++) { - a[i] = i * 2; - } -} - -... - -int my_arr[5]; + +//Function foo's array parameter has a specified size +void foo(int a[10]) { + int i = 0; + for (i = 0; i <10; i++) { + a[i] = i * 2; + } +} + +... + +int my_arr[5]; foo(my_arr); //my_arr is smaller than foo's array parameter, and will cause access to memory outside its bounds \ No newline at end of file diff --git a/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.cpp b/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.cpp index f2f049de4a7..e19d001dd9f 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.cpp +++ b/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.cpp @@ -1,4 +1,4 @@ -//sz is a signed integer, but malloc expects one that is unsigned. -//Negative values will be interpreted as a large number, which may -//lead to unexpected behavior -char *buf = malloc(sz); +//sz is a signed integer, but malloc expects one that is unsigned. +//Negative values will be interpreted as a large number, which may +//lead to unexpected behavior +char *buf = malloc(sz); diff --git a/cpp/ql/src/Likely Bugs/Conversion/LossyPointerCast.cpp b/cpp/ql/src/Likely Bugs/Conversion/LossyPointerCast.cpp index 9f9bc1b08a8..a96b399541a 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/LossyPointerCast.cpp +++ b/cpp/ql/src/Likely Bugs/Conversion/LossyPointerCast.cpp @@ -1,5 +1,5 @@ -void f(char *p) { - int my_ptr = p; //Wrong: pointer assigned to int, would be incorrect if sizeof(char*) - //is larger than sizeof(int) - //... -} +void f(char *p) { + int my_ptr = p; //Wrong: pointer assigned to int, would be incorrect if sizeof(char*) + //is larger than sizeof(int) + //... +} diff --git a/cpp/ql/src/Likely Bugs/InconsistentCheckReturnNull.cpp b/cpp/ql/src/Likely Bugs/InconsistentCheckReturnNull.cpp index 69f25116ca1..302822f7437 100644 --- a/cpp/ql/src/Likely Bugs/InconsistentCheckReturnNull.cpp +++ b/cpp/ql/src/Likely Bugs/InconsistentCheckReturnNull.cpp @@ -1,30 +1,30 @@ -struct property { - char *name; - int value; -}; - -struct property * get_property(char *key); -struct property * get_property_default(char *key, int default_value); - -void check_properties() { - // this call will get flagged since most - // calls to get_property handle NULL - struct property *p1 = get_property("time"); - if(p1->value > 600) { - ... - } - - // this call will not get flagged since - // the result of the call is checked for NULL - struct property *p2 = get_property("time"); - if(p2 != NULL && p2->value > 600) { - ... - } - - // this call will not get flagged since calls - // to get_property_default rarely handle NULL - struct property *p3 = get_property_default("time", 50); - if(p3->value > 60) { - ... - } -} +struct property { + char *name; + int value; +}; + +struct property * get_property(char *key); +struct property * get_property_default(char *key, int default_value); + +void check_properties() { + // this call will get flagged since most + // calls to get_property handle NULL + struct property *p1 = get_property("time"); + if(p1->value > 600) { + ... + } + + // this call will not get flagged since + // the result of the call is checked for NULL + struct property *p2 = get_property("time"); + if(p2 != NULL && p2->value > 600) { + ... + } + + // this call will not get flagged since calls + // to get_property_default rarely handle NULL + struct property *p3 = get_property_default("time", 50); + if(p3->value > 60) { + ... + } +} diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/BoolValueInBitOp.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/BoolValueInBitOp.cpp index 6774921fb0c..155bba73e21 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/BoolValueInBitOp.cpp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/BoolValueInBitOp.cpp @@ -1,13 +1,13 @@ -if (!flags & SOME_BIT) { //wrong: '!' has higher precedence than '&', so this - // is bracketed as '(!flags) & SOME_BIT', and does not - // check whether a particular bit is set. - // ... -} - -if ((p != NULL) & p->f()) { //wrong: The use of '&' rather than '&&' will still - // de-reference the pointer even if it is NULL. - // ... -} - -int bits = (s > 8) & 0xff; //wrong: Invalid attempt to get the 8 most significant - // bits of a short. +if (!flags & SOME_BIT) { //wrong: '!' has higher precedence than '&', so this + // is bracketed as '(!flags) & SOME_BIT', and does not + // check whether a particular bit is set. + // ... +} + +if ((p != NULL) & p->f()) { //wrong: The use of '&' rather than '&&' will still + // de-reference the pointer even if it is NULL. + // ... +} + +int bits = (s > 8) & 0xff; //wrong: Invalid attempt to get the 8 most significant + // bits of a short. diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/LogicalExprCouldBeSimplified.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/LogicalExprCouldBeSimplified.cpp index f2de7c43c92..d54ca4adec2 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/LogicalExprCouldBeSimplified.cpp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/LogicalExprCouldBeSimplified.cpp @@ -1,11 +1,11 @@ -if (0 || condition) { //wrong: can be converted to just 'condition' - //... -} - -if (0 && condition) { //wrong: always evaluates to false, if statement can be removed - // ... -} - -if ('A' == 65 && condition) { // wrong: can be converted to just 'condition' - // ... -} +if (0 || condition) { //wrong: can be converted to just 'condition' + //... +} + +if (0 && condition) { //wrong: always evaluates to false, if statement can be removed + // ... +} + +if ('A' == 65 && condition) { // wrong: can be converted to just 'condition' + // ... +} diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.cpp index cec5e9337e8..11eb9de130e 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.cpp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.cpp @@ -1,30 +1,30 @@ -typedef enum { - RED, - ORANGE, - YELLOW, - GREEN, - BLUE, - INDIGO, - VIOLET -} colors; - -int f(colors c) { - switch (c) { - case RED: - //... - case GREEN: - //... - case BLUE: - //... - //wrong: does not use all enum values, and has no default - } - - switch(c) { - case RED: - //... - case GREEN: - //... - default: - //correct: does not use all enum values, but has a default - } -} +typedef enum { + RED, + ORANGE, + YELLOW, + GREEN, + BLUE, + INDIGO, + VIOLET +} colors; + +int f(colors c) { + switch (c) { + case RED: + //... + case GREEN: + //... + case BLUE: + //... + //wrong: does not use all enum values, and has no default + } + + switch(c) { + case RED: + //... + case GREEN: + //... + default: + //correct: does not use all enum values, but has a default + } +} diff --git a/cpp/ql/src/Likely Bugs/Memory Management/PotentialBufferOverflow.cpp b/cpp/ql/src/Likely Bugs/Memory Management/PotentialBufferOverflow.cpp index efb2569797c..cf83c251efc 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/PotentialBufferOverflow.cpp +++ b/cpp/ql/src/Likely Bugs/Memory Management/PotentialBufferOverflow.cpp @@ -1,12 +1,12 @@ -void f(char* s, float f) { - char buf[30]; - - //wrong: gets has no limit to the length of data it puts in the buffer - gets(buf); - - //wrong: sprintf does not limit the length of the string put into buf - sprintf(buf, "This is a string: %s", s); - - //wrong: %f can expand to a very long string in extreme cases, easily overrunning this buffer - sprintf(buf, "This is a float: %f", f); -} +void f(char* s, float f) { + char buf[30]; + + //wrong: gets has no limit to the length of data it puts in the buffer + gets(buf); + + //wrong: sprintf does not limit the length of the string put into buf + sprintf(buf, "This is a string: %s", s); + + //wrong: %f can expand to a very long string in extreme cases, easily overrunning this buffer + sprintf(buf, "This is a float: %f", f); +} diff --git a/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.cpp b/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.cpp index 219d082414d..c5cbcd2d7f1 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.cpp +++ b/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousCallToStrncat.cpp @@ -1,4 +1,4 @@ -strncat(dest, src, strlen(dest)); //wrong: should use remaining size of dest - -strncat(dest, src, sizeof(dest)); //wrong: should use remaining size of dest. - //Also fails if dest is a pointer and not an array. +strncat(dest, src, strlen(dest)); //wrong: should use remaining size of dest + +strncat(dest, src, sizeof(dest)); //wrong: should use remaining size of dest. + //Also fails if dest is a pointer and not an array. diff --git a/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousSizeof.cpp b/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousSizeof.cpp index 7c38d27a73a..ba76ea2dad7 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousSizeof.cpp +++ b/cpp/ql/src/Likely Bugs/Memory Management/SuspiciousSizeof.cpp @@ -1,4 +1,4 @@ -void f(char s[]) { - int size = sizeof(s); //wrong: s is now a char*, not an array. - //sizeof(s) will evaluate to sizeof(char *) -} +void f(char s[]) { + int size = sizeof(s); //wrong: s is now a char*, not an array. + //sizeof(s) will evaluate to sizeof(char *) +} diff --git a/cpp/ql/src/Likely Bugs/NestedLoopSameVar.cpp b/cpp/ql/src/Likely Bugs/NestedLoopSameVar.cpp index 7dd968cec7d..96aed351778 100644 --- a/cpp/ql/src/Likely Bugs/NestedLoopSameVar.cpp +++ b/cpp/ql/src/Likely Bugs/NestedLoopSameVar.cpp @@ -1,16 +1,16 @@ -int x1 = 0; -for (x1 = 0; x1 < 100; x1++) { - int x2 = 0; - for (x1 = 0; x1 < 300; x1++) { - // this is most likely a typo - // the outer loop will exit immediately - } -} - -for (x1 = 0; x1 < 100; x1++) { - if(x1 == 10 && condition) { - for (; x1 < 75; x1++) { - // this should be written as a while loop - } - } -} +int x1 = 0; +for (x1 = 0; x1 < 100; x1++) { + int x2 = 0; + for (x1 = 0; x1 < 300; x1++) { + // this is most likely a typo + // the outer loop will exit immediately + } +} + +for (x1 = 0; x1 < 100; x1++) { + if(x1 == 10 && condition) { + for (; x1 < 75; x1++) { + // this should be written as a while loop + } + } +} diff --git a/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructor.cpp b/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructor.cpp index 93ceb8dd111..cc9fae1221f 100644 --- a/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructor.cpp +++ b/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructor.cpp @@ -1,31 +1,31 @@ -class Base { -public: - Resource *p; - Base() { - p = createResource(); - } - //... - ~Base() { - //wrong: this destructor is non-virtual, but Base has a derived class - // with a non-virtual destructor - freeResource(p); - } -}; - -class Derived: public Base { -public: - Resource *dp; - Derived() { - dp = createResource2(); - } - ~Derived() { - freeResource2(dp); - } -}; - -int f() { - Base *b = new Derived(); //creates resources for both Base::p and Derived::dp - //... - delete b; //will only call Base::~Base(), leaking the resource dp. - // Change both destructors to virtual to ensure they are both called. -} +class Base { +public: + Resource *p; + Base() { + p = createResource(); + } + //... + ~Base() { + //wrong: this destructor is non-virtual, but Base has a derived class + // with a non-virtual destructor + freeResource(p); + } +}; + +class Derived: public Base { +public: + Resource *dp; + Derived() { + dp = createResource2(); + } + ~Derived() { + freeResource2(dp); + } +}; + +int f() { + Base *b = new Derived(); //creates resources for both Base::p and Derived::dp + //... + delete b; //will only call Base::~Base(), leaking the resource dp. + // Change both destructors to virtual to ensure they are both called. +} diff --git a/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.cpp b/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.cpp index 77f95e0b257..d7dcbec116a 100644 --- a/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.cpp +++ b/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.cpp @@ -1,19 +1,19 @@ -class C { -public: - //... - ~C(){ - if (error) { - throw "Exception in destructor"; //wrong: exception thrown in destructor - } - } -}; - -void f() { - C* c = new C(); - try { - doOperation(c); - delete c; - } catch ( char * do_operation_exception) { - delete c; //would immediately terminate program if C::~C throws an exception - } -} +class C { +public: + //... + ~C(){ + if (error) { + throw "Exception in destructor"; //wrong: exception thrown in destructor + } + } +}; + +void f() { + C* c = new C(); + try { + doOperation(c); + delete c; + } catch ( char * do_operation_exception) { + delete c; //would immediately terminate program if C::~C throws an exception + } +} diff --git a/cpp/ql/src/Likely Bugs/ShortLoopVarName.cpp b/cpp/ql/src/Likely Bugs/ShortLoopVarName.cpp index 568c994ec64..c1d299c231f 100644 --- a/cpp/ql/src/Likely Bugs/ShortLoopVarName.cpp +++ b/cpp/ql/src/Likely Bugs/ShortLoopVarName.cpp @@ -1,14 +1,14 @@ -int i = 0; -for (i = 0; i < NUM_RECORDS; i++) { - int j = 0; - //This loop should have a more descriptive iteration variable - for (j = 0; j < NUM_FIELDS; j++) { - process(record[i]->field[j]); - } - - int field_idx = 0; - //Better: the inner loop has a descriptive name - for (field_idx = 0; field_idx < NUM_FIELDS; field_idx++) { - save(record[i]->field[field_idx]); - } +int i = 0; +for (i = 0; i < NUM_RECORDS; i++) { + int j = 0; + //This loop should have a more descriptive iteration variable + for (j = 0; j < NUM_FIELDS; j++) { + process(record[i]->field[j]); + } + + int field_idx = 0; + //Better: the inner loop has a descriptive name + for (field_idx = 0; field_idx < NUM_FIELDS; field_idx++) { + save(record[i]->field[field_idx]); + } } \ No newline at end of file diff --git a/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.c b/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.c index 4f3b0dd2cf4..62acb4d15e5 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.c +++ b/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.c @@ -1,28 +1,28 @@ -void main(int argc, char **argv) { - uint32_t big_num = INT32_MAX; - char buf[big_num]; - int16_t bytes_received = 0; - int max_get = INT16_MAX + 1; - - // BAD: 'bytes_received' is compared with a value of a wider type. - // 'bytes_received' overflows before reaching 'max_get', - // causing an infinite loop - while (bytes_received < max_get) - bytes_received += get_from_input(buf, bytes_received); - } - - uint32_t bytes_received = 0; - - // GOOD: 'bytes_received2' has a type at least as wide as 'max_get' - while (bytes_received < max_get) { - bytes_received += get_from_input(buf, bytes_received); - } - -} - - -int getFromInput(char *buf, short pos) { - // write to buf - // ... - return 1; -} +void main(int argc, char **argv) { + uint32_t big_num = INT32_MAX; + char buf[big_num]; + int16_t bytes_received = 0; + int max_get = INT16_MAX + 1; + + // BAD: 'bytes_received' is compared with a value of a wider type. + // 'bytes_received' overflows before reaching 'max_get', + // causing an infinite loop + while (bytes_received < max_get) + bytes_received += get_from_input(buf, bytes_received); + } + + uint32_t bytes_received = 0; + + // GOOD: 'bytes_received2' has a type at least as wide as 'max_get' + while (bytes_received < max_get) { + bytes_received += get_from_input(buf, bytes_received); + } + +} + + +int getFromInput(char *buf, short pos) { + // write to buf + // ... + return 1; +} diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.cpp b/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.cpp index 2c9a76e676e..3ae1ca4db66 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.cpp +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.cpp @@ -1,20 +1,20 @@ -enum Shape_color { red, green, blue }; -class Shape -{ - public: - virtual void draw (Shape_color color = green) const; - ... -} -class Circle : public Shape -{ - public: - virtual void draw (Shape_color color = red) const; - ... -} -void fun() -{ - Shape* sp; - - sp = new Circle; - sp->draw (); // Invokes Circle::draw(green) even though the default -} // parameter for Circle is red. +enum Shape_color { red, green, blue }; +class Shape +{ + public: + virtual void draw (Shape_color color = green) const; + ... +} +class Circle : public Shape +{ + public: + virtual void draw (Shape_color color = red) const; + ... +} +void fun() +{ + Shape* sp; + + sp = new Circle; + sp->draw (); // Invokes Circle::draw(green) even though the default +} // parameter for Circle is red. diff --git a/cpp/ql/test/header-variant-tests/multi-target-includes/common.h b/cpp/ql/test/header-variant-tests/multi-target-includes/common.h index 8c20e36220b..a965769ffd6 100644 --- a/cpp/ql/test/header-variant-tests/multi-target-includes/common.h +++ b/cpp/ql/test/header-variant-tests/multi-target-includes/common.h @@ -1,5 +1,5 @@ -// common.h - -#include "nameclash.h" - +// common.h + +#include "nameclash.h" + static int myArray[sizeof(MYTYPE)]; \ No newline at end of file diff --git a/cpp/ql/test/header-variant-tests/multi-target-includes/defines_issue.h b/cpp/ql/test/header-variant-tests/multi-target-includes/defines_issue.h index f80f739121e..ea10509143e 100644 --- a/cpp/ql/test/header-variant-tests/multi-target-includes/defines_issue.h +++ b/cpp/ql/test/header-variant-tests/multi-target-includes/defines_issue.h @@ -1,3 +1,3 @@ -// defines_issue.h - +// defines_issue.h + #include DEFINED_HEADER \ No newline at end of file diff --git a/cpp/ql/test/header-variant-tests/multi-target-includes/main2.cpp b/cpp/ql/test/header-variant-tests/multi-target-includes/main2.cpp index 49ec6536942..9c4ba0e202c 100644 --- a/cpp/ql/test/header-variant-tests/multi-target-includes/main2.cpp +++ b/cpp/ql/test/header-variant-tests/multi-target-includes/main2.cpp @@ -1,7 +1,7 @@ -// semmle-extractor-options: -I${testdir}/subdir2 -// main2.cpp -#include "common.h" - -#define DEFINED_HEADER "define2.h" - -#include "defines_issue.h" +// semmle-extractor-options: -I${testdir}/subdir2 +// main2.cpp +#include "common.h" + +#define DEFINED_HEADER "define2.h" + +#include "defines_issue.h" diff --git a/cpp/ql/test/header-variant-tests/multi-target-includes/nameclash.h b/cpp/ql/test/header-variant-tests/multi-target-includes/nameclash.h index 9ab85dc2b12..bcfe8abed54 100644 --- a/cpp/ql/test/header-variant-tests/multi-target-includes/nameclash.h +++ b/cpp/ql/test/header-variant-tests/multi-target-includes/nameclash.h @@ -1,3 +1,3 @@ -// nameclash.h - +// nameclash.h + #include_next "nameclash.h" \ No newline at end of file diff --git a/cpp/ql/test/header-variant-tests/multi-target-includes/subdir1/nameclash.h b/cpp/ql/test/header-variant-tests/multi-target-includes/subdir1/nameclash.h index d0361b16bdd..f4a942327c2 100644 --- a/cpp/ql/test/header-variant-tests/multi-target-includes/subdir1/nameclash.h +++ b/cpp/ql/test/header-variant-tests/multi-target-includes/subdir1/nameclash.h @@ -1,3 +1,3 @@ -// subdir1/nameclash.h - +// subdir1/nameclash.h + typedef long long int MYTYPE; \ No newline at end of file diff --git a/cpp/ql/test/header-variant-tests/multi-target-includes/subdir2/nameclash.h b/cpp/ql/test/header-variant-tests/multi-target-includes/subdir2/nameclash.h index 469a0c9b303..0ffbb1fd89b 100644 --- a/cpp/ql/test/header-variant-tests/multi-target-includes/subdir2/nameclash.h +++ b/cpp/ql/test/header-variant-tests/multi-target-includes/subdir2/nameclash.h @@ -1,3 +1,3 @@ -// subdir2/nameclash.h - +// subdir2/nameclash.h + typedef char MYTYPE; \ No newline at end of file diff --git a/cpp/ql/test/library-tests/allocators/allocators.cpp b/cpp/ql/test/library-tests/allocators/allocators.cpp index a32c530f583..5f0a535e7f3 100644 --- a/cpp/ql/test/library-tests/allocators/allocators.cpp +++ b/cpp/ql/test/library-tests/allocators/allocators.cpp @@ -1,111 +1,111 @@ -// semmle-extractor-options: -std=c++17 -typedef unsigned long size_t; -namespace std { - enum class align_val_t : size_t {}; -} - -void* operator new(size_t, float); -void* operator new[](size_t, float); -void* operator new(size_t, std::align_val_t, float); -void* operator new[](size_t, std::align_val_t, float); -void operator delete(void*, float); -void operator delete[](void*, float); -void operator delete(void*, std::align_val_t, float); -void operator delete[](void*, std::align_val_t, float); - -struct String { - String(); - String(const String&); - String(String&&); - String(const char*); - ~String(); - - String& operator=(const String&); - String& operator=(String&&); - - const char* c_str() const; - -private: - const char* p; -}; - -struct SizedDealloc { - char a[32]; - void* operator new(size_t); - void* operator new[](size_t); - void operator delete(void*, size_t); - void operator delete[](void*, size_t); -}; - -struct alignas(128) Overaligned { - char a[256]; -}; - -struct PolymorphicBase { - virtual ~PolymorphicBase(); -}; - -void OperatorNew() { - new int; // No constructor - new(1.0f) int; // Placement new, no constructor - new int(); // Zero-init - new String(); // Constructor - new(1.0f) String("hello"); // Placement new, constructor with args - new Overaligned; // Aligned new - new(1.0f) Overaligned(); // Placement aligned new -} - -void OperatorDelete() { - delete static_cast(nullptr); // No destructor - delete static_cast(nullptr); // Non-virtual destructor, with size. - delete static_cast(nullptr); // No destructor, with size. - delete static_cast(nullptr); // No destructor, with size and alignment. - delete static_cast(nullptr); // Virtual destructor - delete static_cast(nullptr); // Pointer to const -} - -void OperatorNewArray(int n) { - new int[n]; // No constructor - new(1.0f) int[n]; // Placement new, no constructor - new String[n]; // Constructor - new Overaligned[n]; // Aligned new - new String[10]; // Constant size -} - -int* const GetPointer(); - -void OperatorDeleteArray() { - delete[] static_cast(nullptr); // No destructor - delete[] static_cast(nullptr); // Non-virtual destructor, with size. - delete[] static_cast(nullptr); // No destructor, with size. - delete[] static_cast(nullptr); // No destructor, with size and alignment. - delete[] static_cast(nullptr); // Virtual destructor - delete[] GetPointer(); -} - -struct FailedInit { - FailedInit(); - ~FailedInit(); - - void* operator new(size_t); // Non-placement - void* operator new[](size_t); // Non-placement - void operator delete(void*, size_t); // Sized deallocation - void operator delete[](void*, size_t); // Sized deallocation -}; - -struct alignas(128) FailedInitOveraligned { - FailedInitOveraligned(); - ~FailedInitOveraligned(); - - void* operator new(size_t, std::align_val_t, float); // Aligned placement - void* operator new[](size_t, std::align_val_t, float); // Aligned placement - void operator delete(void*, std::align_val_t, float); // Aligned placement - void operator delete[](void*, std::align_val_t, float); // Aligned placement -}; - -void TestFailedInit(int n) { - new FailedInit(); - new FailedInit[n]; - new(1.0f) FailedInitOveraligned(); - new(1.0f) FailedInitOveraligned[10]; -} +// semmle-extractor-options: -std=c++17 +typedef unsigned long size_t; +namespace std { + enum class align_val_t : size_t {}; +} + +void* operator new(size_t, float); +void* operator new[](size_t, float); +void* operator new(size_t, std::align_val_t, float); +void* operator new[](size_t, std::align_val_t, float); +void operator delete(void*, float); +void operator delete[](void*, float); +void operator delete(void*, std::align_val_t, float); +void operator delete[](void*, std::align_val_t, float); + +struct String { + String(); + String(const String&); + String(String&&); + String(const char*); + ~String(); + + String& operator=(const String&); + String& operator=(String&&); + + const char* c_str() const; + +private: + const char* p; +}; + +struct SizedDealloc { + char a[32]; + void* operator new(size_t); + void* operator new[](size_t); + void operator delete(void*, size_t); + void operator delete[](void*, size_t); +}; + +struct alignas(128) Overaligned { + char a[256]; +}; + +struct PolymorphicBase { + virtual ~PolymorphicBase(); +}; + +void OperatorNew() { + new int; // No constructor + new(1.0f) int; // Placement new, no constructor + new int(); // Zero-init + new String(); // Constructor + new(1.0f) String("hello"); // Placement new, constructor with args + new Overaligned; // Aligned new + new(1.0f) Overaligned(); // Placement aligned new +} + +void OperatorDelete() { + delete static_cast(nullptr); // No destructor + delete static_cast(nullptr); // Non-virtual destructor, with size. + delete static_cast(nullptr); // No destructor, with size. + delete static_cast(nullptr); // No destructor, with size and alignment. + delete static_cast(nullptr); // Virtual destructor + delete static_cast(nullptr); // Pointer to const +} + +void OperatorNewArray(int n) { + new int[n]; // No constructor + new(1.0f) int[n]; // Placement new, no constructor + new String[n]; // Constructor + new Overaligned[n]; // Aligned new + new String[10]; // Constant size +} + +int* const GetPointer(); + +void OperatorDeleteArray() { + delete[] static_cast(nullptr); // No destructor + delete[] static_cast(nullptr); // Non-virtual destructor, with size. + delete[] static_cast(nullptr); // No destructor, with size. + delete[] static_cast(nullptr); // No destructor, with size and alignment. + delete[] static_cast(nullptr); // Virtual destructor + delete[] GetPointer(); +} + +struct FailedInit { + FailedInit(); + ~FailedInit(); + + void* operator new(size_t); // Non-placement + void* operator new[](size_t); // Non-placement + void operator delete(void*, size_t); // Sized deallocation + void operator delete[](void*, size_t); // Sized deallocation +}; + +struct alignas(128) FailedInitOveraligned { + FailedInitOveraligned(); + ~FailedInitOveraligned(); + + void* operator new(size_t, std::align_val_t, float); // Aligned placement + void* operator new[](size_t, std::align_val_t, float); // Aligned placement + void operator delete(void*, std::align_val_t, float); // Aligned placement + void operator delete[](void*, std::align_val_t, float); // Aligned placement +}; + +void TestFailedInit(int n) { + new FailedInit(); + new FailedInit[n]; + new(1.0f) FailedInitOveraligned(); + new(1.0f) FailedInitOveraligned[10]; +} diff --git a/cpp/ql/test/library-tests/calls/calls1.cpp b/cpp/ql/test/library-tests/calls/calls1.cpp index 0c3f1231227..0b3238b0097 100644 --- a/cpp/ql/test/library-tests/calls/calls1.cpp +++ b/cpp/ql/test/library-tests/calls/calls1.cpp @@ -1,8 +1,8 @@ -#include "calls1.h" - -void swap(int* p, int* q) -{ - int t = *p; - *p = *q; - *q = t; -} +#include "calls1.h" + +void swap(int* p, int* q) +{ + int t = *p; + *p = *q; + *q = t; +} diff --git a/cpp/ql/test/library-tests/calls/calls1.h b/cpp/ql/test/library-tests/calls/calls1.h index 90b150ae9d6..af92b2bded3 100644 --- a/cpp/ql/test/library-tests/calls/calls1.h +++ b/cpp/ql/test/library-tests/calls/calls1.h @@ -1,2 +1,2 @@ - -extern void swap(int*, int*); + +extern void swap(int*, int*); diff --git a/cpp/ql/test/library-tests/calls/calls2.cpp b/cpp/ql/test/library-tests/calls/calls2.cpp index 4f10faa3f20..feedab7f719 100644 --- a/cpp/ql/test/library-tests/calls/calls2.cpp +++ b/cpp/ql/test/library-tests/calls/calls2.cpp @@ -1,20 +1,20 @@ -#include "calls1.h" - -void g() { - int x = 2; - int y = 4; - swap(&x,&y); -} - -void negate(int& c) { c = -c; } - -template void compute(Iter b, Fct f) -{ - f(b); -} - -void f(int aa) -{ - compute(aa, negate); -} - +#include "calls1.h" + +void g() { + int x = 2; + int y = 4; + swap(&x,&y); +} + +void negate(int& c) { c = -c; } + +template void compute(Iter b, Fct f) +{ + f(b); +} + +void f(int aa) +{ + compute(aa, negate); +} + diff --git a/cpp/ql/test/library-tests/classes/classes/Classes.ms.cpp b/cpp/ql/test/library-tests/classes/classes/Classes.ms.cpp index 4dafda9752f..06d239d70cd 100644 --- a/cpp/ql/test/library-tests/classes/classes/Classes.ms.cpp +++ b/cpp/ql/test/library-tests/classes/classes/Classes.ms.cpp @@ -1,41 +1,41 @@ -class A { - -}; - - -class B { - -}; - -class C: A, B { - -}; - -class D: C { - - class E; - -}; - -class D::E { - - class F; - - class G { - public: - /* Non-trivial constructor and destructor */ - G() { 0; } - ~G() { 0; } - }; - -}; - -class D::E::F: D::E::G { - /* Should have generated constructor and destructor, because of D::E::G */ - - static int m() { - D::E::F def; /* Should trigger creation of D::E::F's generated constructor and destructor. */ - } -}; - -// semmle-extractor-options: --microsoft +class A { + +}; + + +class B { + +}; + +class C: A, B { + +}; + +class D: C { + + class E; + +}; + +class D::E { + + class F; + + class G { + public: + /* Non-trivial constructor and destructor */ + G() { 0; } + ~G() { 0; } + }; + +}; + +class D::E::F: D::E::G { + /* Should have generated constructor and destructor, because of D::E::G */ + + static int m() { + D::E::F def; /* Should trigger creation of D::E::F's generated constructor and destructor. */ + } +}; + +// semmle-extractor-options: --microsoft diff --git a/cpp/ql/test/library-tests/classes/derivations/offsets/offsets.cpp b/cpp/ql/test/library-tests/classes/derivations/offsets/offsets.cpp index fed096f45df..745a37ca5c8 100644 --- a/cpp/ql/test/library-tests/classes/derivations/offsets/offsets.cpp +++ b/cpp/ql/test/library-tests/classes/derivations/offsets/offsets.cpp @@ -1,84 +1,84 @@ -struct Base { - int b1; - float b1f; -}; - -struct SingleInheritance : Base { - int si1; - float si1f; -}; - -struct Base2 { - int b2; - float b2f; -}; - -struct MultipleInheritance : Base, Base2 { - int mi1; - float mi1f; -}; - -struct DeepInheritance : MultipleInheritance, SingleInheritance { - int di1; - float di1f; -}; - -struct VirtualInheritance1 : virtual Base { - int vi1; - float vi1f; -}; - -struct VirtualInheritance2 : VirtualInheritance1, virtual Base, virtual Base2 { - int vi2; - float vi2f; -}; - -struct EffectivelyVirtual : virtual SingleInheritance, MultipleInheritance { - int ev1; - float ev1f; -}; - -struct PolymorphicBase { - virtual ~PolymorphicBase(); - int pb1; - float pb1f; -}; - -struct InheritsVTable : PolymorphicBase { - int iv1; - float iv1f; -}; - -struct IntroducesVTable : Base { - virtual ~IntroducesVTable(); - int iv2; - float iv2f; -}; - -struct Left : virtual Base { - int l1; - float l1f; -}; - -struct Right : virtual Base { - int r1; - float r1f; -}; - -struct Bottom : Left, Right { - int b1; - float b1f; -}; - -struct DeepSingleInheritance : SingleInheritance { - int dsi1; - float dsi1f; -}; - -struct Incomplete; -Incomplete* p; - -template -struct TemplateClass : Base -{ -}; +struct Base { + int b1; + float b1f; +}; + +struct SingleInheritance : Base { + int si1; + float si1f; +}; + +struct Base2 { + int b2; + float b2f; +}; + +struct MultipleInheritance : Base, Base2 { + int mi1; + float mi1f; +}; + +struct DeepInheritance : MultipleInheritance, SingleInheritance { + int di1; + float di1f; +}; + +struct VirtualInheritance1 : virtual Base { + int vi1; + float vi1f; +}; + +struct VirtualInheritance2 : VirtualInheritance1, virtual Base, virtual Base2 { + int vi2; + float vi2f; +}; + +struct EffectivelyVirtual : virtual SingleInheritance, MultipleInheritance { + int ev1; + float ev1f; +}; + +struct PolymorphicBase { + virtual ~PolymorphicBase(); + int pb1; + float pb1f; +}; + +struct InheritsVTable : PolymorphicBase { + int iv1; + float iv1f; +}; + +struct IntroducesVTable : Base { + virtual ~IntroducesVTable(); + int iv2; + float iv2f; +}; + +struct Left : virtual Base { + int l1; + float l1f; +}; + +struct Right : virtual Base { + int r1; + float r1f; +}; + +struct Bottom : Left, Right { + int b1; + float b1f; +}; + +struct DeepSingleInheritance : SingleInheritance { + int dsi1; + float dsi1f; +}; + +struct Incomplete; +Incomplete* p; + +template +struct TemplateClass : Base +{ +}; diff --git a/cpp/ql/test/library-tests/controlflow/loopentrycondition/forstmt.cpp b/cpp/ql/test/library-tests/controlflow/loopentrycondition/forstmt.cpp index 8345e3a2da6..f07fec46a58 100644 --- a/cpp/ql/test/library-tests/controlflow/loopentrycondition/forstmt.cpp +++ b/cpp/ql/test/library-tests/controlflow/loopentrycondition/forstmt.cpp @@ -1,102 +1,102 @@ -// GOOD = at least one iteration -// BAD = possibly no iterations - -void test1() { - for (int i = 0; i < 10; i++) { // GOOD - } -} - -void test2() { - for (int i = 0, j = 1; i + j < 10; i++) { // GOOD - } -} - -void test3() { - int j = 2; - for (int i = j = 1; i + j < 10; i++) { // GOOD - } -} - -void test4() { - int i = 2, j = 3; - for (i = j = 1; i + j < 10; i++) { // GOOD - } -} - -void test5() { - int i, k; - for (i = k = 0; i < 10; i++) { // GOOD - } -} - -void test6() { - int i = 0; - for (; i < 10; i++) { // GOOD - i = 1; - } -} - -void test7() { - int i = 0; - for (i = 1; i < 10; i++) { // GOOD - i = 1; - } -} - -void test8() { - int i = 0; - i = 1; - for (; i < 10; i++) { // GOOD (NOT REPORTED) - } -} - -void test9() { - bool done = false; - for (; !done; ) { // GOOD - done = true; - } -} - -void test10(int i) { - bool done = false; - for (; i++; i < 10) { // BAD - for (; !done; ) { // BAD - done = true; - } - } -} - -void test11(int i) { - for (; i++; i < 10) { // BAD - bool done = false; - for (; !done; ) { // GOOD - done = true; - } - } -} - -void test12(int max) { - int i, k; - int max_index = 0; - for (i = k = 0; i < max; i++) { // BAD - max_index = i; - } - for (i = 0; i <= max_index; i++) { // BAD - } -} - -void test13() { - int i; - for (i = 1; i > 0; ) { // GOOD - &i; - } -} - -void test14(bool b) { - int i = 1; - while (b) { - for (; i > 0; ) { // BAD - &i; - } - } +// GOOD = at least one iteration +// BAD = possibly no iterations + +void test1() { + for (int i = 0; i < 10; i++) { // GOOD + } +} + +void test2() { + for (int i = 0, j = 1; i + j < 10; i++) { // GOOD + } +} + +void test3() { + int j = 2; + for (int i = j = 1; i + j < 10; i++) { // GOOD + } +} + +void test4() { + int i = 2, j = 3; + for (i = j = 1; i + j < 10; i++) { // GOOD + } +} + +void test5() { + int i, k; + for (i = k = 0; i < 10; i++) { // GOOD + } +} + +void test6() { + int i = 0; + for (; i < 10; i++) { // GOOD + i = 1; + } +} + +void test7() { + int i = 0; + for (i = 1; i < 10; i++) { // GOOD + i = 1; + } +} + +void test8() { + int i = 0; + i = 1; + for (; i < 10; i++) { // GOOD (NOT REPORTED) + } +} + +void test9() { + bool done = false; + for (; !done; ) { // GOOD + done = true; + } +} + +void test10(int i) { + bool done = false; + for (; i++; i < 10) { // BAD + for (; !done; ) { // BAD + done = true; + } + } +} + +void test11(int i) { + for (; i++; i < 10) { // BAD + bool done = false; + for (; !done; ) { // GOOD + done = true; + } + } +} + +void test12(int max) { + int i, k; + int max_index = 0; + for (i = k = 0; i < max; i++) { // BAD + max_index = i; + } + for (i = 0; i <= max_index; i++) { // BAD + } +} + +void test13() { + int i; + for (i = 1; i > 0; ) { // GOOD + &i; + } +} + +void test14(bool b) { + int i = 1; + while (b) { + for (; i > 0; ) { // BAD + &i; + } + } } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/controlflow/loopentrycondition/whilestmt.cpp b/cpp/ql/test/library-tests/controlflow/loopentrycondition/whilestmt.cpp index e0ddb1b42f1..8155f2fabe9 100644 --- a/cpp/ql/test/library-tests/controlflow/loopentrycondition/whilestmt.cpp +++ b/cpp/ql/test/library-tests/controlflow/loopentrycondition/whilestmt.cpp @@ -1,64 +1,64 @@ -// GOOD = at least one iteration -// BAD = possibly no iterations - -void test1() { - bool done = false; - while (!done) { // GOOD - done = true; - } -} - -void test2() { - bool done = true; - done = false; - while (!done) { // GOOD (NOT REPORTED) - done = true; - } -} - -void test3(int i) { - bool done = false; - for (; i++; i < 10) { - while (!done) { // BAD - done = true; - } - } -} - -void test4(int i) { - for (; i++; i < 10) { - bool done = false; - while (!done) { // GOOD - done = true; - } - } -} - -void test5(int max) { - int i = 0, k = 0; - int max_index = 0; - while (i < max) { // BAD - max_index = i; - i++; - } - i = 0; - while (i <= max_index) { // BAD - i++; - } -} - -void test6() { - int i = 1; - while (i > 0) { // GOOD - &i; - } -} - -void test7(bool b) { - int i = 1; - while (b) { // BAD - while (i > 0) { // BAD - &i; - } - } +// GOOD = at least one iteration +// BAD = possibly no iterations + +void test1() { + bool done = false; + while (!done) { // GOOD + done = true; + } +} + +void test2() { + bool done = true; + done = false; + while (!done) { // GOOD (NOT REPORTED) + done = true; + } +} + +void test3(int i) { + bool done = false; + for (; i++; i < 10) { + while (!done) { // BAD + done = true; + } + } +} + +void test4(int i) { + for (; i++; i < 10) { + bool done = false; + while (!done) { // GOOD + done = true; + } + } +} + +void test5(int max) { + int i = 0, k = 0; + int max_index = 0; + while (i < max) { // BAD + max_index = i; + i++; + } + i = 0; + while (i <= max_index) { // BAD + i++; + } +} + +void test6() { + int i = 1; + while (i > 0) { // GOOD + &i; + } +} + +void test7(bool b) { + int i = 1; + while (b) { // BAD + while (i > 0) { // BAD + &i; + } + } } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/conversions/conversions.cpp b/cpp/ql/test/library-tests/conversions/conversions.cpp index 4fb1fa3c200..b9cdb8df02a 100644 --- a/cpp/ql/test/library-tests/conversions/conversions.cpp +++ b/cpp/ql/test/library-tests/conversions/conversions.cpp @@ -1,250 +1,250 @@ -typedef unsigned short ushort; - -enum E { - E0, - E1 -}; - -enum class EC : int { - EC0, - EC1 -}; - -void ArithmeticConversions() { - char c = 0; - unsigned char uc = 0; - short s = 0; - unsigned short us = 0; - int i = 0; - unsigned int ui = 0; - long l = 0; - unsigned long ul = 0; - long long ll = 0; - unsigned long long ull = 0; - float f = 0; - double d = 0; - wchar_t wc = 0; - E e{}; - EC ec{}; - - c = uc; - c = (char)uc; - c = char(uc); - c = static_cast(uc); - i = s; - i = (int)s; - i = int(s); - i = static_cast(s); - us = i; - us = (unsigned short)i; - us = ushort(i); - us = static_cast(i); - - i = d; - i = (int)d; - i = int(d); - i = static_cast(d); - - f = c; - f = (float)c; - f = float(c); - f = static_cast(c); - - f = d; - f = (float)d; - f = float(d); - f = static_cast(d); - - d = f; - d = (double)f; - d = double(f); - d = static_cast(f); - - i = E0; - i = e; - i = static_cast(EC::EC0); - i = static_cast(ec); - e = static_cast(i); - ec = static_cast(i); -} - -struct S { - int x; - double y; -}; - -void ConversionsToBool() { - bool b = 0; - int i = 0; - double d = 0; - void* p = nullptr; - int S::* pmd = nullptr; - - if (b) { - } - else if ((bool)b) { - } - else if (i) { - } - else if (d) { - } - else if (p) { - } - else if (pmd) { - } -} - -struct Base { - int b1; - void BaseMethod(); -}; - -struct Middle : Base { - int m1; - void MiddleMethod(); -}; - -struct Derived : Middle { - int d1; - void DerivedMethod(); -}; - -void HierarchyCasts() { - Base b; - Middle m; - Derived d; - - Base* pb = &b; - Middle* pm = &m; - Derived* pd = &d; - - b = m; - b = (Base)m; - b = static_cast(m); - pb = pm; - pb = (Base*)pm; - pb = static_cast(pm); - pb = reinterpret_cast(pm); - - m = (Middle&)b; - m = static_cast(b); - pm = (Middle*)pb; - pm = static_cast(pb); - pm = reinterpret_cast(pb); - - b = d; - b = (Base)d; - b = static_cast(d); - pb = pd; - pb = (Base*)pd; - pb = static_cast(pd); - pb = reinterpret_cast(pd); - - d = (Derived&)b; - d = static_cast(b); - pd = (Derived*)pb; - pd = static_cast(pb); - pd = reinterpret_cast(pb); -} - -void PTMCasts() { - int Base::* pb = &Base::b1; - void (Base::* pmfb)() = &Base::BaseMethod; - int Middle::* pm = &Middle::m1; - void (Middle::* pmfm)() = &Middle::MiddleMethod; - int Derived::* pd = &Derived::d1; - void (Derived::* pmfd)() = &Derived::DerivedMethod; - - pb = (int Base::*)pm; - pmfb = (void (Base::*)())pmfm; - pb = static_cast(pm); - pmfb = static_cast(pmfm); - - pm = pb; - pmfm = pmfb; - pm = (int Middle::*)pb; - pmfm = (void (Middle::*)())pmfb; - pm = static_cast(pb); - pmfm = static_cast(pmfb); - - pb = (int Base::*)pd; - pmfb = (void (Base::*)())pmfd; - pb = static_cast(pd); - pmfb = static_cast(pmfd); - - pd = pb; - pmfd = pmfb; - pd = (int Derived::*)pb; - pmfd = (void (Derived::*)())pmfb; - pd = static_cast(pb); - pmfd = static_cast(pmfb); -} - -struct String { - String(); - String(const String&); - ~String(); -}; - -void Adjust() { - const String& s1 = String(); // prvalue adjustment - Base b; - Derived d; - const Base& rb = true ? b : d; // glvalue adjustment - const Base& r = (Base&)s1; -} - -void QualificationConversions() { - const int* pc = nullptr; - const volatile int* pcv = nullptr; - pcv = pc; - pc = const_cast(pcv); -} - -void PointerIntegralConversions() { - void* p = nullptr; - long n = (long)p; - n = reinterpret_cast(p); - p = (void*)n; - p = reinterpret_cast(n); -} - -struct PolymorphicBase { - virtual ~PolymorphicBase(); -}; - -struct PolymorphicDerived : PolymorphicBase { -}; - -void DynamicCast() { - PolymorphicBase b; - PolymorphicDerived d; - - PolymorphicBase* pb = &b; - PolymorphicDerived* pd = &d; - - // These two casts were previously represented as BaseClassCasts because they were resolved at compile time, but the front-end no longer performs this optimization. - pb = dynamic_cast(pd); - PolymorphicBase& rb = dynamic_cast(d); - - pd = dynamic_cast(pb); - PolymorphicDerived& rd = dynamic_cast(b); -} - -void FuncPtrConversions(int(*pfn)(int), void* p) { - p = (void*)pfn; - pfn = (int(*)(int))p; -} - -int Func(); - -void ConversionsToVoid() { - int x; - (void)x; - static_cast(x); - (void)Func(); - static_cast(Func()); - (void)1; - static_cast(1); -} - +typedef unsigned short ushort; + +enum E { + E0, + E1 +}; + +enum class EC : int { + EC0, + EC1 +}; + +void ArithmeticConversions() { + char c = 0; + unsigned char uc = 0; + short s = 0; + unsigned short us = 0; + int i = 0; + unsigned int ui = 0; + long l = 0; + unsigned long ul = 0; + long long ll = 0; + unsigned long long ull = 0; + float f = 0; + double d = 0; + wchar_t wc = 0; + E e{}; + EC ec{}; + + c = uc; + c = (char)uc; + c = char(uc); + c = static_cast(uc); + i = s; + i = (int)s; + i = int(s); + i = static_cast(s); + us = i; + us = (unsigned short)i; + us = ushort(i); + us = static_cast(i); + + i = d; + i = (int)d; + i = int(d); + i = static_cast(d); + + f = c; + f = (float)c; + f = float(c); + f = static_cast(c); + + f = d; + f = (float)d; + f = float(d); + f = static_cast(d); + + d = f; + d = (double)f; + d = double(f); + d = static_cast(f); + + i = E0; + i = e; + i = static_cast(EC::EC0); + i = static_cast(ec); + e = static_cast(i); + ec = static_cast(i); +} + +struct S { + int x; + double y; +}; + +void ConversionsToBool() { + bool b = 0; + int i = 0; + double d = 0; + void* p = nullptr; + int S::* pmd = nullptr; + + if (b) { + } + else if ((bool)b) { + } + else if (i) { + } + else if (d) { + } + else if (p) { + } + else if (pmd) { + } +} + +struct Base { + int b1; + void BaseMethod(); +}; + +struct Middle : Base { + int m1; + void MiddleMethod(); +}; + +struct Derived : Middle { + int d1; + void DerivedMethod(); +}; + +void HierarchyCasts() { + Base b; + Middle m; + Derived d; + + Base* pb = &b; + Middle* pm = &m; + Derived* pd = &d; + + b = m; + b = (Base)m; + b = static_cast(m); + pb = pm; + pb = (Base*)pm; + pb = static_cast(pm); + pb = reinterpret_cast(pm); + + m = (Middle&)b; + m = static_cast(b); + pm = (Middle*)pb; + pm = static_cast(pb); + pm = reinterpret_cast(pb); + + b = d; + b = (Base)d; + b = static_cast(d); + pb = pd; + pb = (Base*)pd; + pb = static_cast(pd); + pb = reinterpret_cast(pd); + + d = (Derived&)b; + d = static_cast(b); + pd = (Derived*)pb; + pd = static_cast(pb); + pd = reinterpret_cast(pb); +} + +void PTMCasts() { + int Base::* pb = &Base::b1; + void (Base::* pmfb)() = &Base::BaseMethod; + int Middle::* pm = &Middle::m1; + void (Middle::* pmfm)() = &Middle::MiddleMethod; + int Derived::* pd = &Derived::d1; + void (Derived::* pmfd)() = &Derived::DerivedMethod; + + pb = (int Base::*)pm; + pmfb = (void (Base::*)())pmfm; + pb = static_cast(pm); + pmfb = static_cast(pmfm); + + pm = pb; + pmfm = pmfb; + pm = (int Middle::*)pb; + pmfm = (void (Middle::*)())pmfb; + pm = static_cast(pb); + pmfm = static_cast(pmfb); + + pb = (int Base::*)pd; + pmfb = (void (Base::*)())pmfd; + pb = static_cast(pd); + pmfb = static_cast(pmfd); + + pd = pb; + pmfd = pmfb; + pd = (int Derived::*)pb; + pmfd = (void (Derived::*)())pmfb; + pd = static_cast(pb); + pmfd = static_cast(pmfb); +} + +struct String { + String(); + String(const String&); + ~String(); +}; + +void Adjust() { + const String& s1 = String(); // prvalue adjustment + Base b; + Derived d; + const Base& rb = true ? b : d; // glvalue adjustment + const Base& r = (Base&)s1; +} + +void QualificationConversions() { + const int* pc = nullptr; + const volatile int* pcv = nullptr; + pcv = pc; + pc = const_cast(pcv); +} + +void PointerIntegralConversions() { + void* p = nullptr; + long n = (long)p; + n = reinterpret_cast(p); + p = (void*)n; + p = reinterpret_cast(n); +} + +struct PolymorphicBase { + virtual ~PolymorphicBase(); +}; + +struct PolymorphicDerived : PolymorphicBase { +}; + +void DynamicCast() { + PolymorphicBase b; + PolymorphicDerived d; + + PolymorphicBase* pb = &b; + PolymorphicDerived* pd = &d; + + // These two casts were previously represented as BaseClassCasts because they were resolved at compile time, but the front-end no longer performs this optimization. + pb = dynamic_cast(pd); + PolymorphicBase& rb = dynamic_cast(d); + + pd = dynamic_cast(pb); + PolymorphicDerived& rd = dynamic_cast(b); +} + +void FuncPtrConversions(int(*pfn)(int), void* p) { + p = (void*)pfn; + pfn = (int(*)(int))p; +} + +int Func(); + +void ConversionsToVoid() { + int x; + (void)x; + static_cast(x); + (void)Func(); + static_cast(Func()); + (void)1; + static_cast(1); +} + diff --git a/cpp/ql/test/library-tests/ctorinits/ctorinits.cpp b/cpp/ql/test/library-tests/ctorinits/ctorinits.cpp index 6d39d6a393c..13d0e1e4b01 100644 --- a/cpp/ql/test/library-tests/ctorinits/ctorinits.cpp +++ b/cpp/ql/test/library-tests/ctorinits/ctorinits.cpp @@ -45,53 +45,53 @@ private: int xs[4]; }; -struct A { - A(int); -}; - -struct B { - B(int); -}; - -struct C { - C(int); -}; - -struct MultipleBases : A, B, C { - int x; - int y; - int z; - - MultipleBases() : - z(5), - B(1), - x(3), - A(0), - C(2), - y(4) { - } -}; - -struct VB { +struct A { + A(int); +}; + +struct B { + B(int); +}; + +struct C { + C(int); +}; + +struct MultipleBases : A, B, C { + int x; + int y; + int z; + + MultipleBases() : + z(5), + B(1), + x(3), + A(0), + C(2), + y(4) { + } +}; + +struct VB { VB(); VB(int); ~VB(); }; -struct VD : virtual VB { -}; - -struct VirtualAndNonVirtual : VD, VB { - VirtualAndNonVirtual() { - } - ~VirtualAndNonVirtual() { - } -}; - -struct AllYourVirtualBaseAreBelongToUs : VD, VirtualAndNonVirtual, virtual VB { - AllYourVirtualBaseAreBelongToUs() : - VB(5) { - } - ~AllYourVirtualBaseAreBelongToUs() { - } +struct VD : virtual VB { +}; + +struct VirtualAndNonVirtual : VD, VB { + VirtualAndNonVirtual() { + } + ~VirtualAndNonVirtual() { + } +}; + +struct AllYourVirtualBaseAreBelongToUs : VD, VirtualAndNonVirtual, virtual VB { + AllYourVirtualBaseAreBelongToUs() : + VB(5) { + } + ~AllYourVirtualBaseAreBelongToUs() { + } }; \ No newline at end of file diff --git a/cpp/ql/test/library-tests/declarationEntry/template/src5.cpp b/cpp/ql/test/library-tests/declarationEntry/template/src5.cpp index 8fc3e31ad72..3e5111f09bf 100644 --- a/cpp/ql/test/library-tests/declarationEntry/template/src5.cpp +++ b/cpp/ql/test/library-tests/declarationEntry/template/src5.cpp @@ -1,10 +1,10 @@ -// src5.cpp - -#include "src5.fwd.hpp" - -template - class my_istream { - }; - -template <> - class my_istream; +// src5.cpp + +#include "src5.fwd.hpp" + +template + class my_istream { + }; + +template <> + class my_istream; diff --git a/cpp/ql/test/library-tests/declarationEntry/template/src5.fwd.hpp b/cpp/ql/test/library-tests/declarationEntry/template/src5.fwd.hpp index 770189f7266..8a7cec05bca 100644 --- a/cpp/ql/test/library-tests/declarationEntry/template/src5.fwd.hpp +++ b/cpp/ql/test/library-tests/declarationEntry/template/src5.fwd.hpp @@ -1,8 +1,8 @@ -// src5.fwd.hpp - -#ifndef SRC5_FWD_HPP -#define SRC5_FWD_HPP - - template class my_istream; - -#endif // SRC5_FWD_HPP +// src5.fwd.hpp + +#ifndef SRC5_FWD_HPP +#define SRC5_FWD_HPP + + template class my_istream; + +#endif // SRC5_FWD_HPP diff --git a/cpp/ql/test/library-tests/declarationEntry/template/src6.cpp b/cpp/ql/test/library-tests/declarationEntry/template/src6.cpp index 729a25f5049..2bb70e22f22 100644 --- a/cpp/ql/test/library-tests/declarationEntry/template/src6.cpp +++ b/cpp/ql/test/library-tests/declarationEntry/template/src6.cpp @@ -1,5 +1,5 @@ -// src6.cpp - -#include "src5.fwd.hpp" - -my_istream *mis_c; +// src6.cpp + +#include "src5.fwd.hpp" + +my_istream *mis_c; diff --git a/cpp/ql/test/library-tests/depends_addressable/addressable.cpp b/cpp/ql/test/library-tests/depends_addressable/addressable.cpp index 40de1850c7e..a6c22730002 100644 --- a/cpp/ql/test/library-tests/depends_addressable/addressable.cpp +++ b/cpp/ql/test/library-tests/depends_addressable/addressable.cpp @@ -1,28 +1,28 @@ -class A { -public: - A() {} -}; - -A a; -void f() {} - - -class Test { - A aa; - - void fa() {} - - void test() { - void (*fptr)(); - void (Test::*mfptr)(); - void *ptr; - - ptr = &a; - ptr = &aa; - - fptr = f; // same as below - fptr = &f; // same as above - mfptr = &Test::fa; - - } -}; +class A { +public: + A() {} +}; + +A a; +void f() {} + + +class Test { + A aa; + + void fa() {} + + void test() { + void (*fptr)(); + void (Test::*mfptr)(); + void *ptr; + + ptr = &a; + ptr = &aa; + + fptr = f; // same as below + fptr = &f; // same as above + mfptr = &Test::fa; + + } +}; diff --git a/cpp/ql/test/library-tests/depends_friends/friends.cpp b/cpp/ql/test/library-tests/depends_friends/friends.cpp index 1acdd763a90..2335b0829e1 100644 --- a/cpp/ql/test/library-tests/depends_friends/friends.cpp +++ b/cpp/ql/test/library-tests/depends_friends/friends.cpp @@ -1,28 +1,28 @@ -class Friend1 { -public: - void f(); -protected: - void g(); -private: - void h(); -}; - -class Friend2 { -public: - void f(); -protected: - void g(); -private: - void h(); -}; - -void Friend2::f() { -} - -void friendFunc() {} - -class C { - friend class Friend1; - friend void Friend2::f(); - friend void friendFunc(); -}; +class Friend1 { +public: + void f(); +protected: + void g(); +private: + void h(); +}; + +class Friend2 { +public: + void f(); +protected: + void g(); +private: + void h(); +}; + +void Friend2::f() { +} + +void friendFunc() {} + +class C { + friend class Friend1; + friend void Friend2::f(); + friend void friendFunc(); +}; diff --git a/cpp/ql/test/library-tests/depends_initializers/initializers.cpp b/cpp/ql/test/library-tests/depends_initializers/initializers.cpp index 079398e20bc..85a83d245eb 100644 --- a/cpp/ql/test/library-tests/depends_initializers/initializers.cpp +++ b/cpp/ql/test/library-tests/depends_initializers/initializers.cpp @@ -1,31 +1,31 @@ -//references(UserType) -class A { -public: - A() {} -}; - -int f() { - void *a_ptr = new A(); //match (1 call) - A a = A(); // match (1 call) - return 1; -} - -//calls(Function) -int g() {return 0;} -extern int h(); - -int x = g(); //match -int y = x + g(); //match (1 call, 1 access) -int z = x + g() + h(); //match(2 calls, 1 access) - -//accesses(Variable) -int i = 1; -int j = i; //match (1 access) - -A a; //match(1 call) -A ax = A(); //match (1 call) -A aax = ax; //match (1 access) - -//array initialization -int myIntArray[5] = {i, 0, 0, 0, 0}; //match(1 access) -A myObjectArray[3]; //match(1 call) +//references(UserType) +class A { +public: + A() {} +}; + +int f() { + void *a_ptr = new A(); //match (1 call) + A a = A(); // match (1 call) + return 1; +} + +//calls(Function) +int g() {return 0;} +extern int h(); + +int x = g(); //match +int y = x + g(); //match (1 call, 1 access) +int z = x + g() + h(); //match(2 calls, 1 access) + +//accesses(Variable) +int i = 1; +int j = i; //match (1 access) + +A a; //match(1 call) +A ax = A(); //match (1 call) +A aax = ax; //match (1 access) + +//array initialization +int myIntArray[5] = {i, 0, 0, 0, 0}; //match(1 access) +A myObjectArray[3]; //match(1 call) diff --git a/cpp/ql/test/library-tests/depends_initializers/template_static.cpp b/cpp/ql/test/library-tests/depends_initializers/template_static.cpp index 956cd767d63..4bc6a869fce 100644 --- a/cpp/ql/test/library-tests/depends_initializers/template_static.cpp +++ b/cpp/ql/test/library-tests/depends_initializers/template_static.cpp @@ -1,89 +1,89 @@ - -const int c = 1; -int v = 1; -int one() {return 1;} - -void myNormalFunction() -{ - static int static_1 = 1; - static int static_c = c; - static int static_v = v; - static int static_one = one(); - int local_1 = 1; - int local_c = c; - int local_v = v; - int local_one = one(); -} - -template void myTemplateFunction() -{ - static int static_int_1 = 1; - static int static_int_c = c; // [initializer is not populated] - static int static_int_v = v; // [initializer is not populated] - static int static_int_one = one(); // [initializer is not populated] - static T static_t_1 = 1; // [initializer is not populated] - static T static_t_c = c; // [initializer is not populated] - static T static_t_v = v; // [initializer is not populated] - static T static_t_one = one(); // [initializer is not populated] - - int local_int_1 = 1; - int local_int_c = c; - int local_int_v = v; - int local_int_one = one(); - T local_t_1 = 1; - T local_t_c = c; - T local_t_v = v; - T local_t_one = one(); -} - -template class myTemplateClass -{ -public: - void myMethod() - { - static int static_int_1 = 1; - static int static_int_c = c; // [initializer is not populated] - static int static_int_v = v; // [initializer is not populated] - static int static_int_one = one(); // [initializer is not populated] - static T static_t_1 = 1; // [initializer is not populated] - static T static_t_c = c; // [initializer is not populated] - static T static_t_v = v; // [initializer is not populated] - static T static_t_one = one(); // [initializer is not populated] - - int local_int_1 = 1; - int local_int_c = c; - int local_int_v = v; - int local_int_one = one(); - T local_t_1 = 1; - T local_t_c = c; - T local_t_v = v; - T local_t_one = one(); - } -}; - -enum myEnum -{ - MYENUM_CONST -}; - -template void myTemplateFunction2(int a = 1, T b = 2) -{ - static int static_int_zero = 0; - static int static_int_ec = MYENUM_CONST; - static int static_int_expr = v + 1; - static int *static_int_addr = &v; - static int static_int_sizeof_v = sizeof(v); - static int static_int_sizeof_t = sizeof(T); - static T static_t_zero = 0; - static T static_t_ec = MYENUM_CONST; - static T static_t_expr = v + 1; - static T *static_t_addr = &v; - static T static_t_sizeof_v = sizeof(v); - static T static_t_sizeof_t = sizeof(T); - - static int static_int_c1 = c; - static int static_int_c2=c; - { - static int static_int_v2 = v; - } -} + +const int c = 1; +int v = 1; +int one() {return 1;} + +void myNormalFunction() +{ + static int static_1 = 1; + static int static_c = c; + static int static_v = v; + static int static_one = one(); + int local_1 = 1; + int local_c = c; + int local_v = v; + int local_one = one(); +} + +template void myTemplateFunction() +{ + static int static_int_1 = 1; + static int static_int_c = c; // [initializer is not populated] + static int static_int_v = v; // [initializer is not populated] + static int static_int_one = one(); // [initializer is not populated] + static T static_t_1 = 1; // [initializer is not populated] + static T static_t_c = c; // [initializer is not populated] + static T static_t_v = v; // [initializer is not populated] + static T static_t_one = one(); // [initializer is not populated] + + int local_int_1 = 1; + int local_int_c = c; + int local_int_v = v; + int local_int_one = one(); + T local_t_1 = 1; + T local_t_c = c; + T local_t_v = v; + T local_t_one = one(); +} + +template class myTemplateClass +{ +public: + void myMethod() + { + static int static_int_1 = 1; + static int static_int_c = c; // [initializer is not populated] + static int static_int_v = v; // [initializer is not populated] + static int static_int_one = one(); // [initializer is not populated] + static T static_t_1 = 1; // [initializer is not populated] + static T static_t_c = c; // [initializer is not populated] + static T static_t_v = v; // [initializer is not populated] + static T static_t_one = one(); // [initializer is not populated] + + int local_int_1 = 1; + int local_int_c = c; + int local_int_v = v; + int local_int_one = one(); + T local_t_1 = 1; + T local_t_c = c; + T local_t_v = v; + T local_t_one = one(); + } +}; + +enum myEnum +{ + MYENUM_CONST +}; + +template void myTemplateFunction2(int a = 1, T b = 2) +{ + static int static_int_zero = 0; + static int static_int_ec = MYENUM_CONST; + static int static_int_expr = v + 1; + static int *static_int_addr = &v; + static int static_int_sizeof_v = sizeof(v); + static int static_int_sizeof_t = sizeof(T); + static T static_t_zero = 0; + static T static_t_ec = MYENUM_CONST; + static T static_t_expr = v + 1; + static T *static_t_addr = &v; + static T static_t_sizeof_v = sizeof(v); + static T static_t_sizeof_t = sizeof(T); + + static int static_int_c1 = c; + static int static_int_c2=c; + { + static int static_int_v2 = v; + } +} diff --git a/cpp/ql/test/library-tests/depends_initializers/template_static_instantiated.cpp b/cpp/ql/test/library-tests/depends_initializers/template_static_instantiated.cpp index 06d5ae355fd..ad703eee4af 100644 --- a/cpp/ql/test/library-tests/depends_initializers/template_static_instantiated.cpp +++ b/cpp/ql/test/library-tests/depends_initializers/template_static_instantiated.cpp @@ -1,74 +1,74 @@ -namespace ns2 { -const int c = 1; -int v = 1; -int one() {return 1;} - -void myNormalFunction() -{ - static int static_1 = 1; - static int static_c = c; - static int static_v = v; - static int static_one = one(); - int local_1 = 1; - int local_c = c; - int local_v = v; - int local_one = one(); -} - -template void myTemplateFunction() -{ - static int static_int_1 = 1; - static int static_int_c = c; // [initializer is not populated] - static int static_int_v = v; // [initializer is not populated] - static int static_int_one = one(); // [initializer is not populated] - static T static_t_1 = 1; // [initializer is not populated] - static T static_t_c = c; // [initializer is not populated] - static T static_t_v = v; // [initializer is not populated] - static T static_t_one = one(); // [initializer is not populated] - - int local_int_1 = 1; - int local_int_c = c; - int local_int_v = v; - int local_int_one = one(); - T local_t_1 = 1; - T local_t_c = c; - T local_t_v = v; - T local_t_one = one(); -} - -template class myTemplateClass -{ -public: - void myMethod() - { - static int static_int_1 = 1; - static int static_int_c = c; // [initializer is not populated] - static int static_int_v = v; // [initializer is not populated] - static int static_int_one = one(); // [initializer is not populated] - static T static_t_1 = 1; // [initializer is not populated] - static T static_t_c = c; // [initializer is not populated] - static T static_t_v = v; // [initializer is not populated] - static T static_t_one = one(); // [initializer is not populated] - - int local_int_1 = 1; - int local_int_c = c; - int local_int_v = v; - int local_int_one = one(); - T local_t_1 = 1; - T local_t_c = c; - T local_t_v = v; - T local_t_one = one(); - } -}; - -void testFunc() -{ - // instantiate the templates - myTemplateFunction(); - - { - myTemplateClass mtc; - mtc.myMethod(); - } -} -} +namespace ns2 { +const int c = 1; +int v = 1; +int one() {return 1;} + +void myNormalFunction() +{ + static int static_1 = 1; + static int static_c = c; + static int static_v = v; + static int static_one = one(); + int local_1 = 1; + int local_c = c; + int local_v = v; + int local_one = one(); +} + +template void myTemplateFunction() +{ + static int static_int_1 = 1; + static int static_int_c = c; // [initializer is not populated] + static int static_int_v = v; // [initializer is not populated] + static int static_int_one = one(); // [initializer is not populated] + static T static_t_1 = 1; // [initializer is not populated] + static T static_t_c = c; // [initializer is not populated] + static T static_t_v = v; // [initializer is not populated] + static T static_t_one = one(); // [initializer is not populated] + + int local_int_1 = 1; + int local_int_c = c; + int local_int_v = v; + int local_int_one = one(); + T local_t_1 = 1; + T local_t_c = c; + T local_t_v = v; + T local_t_one = one(); +} + +template class myTemplateClass +{ +public: + void myMethod() + { + static int static_int_1 = 1; + static int static_int_c = c; // [initializer is not populated] + static int static_int_v = v; // [initializer is not populated] + static int static_int_one = one(); // [initializer is not populated] + static T static_t_1 = 1; // [initializer is not populated] + static T static_t_c = c; // [initializer is not populated] + static T static_t_v = v; // [initializer is not populated] + static T static_t_one = one(); // [initializer is not populated] + + int local_int_1 = 1; + int local_int_c = c; + int local_int_v = v; + int local_int_one = one(); + T local_t_1 = 1; + T local_t_c = c; + T local_t_v = v; + T local_t_one = one(); + } +}; + +void testFunc() +{ + // instantiate the templates + myTemplateFunction(); + + { + myTemplateClass mtc; + mtc.myMethod(); + } +} +} diff --git a/cpp/ql/test/library-tests/derived_types/derivedtype.cpp b/cpp/ql/test/library-tests/derived_types/derivedtype.cpp index 496901e6e09..1f71350d5cd 100644 --- a/cpp/ql/test/library-tests/derived_types/derivedtype.cpp +++ b/cpp/ql/test/library-tests/derived_types/derivedtype.cpp @@ -1,9 +1,9 @@ -class C { - C() {} -}; - -typedef C CC; - -CC** f() { - return 0; -} +class C { + C() {} +}; + +typedef C CC; + +CC** f() { + return 0; +} diff --git a/cpp/ql/test/library-tests/enums/enums/enums.cpp b/cpp/ql/test/library-tests/enums/enums/enums.cpp index 1fb523eca80..8404970fa3a 100644 --- a/cpp/ql/test/library-tests/enums/enums/enums.cpp +++ b/cpp/ql/test/library-tests/enums/enums/enums.cpp @@ -1,15 +1,15 @@ -const int j = 0; - -enum Day { sun, mon, tue, wed, thu, fri, sat }; -enum Day2 { sun2 = j, mon2, tue2 }; -enum Flag { b = 'a', c = 'b', d = 'd' }; - -Day& operator++(Day& d) -{ - int i = d; - Flag f = Flag(7); - Flag g = Flag(8); - //const int *p = &sat; - Day2 d2 = (Day2)d; - return d = (sat==d) ? sun: Day(d+1); -} +const int j = 0; + +enum Day { sun, mon, tue, wed, thu, fri, sat }; +enum Day2 { sun2 = j, mon2, tue2 }; +enum Flag { b = 'a', c = 'b', d = 'd' }; + +Day& operator++(Day& d) +{ + int i = d; + Flag f = Flag(7); + Flag g = Flag(8); + //const int *p = &sat; + Day2 d2 = (Day2)d; + return d = (sat==d) ? sun: Day(d+1); +} diff --git a/cpp/ql/test/library-tests/exprs/comparison_operation/test.cpp b/cpp/ql/test/library-tests/exprs/comparison_operation/test.cpp index 0735583e171..8fd8cb45172 100644 --- a/cpp/ql/test/library-tests/exprs/comparison_operation/test.cpp +++ b/cpp/ql/test/library-tests/exprs/comparison_operation/test.cpp @@ -1,14 +1,14 @@ - -int main() -{ - int x; - - if (x == 1) {} - if (x != 1) {} - if (x < 1) {} - if (x > 1) {} - if (x <= 1) {} - if (x >= 1) {} - - return 0; -} + +int main() +{ + int x; + + if (x == 1) {} + if (x != 1) {} + if (x < 1) {} + if (x > 1) {} + if (x <= 1) {} + if (x >= 1) {} + + return 0; +} diff --git a/cpp/ql/test/library-tests/exprs/unary_operation/test.cpp b/cpp/ql/test/library-tests/exprs/unary_operation/test.cpp index 8b33083b13f..2400527d174 100644 --- a/cpp/ql/test/library-tests/exprs/unary_operation/test.cpp +++ b/cpp/ql/test/library-tests/exprs/unary_operation/test.cpp @@ -1,15 +1,15 @@ - -int main() -{ - int i; - int *ip; - - i = +(-1); - i++; - ip = &i; - *ip--; - ++i; - --i; - - return 0; -} + +int main() +{ + int i; + int *ip; + + i = +(-1); + i++; + ip = &i; + *ip--; + ++i; + --i; + + return 0; +} diff --git a/cpp/ql/test/library-tests/exprs/value_categories/value_categories.cpp b/cpp/ql/test/library-tests/exprs/value_categories/value_categories.cpp index 05cd6c16583..bf0a6176948 100644 --- a/cpp/ql/test/library-tests/exprs/value_categories/value_categories.cpp +++ b/cpp/ql/test/library-tests/exprs/value_categories/value_categories.cpp @@ -1,155 +1,155 @@ -int ParamsAndLocals(int x) -{ - int y; - - // y is an lvalue, as is the result of the assignment. x is a load. - y = x + 1; - - // y is a load. - return y; -} - -int Dereference(int* p, int *q) -{ - // *p is an lvalue, as is the result of the assignment. - // p, q, and *q are loads. - *p = *q; - - int x = 5; - - // x is an lvalue. - // *&x is a load. - return *&x; -} - -int& References(int& r) -{ - // The reference r is a load, as is the result of dereferencing the - // reference r. - int x = r; - - // The result of dereferencing the reference r is an lvalue. - // The reference r is a load. - int* p = &r; - - // The result of deferencing the reference r is an lvalue, as is the result - // of the assignment. - // The reference r is a load. - r = 5; - - // The result of dereferencing the reference r is an lvalue. - // The reference r is a load. - return r; -} - -int&& GetRValueRef(); -void CallRValueRef(int&& rr); - -int&& RValueReferences(int&& rr) -{ - // The result of dereferencing the reference returned by GetRValueRef() is - // an xvalue. - CallRValueRef(GetRValueRef()); - - // The result of dereferencing the reference rr is an lvalue, as is the - // result of the assignment. - // The reference rr is a load. - rr = 5; - - // The result of the static cast is an xvalue. The result of dereferencing - // the reference rr is an lvalue. - // The reference rr is a load. - return static_cast(rr); -} - -struct S -{ - int MemberFunction(); -}; - -int CallMemberFunction(S& s) -{ - // The result of dereferencing the reference s is an lvalue. - // The reference s is a load. - return s.MemberFunction(); -} - -int Func(); -void AddressOfFunc() -{ - // Func is a load due to the function-to-function-pointer conversions. - int (*p)() = Func; -} - -struct T -{ - int x; - int y; - int MemberFunc(float); -}; - -void FieldAccesses() -{ - T t; - // t, t.x, and the assignment are all lvalues. - t.x = 0; - // t is an lvalue. - // t.x is a load. - int a = t.x; -} - -void StringLiterals() -{ - // All string literals are lvalues - "String"; - const char* p = "String"; - const char (&a)[7] = "String"; - // The array access is a load - char c = "String"[1]; -} - -void Crement() -{ - int x = 0; - // x is an lvalue. - x++; - // x is an lvalue. - x--; - // x is an lvalue, as is the result of ++x. - ++x; - // x is an lvalue, as is the result of --x. - --x; -} - -void CompoundAssignment() -{ - int x = 0; - - // x is an lvalue, as is the result of x += 1 - x += 1; - // x is an lvalue, as is the result of x -= 1 - x -= 1; - // x is an lvalue, as is the result of x *= 1 - x *= 1; - // x is an lvalue, as is the result of x /= 1 - x /= 1; - // x is an lvalue, as is the result of x %= 1 - x %= 1; - // x is an lvalue, as is the result of x <<= 1 - x <<= 1; - // x is an lvalue, as is the result of x >>= 1 - x >>= 1; - // x is an lvalue, as is the result of x |= 1 - x |= 1; - // x is an lvalue, as is the result of x &= 1 - x &= 1; - // x is an lvalue, as is the result of x ^= 1 - x ^= 1; -} - -void PointerToMemberLiteral() -{ - // All pointer-to-member literals are prvalues - int T::* pmd = &T::x; - int (T::* pmf)(float) = &T::MemberFunc; -} +int ParamsAndLocals(int x) +{ + int y; + + // y is an lvalue, as is the result of the assignment. x is a load. + y = x + 1; + + // y is a load. + return y; +} + +int Dereference(int* p, int *q) +{ + // *p is an lvalue, as is the result of the assignment. + // p, q, and *q are loads. + *p = *q; + + int x = 5; + + // x is an lvalue. + // *&x is a load. + return *&x; +} + +int& References(int& r) +{ + // The reference r is a load, as is the result of dereferencing the + // reference r. + int x = r; + + // The result of dereferencing the reference r is an lvalue. + // The reference r is a load. + int* p = &r; + + // The result of deferencing the reference r is an lvalue, as is the result + // of the assignment. + // The reference r is a load. + r = 5; + + // The result of dereferencing the reference r is an lvalue. + // The reference r is a load. + return r; +} + +int&& GetRValueRef(); +void CallRValueRef(int&& rr); + +int&& RValueReferences(int&& rr) +{ + // The result of dereferencing the reference returned by GetRValueRef() is + // an xvalue. + CallRValueRef(GetRValueRef()); + + // The result of dereferencing the reference rr is an lvalue, as is the + // result of the assignment. + // The reference rr is a load. + rr = 5; + + // The result of the static cast is an xvalue. The result of dereferencing + // the reference rr is an lvalue. + // The reference rr is a load. + return static_cast(rr); +} + +struct S +{ + int MemberFunction(); +}; + +int CallMemberFunction(S& s) +{ + // The result of dereferencing the reference s is an lvalue. + // The reference s is a load. + return s.MemberFunction(); +} + +int Func(); +void AddressOfFunc() +{ + // Func is a load due to the function-to-function-pointer conversions. + int (*p)() = Func; +} + +struct T +{ + int x; + int y; + int MemberFunc(float); +}; + +void FieldAccesses() +{ + T t; + // t, t.x, and the assignment are all lvalues. + t.x = 0; + // t is an lvalue. + // t.x is a load. + int a = t.x; +} + +void StringLiterals() +{ + // All string literals are lvalues + "String"; + const char* p = "String"; + const char (&a)[7] = "String"; + // The array access is a load + char c = "String"[1]; +} + +void Crement() +{ + int x = 0; + // x is an lvalue. + x++; + // x is an lvalue. + x--; + // x is an lvalue, as is the result of ++x. + ++x; + // x is an lvalue, as is the result of --x. + --x; +} + +void CompoundAssignment() +{ + int x = 0; + + // x is an lvalue, as is the result of x += 1 + x += 1; + // x is an lvalue, as is the result of x -= 1 + x -= 1; + // x is an lvalue, as is the result of x *= 1 + x *= 1; + // x is an lvalue, as is the result of x /= 1 + x /= 1; + // x is an lvalue, as is the result of x %= 1 + x %= 1; + // x is an lvalue, as is the result of x <<= 1 + x <<= 1; + // x is an lvalue, as is the result of x >>= 1 + x >>= 1; + // x is an lvalue, as is the result of x |= 1 + x |= 1; + // x is an lvalue, as is the result of x &= 1 + x &= 1; + // x is an lvalue, as is the result of x ^= 1 + x ^= 1; +} + +void PointerToMemberLiteral() +{ + // All pointer-to-member literals are prvalues + int T::* pmd = &T::x; + int (T::* pmf)(float) = &T::MemberFunc; +} diff --git a/cpp/ql/test/library-tests/exprs_basic/exprs_basic1.cpp b/cpp/ql/test/library-tests/exprs_basic/exprs_basic1.cpp index a1190b7955d..159336371b4 100644 --- a/cpp/ql/test/library-tests/exprs_basic/exprs_basic1.cpp +++ b/cpp/ql/test/library-tests/exprs_basic/exprs_basic1.cpp @@ -1,33 +1,33 @@ -enum Type { S, I }; - -struct Foo { - char* name; - int count; - char* another_name; - char* yet_another_name; - char initials[2]; - long very_long; -}; - -void create_foo() -{ - Foo xx; - char name[] = "Foo McFoo"; - xx.name = name; - xx.count = 123; - Foo yy = { "Barry McBar", 42, "Baz", "Basildon", { 'B', 'X' }, 5678 }; -} - -void print_foo(Foo* p) -{ - -} - -Foo current_foo; - -Foo set_current_foo(Foo next) -{ - Foo prev = current_foo; - current_foo = next; - return prev; -} +enum Type { S, I }; + +struct Foo { + char* name; + int count; + char* another_name; + char* yet_another_name; + char initials[2]; + long very_long; +}; + +void create_foo() +{ + Foo xx; + char name[] = "Foo McFoo"; + xx.name = name; + xx.count = 123; + Foo yy = { "Barry McBar", 42, "Baz", "Basildon", { 'B', 'X' }, 5678 }; +} + +void print_foo(Foo* p) +{ + +} + +Foo current_foo; + +Foo set_current_foo(Foo next) +{ + Foo prev = current_foo; + current_foo = next; + return prev; +} diff --git a/cpp/ql/test/library-tests/fields/fields/fields.cpp b/cpp/ql/test/library-tests/fields/fields/fields.cpp index c4e26495b4c..ce65bee0afe 100644 --- a/cpp/ql/test/library-tests/fields/fields/fields.cpp +++ b/cpp/ql/test/library-tests/fields/fields/fields.cpp @@ -1,33 +1,33 @@ -enum Type { S, I }; - -struct Entry { - char* name; - Type t; - char* s; - int i; -private: - int internal; -}; - -class Name { - const char* s; -}; - -class Table { - Name* p; - int sz; -public: - Table(int s=15) { p = new Name[sz=s]; } // constructor - ~Table() { delete[] p; } - Name* lookup (const char*); - bool insert(Name*); -}; - -class Date { - static Table memtbl; - mutable bool cache_valid; -public: - mutable char* cache; - void compute_cache_value() const; -}; - +enum Type { S, I }; + +struct Entry { + char* name; + Type t; + char* s; + int i; +private: + int internal; +}; + +class Name { + const char* s; +}; + +class Table { + Name* p; + int sz; +public: + Table(int s=15) { p = new Name[sz=s]; } // constructor + ~Table() { delete[] p; } + Name* lookup (const char*); + bool insert(Name*); +}; + +class Date { + static Table memtbl; + mutable bool cache_valid; +public: + mutable char* cache; + void compute_cache_value() const; +}; + diff --git a/cpp/ql/test/library-tests/files/files1.cpp b/cpp/ql/test/library-tests/files/files1.cpp index cd30b0b78ba..210c5586e7a 100644 --- a/cpp/ql/test/library-tests/files/files1.cpp +++ b/cpp/ql/test/library-tests/files/files1.cpp @@ -1,9 +1,9 @@ -#include "files1.h" - - -void swap(int* p, int* q) -{ - int t = *p; - *p = *q; - *q = t; -} +#include "files1.h" + + +void swap(int* p, int* q) +{ + int t = *p; + *p = *q; + *q = t; +} diff --git a/cpp/ql/test/library-tests/files/files1.h b/cpp/ql/test/library-tests/files/files1.h index 90b150ae9d6..af92b2bded3 100644 --- a/cpp/ql/test/library-tests/files/files1.h +++ b/cpp/ql/test/library-tests/files/files1.h @@ -1,2 +1,2 @@ - -extern void swap(int*, int*); + +extern void swap(int*, int*); diff --git a/cpp/ql/test/library-tests/files/files2.cpp b/cpp/ql/test/library-tests/files/files2.cpp index 301b082a534..6dd7ec111ee 100644 --- a/cpp/ql/test/library-tests/files/files2.cpp +++ b/cpp/ql/test/library-tests/files/files2.cpp @@ -1,7 +1,7 @@ -#include "files1.h" - -void g() { - int x = 2; - int y = 4; - swap(&x,&y); -} +#include "files1.h" + +void g() { + int x = 2; + int y = 4; + swap(&x,&y); +} diff --git a/cpp/ql/test/library-tests/functions/functions/functions.cpp b/cpp/ql/test/library-tests/functions/functions/functions.cpp index f3c630cebbb..18b4f6ee5e2 100644 --- a/cpp/ql/test/library-tests/functions/functions/functions.cpp +++ b/cpp/ql/test/library-tests/functions/functions/functions.cpp @@ -1,33 +1,33 @@ -void f(int a, int b) { - bool c = a==b; -} - -void g(); - -struct A { - void af() { - - } - void ag(); -}; - -void g() { - A a; - a.ag(); -} - -class Name { - const char* s; -}; - -class Table { - Name* p; - int sz; -public: - Table(int s=15) { p = new Name[sz=s]; } // constructor - ~Table() { delete[] p; } - Name* lookup (const char*); - bool insert(Name*); -}; - - +void f(int a, int b) { + bool c = a==b; +} + +void g(); + +struct A { + void af() { + + } + void ag(); +}; + +void g() { + A a; + a.ag(); +} + +class Name { + const char* s; +}; + +class Table { + Name* p; + int sz; +public: + Table(int s=15) { p = new Name[sz=s]; } // constructor + ~Table() { delete[] p; } + Name* lookup (const char*); + bool insert(Name*); +}; + + diff --git a/cpp/ql/test/library-tests/ir/constant_func/constant_func.cpp b/cpp/ql/test/library-tests/ir/constant_func/constant_func.cpp index 9a176b82b61..107d79da46b 100644 --- a/cpp/ql/test/library-tests/ir/constant_func/constant_func.cpp +++ b/cpp/ql/test/library-tests/ir/constant_func/constant_func.cpp @@ -1,32 +1,32 @@ -int ReturnConstant() { - return 7; -} - -int ReturnConstantPhi(bool b) { - if (b) { - return 7; - } - else { - return 7; - } -} - -int GetInt(); - -int ReturnNonConstantPhi(bool b) { - if (b) { - return 7; - } - else { - return GetInt(); - } -} - -int ReturnConstantPhiLoop(int x) { - int y = 7; - while (x > 0) { - y = 7; - --x; - } - return y; -} +int ReturnConstant() { + return 7; +} + +int ReturnConstantPhi(bool b) { + if (b) { + return 7; + } + else { + return 7; + } +} + +int GetInt(); + +int ReturnNonConstantPhi(bool b) { + if (b) { + return 7; + } + else { + return GetInt(); + } +} + +int ReturnConstantPhiLoop(int x) { + int y = 7; + while (x > 0) { + y = 7; + --x; + } + return y; +} diff --git a/cpp/ql/test/library-tests/ir/escape/escape.cpp b/cpp/ql/test/library-tests/ir/escape/escape.cpp index 81a23ac4fb2..8a3e57a25d2 100644 --- a/cpp/ql/test/library-tests/ir/escape/escape.cpp +++ b/cpp/ql/test/library-tests/ir/escape/escape.cpp @@ -1,98 +1,98 @@ -void CallByPointer(int* p); -void CallByReference(int& r); - -struct Point { - float x; - float y; - float z; -}; - -struct Base { - float b; -}; - -struct ReusedBase { - float rb; -}; - -struct Intermediate1 : Base, ReusedBase { - float i1; -}; - -struct Intermediate2 : ReusedBase { - float i2; -}; - -struct Derived : Intermediate1, Intermediate2 { - float d; -}; - -void Escape() -{ - int no_result; - int no_; - - no_ = 1; - no_ = no_; - no_result = no_; - no_result = *&no_; -// no_result = (int&)no_; Restore when we have correct IR types for glvalues - no_; - &no_; - no_result = *((&no_) + 0); - no_result = *((&no_) - 0); - no_result = *(0 + &no_); - if (&no_) { - } - while (&no_) { - } - do { - } while (&no_); - for(&no_; &no_; &no_) { - } - - if (&no_ == nullptr) { - } - while (&no_ != nullptr) { - } - - int no_Array[10]; - no_Array; - (int*)no_Array; - no_Array[5]; - 5[no_Array]; - no_result = no_Array[5]; - no_result = 5[no_Array]; - - Point no_Point = { 1, 2, 3 }; - float no_x = no_Point.x; - no_Point.y = no_x; - float no_y = (&no_Point)->y; - (&no_Point)->y = no_y; - float no_z = *(&no_Point.z); - *(&no_Point.z) = no_z; - - Derived no_Derived; - no_Derived.b = 0; - float no_b = no_Derived.b; - no_Derived.i2 = 1; - float no_i2 = no_Derived.i2; - - int no_ssa_addrOf; - int* no_p = &no_ssa_addrOf; - - int no_ssa_refTo; - int& no_r = no_ssa_refTo; - - int no_ssa_refToArrayElement[10]; - int& no_rae = no_ssa_refToArrayElement[5]; - - int no_ssa_refToArray[10]; - int (&no_ra)[10] = no_ssa_refToArray; - - int passByPtr; - CallByPointer(&passByPtr); - - int passByRef; - CallByReference(passByRef); -} +void CallByPointer(int* p); +void CallByReference(int& r); + +struct Point { + float x; + float y; + float z; +}; + +struct Base { + float b; +}; + +struct ReusedBase { + float rb; +}; + +struct Intermediate1 : Base, ReusedBase { + float i1; +}; + +struct Intermediate2 : ReusedBase { + float i2; +}; + +struct Derived : Intermediate1, Intermediate2 { + float d; +}; + +void Escape() +{ + int no_result; + int no_; + + no_ = 1; + no_ = no_; + no_result = no_; + no_result = *&no_; +// no_result = (int&)no_; Restore when we have correct IR types for glvalues + no_; + &no_; + no_result = *((&no_) + 0); + no_result = *((&no_) - 0); + no_result = *(0 + &no_); + if (&no_) { + } + while (&no_) { + } + do { + } while (&no_); + for(&no_; &no_; &no_) { + } + + if (&no_ == nullptr) { + } + while (&no_ != nullptr) { + } + + int no_Array[10]; + no_Array; + (int*)no_Array; + no_Array[5]; + 5[no_Array]; + no_result = no_Array[5]; + no_result = 5[no_Array]; + + Point no_Point = { 1, 2, 3 }; + float no_x = no_Point.x; + no_Point.y = no_x; + float no_y = (&no_Point)->y; + (&no_Point)->y = no_y; + float no_z = *(&no_Point.z); + *(&no_Point.z) = no_z; + + Derived no_Derived; + no_Derived.b = 0; + float no_b = no_Derived.b; + no_Derived.i2 = 1; + float no_i2 = no_Derived.i2; + + int no_ssa_addrOf; + int* no_p = &no_ssa_addrOf; + + int no_ssa_refTo; + int& no_r = no_ssa_refTo; + + int no_ssa_refToArrayElement[10]; + int& no_rae = no_ssa_refToArrayElement[5]; + + int no_ssa_refToArray[10]; + int (&no_ra)[10] = no_ssa_refToArray; + + int passByPtr; + CallByPointer(&passByPtr); + + int passByRef; + CallByReference(passByRef); +} diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 5490cd0f2d9..3ff4c53c17e 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -1,984 +1,984 @@ -void Constants() { - char c_i = 1; - char c_c = 'A'; - - signed char sc_i = -1; - signed char sc_c = 'A'; - - unsigned char uc_i = 5; - unsigned char uc_c = 'A'; - - short s = 5; - unsigned short us = 5; - - int i = 5; - unsigned int ui = 5; - - long l = 5; - unsigned long ul = 5; - - long long ll_i = 5; - long long ll_ll = 5LL; - unsigned long long ull_i = 5; - unsigned long long ull_ull = 5ULL; - - bool b_t = true; - bool b_f = false; - - wchar_t wc_i = 5; - wchar_t wc_c = L'A'; - - char16_t c16 = u'A'; - char32_t c32 = U'A'; - - float f_i = 1; - float f_f = 1.0f; - float f_d = 1.0; - - double d_i = 1; - double d_f = 1.0f; - double d_d = 1.0; -} - -void Foo() { - int x = 5 + 12; - short y = 7; - y = x + y; - x = x * y; -} - -void IntegerOps(int x, int y) { - int z; - - z = x + y; - z = x - y; - z = x * y; - z = x / y; - z = x % y; - - z = x & y; - z = x | y; - z = x ^ y; - - z = x << y; - z = x >> y; - - z = x; - - z += x; - z -= x; - z *= x; - z /= x; - z %= x; - - z &= x; - z |= x; - z ^= x; - - z <<= x; - z >>= x; - - z = +x; - z = -x; - z = ~x; - z = !x; -} - -void IntegerCompare(int x, int y) { - bool b; - - b = x == y; - b = x != y; - b = x < y; - b = x > y; - b = x <= y; - b = x >= y; -} - -void IntegerCrement(int x) { - int y; - - y = ++x; - y = --x; - y = x++; - y = x--; -} - -void IntegerCrement_LValue(int x) { - int* p; - - p = &(++x); - p = &(--x); -} - -void FloatOps(double x, double y) { - double z; - - z = x + y; - z = x - y; - z = x * y; - z = x / y; - - z = x; - - z += x; - z -= x; - z *= x; - z /= x; - - z = +x; - z = -x; -} - -void FloatCompare(double x, double y) { - bool b; - - b = x == y; - b = x != y; - b = x < y; - b = x > y; - b = x <= y; - b = x >= y; -} - -void FloatCrement(float x) { - float y; - - y = ++x; - y = --x; - y = x++; - y = x--; -} - -void PointerOps(int* p, int i) { - int* q; - bool b; - - q = p + i; - q = i + p; - q = p - i; - i = p - q; - - q = p; - - q += i; - q -= i; - - b = p; - b = !p; -} - -void ArrayAccess(int* p, int i) { - int x; - - x = p[i]; - x = i[p]; - - p[i] = x; - i[p] = x; - - int a[10]; - x = a[i]; - x = i[a]; - a[i] = x; - i[a] = x; -} - -void StringLiteral(int i) { - char c = "Foo"[i]; - wchar_t* pwc = L"Bar"; - wchar_t wc = pwc[i]; -} - -void PointerCompare(int* p, int* q) { - bool b; - - b = p == q; - b = p != q; - b = p < q; - b = p > q; - b = p <= q; - b = p >= q; -} - -void PointerCrement(int* p) { - int* q; - - q = ++p; - q = --p; - q = p++; - q = p--; -} - -void CompoundAssignment() { - // No conversion necessary - int x = 5; - x += 7; - - // Left side is converted to 'int' - short y = 5; - y += x; - - // Technically the left side is promoted to int, but we don't model that - y <<= 1; - - // Left side is converted to 'float' - long z = 7; - z += 2.0f; -} - -void UninitializedVariables() { - int x; - int y = x; -} - -int Parameters(int x, int y) { - return x % y; -} - -void IfStatements(bool b, int x, int y) { - if (b) { - } - - if (b) { - x = y; - } - - if (x < 7) - x = 2; - else - x = 7; -} - -void WhileStatements(int n) { - while (n > 0) { - n -= 1; - } -} - -void DoStatements(int n) { - do { - n -= 1; - } while (n > 0); -} - -void For_Empty() { - int j; - for (;;) { - ; - } -} - -void For_Init() { - for (int i = 0;;) { - ; - } -} - -void For_Condition() { - int i = 0; - for (; i < 10;) { - ; - } -} - -void For_Update() { - int i = 0; - for (;; i += 1) { - ; - } -} - -void For_InitCondition() { - for (int i = 0; i < 10;) { - ; - } -} - -void For_InitUpdate() { - for (int i = 0;; i += 1) { - ; - } -} - -void For_ConditionUpdate() { - int i = 0; - for (; i < 10; i += 1) { - ; - } -} - -void For_InitConditionUpdate() { - for (int i = 0; i < 10; i += 1) { - ; - } -} - -void For_Break() { - for (int i = 0; i < 10; i += 1) { - if (i == 5) { - break; - } - } -} - -void For_Continue_Update() { - for (int i = 0; i < 10; i += 1) { - if (i == 5) { - continue; - } - } -} - -void For_Continue_NoUpdate() { - for (int i = 0; i < 10;) { - if (i == 5) { - continue; - } - } -} - -int Dereference(int* p) { - *p = 1; - return *p; -} - -int g; - -int* AddressOf() { - return &g; -} - -void Break(int n) { - while (n > 0) { - if (n == 1) - break; - n -= 1; - } -} - -void Continue(int n) { - do { - if (n == 1) { - continue; - } - n -= 1; - } while (n > 0); -} - -void VoidFunc(); -int Add(int x, int y); - -void Call() { - VoidFunc(); -} - -int CallAdd(int x, int y) { - return Add(x, y); -} - -int Comma(int x, int y) { - return VoidFunc(), CallAdd(x, y); -} - -void Switch(int x) { - int y; - switch (x) { - y = 1234; - - case -1: - y = -1; - break; - - case 1: - case 2: - y = 1; - break; - - case 3: - y = 3; - case 4: - y = 4; - break; - - default: - y = 0; - break; - - y = 5678; - } -} - -struct Point { - int x; - int y; -}; - -struct Rect { - Point topLeft; - Point bottomRight; -}; - -Point ReturnStruct(Point pt) { - return pt; -} - -void FieldAccess() { - Point pt; - pt.x = 5; - pt.y = pt.x; - int* p = &pt.y; -} - -void LogicalOr(bool a, bool b) { - int x; - if (a || b) { - x = 7; - } - - if (a || b) { - x = 1; - } - else { - x = 5; - } -} - -void LogicalAnd(bool a, bool b) { - int x; - if (a && b) { - x = 7; - } - - if (a && b) { - x = 1; - } - else { - x = 5; - } -} - -void LogicalNot(bool a, bool b) { - int x; - if (!a) { - x = 1; - } - - if (!(a && b)) { - x = 2; - } - else { - x = 3; - } -} - -void ConditionValues(bool a, bool b) { - bool x; - x = a && b; - x = a || b; - x = !(a || b); -} - -void Conditional(bool a, int x, int y) { - int z = a ? x : y; -} - -void Conditional_LValue(bool a) { - int x; - int y; - (a ? x : y) = 5; -} - -void Conditional_Void(bool a) { - a ? VoidFunc() : VoidFunc(); -} - -void Nullptr() { - int* p = nullptr; - int* q = 0; - p = nullptr; - q = 0; -} - -void InitList(int x, float f) { - Point pt1 = { x, f }; - Point pt2 = { x }; - Point pt3 = {}; - - int x1 = { 1 }; - int x2 = {}; -} - -void NestedInitList(int x, float f) { - Rect r1 = {}; - Rect r2 = { { x, f } }; - Rect r3 = { { x, f }, { x, f } }; - Rect r4 = { { x }, { x } }; -} - -void ArrayInit(int x, float f) { - int a1[3] = {}; - int a2[3] = { x, f, 0 }; - int a3[3] = { x }; -} - -union U { - double d; - int i; -}; - -void UnionInit(int x, float f) { - U u1 = { f }; -// U u2 = {}; Waiting for fix -} - -void EarlyReturn(int x, int y) { - if (x < y) { - return; - } - - y = x; -} - -int EarlyReturnValue(int x, int y) { - if (x < y) { - return x; - } - - return x + y; -} - -int CallViaFuncPtr(int (*pfn)(int)) { - return pfn(5); -} - -typedef enum { - E_0, - E_1 -} E; - -int EnumSwitch(E e) { - switch (e) { - case E_0: - return 0; - case E_1: - return 1; - default: - return -1; - } -} - -void InitArray() { - char a_pad[32] = ""; - char a_nopad[4] = "foo"; - char a_infer[] = "blah"; - char b[2]; - char c[2] = {}; - char d[2] = { 0 }; - char e[2] = { 0, 1 }; - char f[3] = { 0 }; -} - -void VarArgFunction(const char* s, ...); - -void VarArgs() { - VarArgFunction("%d %s", 1, "string"); -} - -int FuncPtrTarget(int); - -void SetFuncPtr() { - int (*pfn)(int) = FuncPtrTarget; - pfn = &FuncPtrTarget; - pfn = *FuncPtrTarget; - pfn = ***&FuncPtrTarget; -} - -struct String { - String(); - String(const String&); - String(String&&); - String(const char*); - ~String(); - - String& operator=(const String&); - String& operator=(String&&); - - const char* c_str() const; - -private: - const char* p; -}; - -String ReturnObject(); - -void DeclareObject() { - String s1; - String s2("hello"); - String s3 = ReturnObject(); - String s4 = String("test"); -} - -void CallMethods(String& r, String* p, String s) { - r.c_str(); - p->c_str(); - s.c_str(); -} - -class C { -public: - static int StaticMemberFunction(int x) { - return x; - } - - int InstanceMemberFunction(int x) { - return x; - } - - virtual int VirtualMemberFunction(int x) { - return x; - } - - void FieldAccess() { - this->m_a = 0; - (*this).m_a = 1; - m_a = 2; - int x; - x = this->m_a; - x = (*this).m_a; - x = m_a; - } - - void MethodCalls() { - this->InstanceMemberFunction(0); - (*this).InstanceMemberFunction(1); - InstanceMemberFunction(2); - } - - C() : - m_a(1), - m_c(3), - m_e{}, - m_f("test") - { - } - -private: - int m_a; - String m_b; - char m_c; - float m_d; - void* m_e; - String m_f; -}; - -int DerefReference(int& r) { - return r; -} - -int& TakeReference() { - return g; -} - -String& ReturnReference(); - -void InitReference(int x) { - int& r = x; - int& r2 = r; - const String& r3 = ReturnReference(); -} - -void ArrayReferences() { - int a[10]; - int (&ra)[10] = a; - int x = ra[5]; -} - -void FunctionReferences() { - int(&rfn)(int) = FuncPtrTarget; - int(*pfn)(int) = rfn; - rfn(5); -} - -template -T min(T x, T y) { - return (x < y) ? x : y; -} - -int CallMin(int x, int y) { - return min(x, y); -} - -template -struct Outer { - template - static T Func(U x, V y) { - return T(); - } -}; - -double CallNestedTemplateFunc() { - return Outer::Func(nullptr, 'o'); -} - -void TryCatch(bool b) { - try { - int x = 5; - if (b) { - throw "string literal"; - } - else if (x < 2) { - x = b ? 7 : throw String("String object"); - } - x = 7; - } - catch (const char* s) { - throw String(s); - } - catch (const String& e) { - } - catch (...) { - throw; - } -} - -struct Base { - String base_s; - - Base() { - } - ~Base() { - } -}; - -struct Middle : Base { - String middle_s; - - Middle() { - } - ~Middle() { - } -}; - -struct Derived : Middle { - String derived_s; - - Derived() { - } - ~Derived() { - } -}; - -struct MiddleVB1 : virtual Base { - String middlevb1_s; - - MiddleVB1() { - } - ~MiddleVB1() { - } -}; - -struct MiddleVB2 : virtual Base { - String middlevb2_s; - - MiddleVB2() { - } - ~MiddleVB2() { - } -}; - -struct DerivedVB : MiddleVB1, MiddleVB2 { - String derivedvb_s; - - DerivedVB() { - } - ~DerivedVB() { - } -}; - -void HierarchyConversions() { - Base b; - Middle m; - Derived d; - - Base* pb = &b; - Middle* pm = &m; - Derived* pd = &d; - - b = m; - b = (Base)m; - b = static_cast(m); - pb = pm; - pb = (Base*)pm; - pb = static_cast(pm); - pb = reinterpret_cast(pm); - - m = (Middle&)b; - m = static_cast(b); - pm = (Middle*)pb; - pm = static_cast(pb); - pm = reinterpret_cast(pb); - - b = d; - b = (Base)d; - b = static_cast(d); - pb = pd; - pb = (Base*)pd; - pb = static_cast(pd); - pb = reinterpret_cast(pd); - - d = (Derived&)b; - d = static_cast(b); - pd = (Derived*)pb; - pd = static_cast(pb); - pd = reinterpret_cast(pb); - - MiddleVB1* pmv = nullptr; - DerivedVB* pdv = nullptr; - pb = pmv; - pb = pdv; -} - -struct PolymorphicBase { - virtual ~PolymorphicBase(); -}; - -struct PolymorphicDerived : PolymorphicBase { -}; - -void DynamicCast() { - PolymorphicBase b; - PolymorphicDerived d; - - PolymorphicBase* pb = &b; - PolymorphicDerived* pd = &d; - - // These two casts are represented as BaseClassCasts because they can be resolved at compile time. - pb = dynamic_cast(pd); - PolymorphicBase& rb = dynamic_cast(d); - - pd = dynamic_cast(pb); - PolymorphicDerived& rd = dynamic_cast(b); - - void* pv = dynamic_cast(pb); - const void* pcv = dynamic_cast(pd); -} - -String::String() : - String("") { // Delegating constructor call -} - -void ArrayConversions() { - char a[5]; - const char* p = a; - p = "test"; - p = &a[0]; - p = &"test"[0]; - char (&ra)[5] = a; - const char (&rs)[5] = "test"; - const char (*pa)[5] = &a; - pa = &"test"; -} - -void FuncPtrConversions(int(*pfn)(int), void* p) { - p = (void*)pfn; - pfn = (int(*)(int))p; -} - -void VarArgUsage(int x, ...) { - __builtin_va_list args; - - __builtin_va_start(args, x); - __builtin_va_list args2; - __builtin_va_start(args2, args); - double d = __builtin_va_arg(args, double); - float f = __builtin_va_arg(args, float); - __builtin_va_end(args); - __builtin_va_end(args2); -} - -void CastToVoid(int x) { - (void)x; -} - -void ConstantConditions(int x) { - bool a = true && true; - int b = (true) ? x : x; -} - -typedef unsigned long size_t; - -namespace std { - enum class align_val_t : size_t {}; -} - -void* operator new(size_t, float); -void* operator new[](size_t, float); -void* operator new(size_t, std::align_val_t, float); -void* operator new[](size_t, std::align_val_t, float); -void operator delete(void*, float); -void operator delete[](void*, float); -void operator delete(void*, std::align_val_t, float); -void operator delete[](void*, std::align_val_t, float); - -struct SizedDealloc { - char a[32]; - void* operator new(size_t); - void* operator new[](size_t); - void operator delete(void*, size_t); - void operator delete[](void*, size_t); -}; - -struct alignas(128) Overaligned { - char a[256]; -}; - -struct DefaultCtorWithDefaultParam { - DefaultCtorWithDefaultParam(double d = 1.0); -}; - -void OperatorNew() { - new int; // No constructor - new(1.0f) int; // Placement new, no constructor - new int(); // Zero-init - new String(); // Constructor - new(1.0f) String("hello"); // Placement new, constructor with args - new Overaligned; // Aligned new - new(1.0f) Overaligned(); // Placement aligned new with zero-init -} - -void OperatorNewArray(int n) { - new int[10]; // Constant size - new int[n]; // No constructor - new(1.0f) int[n]; // Placement new, no constructor - new String[n]; // Constructor - new Overaligned[n]; // Aligned new - new(1.0f) Overaligned[10]; // Aligned placement new - new DefaultCtorWithDefaultParam[n]; - new int[n] { 0, 1, 2 }; -} - -int designatedInit() { - int a1[1000] = { [2] = 10002, [900] = 10900 }; - return a1[900]; -} - -#if 0 -void OperatorDelete() { - delete static_cast(nullptr); // No destructor - delete static_cast(nullptr); // Non-virtual destructor, with size. - delete static_cast(nullptr); // No destructor, with size. - delete static_cast(nullptr); // No destructor, with size and alignment. - delete static_cast(nullptr); // Virtual destructor -} - -void OperatorDeleteArray() { - delete[] static_cast(nullptr); // No destructor - delete[] static_cast(nullptr); // Non-virtual destructor, with size. - delete[] static_cast(nullptr); // No destructor, with size. - delete[] static_cast(nullptr); // No destructor, with size and alignment. - delete[] static_cast(nullptr); // Virtual destructor -} -#endif - -// semmle-extractor-options: -std=c++17 +void Constants() { + char c_i = 1; + char c_c = 'A'; + + signed char sc_i = -1; + signed char sc_c = 'A'; + + unsigned char uc_i = 5; + unsigned char uc_c = 'A'; + + short s = 5; + unsigned short us = 5; + + int i = 5; + unsigned int ui = 5; + + long l = 5; + unsigned long ul = 5; + + long long ll_i = 5; + long long ll_ll = 5LL; + unsigned long long ull_i = 5; + unsigned long long ull_ull = 5ULL; + + bool b_t = true; + bool b_f = false; + + wchar_t wc_i = 5; + wchar_t wc_c = L'A'; + + char16_t c16 = u'A'; + char32_t c32 = U'A'; + + float f_i = 1; + float f_f = 1.0f; + float f_d = 1.0; + + double d_i = 1; + double d_f = 1.0f; + double d_d = 1.0; +} + +void Foo() { + int x = 5 + 12; + short y = 7; + y = x + y; + x = x * y; +} + +void IntegerOps(int x, int y) { + int z; + + z = x + y; + z = x - y; + z = x * y; + z = x / y; + z = x % y; + + z = x & y; + z = x | y; + z = x ^ y; + + z = x << y; + z = x >> y; + + z = x; + + z += x; + z -= x; + z *= x; + z /= x; + z %= x; + + z &= x; + z |= x; + z ^= x; + + z <<= x; + z >>= x; + + z = +x; + z = -x; + z = ~x; + z = !x; +} + +void IntegerCompare(int x, int y) { + bool b; + + b = x == y; + b = x != y; + b = x < y; + b = x > y; + b = x <= y; + b = x >= y; +} + +void IntegerCrement(int x) { + int y; + + y = ++x; + y = --x; + y = x++; + y = x--; +} + +void IntegerCrement_LValue(int x) { + int* p; + + p = &(++x); + p = &(--x); +} + +void FloatOps(double x, double y) { + double z; + + z = x + y; + z = x - y; + z = x * y; + z = x / y; + + z = x; + + z += x; + z -= x; + z *= x; + z /= x; + + z = +x; + z = -x; +} + +void FloatCompare(double x, double y) { + bool b; + + b = x == y; + b = x != y; + b = x < y; + b = x > y; + b = x <= y; + b = x >= y; +} + +void FloatCrement(float x) { + float y; + + y = ++x; + y = --x; + y = x++; + y = x--; +} + +void PointerOps(int* p, int i) { + int* q; + bool b; + + q = p + i; + q = i + p; + q = p - i; + i = p - q; + + q = p; + + q += i; + q -= i; + + b = p; + b = !p; +} + +void ArrayAccess(int* p, int i) { + int x; + + x = p[i]; + x = i[p]; + + p[i] = x; + i[p] = x; + + int a[10]; + x = a[i]; + x = i[a]; + a[i] = x; + i[a] = x; +} + +void StringLiteral(int i) { + char c = "Foo"[i]; + wchar_t* pwc = L"Bar"; + wchar_t wc = pwc[i]; +} + +void PointerCompare(int* p, int* q) { + bool b; + + b = p == q; + b = p != q; + b = p < q; + b = p > q; + b = p <= q; + b = p >= q; +} + +void PointerCrement(int* p) { + int* q; + + q = ++p; + q = --p; + q = p++; + q = p--; +} + +void CompoundAssignment() { + // No conversion necessary + int x = 5; + x += 7; + + // Left side is converted to 'int' + short y = 5; + y += x; + + // Technically the left side is promoted to int, but we don't model that + y <<= 1; + + // Left side is converted to 'float' + long z = 7; + z += 2.0f; +} + +void UninitializedVariables() { + int x; + int y = x; +} + +int Parameters(int x, int y) { + return x % y; +} + +void IfStatements(bool b, int x, int y) { + if (b) { + } + + if (b) { + x = y; + } + + if (x < 7) + x = 2; + else + x = 7; +} + +void WhileStatements(int n) { + while (n > 0) { + n -= 1; + } +} + +void DoStatements(int n) { + do { + n -= 1; + } while (n > 0); +} + +void For_Empty() { + int j; + for (;;) { + ; + } +} + +void For_Init() { + for (int i = 0;;) { + ; + } +} + +void For_Condition() { + int i = 0; + for (; i < 10;) { + ; + } +} + +void For_Update() { + int i = 0; + for (;; i += 1) { + ; + } +} + +void For_InitCondition() { + for (int i = 0; i < 10;) { + ; + } +} + +void For_InitUpdate() { + for (int i = 0;; i += 1) { + ; + } +} + +void For_ConditionUpdate() { + int i = 0; + for (; i < 10; i += 1) { + ; + } +} + +void For_InitConditionUpdate() { + for (int i = 0; i < 10; i += 1) { + ; + } +} + +void For_Break() { + for (int i = 0; i < 10; i += 1) { + if (i == 5) { + break; + } + } +} + +void For_Continue_Update() { + for (int i = 0; i < 10; i += 1) { + if (i == 5) { + continue; + } + } +} + +void For_Continue_NoUpdate() { + for (int i = 0; i < 10;) { + if (i == 5) { + continue; + } + } +} + +int Dereference(int* p) { + *p = 1; + return *p; +} + +int g; + +int* AddressOf() { + return &g; +} + +void Break(int n) { + while (n > 0) { + if (n == 1) + break; + n -= 1; + } +} + +void Continue(int n) { + do { + if (n == 1) { + continue; + } + n -= 1; + } while (n > 0); +} + +void VoidFunc(); +int Add(int x, int y); + +void Call() { + VoidFunc(); +} + +int CallAdd(int x, int y) { + return Add(x, y); +} + +int Comma(int x, int y) { + return VoidFunc(), CallAdd(x, y); +} + +void Switch(int x) { + int y; + switch (x) { + y = 1234; + + case -1: + y = -1; + break; + + case 1: + case 2: + y = 1; + break; + + case 3: + y = 3; + case 4: + y = 4; + break; + + default: + y = 0; + break; + + y = 5678; + } +} + +struct Point { + int x; + int y; +}; + +struct Rect { + Point topLeft; + Point bottomRight; +}; + +Point ReturnStruct(Point pt) { + return pt; +} + +void FieldAccess() { + Point pt; + pt.x = 5; + pt.y = pt.x; + int* p = &pt.y; +} + +void LogicalOr(bool a, bool b) { + int x; + if (a || b) { + x = 7; + } + + if (a || b) { + x = 1; + } + else { + x = 5; + } +} + +void LogicalAnd(bool a, bool b) { + int x; + if (a && b) { + x = 7; + } + + if (a && b) { + x = 1; + } + else { + x = 5; + } +} + +void LogicalNot(bool a, bool b) { + int x; + if (!a) { + x = 1; + } + + if (!(a && b)) { + x = 2; + } + else { + x = 3; + } +} + +void ConditionValues(bool a, bool b) { + bool x; + x = a && b; + x = a || b; + x = !(a || b); +} + +void Conditional(bool a, int x, int y) { + int z = a ? x : y; +} + +void Conditional_LValue(bool a) { + int x; + int y; + (a ? x : y) = 5; +} + +void Conditional_Void(bool a) { + a ? VoidFunc() : VoidFunc(); +} + +void Nullptr() { + int* p = nullptr; + int* q = 0; + p = nullptr; + q = 0; +} + +void InitList(int x, float f) { + Point pt1 = { x, f }; + Point pt2 = { x }; + Point pt3 = {}; + + int x1 = { 1 }; + int x2 = {}; +} + +void NestedInitList(int x, float f) { + Rect r1 = {}; + Rect r2 = { { x, f } }; + Rect r3 = { { x, f }, { x, f } }; + Rect r4 = { { x }, { x } }; +} + +void ArrayInit(int x, float f) { + int a1[3] = {}; + int a2[3] = { x, f, 0 }; + int a3[3] = { x }; +} + +union U { + double d; + int i; +}; + +void UnionInit(int x, float f) { + U u1 = { f }; +// U u2 = {}; Waiting for fix +} + +void EarlyReturn(int x, int y) { + if (x < y) { + return; + } + + y = x; +} + +int EarlyReturnValue(int x, int y) { + if (x < y) { + return x; + } + + return x + y; +} + +int CallViaFuncPtr(int (*pfn)(int)) { + return pfn(5); +} + +typedef enum { + E_0, + E_1 +} E; + +int EnumSwitch(E e) { + switch (e) { + case E_0: + return 0; + case E_1: + return 1; + default: + return -1; + } +} + +void InitArray() { + char a_pad[32] = ""; + char a_nopad[4] = "foo"; + char a_infer[] = "blah"; + char b[2]; + char c[2] = {}; + char d[2] = { 0 }; + char e[2] = { 0, 1 }; + char f[3] = { 0 }; +} + +void VarArgFunction(const char* s, ...); + +void VarArgs() { + VarArgFunction("%d %s", 1, "string"); +} + +int FuncPtrTarget(int); + +void SetFuncPtr() { + int (*pfn)(int) = FuncPtrTarget; + pfn = &FuncPtrTarget; + pfn = *FuncPtrTarget; + pfn = ***&FuncPtrTarget; +} + +struct String { + String(); + String(const String&); + String(String&&); + String(const char*); + ~String(); + + String& operator=(const String&); + String& operator=(String&&); + + const char* c_str() const; + +private: + const char* p; +}; + +String ReturnObject(); + +void DeclareObject() { + String s1; + String s2("hello"); + String s3 = ReturnObject(); + String s4 = String("test"); +} + +void CallMethods(String& r, String* p, String s) { + r.c_str(); + p->c_str(); + s.c_str(); +} + +class C { +public: + static int StaticMemberFunction(int x) { + return x; + } + + int InstanceMemberFunction(int x) { + return x; + } + + virtual int VirtualMemberFunction(int x) { + return x; + } + + void FieldAccess() { + this->m_a = 0; + (*this).m_a = 1; + m_a = 2; + int x; + x = this->m_a; + x = (*this).m_a; + x = m_a; + } + + void MethodCalls() { + this->InstanceMemberFunction(0); + (*this).InstanceMemberFunction(1); + InstanceMemberFunction(2); + } + + C() : + m_a(1), + m_c(3), + m_e{}, + m_f("test") + { + } + +private: + int m_a; + String m_b; + char m_c; + float m_d; + void* m_e; + String m_f; +}; + +int DerefReference(int& r) { + return r; +} + +int& TakeReference() { + return g; +} + +String& ReturnReference(); + +void InitReference(int x) { + int& r = x; + int& r2 = r; + const String& r3 = ReturnReference(); +} + +void ArrayReferences() { + int a[10]; + int (&ra)[10] = a; + int x = ra[5]; +} + +void FunctionReferences() { + int(&rfn)(int) = FuncPtrTarget; + int(*pfn)(int) = rfn; + rfn(5); +} + +template +T min(T x, T y) { + return (x < y) ? x : y; +} + +int CallMin(int x, int y) { + return min(x, y); +} + +template +struct Outer { + template + static T Func(U x, V y) { + return T(); + } +}; + +double CallNestedTemplateFunc() { + return Outer::Func(nullptr, 'o'); +} + +void TryCatch(bool b) { + try { + int x = 5; + if (b) { + throw "string literal"; + } + else if (x < 2) { + x = b ? 7 : throw String("String object"); + } + x = 7; + } + catch (const char* s) { + throw String(s); + } + catch (const String& e) { + } + catch (...) { + throw; + } +} + +struct Base { + String base_s; + + Base() { + } + ~Base() { + } +}; + +struct Middle : Base { + String middle_s; + + Middle() { + } + ~Middle() { + } +}; + +struct Derived : Middle { + String derived_s; + + Derived() { + } + ~Derived() { + } +}; + +struct MiddleVB1 : virtual Base { + String middlevb1_s; + + MiddleVB1() { + } + ~MiddleVB1() { + } +}; + +struct MiddleVB2 : virtual Base { + String middlevb2_s; + + MiddleVB2() { + } + ~MiddleVB2() { + } +}; + +struct DerivedVB : MiddleVB1, MiddleVB2 { + String derivedvb_s; + + DerivedVB() { + } + ~DerivedVB() { + } +}; + +void HierarchyConversions() { + Base b; + Middle m; + Derived d; + + Base* pb = &b; + Middle* pm = &m; + Derived* pd = &d; + + b = m; + b = (Base)m; + b = static_cast(m); + pb = pm; + pb = (Base*)pm; + pb = static_cast(pm); + pb = reinterpret_cast(pm); + + m = (Middle&)b; + m = static_cast(b); + pm = (Middle*)pb; + pm = static_cast(pb); + pm = reinterpret_cast(pb); + + b = d; + b = (Base)d; + b = static_cast(d); + pb = pd; + pb = (Base*)pd; + pb = static_cast(pd); + pb = reinterpret_cast(pd); + + d = (Derived&)b; + d = static_cast(b); + pd = (Derived*)pb; + pd = static_cast(pb); + pd = reinterpret_cast(pb); + + MiddleVB1* pmv = nullptr; + DerivedVB* pdv = nullptr; + pb = pmv; + pb = pdv; +} + +struct PolymorphicBase { + virtual ~PolymorphicBase(); +}; + +struct PolymorphicDerived : PolymorphicBase { +}; + +void DynamicCast() { + PolymorphicBase b; + PolymorphicDerived d; + + PolymorphicBase* pb = &b; + PolymorphicDerived* pd = &d; + + // These two casts are represented as BaseClassCasts because they can be resolved at compile time. + pb = dynamic_cast(pd); + PolymorphicBase& rb = dynamic_cast(d); + + pd = dynamic_cast(pb); + PolymorphicDerived& rd = dynamic_cast(b); + + void* pv = dynamic_cast(pb); + const void* pcv = dynamic_cast(pd); +} + +String::String() : + String("") { // Delegating constructor call +} + +void ArrayConversions() { + char a[5]; + const char* p = a; + p = "test"; + p = &a[0]; + p = &"test"[0]; + char (&ra)[5] = a; + const char (&rs)[5] = "test"; + const char (*pa)[5] = &a; + pa = &"test"; +} + +void FuncPtrConversions(int(*pfn)(int), void* p) { + p = (void*)pfn; + pfn = (int(*)(int))p; +} + +void VarArgUsage(int x, ...) { + __builtin_va_list args; + + __builtin_va_start(args, x); + __builtin_va_list args2; + __builtin_va_start(args2, args); + double d = __builtin_va_arg(args, double); + float f = __builtin_va_arg(args, float); + __builtin_va_end(args); + __builtin_va_end(args2); +} + +void CastToVoid(int x) { + (void)x; +} + +void ConstantConditions(int x) { + bool a = true && true; + int b = (true) ? x : x; +} + +typedef unsigned long size_t; + +namespace std { + enum class align_val_t : size_t {}; +} + +void* operator new(size_t, float); +void* operator new[](size_t, float); +void* operator new(size_t, std::align_val_t, float); +void* operator new[](size_t, std::align_val_t, float); +void operator delete(void*, float); +void operator delete[](void*, float); +void operator delete(void*, std::align_val_t, float); +void operator delete[](void*, std::align_val_t, float); + +struct SizedDealloc { + char a[32]; + void* operator new(size_t); + void* operator new[](size_t); + void operator delete(void*, size_t); + void operator delete[](void*, size_t); +}; + +struct alignas(128) Overaligned { + char a[256]; +}; + +struct DefaultCtorWithDefaultParam { + DefaultCtorWithDefaultParam(double d = 1.0); +}; + +void OperatorNew() { + new int; // No constructor + new(1.0f) int; // Placement new, no constructor + new int(); // Zero-init + new String(); // Constructor + new(1.0f) String("hello"); // Placement new, constructor with args + new Overaligned; // Aligned new + new(1.0f) Overaligned(); // Placement aligned new with zero-init +} + +void OperatorNewArray(int n) { + new int[10]; // Constant size + new int[n]; // No constructor + new(1.0f) int[n]; // Placement new, no constructor + new String[n]; // Constructor + new Overaligned[n]; // Aligned new + new(1.0f) Overaligned[10]; // Aligned placement new + new DefaultCtorWithDefaultParam[n]; + new int[n] { 0, 1, 2 }; +} + +int designatedInit() { + int a1[1000] = { [2] = 10002, [900] = 10900 }; + return a1[900]; +} + +#if 0 +void OperatorDelete() { + delete static_cast(nullptr); // No destructor + delete static_cast(nullptr); // Non-virtual destructor, with size. + delete static_cast(nullptr); // No destructor, with size. + delete static_cast(nullptr); // No destructor, with size and alignment. + delete static_cast(nullptr); // Virtual destructor +} + +void OperatorDeleteArray() { + delete[] static_cast(nullptr); // No destructor + delete[] static_cast(nullptr); // Non-virtual destructor, with size. + delete[] static_cast(nullptr); // No destructor, with size. + delete[] static_cast(nullptr); // No destructor, with size and alignment. + delete[] static_cast(nullptr); // Virtual destructor +} +#endif + +// semmle-extractor-options: -std=c++17 diff --git a/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals.c b/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals.c index 22992df95ea..ee5c611b43f 100644 --- a/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals.c +++ b/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals.c @@ -1,102 +1,102 @@ -struct someStruct { - int i; - int j; -}; - -struct someOtherStruct { - int a; - int b; -}; - -union someUnion { - int n; - double d; -}; - -void f(int x, int y) { - struct someStruct sInit1 = { - .i = x + x, - .j = y - y, - }; - - struct someStruct sInit2 = { x + x, y - y }; - - struct someStruct ss[] = {{x + x, y - y}, {x * x, y / y}}; - - struct someStruct sInit3 = { x }; - - struct someStruct sInit4 = { .j = y }; - - int aInit1[2] = { x, y }; - - int aInit2[2] = { x }; - - int aInit3[2] = { [1] = y }; - - union someUnion uInit1 = { x }; - union someUnion uInit2 = { .n = x }; - union someUnion uInit3 = { .d = 5.0 }; -} - -struct complexStruct { - struct someStruct sss[3]; - int as[3]; - struct someOtherStruct soss[3]; - int z; -}; - -void g(int x, int y) { - // Nested aggregate designated initializers - struct complexStruct complexInit1 = { - .as = { - [2] = x, - [0] = y, - x+y // as[1] - }, - .z = 42, - .soss = { - [1] = { - .a = x+y, - .b = x-y - }, - [0] = { - .b = x*y, - .a = x/y - } - // soss[2] is value initializaed - } - // sss is value initialized - }; - - // Nested aggregate non-designated initializers - struct complexStruct complexInit2 = { - { // sss - { // sss[0] - x, // sss[0].i - y // sss[0].j - }, - { // sss[1] - x+1, // sss[1].i - // sss[1].j is value initialized - } - // ss[2] is value initialized - }, - { // as - 99, // as[0] - x*y // as[1] - // as[2] is value initialized - }, - { // soss - { // soss[0] - 123, // soss[0].a - y+1 // soss[0].b - }, - { // soss[1] - x, // soss[1].a - // soss[1].b is value initialized - } - // soss[2] is value initialized - } - // z is value initialized - }; -} +struct someStruct { + int i; + int j; +}; + +struct someOtherStruct { + int a; + int b; +}; + +union someUnion { + int n; + double d; +}; + +void f(int x, int y) { + struct someStruct sInit1 = { + .i = x + x, + .j = y - y, + }; + + struct someStruct sInit2 = { x + x, y - y }; + + struct someStruct ss[] = {{x + x, y - y}, {x * x, y / y}}; + + struct someStruct sInit3 = { x }; + + struct someStruct sInit4 = { .j = y }; + + int aInit1[2] = { x, y }; + + int aInit2[2] = { x }; + + int aInit3[2] = { [1] = y }; + + union someUnion uInit1 = { x }; + union someUnion uInit2 = { .n = x }; + union someUnion uInit3 = { .d = 5.0 }; +} + +struct complexStruct { + struct someStruct sss[3]; + int as[3]; + struct someOtherStruct soss[3]; + int z; +}; + +void g(int x, int y) { + // Nested aggregate designated initializers + struct complexStruct complexInit1 = { + .as = { + [2] = x, + [0] = y, + x+y // as[1] + }, + .z = 42, + .soss = { + [1] = { + .a = x+y, + .b = x-y + }, + [0] = { + .b = x*y, + .a = x/y + } + // soss[2] is value initializaed + } + // sss is value initialized + }; + + // Nested aggregate non-designated initializers + struct complexStruct complexInit2 = { + { // sss + { // sss[0] + x, // sss[0].i + y // sss[0].j + }, + { // sss[1] + x+1, // sss[1].i + // sss[1].j is value initialized + } + // ss[2] is value initialized + }, + { // as + 99, // as[0] + x*y // as[1] + // as[2] is value initialized + }, + { // soss + { // soss[0] + 123, // soss[0].a + y+1 // soss[0].b + }, + { // soss[1] + x, // soss[1].a + // soss[1].b is value initialized + } + // soss[2] is value initialized + } + // z is value initialized + }; +} diff --git a/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals_cpp.cpp b/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals_cpp.cpp index ba1acfbe0ff..8b335fe3cae 100644 --- a/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals_cpp.cpp +++ b/cpp/ql/test/library-tests/literals/aggregate_literals/aggregate_literals_cpp.cpp @@ -1,28 +1,28 @@ -struct StructWithBitfields { - void Method(); - - unsigned int a : 12; - - static int s; // Static member variables aren't initialized - - unsigned int b : 5; - unsigned int : 15; // Unnamed bitfields aren't initialized - unsigned int c : 7; -}; - -union UnionWithMethods { - void Method(); - - static int s; - - double d; - int x; -}; - -void Init(int x, int y, int z) { - StructWithBitfields s1 = { x, y, z }; - StructWithBitfields s2 = { x, y }; // s2.c is value initialized - StructWithBitfields s3 = {}; // s3 is value initialized - UnionWithMethods u1 = { x }; - UnionWithMethods u2 = {}; -} +struct StructWithBitfields { + void Method(); + + unsigned int a : 12; + + static int s; // Static member variables aren't initialized + + unsigned int b : 5; + unsigned int : 15; // Unnamed bitfields aren't initialized + unsigned int c : 7; +}; + +union UnionWithMethods { + void Method(); + + static int s; + + double d; + int x; +}; + +void Init(int x, int y, int z) { + StructWithBitfields s1 = { x, y, z }; + StructWithBitfields s2 = { x, y }; // s2.c is value initialized + StructWithBitfields s3 = {}; // s3 is value initialized + UnionWithMethods u1 = { x }; + UnionWithMethods u2 = {}; +} diff --git a/cpp/ql/test/library-tests/loops/loops.cpp b/cpp/ql/test/library-tests/loops/loops.cpp index e87c918225c..44450e745b0 100644 --- a/cpp/ql/test/library-tests/loops/loops.cpp +++ b/cpp/ql/test/library-tests/loops/loops.cpp @@ -1,36 +1,36 @@ -void update(bool b); -void init(int &i); -bool cond(int i); -void update(int &i); - -void test_while() -{ - bool b; - - b = true; - while (b) update(b); - - do - { - update(b); - } while (b); -} - -void test_for() -{ - int i, j; - - for (i = 0; i < 10; i++) { - } - - for (j = 10; j >= 0; ) j--; - - for (i = 0, j = 0; i < 10; i++, j++) { - } - - for (init(i); cond(i); update(i)) { - } - - for ((i = 100); (i >= 0); (i--)) { - } -} +void update(bool b); +void init(int &i); +bool cond(int i); +void update(int &i); + +void test_while() +{ + bool b; + + b = true; + while (b) update(b); + + do + { + update(b); + } while (b); +} + +void test_for() +{ + int i, j; + + for (i = 0; i < 10; i++) { + } + + for (j = 10; j >= 0; ) j--; + + for (i = 0, j = 0; i < 10; i++, j++) { + } + + for (init(i); cond(i); update(i)) { + } + + for ((i = 100); (i >= 0); (i--)) { + } +} diff --git a/cpp/ql/test/library-tests/namespaces/namespaces/namespaces.cpp b/cpp/ql/test/library-tests/namespaces/namespaces/namespaces.cpp index f75c9883dbb..e9a28fe1b1f 100644 --- a/cpp/ql/test/library-tests/namespaces/namespaces/namespaces.cpp +++ b/cpp/ql/test/library-tests/namespaces/namespaces/namespaces.cpp @@ -1,44 +1,44 @@ -namespace A { - -} - -namespace B { - -} - -namespace C { - - namespace D { - - inline int f() { return 0; } - - class E { - - void g(int p) { - int a; - { - int b; - } - } - - }; - - } - -} - -namespace B { - - int x = C::D::f(); - -} - -namespace std { - -} - -int globalInt; - -void globalIntUser(void) { - extern int globalInt; -} +namespace A { + +} + +namespace B { + +} + +namespace C { + + namespace D { + + inline int f() { return 0; } + + class E { + + void g(int p) { + int a; + { + int b; + } + } + + }; + + } + +} + +namespace B { + + int x = C::D::f(); + +} + +namespace std { + +} + +int globalInt; + +void globalIntUser(void) { + extern int globalInt; +} diff --git a/cpp/ql/test/library-tests/namespaces/same_name/same_name.cpp b/cpp/ql/test/library-tests/namespaces/same_name/same_name.cpp index 6e7d7204e73..8f45748a1d7 100644 --- a/cpp/ql/test/library-tests/namespaces/same_name/same_name.cpp +++ b/cpp/ql/test/library-tests/namespaces/same_name/same_name.cpp @@ -1,16 +1,16 @@ - -const int c = 1; - -namespace namespace_a -{ - const int c = 1; -} - -namespace namespace_b -{ - //const int c = 1; - // - // this example is causing a DBCheck failure along the lines of: - // - // [INVALID_KEY] Relation namespacembrs((@namespace parentid, unique @namespacembr memberid)): Value 132 of key field memberid occurs in several tuples. Two such tuples are: (134,132) and (144,132) -} + +const int c = 1; + +namespace namespace_a +{ + const int c = 1; +} + +namespace namespace_b +{ + //const int c = 1; + // + // this example is causing a DBCheck failure along the lines of: + // + // [INVALID_KEY] Relation namespacembrs((@namespace parentid, unique @namespacembr memberid)): Value 132 of key field memberid occurs in several tuples. Two such tuples are: (134,132) and (144,132) +} diff --git a/cpp/ql/test/library-tests/operators/operators.cpp b/cpp/ql/test/library-tests/operators/operators.cpp index 79034297725..164d2c19e84 100644 --- a/cpp/ql/test/library-tests/operators/operators.cpp +++ b/cpp/ql/test/library-tests/operators/operators.cpp @@ -1,27 +1,27 @@ -class Name { - const char* s; -}; - -class Table { - Name* p; - int sz; -public: - // See JIRA 521. Including a non-default copy constructor for now. - Table(const Table& other) { } - Table(int s=15) { p = new Name[sz=s]; } // constructor - ~Table() { delete[] p; } - Name* lookup (const char*); - bool insert(Name*); -}; - -void foo() { - Table t1; // call to user-defined constructor - Table t2(t1); // call to default copy constructor - t2.insert(0); -} - -// This used to have TRAP import errors -struct A { A() {} A(A&) {} } a; -A operator+(int, A) { return a; } -int f_A() { 0 + a; } - +class Name { + const char* s; +}; + +class Table { + Name* p; + int sz; +public: + // See JIRA 521. Including a non-default copy constructor for now. + Table(const Table& other) { } + Table(int s=15) { p = new Name[sz=s]; } // constructor + ~Table() { delete[] p; } + Name* lookup (const char*); + bool insert(Name*); +}; + +void foo() { + Table t1; // call to user-defined constructor + Table t2(t1); // call to default copy constructor + t2.insert(0); +} + +// This used to have TRAP import errors +struct A { A() {} A(A&) {} } a; +A operator+(int, A) { return a; } +int f_A() { 0 + a; } + diff --git a/cpp/ql/test/library-tests/padding/size_asserts.h b/cpp/ql/test/library-tests/padding/size_asserts.h index 674257cba41..1b68ed8472d 100644 --- a/cpp/ql/test/library-tests/padding/size_asserts.h +++ b/cpp/ql/test/library-tests/padding/size_asserts.h @@ -1,46 +1,46 @@ -// Static assert macro -#define CASSERT(condition) typedef char cassertTypedef[((condition) != 0) ? 1 : -1] - -#if defined(_MSC_VER) -#define CASSERT_MSVC(condition) CASSERT(condition) -#define CASSERT_GCC(condition) -#if defined(_WIN64) -#define TARGET_BIT_SIZE 64 -#else -#define TARGET_BIT_SIZE 32 -#endif -#elif defined(__GNUC__) -#define CASSERT_MSVC(condition) -#define CASSERT_GCC(condition) CASSERT(condition) -#if defined(__x86_64) -#define TARGET_BIT_SIZE 64 -#else -#define TARGET_BIT_SIZE 32 -#endif -#else -CASSERT(0); -#endif - -#if defined(_MSC_VER) && (TARGET_BIT_SIZE == 32) -#define CASSERT_MSVC32(condition) CASSERT(condition) -#else -#define CASSERT_MSVC32(condition) -#endif - -#if defined(_MSC_VER) && (TARGET_BIT_SIZE == 64) -#define CASSERT_MSVC64(condition) CASSERT(condition) -#else -#define CASSERT_MSVC64(condition) -#endif - -#if defined(__GNUC__) && (TARGET_BIT_SIZE == 32) -#define CASSERT_GCC32(condition) CASSERT(condition) -#else -#define CASSERT_GCC32(condition) -#endif - -#if defined(__GNUC__) && (TARGET_BIT_SIZE == 64) -#define CASSERT_GCC64(condition) CASSERT(condition) -#else -#define CASSERT_GCC64(condition) -#endif +// Static assert macro +#define CASSERT(condition) typedef char cassertTypedef[((condition) != 0) ? 1 : -1] + +#if defined(_MSC_VER) +#define CASSERT_MSVC(condition) CASSERT(condition) +#define CASSERT_GCC(condition) +#if defined(_WIN64) +#define TARGET_BIT_SIZE 64 +#else +#define TARGET_BIT_SIZE 32 +#endif +#elif defined(__GNUC__) +#define CASSERT_MSVC(condition) +#define CASSERT_GCC(condition) CASSERT(condition) +#if defined(__x86_64) +#define TARGET_BIT_SIZE 64 +#else +#define TARGET_BIT_SIZE 32 +#endif +#else +CASSERT(0); +#endif + +#if defined(_MSC_VER) && (TARGET_BIT_SIZE == 32) +#define CASSERT_MSVC32(condition) CASSERT(condition) +#else +#define CASSERT_MSVC32(condition) +#endif + +#if defined(_MSC_VER) && (TARGET_BIT_SIZE == 64) +#define CASSERT_MSVC64(condition) CASSERT(condition) +#else +#define CASSERT_MSVC64(condition) +#endif + +#if defined(__GNUC__) && (TARGET_BIT_SIZE == 32) +#define CASSERT_GCC32(condition) CASSERT(condition) +#else +#define CASSERT_GCC32(condition) +#endif + +#if defined(__GNUC__) && (TARGET_BIT_SIZE == 64) +#define CASSERT_GCC64(condition) CASSERT(condition) +#else +#define CASSERT_GCC64(condition) +#endif diff --git a/cpp/ql/test/library-tests/parameters/parameters/parameters.cpp b/cpp/ql/test/library-tests/parameters/parameters/parameters.cpp index 1c85d65409b..c0965c33172 100644 --- a/cpp/ql/test/library-tests/parameters/parameters/parameters.cpp +++ b/cpp/ql/test/library-tests/parameters/parameters/parameters.cpp @@ -1,28 +1,28 @@ -typedef int (*CallbackFn)(int a, int b); - -int Callback_1(int a, int b) -{ - return a + b; -} - -int Callback_2(int a, int b) -{ - return a; -} - -int Callback_3(int, int b) -{ - return b; -} - -void Dispatch(int n, int a, int b, int c, int) -{ - CallbackFn pFn; - switch(n) - { - case 0: pFn = &Callback_1; break; - case 1: pFn = &Callback_2; break; - default: pFn = &Callback_3; break; - } - (*pFn)(a,b); -} +typedef int (*CallbackFn)(int a, int b); + +int Callback_1(int a, int b) +{ + return a + b; +} + +int Callback_2(int a, int b) +{ + return a; +} + +int Callback_3(int, int b) +{ + return b; +} + +void Dispatch(int n, int a, int b, int c, int) +{ + CallbackFn pFn; + switch(n) + { + case 0: pFn = &Callback_1; break; + case 1: pFn = &Callback_2; break; + default: pFn = &Callback_3; break; + } + (*pFn)(a,b); +} diff --git a/cpp/ql/test/library-tests/preprocessor/include/guarded.h b/cpp/ql/test/library-tests/preprocessor/include/guarded.h index 96fb298d5c9..fb7c9149e9f 100644 --- a/cpp/ql/test/library-tests/preprocessor/include/guarded.h +++ b/cpp/ql/test/library-tests/preprocessor/include/guarded.h @@ -1,8 +1,8 @@ -// guarded.h - -#ifndef GUARDED_H -#define GUARDED_H - - // ... content ... - +// guarded.h + +#ifndef GUARDED_H +#define GUARDED_H + + // ... content ... + #endif // GUARDED_H \ No newline at end of file diff --git a/cpp/ql/test/library-tests/preprocessor/include/unguarded.h b/cpp/ql/test/library-tests/preprocessor/include/unguarded.h index 14f174c8729..bf1b9844e68 100644 --- a/cpp/ql/test/library-tests/preprocessor/include/unguarded.h +++ b/cpp/ql/test/library-tests/preprocessor/include/unguarded.h @@ -1,3 +1,3 @@ -// unguarded.h - -// ... content ... +// unguarded.h + +// ... content ... diff --git a/cpp/ql/test/library-tests/preprocessor/linedirective/header.h b/cpp/ql/test/library-tests/preprocessor/linedirective/header.h index 51fb5f568d6..6865877d950 100644 --- a/cpp/ql/test/library-tests/preprocessor/linedirective/header.h +++ b/cpp/ql/test/library-tests/preprocessor/linedirective/header.h @@ -1,3 +1,3 @@ -// header.h - -// ... content ... +// header.h + +// ... content ... diff --git a/cpp/ql/test/library-tests/preprocessor/linedirective/line.h b/cpp/ql/test/library-tests/preprocessor/linedirective/line.h index 5ec8cc56e1f..1b4fc1a6aee 100644 --- a/cpp/ql/test/library-tests/preprocessor/linedirective/line.h +++ b/cpp/ql/test/library-tests/preprocessor/linedirective/line.h @@ -1,14 +1,14 @@ -// line.h - -#line 100 "line.h" - -#include "header.h" - -void myLineFunction(); - -#define MYLINEDEFINE (1) - -struct myLineStruct -{ - int v; -}; +// line.h + +#line 100 "line.h" + +#include "header.h" + +void myLineFunction(); + +#define MYLINEDEFINE (1) + +struct myLineStruct +{ + int v; +}; diff --git a/cpp/ql/test/library-tests/preprocessor/linedirective/system.h b/cpp/ql/test/library-tests/preprocessor/linedirective/system.h index eec178192a5..407507af89a 100644 --- a/cpp/ql/test/library-tests/preprocessor/linedirective/system.h +++ b/cpp/ql/test/library-tests/preprocessor/linedirective/system.h @@ -1,14 +1,14 @@ -// system.h - -#pragma GCC system_header - -#include "header.h" - -void mySystemFunction(); - -#define MYSYSTEMDEFINE (2) - -struct mySystemStruct -{ - int v; -}; +// system.h + +#pragma GCC system_header + +#include "header.h" + +void mySystemFunction(); + +#define MYSYSTEMDEFINE (2) + +struct mySystemStruct +{ + int v; +}; diff --git a/cpp/ql/test/library-tests/scopes/scopes/scopes.cpp b/cpp/ql/test/library-tests/scopes/scopes/scopes.cpp index 3e1353e1ff7..70dc0a195dd 100644 --- a/cpp/ql/test/library-tests/scopes/scopes/scopes.cpp +++ b/cpp/ql/test/library-tests/scopes/scopes/scopes.cpp @@ -1,104 +1,104 @@ - -class A { - -}; - - -class B { - -}; - -class C: A, B { - -}; - -class D: C { - - class E; - -}; - -class D::E { - - class F; - - class G { - - }; - -}; - -class D::E::F: D::E::G { - void doubleNestedFunction() {} -}; - -void f(int a, int b) { - bool c = a==b; - - switch (a) - { - default: - } -} - -void g(); - -struct S { - void af() { - - } - void ag(); -}; - -void g() { - S s; - s.ag(); -} - -class Name { - const char* s; -}; - -class Table { - Name* p; - int sz; -public: - Table(int s=15) { p = new Name[sz=s]; } // constructor - ~Table() { delete[] p; } - Name* lookup (const char*); - bool insert(Name*); -}; - -extern "C" int strlen(const char*); - -namespace One -{ - template - class H - { - T t; - }; - - H h_short; - H h_long; - - namespace Two - { - enum myEnum - { - myOne, - myTwo, - myThree - }; - }; - - class I - { - enum myEnum2 - { - Alpha, - Beta, - Gamma - }; - }; + +class A { + +}; + + +class B { + +}; + +class C: A, B { + +}; + +class D: C { + + class E; + +}; + +class D::E { + + class F; + + class G { + + }; + +}; + +class D::E::F: D::E::G { + void doubleNestedFunction() {} +}; + +void f(int a, int b) { + bool c = a==b; + + switch (a) + { + default: + } +} + +void g(); + +struct S { + void af() { + + } + void ag(); +}; + +void g() { + S s; + s.ag(); +} + +class Name { + const char* s; +}; + +class Table { + Name* p; + int sz; +public: + Table(int s=15) { p = new Name[sz=s]; } // constructor + ~Table() { delete[] p; } + Name* lookup (const char*); + bool insert(Name*); +}; + +extern "C" int strlen(const char*); + +namespace One +{ + template + class H + { + T t; + }; + + H h_short; + H h_long; + + namespace Two + { + enum myEnum + { + myOne, + myTwo, + myThree + }; + }; + + class I + { + enum myEnum2 + { + Alpha, + Beta, + Gamma + }; + }; }; \ No newline at end of file diff --git a/cpp/ql/test/library-tests/sideEffects/exprs/exprs.cpp b/cpp/ql/test/library-tests/sideEffects/exprs/exprs.cpp index d28e8513e84..30b0f5cf6fc 100644 --- a/cpp/ql/test/library-tests/sideEffects/exprs/exprs.cpp +++ b/cpp/ql/test/library-tests/sideEffects/exprs/exprs.cpp @@ -1,40 +1,40 @@ - -class MyIterator - { -public: - MyIterator &operator++() - { - return (*this); - } - - MyIterator &operator--() - { - v--; - return (*this); - } - -private: - int v; - }; - -void f2() { - MyIterator mi; - - ++mi; - --mi; -} - -template void myTemplateFunction() { - static MyIterator mi; - static int i; - static T t; - - ++mi; // pure - ++i; // impure - ++t; // varies -} - -void f3() { - myTemplateFunction(); - myTemplateFunction(); -} + +class MyIterator + { +public: + MyIterator &operator++() + { + return (*this); + } + + MyIterator &operator--() + { + v--; + return (*this); + } + +private: + int v; + }; + +void f2() { + MyIterator mi; + + ++mi; + --mi; +} + +template void myTemplateFunction() { + static MyIterator mi; + static int i; + static T t; + + ++mi; // pure + ++i; // impure + ++t; // varies +} + +void f3() { + myTemplateFunction(); + myTemplateFunction(); +} diff --git a/cpp/ql/test/library-tests/specifiers/specifiers.cpp b/cpp/ql/test/library-tests/specifiers/specifiers.cpp index db40595b09c..c103e4198c7 100644 --- a/cpp/ql/test/library-tests/specifiers/specifiers.cpp +++ b/cpp/ql/test/library-tests/specifiers/specifiers.cpp @@ -1,22 +1,22 @@ -extern int i; -extern int i; -extern int i; - -const int c = 7; -const double pi = 3.1415926535897932385; - -unsigned a; - -unsigned int b; -int b2; - - int * const int_pointer1 = &b2; -const int * int_pointer2 = &c; // Note: int_pointer2 is not const itself -const int * const int_pointer3 = &c; - -typedef char* Pchar; - -const char* kings[] = { "Antigonus", "Seleucus", "Ptolemy" }; - -int* p, q; -int v[10], *pv; +extern int i; +extern int i; +extern int i; + +const int c = 7; +const double pi = 3.1415926535897932385; + +unsigned a; + +unsigned int b; +int b2; + + int * const int_pointer1 = &b2; +const int * int_pointer2 = &c; // Note: int_pointer2 is not const itself +const int * const int_pointer3 = &c; + +typedef char* Pchar; + +const char* kings[] = { "Antigonus", "Seleucus", "Ptolemy" }; + +int* p, q; +int v[10], *pv; diff --git a/cpp/ql/test/library-tests/string_analysis/string_analysis.cpp b/cpp/ql/test/library-tests/string_analysis/string_analysis.cpp index 283baabd2ac..7d98961f04b 100644 --- a/cpp/ql/test/library-tests/string_analysis/string_analysis.cpp +++ b/cpp/ql/test/library-tests/string_analysis/string_analysis.cpp @@ -1,44 +1,44 @@ -int main(int argc, char *argv[]) -{ - char *str1, *str2, *str3, *result; - int cond1, cond2, cond3, cond4; - - str1 = "1"; - str2 = "22"; - str3 = "333"; - - result = str1; // max length 1 - if (cond1) - { - result = (cond2 ? str2 : str3); // max length 3 - } - result = (cond3 ? str1 : result); // max length 3 - result = (cond4 ? str1 : argv[0]); // max unknown - - return 0; -} - -namespace std -{ - class string - { - public: - string(char *_str) : str(_str) {}; - ~string() {}; - - string &operator=(string &other) { - str = other.str; - }; - - private: - char *str; - }; -} - -void more_cases() -{ - wchar_t *wstr1 = L"4444"; - wchar_t *wstr2 = wstr1; - std::string str1 = "666666"; - std::string str2 = str1; -} +int main(int argc, char *argv[]) +{ + char *str1, *str2, *str3, *result; + int cond1, cond2, cond3, cond4; + + str1 = "1"; + str2 = "22"; + str3 = "333"; + + result = str1; // max length 1 + if (cond1) + { + result = (cond2 ? str2 : str3); // max length 3 + } + result = (cond3 ? str1 : result); // max length 3 + result = (cond4 ? str1 : argv[0]); // max unknown + + return 0; +} + +namespace std +{ + class string + { + public: + string(char *_str) : str(_str) {}; + ~string() {}; + + string &operator=(string &other) { + str = other.str; + }; + + private: + char *str; + }; +} + +void more_cases() +{ + wchar_t *wstr1 = L"4444"; + wchar_t *wstr2 = wstr1; + std::string str1 = "666666"; + std::string str2 = str1; +} diff --git a/cpp/ql/test/library-tests/structs/compatible_variables/a.c b/cpp/ql/test/library-tests/structs/compatible_variables/a.c index bac709efb95..6f6b1800d8b 100644 --- a/cpp/ql/test/library-tests/structs/compatible_variables/a.c +++ b/cpp/ql/test/library-tests/structs/compatible_variables/a.c @@ -1,14 +1,14 @@ -#include "h.h" - -// Provide a complete definition of Foo. -struct Foo { - int foo_x; -}; - -// This definition is incompatible with the one in b.c, so... -struct Bar { - int bar_y; -}; - -// ...we'd expect this declaration to create a separate variable in the db -extern struct Bar bar; +#include "h.h" + +// Provide a complete definition of Foo. +struct Foo { + int foo_x; +}; + +// This definition is incompatible with the one in b.c, so... +struct Bar { + int bar_y; +}; + +// ...we'd expect this declaration to create a separate variable in the db +extern struct Bar bar; diff --git a/cpp/ql/test/library-tests/structs/compatible_variables/b.c b/cpp/ql/test/library-tests/structs/compatible_variables/b.c index 5037af9500d..a7dd16e2d38 100644 --- a/cpp/ql/test/library-tests/structs/compatible_variables/b.c +++ b/cpp/ql/test/library-tests/structs/compatible_variables/b.c @@ -1,17 +1,17 @@ -// The extractor will not see a complete definition of Foo for this file. - -#include "h.h" - -// We want to check that these two variables don't get duplicated in the -// database. -void (*some_func_ptr)(struct Foo *foo); -struct Foo* foo_ptr1; -FooPtr foo_ptr2; - -// This definition is incompatible with the one in a.c, so... -struct Bar { - unsigned long bar_x; -}; - -// ...we'd expect this declaration to create a separate variable in the db -extern struct Bar bar; +// The extractor will not see a complete definition of Foo for this file. + +#include "h.h" + +// We want to check that these two variables don't get duplicated in the +// database. +void (*some_func_ptr)(struct Foo *foo); +struct Foo* foo_ptr1; +FooPtr foo_ptr2; + +// This definition is incompatible with the one in a.c, so... +struct Bar { + unsigned long bar_x; +}; + +// ...we'd expect this declaration to create a separate variable in the db +extern struct Bar bar; diff --git a/cpp/ql/test/library-tests/structs/compatible_variables/h.h b/cpp/ql/test/library-tests/structs/compatible_variables/h.h index 95cf6d42860..b94a97f9a4b 100644 --- a/cpp/ql/test/library-tests/structs/compatible_variables/h.h +++ b/cpp/ql/test/library-tests/structs/compatible_variables/h.h @@ -1,10 +1,10 @@ -// Provide an incomplete definition of Foo. -struct Foo; -typedef struct Foo* FooPtr; - -// When this file is included from a.c, the extractor will see a complete -// definition of Foo, but not when it's included b.c. We want to check that we -// don't see these variables duplicated in the database because of it. -extern void (*some_func_ptr)(struct Foo *foo); -extern struct Foo* foo_ptr1; -extern FooPtr foo_ptr2; +// Provide an incomplete definition of Foo. +struct Foo; +typedef struct Foo* FooPtr; + +// When this file is included from a.c, the extractor will see a complete +// definition of Foo, but not when it's included b.c. We want to check that we +// don't see these variables duplicated in the database because of it. +extern void (*some_func_ptr)(struct Foo *foo); +extern struct Foo* foo_ptr1; +extern FooPtr foo_ptr2; diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/a.h b/cpp/ql/test/library-tests/structs/incomplete_definition/a.h index d09cac85aa5..a051126f271 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/a.h +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/a.h @@ -1,6 +1,6 @@ -// Incomplete definition of Foo -struct Foo; - -struct Bar { - Foo *cheese; -}; +// Incomplete definition of Foo +struct Foo; + +struct Bar { + Foo *cheese; +}; diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp b/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp index ab5eb947455..e0e0338c831 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/x.cpp @@ -1,31 +1,31 @@ -#include "a.h" - -Bar *bar_x; - -namespace unrelated { - struct Foo { - short val; - }; -} - -struct ContainsAnotherFoo { - class Foo { - long val; - }; -}; - -// The type of `foo_x` should not refer to any of the above classes, none of -// which are named `Foo` in the global scope. -Foo *foo_x; - -template -class Template { - T templateField; -}; - -Template *template_foo; - -// Instantiation of the template with unrelated classes named `Foo` should not -// get mixed up with the instantiation above. -template class Template; -template class Template; +#include "a.h" + +Bar *bar_x; + +namespace unrelated { + struct Foo { + short val; + }; +} + +struct ContainsAnotherFoo { + class Foo { + long val; + }; +}; + +// The type of `foo_x` should not refer to any of the above classes, none of +// which are named `Foo` in the global scope. +Foo *foo_x; + +template +class Template { + T templateField; +}; + +Template *template_foo; + +// Instantiation of the template with unrelated classes named `Foo` should not +// get mixed up with the instantiation above. +template class Template; +template class Template; diff --git a/cpp/ql/test/library-tests/structs/incomplete_definition/y.cpp b/cpp/ql/test/library-tests/structs/incomplete_definition/y.cpp index 6059af31766..ae8de1d55fa 100644 --- a/cpp/ql/test/library-tests/structs/incomplete_definition/y.cpp +++ b/cpp/ql/test/library-tests/structs/incomplete_definition/y.cpp @@ -1,8 +1,8 @@ -#include "a.h" - -// Completes definition of Foo -struct Foo { - int val; -}; - -Bar bar_y; +#include "a.h" + +// Completes definition of Foo +struct Foo { + int val; +}; + +Bar bar_y; diff --git a/cpp/ql/test/library-tests/structs/mutual_recursion/a.c b/cpp/ql/test/library-tests/structs/mutual_recursion/a.c index 6fd3d62ba24..6af982609ad 100644 --- a/cpp/ql/test/library-tests/structs/mutual_recursion/a.c +++ b/cpp/ql/test/library-tests/structs/mutual_recursion/a.c @@ -1,61 +1,61 @@ -struct Node { - struct Node *next; -}; - -struct CompatibleB; -struct CompatibleC; - -struct CompatibleA { - struct CompatibleB *b; -}; - -struct CompatibleB { - struct CompatibleC *c; -}; - -// The 2 definitions of CompatibleC use different but compatible types for x -struct CompatibleC { - struct CompatibleA *a; - int x; -}; - -// The initial handling of recursion didn't catch this case - if you start from -// D, you'll never revisit it, but you will revisit A/B/C. -struct CompatibleD { - struct CompatibleA *a; -}; - -// Ideally, we'd detect that the definitions of Incompatible{A,B} are incompatible, but since their -// fields are pointers, we can't deeply inspect them (it would be possible to have pointers to -// incomplete types that we *can't* deeply inspect). -struct IncompatibleB; -struct IncompatibleC; - -struct IncompatibleA { - struct IncompatibleB *b; -}; - -struct IncompatibleB { - struct IncompatibleC *c; -}; - -// The 2 definitions of IncompatibleC use different and incompatible types for x -struct IncompatibleC { - struct IncompatibleA *a; - short x; -}; - -struct IncompatibleD { - struct IncompatibleA *a; -}; - -// We should be able to detect that the definitions of NonRecursiveA and NonRecursiveB are -// incompatible - unlike the above cases, there's no mutual recursion and no pointer type, so we can -// deeply inspect NonRecursiveA when it's used from NonRecursiveB. -struct NonRecursiveA { - int val; -}; - -struct NonRecursiveB { - struct NonRecursiveA a; -}; +struct Node { + struct Node *next; +}; + +struct CompatibleB; +struct CompatibleC; + +struct CompatibleA { + struct CompatibleB *b; +}; + +struct CompatibleB { + struct CompatibleC *c; +}; + +// The 2 definitions of CompatibleC use different but compatible types for x +struct CompatibleC { + struct CompatibleA *a; + int x; +}; + +// The initial handling of recursion didn't catch this case - if you start from +// D, you'll never revisit it, but you will revisit A/B/C. +struct CompatibleD { + struct CompatibleA *a; +}; + +// Ideally, we'd detect that the definitions of Incompatible{A,B} are incompatible, but since their +// fields are pointers, we can't deeply inspect them (it would be possible to have pointers to +// incomplete types that we *can't* deeply inspect). +struct IncompatibleB; +struct IncompatibleC; + +struct IncompatibleA { + struct IncompatibleB *b; +}; + +struct IncompatibleB { + struct IncompatibleC *c; +}; + +// The 2 definitions of IncompatibleC use different and incompatible types for x +struct IncompatibleC { + struct IncompatibleA *a; + short x; +}; + +struct IncompatibleD { + struct IncompatibleA *a; +}; + +// We should be able to detect that the definitions of NonRecursiveA and NonRecursiveB are +// incompatible - unlike the above cases, there's no mutual recursion and no pointer type, so we can +// deeply inspect NonRecursiveA when it's used from NonRecursiveB. +struct NonRecursiveA { + int val; +}; + +struct NonRecursiveB { + struct NonRecursiveA a; +}; diff --git a/cpp/ql/test/library-tests/structs/mutual_recursion/b.c b/cpp/ql/test/library-tests/structs/mutual_recursion/b.c index 234e1f84e49..1b4d486059a 100644 --- a/cpp/ql/test/library-tests/structs/mutual_recursion/b.c +++ b/cpp/ql/test/library-tests/structs/mutual_recursion/b.c @@ -1,57 +1,57 @@ -struct Node { - struct Node *next; -}; - -struct CompatibleB; -struct CompatibleC; - -struct CompatibleA { - struct CompatibleB *b; -}; - -struct CompatibleB { - struct CompatibleC *c; -}; - -// The 2 definitions of CompatibleC use different but compatible types for x -typedef int AnInt; -struct CompatibleC { - struct CompatibleA *a; - AnInt x; -}; - -struct CompatibleD { - struct CompatibleA *a; -}; - -struct IncompatibleB; -struct IncompatibleC; - -struct IncompatibleA { - struct IncompatibleB *b; -}; - -struct IncompatibleB { - struct IncompatibleC *c; -}; - -// The 2 definitions of IncompatibleC use different and incompatible types for x -struct IncompatibleC { - struct IncompatibleA *a; - int x; -}; - -struct IncompatibleD { - struct IncompatibleA *a; -}; - -// We should be able to detect that the definitions of NonRecursiveA and NonRecursiveB are -// incompatible - unlike the above cases, there's no mutual recursion and no pointer type, so we can -// deeply inspect NonRecursiveA when it's used from NonRecursiveB. -struct NonRecursiveA { - short val; -}; - -struct NonRecursiveB { - struct NonRecursiveA a; -}; +struct Node { + struct Node *next; +}; + +struct CompatibleB; +struct CompatibleC; + +struct CompatibleA { + struct CompatibleB *b; +}; + +struct CompatibleB { + struct CompatibleC *c; +}; + +// The 2 definitions of CompatibleC use different but compatible types for x +typedef int AnInt; +struct CompatibleC { + struct CompatibleA *a; + AnInt x; +}; + +struct CompatibleD { + struct CompatibleA *a; +}; + +struct IncompatibleB; +struct IncompatibleC; + +struct IncompatibleA { + struct IncompatibleB *b; +}; + +struct IncompatibleB { + struct IncompatibleC *c; +}; + +// The 2 definitions of IncompatibleC use different and incompatible types for x +struct IncompatibleC { + struct IncompatibleA *a; + int x; +}; + +struct IncompatibleD { + struct IncompatibleA *a; +}; + +// We should be able to detect that the definitions of NonRecursiveA and NonRecursiveB are +// incompatible - unlike the above cases, there's no mutual recursion and no pointer type, so we can +// deeply inspect NonRecursiveA when it's used from NonRecursiveB. +struct NonRecursiveA { + short val; +}; + +struct NonRecursiveB { + struct NonRecursiveA a; +}; diff --git a/cpp/ql/test/library-tests/typedefs/typedefs.cpp b/cpp/ql/test/library-tests/typedefs/typedefs.cpp index 37043e5cf46..6998b6c8ef7 100644 --- a/cpp/ql/test/library-tests/typedefs/typedefs.cpp +++ b/cpp/ql/test/library-tests/typedefs/typedefs.cpp @@ -1,31 +1,31 @@ -namespace NS1 -{ - typedef int WIDTH; -} - -void f1() -{ - typedef int TYPE; - class D {}; -} - -class A -{ - -protected: - typedef NS1::WIDTH WIDTH; - typedef WIDTH WIDTH2; - -public: - typedef WIDTH WIDTH3; - -private: - typedef WIDTH WIDTH4; -}; - -class B: public A { - WIDTH i; - WIDTH2 i2; - WIDTH3 i3; - //WIDTH4 i4; --- inaccessible -}; +namespace NS1 +{ + typedef int WIDTH; +} + +void f1() +{ + typedef int TYPE; + class D {}; +} + +class A +{ + +protected: + typedef NS1::WIDTH WIDTH; + typedef WIDTH WIDTH2; + +public: + typedef WIDTH WIDTH3; + +private: + typedef WIDTH WIDTH4; +}; + +class B: public A { + WIDTH i; + WIDTH2 i2; + WIDTH3 i3; + //WIDTH4 i4; --- inaccessible +}; diff --git a/cpp/ql/test/library-tests/types/integral_types_ms/integral_types.cpp b/cpp/ql/test/library-tests/types/integral_types_ms/integral_types.cpp index aab2fa52924..cacb48b3b8c 100644 --- a/cpp/ql/test/library-tests/types/integral_types_ms/integral_types.cpp +++ b/cpp/ql/test/library-tests/types/integral_types_ms/integral_types.cpp @@ -1,5 +1,5 @@ - -__int8 i8; -__int16 i16; -__int32 i32; -__int64 i64; + +__int8 i8; +__int16 i16; +__int32 i32; +__int64 i64; diff --git a/cpp/ql/test/library-tests/types/pointertypes/pointertypes.c b/cpp/ql/test/library-tests/types/pointertypes/pointertypes.c index 2881dc87853..65bca5fa9da 100644 --- a/cpp/ql/test/library-tests/types/pointertypes/pointertypes.c +++ b/cpp/ql/test/library-tests/types/pointertypes/pointertypes.c @@ -1,40 +1,40 @@ - -char c; -char *cp; - -const char cc; -char const cc2; -const char *ccp; -char const *ccp2; -char * const ccp3; -char const * const ccp4; - -volatile char vc; -char volatile vc2; -volatile char *vcp; -char volatile *vcp2; -char * volatile vcp3; -char volatile * volatile vcp4; - -char * restrict rcp; -char *__restrict__ rcp2; - -void *vp; - -const void *cvp; -void const *cvp2; -void * const cvp3; -void const * const cvp4; - -void *restrict rvp1; -void *__restrict__ rvp2; - -const struct s *csp; -struct s const *csp2; -struct s * const csp3; -struct s const * const csp4; - -struct s *restrict rsp1; -struct s *__restrict__ rsp2; - -char * const volatile restrict cvrcp; + +char c; +char *cp; + +const char cc; +char const cc2; +const char *ccp; +char const *ccp2; +char * const ccp3; +char const * const ccp4; + +volatile char vc; +char volatile vc2; +volatile char *vcp; +char volatile *vcp2; +char * volatile vcp3; +char volatile * volatile vcp4; + +char * restrict rcp; +char *__restrict__ rcp2; + +void *vp; + +const void *cvp; +void const *cvp2; +void * const cvp3; +void const * const cvp4; + +void *restrict rvp1; +void *__restrict__ rvp2; + +const struct s *csp; +struct s const *csp2; +struct s * const csp3; +struct s const * const csp4; + +struct s *restrict rsp1; +struct s *__restrict__ rsp2; + +char * const volatile restrict cvrcp; diff --git a/cpp/ql/test/library-tests/types/refersTo/refersTo.cpp b/cpp/ql/test/library-tests/types/refersTo/refersTo.cpp index 05564ae604b..8a277a1d753 100644 --- a/cpp/ql/test/library-tests/types/refersTo/refersTo.cpp +++ b/cpp/ql/test/library-tests/types/refersTo/refersTo.cpp @@ -1,20 +1,20 @@ - -class a -{ -}; - -typedef a &a_ref; -typedef a *a_ptr; -typedef a a_array[10]; - -template -class container -{ -public: - T t; -}; - -class strange : public container > -{ -public: -}; + +class a +{ +}; + +typedef a &a_ref; +typedef a *a_ptr; +typedef a a_array[10]; + +template +class container +{ +public: + T t; +}; + +class strange : public container > +{ +public: +}; diff --git a/cpp/ql/test/library-tests/types/scope/scope.cpp b/cpp/ql/test/library-tests/types/scope/scope.cpp index c9d0d962d62..2a7b6501d3f 100644 --- a/cpp/ql/test/library-tests/types/scope/scope.cpp +++ b/cpp/ql/test/library-tests/types/scope/scope.cpp @@ -1,27 +1,27 @@ - -int a[100]; -typedef int my_array[200]; - -void g1(int b[300]); -void g1(int b[300]) { - int c[400]; - - typedef int my_array_2[500]; - my_array d; - my_array_2 e; - - class f - { - public: - void g2() - { - int g[600]; - } - - int h[700]; - }; - - int i = sizeof(int[800]); - auto j = new int[900]; - int *k = new int[1000]; -} + +int a[100]; +typedef int my_array[200]; + +void g1(int b[300]); +void g1(int b[300]) { + int c[400]; + + typedef int my_array_2[500]; + my_array d; + my_array_2 e; + + class f + { + public: + void g2() + { + int g[600]; + } + + int h[700]; + }; + + int i = sizeof(int[800]); + auto j = new int[900]; + int *k = new int[1000]; +} diff --git a/cpp/ql/test/library-tests/types/types/types.cpp b/cpp/ql/test/library-tests/types/types/types.cpp index ab811aea829..903ede7c49b 100644 --- a/cpp/ql/test/library-tests/types/types/types.cpp +++ b/cpp/ql/test/library-tests/types/types/types.cpp @@ -1,82 +1,82 @@ -extern int i; - -const int c = 7; -const double pi = 3.1415926535897932385; - -unsigned a; - -unsigned int b; - -typedef char* Pchar; - -const char* kings[] = { "Antigonus", "Seleucus", "Ptolemy" }; - -int* p, q; -int v1[10], *pv; - -int (*fp)(char *); // pointer to function - -float v2[3]; -char* v3[32]; - -int d2[10][20]; - -char v4[3] = { 'a', 'b', 0 }; - -int v5[8] = { 1, 2, 3, 4 }; - -char* p2 = "Plato"; -char p3[] = "Zeno"; - -char alpha[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -int av[] = { 1, 2 , 3, 4 }; -int* ap1 = av; -int* ap2 = &av[0]; -int* ap3 = &av[4]; - -int f(int* pi) -{ - void* pv = pi; - return 0; -} - -void f1(char* p) -{ - char s[] = "Gorm"; - const char* pc = s; - pc = p; - - char *const cp = s; - cp[3] = 'a'; - - const char *const cpc = s; - char const* pc2 = s; -} - -void f2() -{ - int i = 1; - int& r = i; - int x = r; - r = 2; - const double& cdr = 1; -} - -void increment(int& aa) { aa++; } - -__int128 i128; -signed __int128 i128s; -unsigned __int128 i128u; - -Pchar pchar; - -typedef unsigned long size_t; -typedef long ssize_t; -typedef long ptrdiff_t; - -size_t st; -ssize_t sst; -ptrdiff_t pdt; -wchar_t wct; +extern int i; + +const int c = 7; +const double pi = 3.1415926535897932385; + +unsigned a; + +unsigned int b; + +typedef char* Pchar; + +const char* kings[] = { "Antigonus", "Seleucus", "Ptolemy" }; + +int* p, q; +int v1[10], *pv; + +int (*fp)(char *); // pointer to function + +float v2[3]; +char* v3[32]; + +int d2[10][20]; + +char v4[3] = { 'a', 'b', 0 }; + +int v5[8] = { 1, 2, 3, 4 }; + +char* p2 = "Plato"; +char p3[] = "Zeno"; + +char alpha[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +int av[] = { 1, 2 , 3, 4 }; +int* ap1 = av; +int* ap2 = &av[0]; +int* ap3 = &av[4]; + +int f(int* pi) +{ + void* pv = pi; + return 0; +} + +void f1(char* p) +{ + char s[] = "Gorm"; + const char* pc = s; + pc = p; + + char *const cp = s; + cp[3] = 'a'; + + const char *const cpc = s; + char const* pc2 = s; +} + +void f2() +{ + int i = 1; + int& r = i; + int x = r; + r = 2; + const double& cdr = 1; +} + +void increment(int& aa) { aa++; } + +__int128 i128; +signed __int128 i128s; +unsigned __int128 i128u; + +Pchar pchar; + +typedef unsigned long size_t; +typedef long ssize_t; +typedef long ptrdiff_t; + +size_t st; +ssize_t sst; +ptrdiff_t pdt; +wchar_t wct; diff --git a/cpp/ql/test/library-tests/types/wchar_t_typedef/ms.c b/cpp/ql/test/library-tests/types/wchar_t_typedef/ms.c index e1c0bcc4c4a..f8c5cf9d2fa 100644 --- a/cpp/ql/test/library-tests/types/wchar_t_typedef/ms.c +++ b/cpp/ql/test/library-tests/types/wchar_t_typedef/ms.c @@ -1,4 +1,4 @@ - -typedef unsigned short wchar_t; - -wchar_t *wstring; + +typedef unsigned short wchar_t; + +wchar_t *wstring; diff --git a/cpp/ql/test/library-tests/unions/unions.cpp b/cpp/ql/test/library-tests/unions/unions.cpp index 6122c4e379d..a693e3bc9d8 100644 --- a/cpp/ql/test/library-tests/unions/unions.cpp +++ b/cpp/ql/test/library-tests/unions/unions.cpp @@ -1,23 +1,23 @@ - -enum Type { S, I }; - -struct Entry { - - char* name; - Type t; - char* s; - int i; - -}; - -union Value { - char* s; - int i; -}; - - -struct EntryWithMethod: Entry { - int getAsInt() { - return i; - } -}; + +enum Type { S, I }; + +struct Entry { + + char* name; + Type t; + char* s; + int i; + +}; + +union Value { + char* s; + int i; +}; + + +struct EntryWithMethod: Entry { + int getAsInt() { + return i; + } +}; diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp index 2003a299aab..d18ffed10ea 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp @@ -93,15 +93,15 @@ int regression_test00() { return x; } -struct Base { +struct Base { int b; }; -struct Derived : Base { +struct Derived : Base { int d; }; -int inheritanceConversions(Derived* pd) { +int inheritanceConversions(Derived* pd) { int x = pd->b; Base* pb = static_cast(pd); int y = pb->b; diff --git a/cpp/ql/test/library-tests/variables/variables/variables.cpp b/cpp/ql/test/library-tests/variables/variables/variables.cpp index 28aae674374..cbca2b3b822 100644 --- a/cpp/ql/test/library-tests/variables/variables/variables.cpp +++ b/cpp/ql/test/library-tests/variables/variables/variables.cpp @@ -1,53 +1,53 @@ -extern int i; -extern int i; -extern int i; - -const int c = 7; -const double pi = 3.1415926535897932385; - -unsigned a; - -unsigned int b; - -const char* kings[] = { "Antigonus", "Seleucus", "Ptolemy" }; - -int* p, q; -static int v1[10], *pv; - -int (*fp)(char *); // pointer to function - -float v2[3]; -char* v3[32]; - -int d2[10][20]; - -char v4[3] = { 'a', 'b', 0 }; - -int v5[8] = { 1, 2, 3, 4 }; - -char* p2 = "Plato"; -char p3[] = "Zeno"; - -char alpha[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -int av[] = { 1, 2 , 3, 4 }; -int* ap1 = av; -int* ap2 = &av[0]; -int* ap3 = &av[4]; - - -void f() { - char local[] = { 'a', 'b' }; - { - static int local; - } -} - -struct address { - char* name; - long int number; - char* street; - char* town; - static char* country; -}; +extern int i; +extern int i; +extern int i; + +const int c = 7; +const double pi = 3.1415926535897932385; + +unsigned a; + +unsigned int b; + +const char* kings[] = { "Antigonus", "Seleucus", "Ptolemy" }; + +int* p, q; +static int v1[10], *pv; + +int (*fp)(char *); // pointer to function + +float v2[3]; +char* v3[32]; + +int d2[10][20]; + +char v4[3] = { 'a', 'b', 0 }; + +int v5[8] = { 1, 2, 3, 4 }; + +char* p2 = "Plato"; +char p3[] = "Zeno"; + +char alpha[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +int av[] = { 1, 2 , 3, 4 }; +int* ap1 = av; +int* ap2 = &av[0]; +int* ap3 = &av[4]; + + +void f() { + char local[] = { 'a', 'b' }; + { + static int local; + } +} + +struct address { + char* name; + long int number; + char* street; + char* town; + static char* country; +}; diff --git a/cpp/ql/test/library-tests/virtual_functions/virtual_functions/virtual_functions.cpp b/cpp/ql/test/library-tests/virtual_functions/virtual_functions/virtual_functions.cpp index 2ecea309538..61a4e4ec545 100644 --- a/cpp/ql/test/library-tests/virtual_functions/virtual_functions/virtual_functions.cpp +++ b/cpp/ql/test/library-tests/virtual_functions/virtual_functions/virtual_functions.cpp @@ -1,48 +1,48 @@ -class A -{ -public: - virtual void withunusedpara(int * para1, int unusedpara) = 0; - virtual void withunusedpara(int * para1, int & para2) = 0; -}; - -class B1: public A -{ -public: - virtual void withunusedpara(int * para1, int unusedpara) - { - *para1 = 1U; - } - virtual void withunusedpara(int * para1, int & para2) - { - *para1 = 1U; - } -}; - -class B2: public A -{ -public: - virtual void withunusedpara(int * para1, int unusedpara) - { - *para1 = 1U; - } - virtual void withunusedpara(int * para1, int & para2) - { - para2 = 0; - } -}; - -struct X1 { virtual void f() {} }; -struct X2 : X1 {}; -struct X3 : X2 { void f() {} }; -struct X4 : X2 { void f() {} }; -struct X5 : X3, X4 { void f() {} }; -struct X6 : X5 {}; -struct X7 : X6 { void f() {} }; - -struct Y1 { virtual void f() {} }; -struct Y2 : Y1 {}; -struct Y3 : virtual Y2 { void f() {} }; -struct Y4 : virtual Y2 { void f() {} }; -struct Y5 : Y3, Y4 { void f() {} }; -struct Y6 : Y5 {}; -struct Y7 : Y6 { void f() {} }; +class A +{ +public: + virtual void withunusedpara(int * para1, int unusedpara) = 0; + virtual void withunusedpara(int * para1, int & para2) = 0; +}; + +class B1: public A +{ +public: + virtual void withunusedpara(int * para1, int unusedpara) + { + *para1 = 1U; + } + virtual void withunusedpara(int * para1, int & para2) + { + *para1 = 1U; + } +}; + +class B2: public A +{ +public: + virtual void withunusedpara(int * para1, int unusedpara) + { + *para1 = 1U; + } + virtual void withunusedpara(int * para1, int & para2) + { + para2 = 0; + } +}; + +struct X1 { virtual void f() {} }; +struct X2 : X1 {}; +struct X3 : X2 { void f() {} }; +struct X4 : X2 { void f() {} }; +struct X5 : X3, X4 { void f() {} }; +struct X6 : X5 {}; +struct X7 : X6 { void f() {} }; + +struct Y1 { virtual void f() {} }; +struct Y2 : Y1 {}; +struct Y3 : virtual Y2 { void f() {} }; +struct Y4 : virtual Y2 { void f() {} }; +struct Y5 : Y3, Y4 { void f() {} }; +struct Y6 : Y5 {}; +struct Y7 : Y6 { void f() {} }; diff --git a/cpp/ql/test/query-tests/AlertSuppression/.gitattributes b/cpp/ql/test/query-tests/AlertSuppression/.gitattributes new file mode 100644 index 00000000000..03feb5510a3 --- /dev/null +++ b/cpp/ql/test/query-tests/AlertSuppression/.gitattributes @@ -0,0 +1 @@ +tstWindows.c eol=crlf diff --git a/cpp/ql/test/query-tests/AlertSuppression/tstWindows.c b/cpp/ql/test/query-tests/AlertSuppression/tstWindows.c index ee53d91dd79..a669e765981 100644 --- a/cpp/ql/test/query-tests/AlertSuppression/tstWindows.c +++ b/cpp/ql/test/query-tests/AlertSuppression/tstWindows.c @@ -1,28 +1,28 @@ -int x = 0; // lgtm -// lgtm[js/debugger-statement] -// lgtm[js/debugger-statement, js/invocation-of-non-function] -// lgtm[@tag:nullness] -// lgtm[@tag:nullness,js/debugger-statement] -// lgtm[@expires:2017-06-11] -// lgtm[js/invocation-of-non-function] because I know better than lgtm -// lgtm: blah blah -// lgtm blah blah #falsepositive -//lgtm [js/invocation-of-non-function] -/* lgtm */ -// lgtm[] -// lgtmfoo -//lgtm -// lgtm -// lgtm [js/debugger-statement] -// foolgtm[js/debugger-statement] -// foolgtm -// foo; lgtm -// foo; lgtm[js/debugger-statement] -// foo lgtm -// foo lgtm[js/debugger-statement] -// foo lgtm bar -// foo lgtm[js/debugger-statement] bar -// LGTM! -// LGTM[js/debugger-statement] -// lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] -// lgtm[js/debugger-statement]; lgtm +int x = 0; // lgtm +// lgtm[js/debugger-statement] +// lgtm[js/debugger-statement, js/invocation-of-non-function] +// lgtm[@tag:nullness] +// lgtm[@tag:nullness,js/debugger-statement] +// lgtm[@expires:2017-06-11] +// lgtm[js/invocation-of-non-function] because I know better than lgtm +// lgtm: blah blah +// lgtm blah blah #falsepositive +//lgtm [js/invocation-of-non-function] +/* lgtm */ +// lgtm[] +// lgtmfoo +//lgtm +// lgtm +// lgtm [js/debugger-statement] +// foolgtm[js/debugger-statement] +// foolgtm +// foo; lgtm +// foo; lgtm[js/debugger-statement] +// foo lgtm +// foo lgtm[js/debugger-statement] +// foo lgtm bar +// foo lgtm[js/debugger-statement] bar +// LGTM! +// LGTM[js/debugger-statement] +// lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] +// lgtm[js/debugger-statement]; lgtm diff --git a/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/functions.h b/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/functions.h index 31201fb5c11..43e7b089389 100644 --- a/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/functions.h +++ b/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/functions.h @@ -1,33 +1,33 @@ - -int myFunction1(int x = - 102 + 102 + 102 + - 102 + 102 + 102 + - 102 + 102 + 102 + - 102 + 102 + 102 + - 102 + 102 + 102 + - 102 + 102 + 102 + - 102 + 102 + 102); - -void myFunction2( - int p1 = 103, - int p2 = 103, - int p3 = 103, - int p4 = 103, - int p5 = 103, - int p6 = 103, - int p7 = 103, - int p8 = 103, - int p9 = 103, - int p10 = 103, - int p11 = 103, - int p12 = 103, - int p13 = 103, - int p14 = 103, - int p15 = 103, - int p16 = 103, - int p17 = 103, - int p18 = 103, - int p19 = 103, - int p20 = 103, - int p21 = 103 - ) {}; + +int myFunction1(int x = + 102 + 102 + 102 + + 102 + 102 + 102 + + 102 + 102 + 102 + + 102 + 102 + 102 + + 102 + 102 + 102 + + 102 + 102 + 102 + + 102 + 102 + 102); + +void myFunction2( + int p1 = 103, + int p2 = 103, + int p3 = 103, + int p4 = 103, + int p5 = 103, + int p6 = 103, + int p7 = 103, + int p8 = 103, + int p9 = 103, + int p10 = 103, + int p11 = 103, + int p12 = 103, + int p13 = 103, + int p14 = 103, + int p15 = 103, + int p16 = 103, + int p17 = 103, + int p18 = 103, + int p19 = 103, + int p20 = 103, + int p21 = 103 + ) {}; diff --git a/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/test.cpp b/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/test.cpp index 3e331dbb34c..268cb4e91c9 100644 --- a/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/test.cpp +++ b/cpp/ql/test/query-tests/Best Practices/Magic Constants/MagicConstantsNumbers/test.cpp @@ -1,14 +1,14 @@ - -#include "functions.h" - -int myFunction1(int x) { - return x; -} - -void myCaller() { - myFunction1(); - myFunction1(); - myFunction1(104); - myFunction2(105); - myFunction2(); + +#include "functions.h" + +int myFunction1(int x) { + return x; +} + +void myCaller() { + myFunction1(); + myFunction1(); + myFunction1(104); + myFunction2(105); + myFunction2(); } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/a.h b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/a.h index a0da4edfc5e..6addf5ae76d 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/a.h +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/a.h @@ -1,3 +1,3 @@ -// a.h - -int my_func_a(); +// a.h + +int my_func_a(); diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/b.h b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/b.h index 55666fde62e..e9f8542fdf5 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/b.h +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/b.h @@ -1,3 +1,3 @@ -// b.h - -int my_func_b(); +// b.h + +int my_func_b(); diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/c.h b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/c.h index dfae8989d79..f4054f52983 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/c.h +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/c.h @@ -1,3 +1,3 @@ -// c.h - -extern int my_var_c; +// c.h + +extern int my_var_c; diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/d.hpp b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/d.hpp index 1a53af694b8..ddb004892b5 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/d.hpp +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/d.hpp @@ -1,3 +1,3 @@ -// d.hpp - -class class_d; +// d.hpp + +class class_d; diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/e.hpp b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/e.hpp index 814c86a34cf..f75c2430d0e 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/e.hpp +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/e.hpp @@ -1,3 +1,3 @@ -// e.hpp - -class class_e; +// e.hpp + +class class_e; diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/f.fwd.hpp b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/f.fwd.hpp index 1eebacaf324..ace4a0b7082 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/f.fwd.hpp +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/f.fwd.hpp @@ -1,3 +1,3 @@ -// f.fwd.hpp - -class class_f; +// f.fwd.hpp + +class class_f; diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header1.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header1.h index ab3226d8e65..a0fa07dbb50 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header1.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header1.h @@ -1,8 +1,8 @@ -// header1.h - -#ifndef INCLUDED_HEADER1 -#define INCLUDED_HEADER1 - - // ... - -#endif // INCLUDED_HEADER1 +// header1.h + +#ifndef INCLUDED_HEADER1 +#define INCLUDED_HEADER1 + + // ... + +#endif // INCLUDED_HEADER1 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header2.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header2.h index f9f62cc8d75..9e4ad972812 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header2.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header2.h @@ -1,8 +1,8 @@ -// header2.h - -#ifndef INCLUDED_HEADER1 // oops! -#define INCLUDED_HEADER1 - - // ... - -#endif // INCLUDED_HEADER1 +// header2.h + +#ifndef INCLUDED_HEADER1 // oops! +#define INCLUDED_HEADER1 + + // ... + +#endif // INCLUDED_HEADER1 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header3.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header3.h index 789c3354309..ed4e1e65dde 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header3.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header3.h @@ -1,12 +1,12 @@ -// header3.h - -#ifndef INCLUDED_HEADER3 -#define INCLUDED_HEADER3 - - // ... - - #ifndef INCLUDED_HEADER1 // (not an include guard) - - #endif - -#endif // INCLUDED_HEADER3 +// header3.h + +#ifndef INCLUDED_HEADER3 +#define INCLUDED_HEADER3 + + // ... + + #ifndef INCLUDED_HEADER1 // (not an include guard) + + #endif + +#endif // INCLUDED_HEADER3 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header4.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header4.h index 6c990c74aa4..57b36896ebd 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header4.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header4.h @@ -1,8 +1,8 @@ -// header4.h - -#ifndef INCLUDED_HEADER4 -#define INCLUDED_HEADER4 - - // ... - -#endif // INCLUDED_HEADER4 +// header4.h + +#ifndef INCLUDED_HEADER4 +#define INCLUDED_HEADER4 + + // ... + +#endif // INCLUDED_HEADER4 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header6.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header6.h index c8a1a968f18..2148e608917 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header6.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header6.h @@ -1,8 +1,8 @@ -// header6.h - -#ifndef INCLUDED_HEADER6 -#define INCLUDED_HEADER6 - - // ... - -#endif // INCLUDED_HEADER6 +// header6.h + +#ifndef INCLUDED_HEADER6 +#define INCLUDED_HEADER6 + + // ... + +#endif // INCLUDED_HEADER6 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header7.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header7.h index 0687d80c60c..4dd8875d69d 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header7.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/header7.h @@ -1,8 +1,8 @@ -// header7.h - -#ifndef INCLUDED_HEADER6 // oops! -#define INCLUDED_HEADER6(x) (x) - - // ... - -#endif // INCLUDED_HEADER6 +// header7.h + +#ifndef INCLUDED_HEADER6 // oops! +#define INCLUDED_HEADER6(x) (x) + + // ... + +#endif // INCLUDED_HEADER6 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/main.c b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/main.c index 40cbdbb9443..0736e1517ef 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/main.c +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/main.c @@ -1,13 +1,13 @@ -// main.c - Cleanup-DuplicateIncludeGuard test - -#include "header1.h" -#include "header2.h" -#include "header3.h" -#include "header3.h" - -#include "header4.h" -#include "subfolder/header4.h" -#include "subfolder/header5.h" - -#include "header6.h" -#include "header7.h" +// main.c - Cleanup-DuplicateIncludeGuard test + +#include "header1.h" +#include "header2.h" +#include "header3.h" +#include "header3.h" + +#include "header4.h" +#include "subfolder/header4.h" +#include "subfolder/header5.h" + +#include "header6.h" +#include "header7.h" diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header4.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header4.h index f369cf90544..c5e44813dcd 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header4.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header4.h @@ -1,8 +1,8 @@ -// header4.h - -#ifndef INCLUDED_HEADER4 // duplicate -#define INCLUDED_HEADER4 - - // ... - -#endif // INCLUDED_HEADER4 +// header4.h + +#ifndef INCLUDED_HEADER4 // duplicate +#define INCLUDED_HEADER4 + + // ... + +#endif // INCLUDED_HEADER4 diff --git a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header5.h b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header5.h index 2f89436d7a8..ed54e7ea68c 100644 --- a/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header5.h +++ b/cpp/ql/test/query-tests/Header Cleanup/Cleanup-DuplicateIncludeGuard/subfolder/header5.h @@ -1,8 +1,8 @@ -// header5.h - -#ifndef INCLUDED_HEADER4 // duplicate -#define INCLUDED_HEADER4 - - // ... - -#endif // INCLUDED_HEADER4 +// header5.h + +#ifndef INCLUDED_HEADER4 // duplicate +#define INCLUDED_HEADER4 + + // ... + +#endif // INCLUDED_HEADER4 diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/common.h b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/common.h index baffbb6f36f..8dda6a8a8d3 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/common.h +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/common.h @@ -1,20 +1,20 @@ - -struct _IO_FILE -{ - // ... -}; -typedef struct _IO_FILE FILE; - -#define va_list void * -#define va_start(x, y) -#define va_end(x) - -extern int printf(const char *fmt, ...); -extern int vprintf(const char *fmt, va_list ap); -extern int vfprintf(FILE *stream, const char *format, va_list ap); - -#include "printf1.h" -#include "real_world.h" -#include "wide_string.h" -#include "format.h" -#include "pri_macros.h" + +struct _IO_FILE +{ + // ... +}; +typedef struct _IO_FILE FILE; + +#define va_list void * +#define va_start(x, y) +#define va_end(x) + +extern int printf(const char *fmt, ...); +extern int vprintf(const char *fmt, va_list ap); +extern int vfprintf(FILE *stream, const char *format, va_list ap); + +#include "printf1.h" +#include "real_world.h" +#include "wide_string.h" +#include "format.h" +#include "pri_macros.h" diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_unsigned_chars/common.h b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_unsigned_chars/common.h index baffbb6f36f..8dda6a8a8d3 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_unsigned_chars/common.h +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_unsigned_chars/common.h @@ -1,20 +1,20 @@ - -struct _IO_FILE -{ - // ... -}; -typedef struct _IO_FILE FILE; - -#define va_list void * -#define va_start(x, y) -#define va_end(x) - -extern int printf(const char *fmt, ...); -extern int vprintf(const char *fmt, va_list ap); -extern int vfprintf(FILE *stream, const char *format, va_list ap); - -#include "printf1.h" -#include "real_world.h" -#include "wide_string.h" -#include "format.h" -#include "pri_macros.h" + +struct _IO_FILE +{ + // ... +}; +typedef struct _IO_FILE FILE; + +#define va_list void * +#define va_start(x, y) +#define va_end(x) + +extern int printf(const char *fmt, ...); +extern int vprintf(const char *fmt, va_list ap); +extern int vfprintf(FILE *stream, const char *format, va_list ap); + +#include "printf1.h" +#include "real_world.h" +#include "wide_string.h" +#include "format.h" +#include "pri_macros.h" diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft/common.h b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft/common.h index baffbb6f36f..8dda6a8a8d3 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft/common.h +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft/common.h @@ -1,20 +1,20 @@ - -struct _IO_FILE -{ - // ... -}; -typedef struct _IO_FILE FILE; - -#define va_list void * -#define va_start(x, y) -#define va_end(x) - -extern int printf(const char *fmt, ...); -extern int vprintf(const char *fmt, va_list ap); -extern int vfprintf(FILE *stream, const char *format, va_list ap); - -#include "printf1.h" -#include "real_world.h" -#include "wide_string.h" -#include "format.h" -#include "pri_macros.h" + +struct _IO_FILE +{ + // ... +}; +typedef struct _IO_FILE FILE; + +#define va_list void * +#define va_start(x, y) +#define va_end(x) + +extern int printf(const char *fmt, ...); +extern int vprintf(const char *fmt, va_list ap); +extern int vfprintf(FILE *stream, const char *format, va_list ap); + +#include "printf1.h" +#include "real_world.h" +#include "wide_string.h" +#include "format.h" +#include "pri_macros.h" diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft_no_wchar/common.h b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft_no_wchar/common.h index baffbb6f36f..8dda6a8a8d3 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft_no_wchar/common.h +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft_no_wchar/common.h @@ -1,20 +1,20 @@ - -struct _IO_FILE -{ - // ... -}; -typedef struct _IO_FILE FILE; - -#define va_list void * -#define va_start(x, y) -#define va_end(x) - -extern int printf(const char *fmt, ...); -extern int vprintf(const char *fmt, va_list ap); -extern int vfprintf(FILE *stream, const char *format, va_list ap); - -#include "printf1.h" -#include "real_world.h" -#include "wide_string.h" -#include "format.h" -#include "pri_macros.h" + +struct _IO_FILE +{ + // ... +}; +typedef struct _IO_FILE FILE; + +#define va_list void * +#define va_start(x, y) +#define va_end(x) + +extern int printf(const char *fmt, ...); +extern int vprintf(const char *fmt, va_list ap); +extern int vfprintf(FILE *stream, const char *format, va_list ap); + +#include "printf1.h" +#include "real_world.h" +#include "wide_string.h" +#include "format.h" +#include "pri_macros.h" diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StackAddressEscapes/manager.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StackAddressEscapes/manager.cpp index 843ffb340be..8b73bffb04a 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StackAddressEscapes/manager.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StackAddressEscapes/manager.cpp @@ -1,54 +1,54 @@ -// test cases for StackAddressEscapes.ql - -namespace std -{ - class string; - - template class vector - { - }; -}; - -class manager -{ -public: - manager() {}; - ~manager() {}; -}; - -class resource -{ -public: - resource(manager *_m) : m(_m) {}; - - void set_strings(std::vector const &_strings); - -private: - manager *m; - std::vector const *strings; -}; - -void resource :: set_strings(std::vector const &_strings) -{ - strings = &_strings; -} - -manager *glob_man; - -manager *test_managers() -{ - manager man; - manager *man_ptr; - man_ptr = &man; - - resource a(&man); // BAD: stack address `&man` escapes [NOT DETECTED] - resource b(man_ptr); // BAD: stack address `man_ptr` escapes [NOT DETECTED] - resource *c = new resource(&man); // BAD: stack address `&man` escapes [NOT DETECTED] - - std::vector vs; - a.set_strings(vs); // BAD: stack address `&vs` escapes [NOT DETECTED] - - glob_man = &man; // BAD: stack address `&man` escapes - - return &man; // BAD: stack address `&man` escapes [NOT DETECTED] -} +// test cases for StackAddressEscapes.ql + +namespace std +{ + class string; + + template class vector + { + }; +}; + +class manager +{ +public: + manager() {}; + ~manager() {}; +}; + +class resource +{ +public: + resource(manager *_m) : m(_m) {}; + + void set_strings(std::vector const &_strings); + +private: + manager *m; + std::vector const *strings; +}; + +void resource :: set_strings(std::vector const &_strings) +{ + strings = &_strings; +} + +manager *glob_man; + +manager *test_managers() +{ + manager man; + manager *man_ptr; + man_ptr = &man; + + resource a(&man); // BAD: stack address `&man` escapes [NOT DETECTED] + resource b(man_ptr); // BAD: stack address `man_ptr` escapes [NOT DETECTED] + resource *c = new resource(&man); // BAD: stack address `&man` escapes [NOT DETECTED] + + std::vector vs; + a.set_strings(vs); // BAD: stack address `&vs` escapes [NOT DETECTED] + + glob_man = &man; // BAD: stack address `&man` escapes + + return &man; // BAD: stack address `&man` escapes [NOT DETECTED] +} diff --git a/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.CPP b/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.CPP index c17c5ea6e5f..04637aa9c90 100644 --- a/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.CPP +++ b/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.CPP @@ -1,2 +1,2 @@ -#include "test.c++" -#include "test.hpp" +#include "test.c++" +#include "test.hpp" diff --git a/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.c b/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.c index 1da91c1cfda..47c2408c2fb 100644 --- a/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.c +++ b/cpp/ql/test/query-tests/jsf/4.09 Style/AV Rule 53 54/test.c @@ -1,4 +1,4 @@ -#include "test" -#include "test.abc" -#include "test.H" -#include "test'.h" +#include "test" +#include "test.abc" +#include "test.H" +#include "test'.h" diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 73/original.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 73/original.cpp index 78001340db4..5c86702e2c2 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 73/original.cpp +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 73/original.cpp @@ -1,160 +1,160 @@ -// bad: gratuitous default constructor -class Bad -{ -private: - int key; - int value; -public: - Bad(); - Bad(int); - Bad(int, int); - int cmp(const Bad& that); -}; - -Bad::Bad() : key(-1) // non-compliant -{ -} - -Bad::Bad(int k) : key(k) // compliant -{ -} - -Bad::Bad(int k, int v) // compliant -{ - key = k; - value = v; -} - -int Bad::cmp(const Bad& that) -{ - if(this->key == -1) - return 1; - if(that.key == -1) - return -1; - return this->key - that.key; -} - -// good: default constructor is necessary because we allocate an array of Good -class Good -{ -private: - char *cp; -public: - Good(); - Good(char *const cpp); - char getChar(); -}; - -Good::Good() : cp(0) // compliant -{ -} - -Good::Good(char *const cpp) : cp(cpp) -{ -} - -char Good::getChar() -{ - if(cp == 0) - return '\0'; - return *cp; -} - -Good *gd = new Good[16]; - -// good: default constructor is necessary because we instantiate a template with AlsoGood -class AlsoGood -{ -private: - char *cp; -public: - AlsoGood(); - AlsoGood(char *const cpp); - char getChar(); -}; - -AlsoGood::AlsoGood() // compliant [FALSE POSITIVE] -{ - cp = 0; -} - -AlsoGood::AlsoGood(char *const cpp) : cp(cpp) -{ -} - -char AlsoGood::getChar() -{ - if(cp == 0) - return '\0'; - return *cp; -} - -template class Container { -private: - T *data; -public: - Container(); -}; - -template Container::Container() -{ - data = new T(); -} - -Container *foo; - -// good: default constructor is convenient since StillGood is a virtual base class -class StillGood -{ -private: - char *cp; -public: - StillGood(); - StillGood(char *const cpp); - char getChar(); -}; - -StillGood::StillGood() : cp(0) // compliant -{ -} - -StillGood::StillGood(char *const cpp) : cp(cpp) -{ -} - -char StillGood::getChar() -{ - if(cp == 0) - return '\0'; - return *cp; -} - -class Child : public virtual StillGood -{ -}; - -double sqrt(double d); - -// good: members have sensible default values -class Coord -{ -private: - double x, y; -public: - Coord(); - Coord(double, double); - double dist(); -}; - -Coord::Coord() : x(0), y(0) // compliant -{ -} - -Coord::Coord(double x, double y) : x(x), y(y) -{ -} - -double Coord::dist() -{ - return sqrt(x*x+y*y); -} +// bad: gratuitous default constructor +class Bad +{ +private: + int key; + int value; +public: + Bad(); + Bad(int); + Bad(int, int); + int cmp(const Bad& that); +}; + +Bad::Bad() : key(-1) // non-compliant +{ +} + +Bad::Bad(int k) : key(k) // compliant +{ +} + +Bad::Bad(int k, int v) // compliant +{ + key = k; + value = v; +} + +int Bad::cmp(const Bad& that) +{ + if(this->key == -1) + return 1; + if(that.key == -1) + return -1; + return this->key - that.key; +} + +// good: default constructor is necessary because we allocate an array of Good +class Good +{ +private: + char *cp; +public: + Good(); + Good(char *const cpp); + char getChar(); +}; + +Good::Good() : cp(0) // compliant +{ +} + +Good::Good(char *const cpp) : cp(cpp) +{ +} + +char Good::getChar() +{ + if(cp == 0) + return '\0'; + return *cp; +} + +Good *gd = new Good[16]; + +// good: default constructor is necessary because we instantiate a template with AlsoGood +class AlsoGood +{ +private: + char *cp; +public: + AlsoGood(); + AlsoGood(char *const cpp); + char getChar(); +}; + +AlsoGood::AlsoGood() // compliant [FALSE POSITIVE] +{ + cp = 0; +} + +AlsoGood::AlsoGood(char *const cpp) : cp(cpp) +{ +} + +char AlsoGood::getChar() +{ + if(cp == 0) + return '\0'; + return *cp; +} + +template class Container { +private: + T *data; +public: + Container(); +}; + +template Container::Container() +{ + data = new T(); +} + +Container *foo; + +// good: default constructor is convenient since StillGood is a virtual base class +class StillGood +{ +private: + char *cp; +public: + StillGood(); + StillGood(char *const cpp); + char getChar(); +}; + +StillGood::StillGood() : cp(0) // compliant +{ +} + +StillGood::StillGood(char *const cpp) : cp(cpp) +{ +} + +char StillGood::getChar() +{ + if(cp == 0) + return '\0'; + return *cp; +} + +class Child : public virtual StillGood +{ +}; + +double sqrt(double d); + +// good: members have sensible default values +class Coord +{ +private: + double x, y; +public: + Coord(); + Coord(double, double); + double dist(); +}; + +Coord::Coord() : x(0), y(0) // compliant +{ +} + +Coord::Coord(double x, double y) : x(x), y(y) +{ +} + +double Coord::dist() +{ + return sqrt(x*x+y*y); +} diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 78/AV Rule 78.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 78/AV Rule 78.cpp index 08442008309..7612ac07c8c 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 78/AV Rule 78.cpp +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 78/AV Rule 78.cpp @@ -1,108 +1,108 @@ -struct HasDtor -{ - ~HasDtor(); -}; - -struct Base_NonVirtual_NoDtor -{ - void NonVirtualFunction(); -}; - -struct Base_NonVirtual_VirtualDtor -{ - virtual ~Base_NonVirtual_VirtualDtor(); - void NonVirtualFunction(); -}; - -struct Base_NonVirtual_NonVirtualDtor -{ - ~Base_NonVirtual_NonVirtualDtor(); - void NonVirtualFunction(); -}; - -struct Base_NonVirtual_ImplicitDtor -{ - HasDtor m_hasDtor; - void NonVirtualFunction(); -}; - -struct Derived_NonVirtual_NoDtor : public Base_NonVirtual_NoDtor -{ -}; - -struct Derived_NonVirtual_VirtualDtor : public Base_NonVirtual_VirtualDtor -{ -}; - -struct Derived_NonVirtual_NonVirtualDtor : public Base_NonVirtual_NonVirtualDtor -{ -}; - -struct Derived_NonVirtual_ImplicitDtor : public Base_NonVirtual_ImplicitDtor -{ -}; - -struct Base_Virtual_NoDtor -{ - virtual void VirtualFunction(); -}; - -struct Base_Virtual_VirtualDtor -{ - virtual ~Base_Virtual_VirtualDtor(); - virtual void VirtualFunction(); -}; - -struct Base_Virtual_NonVirtualDtor -{ - ~Base_Virtual_NonVirtualDtor(); - virtual void VirtualFunction(); -}; - -struct Base_Virtual_ImplicitDtor -{ - HasDtor m_hasDtor; - virtual void VirtualFunction(); -}; - -struct Base_Virtual_NonVirtualDtorWithDefinition -{ - ~Base_Virtual_NonVirtualDtorWithDefinition(); - virtual void VirtualFunction(); -}; - -Base_Virtual_NonVirtualDtorWithDefinition::~Base_Virtual_NonVirtualDtorWithDefinition() -{ -} - -struct Base_Virtual_NonVirtualDtorWithInlineDefinition -{ - ~Base_Virtual_NonVirtualDtorWithInlineDefinition() - { - } - virtual void VirtualFunction(); -}; - -struct Derived_Virtual_NoDtor : public Base_Virtual_NoDtor -{ -}; - -struct Derived_Virtual_VirtualDtor : public Base_Virtual_VirtualDtor -{ -}; - -struct Derived_Virtual_NonVirtualDtor : public Base_Virtual_NonVirtualDtor -{ -}; - -struct Derived_Virtual_ImplicitDtor : public Base_Virtual_ImplicitDtor -{ -}; - -struct Derived_Virtual_NonVirtualDtorWithDefinition: public Base_Virtual_NonVirtualDtorWithDefinition -{ -}; - -struct Derived_Virtual_NonVirtualDtorWithInlineDefinition: public Base_Virtual_NonVirtualDtorWithInlineDefinition -{ -}; +struct HasDtor +{ + ~HasDtor(); +}; + +struct Base_NonVirtual_NoDtor +{ + void NonVirtualFunction(); +}; + +struct Base_NonVirtual_VirtualDtor +{ + virtual ~Base_NonVirtual_VirtualDtor(); + void NonVirtualFunction(); +}; + +struct Base_NonVirtual_NonVirtualDtor +{ + ~Base_NonVirtual_NonVirtualDtor(); + void NonVirtualFunction(); +}; + +struct Base_NonVirtual_ImplicitDtor +{ + HasDtor m_hasDtor; + void NonVirtualFunction(); +}; + +struct Derived_NonVirtual_NoDtor : public Base_NonVirtual_NoDtor +{ +}; + +struct Derived_NonVirtual_VirtualDtor : public Base_NonVirtual_VirtualDtor +{ +}; + +struct Derived_NonVirtual_NonVirtualDtor : public Base_NonVirtual_NonVirtualDtor +{ +}; + +struct Derived_NonVirtual_ImplicitDtor : public Base_NonVirtual_ImplicitDtor +{ +}; + +struct Base_Virtual_NoDtor +{ + virtual void VirtualFunction(); +}; + +struct Base_Virtual_VirtualDtor +{ + virtual ~Base_Virtual_VirtualDtor(); + virtual void VirtualFunction(); +}; + +struct Base_Virtual_NonVirtualDtor +{ + ~Base_Virtual_NonVirtualDtor(); + virtual void VirtualFunction(); +}; + +struct Base_Virtual_ImplicitDtor +{ + HasDtor m_hasDtor; + virtual void VirtualFunction(); +}; + +struct Base_Virtual_NonVirtualDtorWithDefinition +{ + ~Base_Virtual_NonVirtualDtorWithDefinition(); + virtual void VirtualFunction(); +}; + +Base_Virtual_NonVirtualDtorWithDefinition::~Base_Virtual_NonVirtualDtorWithDefinition() +{ +} + +struct Base_Virtual_NonVirtualDtorWithInlineDefinition +{ + ~Base_Virtual_NonVirtualDtorWithInlineDefinition() + { + } + virtual void VirtualFunction(); +}; + +struct Derived_Virtual_NoDtor : public Base_Virtual_NoDtor +{ +}; + +struct Derived_Virtual_VirtualDtor : public Base_Virtual_VirtualDtor +{ +}; + +struct Derived_Virtual_NonVirtualDtor : public Base_Virtual_NonVirtualDtor +{ +}; + +struct Derived_Virtual_ImplicitDtor : public Base_Virtual_ImplicitDtor +{ +}; + +struct Derived_Virtual_NonVirtualDtorWithDefinition: public Base_Virtual_NonVirtualDtorWithDefinition +{ +}; + +struct Derived_Virtual_NonVirtualDtorWithInlineDefinition: public Base_Virtual_NonVirtualDtorWithInlineDefinition +{ +}; diff --git a/cpp/ql/test/successor-tests/assignexpr/assignexpr.cpp b/cpp/ql/test/successor-tests/assignexpr/assignexpr.cpp index 1bd6c572eec..b1ceec88282 100644 --- a/cpp/ql/test/successor-tests/assignexpr/assignexpr.cpp +++ b/cpp/ql/test/successor-tests/assignexpr/assignexpr.cpp @@ -1,11 +1,11 @@ -class C { - public: - int i; -}; - -void f() { - C c; - int a, b; - c.i = a + b; - ; -} +class C { + public: + int i; +}; + +void f() { + C c; + int a, b; + c.i = a + b; + ; +} diff --git a/cpp/ql/test/successor-tests/block/dummyblock/dummyblock.c b/cpp/ql/test/successor-tests/block/dummyblock/dummyblock.c index f113a35f204..1307903ecf5 100644 --- a/cpp/ql/test/successor-tests/block/dummyblock/dummyblock.c +++ b/cpp/ql/test/successor-tests/block/dummyblock/dummyblock.c @@ -1,4 +1,4 @@ -void f() { - if (1) - ; -} +void f() { + if (1) + ; +} diff --git a/cpp/ql/test/successor-tests/block/emptyblock/emptyblock.c b/cpp/ql/test/successor-tests/block/emptyblock/emptyblock.c index 87680af388d..33ef4b879cd 100644 --- a/cpp/ql/test/successor-tests/block/emptyblock/emptyblock.c +++ b/cpp/ql/test/successor-tests/block/emptyblock/emptyblock.c @@ -1,5 +1,5 @@ -void f() { - { - } - ; -} +void f() { + { + } + ; +} diff --git a/cpp/ql/test/successor-tests/callexpr/args/membercallexpr/membercallexpr.cpp b/cpp/ql/test/successor-tests/callexpr/args/membercallexpr/membercallexpr.cpp index 9d4edb8979b..5009f913255 100644 --- a/cpp/ql/test/successor-tests/callexpr/args/membercallexpr/membercallexpr.cpp +++ b/cpp/ql/test/successor-tests/callexpr/args/membercallexpr/membercallexpr.cpp @@ -1,11 +1,11 @@ -class C { - public: - C* d; - void g(int x, int y); -}; - -void f() { - int i, j, k, l; - C *c; - c->d->g(i + j, k - l); -} +class C { + public: + C* d; + void g(int x, int y); +}; + +void f() { + int i, j, k, l; + C *c; + c->d->g(i + j, k - l); +} diff --git a/cpp/ql/test/successor-tests/callexpr/args/staticmembercallexpr/staticmembercallexpr.cpp b/cpp/ql/test/successor-tests/callexpr/args/staticmembercallexpr/staticmembercallexpr.cpp index 10acb0fbc1f..df553720dab 100644 --- a/cpp/ql/test/successor-tests/callexpr/args/staticmembercallexpr/staticmembercallexpr.cpp +++ b/cpp/ql/test/successor-tests/callexpr/args/staticmembercallexpr/staticmembercallexpr.cpp @@ -1,11 +1,11 @@ -class C { - public: - C* d; - static void g(int x, int y); -}; - -void f() { - int i, j, k, l; - C c; - c.d->g(i + j, k - l); -} +class C { + public: + C* d; + static void g(int x, int y); +}; + +void f() { + int i, j, k, l; + C c; + c.d->g(i + j, k - l); +} diff --git a/cpp/ql/test/successor-tests/callexpr/noargs/membercallexpr/membercallexpr.cpp b/cpp/ql/test/successor-tests/callexpr/noargs/membercallexpr/membercallexpr.cpp index 1548f3f81a7..035db2d5856 100644 --- a/cpp/ql/test/successor-tests/callexpr/noargs/membercallexpr/membercallexpr.cpp +++ b/cpp/ql/test/successor-tests/callexpr/noargs/membercallexpr/membercallexpr.cpp @@ -1,10 +1,10 @@ -class C { - public: - void g(); -}; - -void f() { - C *c; - c->g(); - ; -} +class C { + public: + void g(); +}; + +void f() { + C *c; + c->g(); + ; +} diff --git a/cpp/ql/test/successor-tests/callexpr/noargs/nonmembercallexpr/nonmembercallexpr.c b/cpp/ql/test/successor-tests/callexpr/noargs/nonmembercallexpr/nonmembercallexpr.c index fc37abcdfdb..4c949924900 100644 --- a/cpp/ql/test/successor-tests/callexpr/noargs/nonmembercallexpr/nonmembercallexpr.c +++ b/cpp/ql/test/successor-tests/callexpr/noargs/nonmembercallexpr/nonmembercallexpr.c @@ -1,6 +1,6 @@ -void g() { } - -void f() { - g(); - ; -} +void g() { } + +void f() { + g(); + ; +} diff --git a/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfp2callexpr/nonmemberfp2callexpr.c b/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfp2callexpr/nonmemberfp2callexpr.c index b04b51fcb14..9e458f2f50d 100644 --- a/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfp2callexpr/nonmemberfp2callexpr.c +++ b/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfp2callexpr/nonmemberfp2callexpr.c @@ -1,6 +1,6 @@ -void (*g())(); - -void f() { - g()(); - ; -} +void (*g())(); + +void f() { + g()(); + ; +} diff --git a/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfpcallexpr/nonmemberfpcallexpr.c b/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfpcallexpr/nonmemberfpcallexpr.c index e22a8d4a1a0..51e06cec04b 100644 --- a/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfpcallexpr/nonmemberfpcallexpr.c +++ b/cpp/ql/test/successor-tests/callexpr/noargs/nonmemberfpcallexpr/nonmemberfpcallexpr.c @@ -1,5 +1,5 @@ -void f() { - int (*g)(); - g(); - ; -} +void f() { + int (*g)(); + g(); + ; +} diff --git a/cpp/ql/test/successor-tests/callexpr/noargs/pmcallexpr/pmcallexpr.cpp b/cpp/ql/test/successor-tests/callexpr/noargs/pmcallexpr/pmcallexpr.cpp index 76c085f8ec0..75e143d846a 100644 --- a/cpp/ql/test/successor-tests/callexpr/noargs/pmcallexpr/pmcallexpr.cpp +++ b/cpp/ql/test/successor-tests/callexpr/noargs/pmcallexpr/pmcallexpr.cpp @@ -1,10 +1,10 @@ -class C { - public: - void (C::*g)(); -}; - -void f() { - C *c, *d; - (c->*(d->g))(); - ; -} +class C { + public: + void (C::*g)(); +}; + +void f() { + C *c, *d; + (c->*(d->g))(); + ; +} diff --git a/cpp/ql/test/successor-tests/callexpr/noargs/staticmembercallexpr/staticmembercallexpr.cpp b/cpp/ql/test/successor-tests/callexpr/noargs/staticmembercallexpr/staticmembercallexpr.cpp index 0b744c9d1c1..216b450e0dd 100644 --- a/cpp/ql/test/successor-tests/callexpr/noargs/staticmembercallexpr/staticmembercallexpr.cpp +++ b/cpp/ql/test/successor-tests/callexpr/noargs/staticmembercallexpr/staticmembercallexpr.cpp @@ -1,10 +1,10 @@ -class C { - public: - static void g(); -}; - -void f() { - C c; - c.g(); - ; -} +class C { + public: + static void g(); +}; + +void f() { + C c; + c.g(); + ; +} diff --git a/cpp/ql/test/successor-tests/deleteexpr/defdestructordeleteexpr/defdestructordeleteexpr.cpp b/cpp/ql/test/successor-tests/deleteexpr/defdestructordeleteexpr/defdestructordeleteexpr.cpp index ce92915640f..213898543a6 100644 --- a/cpp/ql/test/successor-tests/deleteexpr/defdestructordeleteexpr/defdestructordeleteexpr.cpp +++ b/cpp/ql/test/successor-tests/deleteexpr/defdestructordeleteexpr/defdestructordeleteexpr.cpp @@ -1,6 +1,6 @@ -class C { }; - -void f() { - C* c = new C(); - delete c; -} +class C { }; + +void f() { + C* c = new C(); + delete c; +} diff --git a/cpp/ql/test/successor-tests/deleteexpr/deleteexpr/deleteexpr.cpp b/cpp/ql/test/successor-tests/deleteexpr/deleteexpr/deleteexpr.cpp index 1b22a4736b1..5e997100e37 100644 --- a/cpp/ql/test/successor-tests/deleteexpr/deleteexpr/deleteexpr.cpp +++ b/cpp/ql/test/successor-tests/deleteexpr/deleteexpr/deleteexpr.cpp @@ -1,9 +1,9 @@ -class C { - public: - ~C(); -}; - -void f() { - C* c = new C(); - delete c; -} +class C { + public: + ~C(); +}; + +void f() { + C* c = new C(); + delete c; +} diff --git a/cpp/ql/test/successor-tests/dostmt/dostmt.c b/cpp/ql/test/successor-tests/dostmt/dostmt.c index 1b8f4ed2e69..5f1d14488dd 100644 --- a/cpp/ql/test/successor-tests/dostmt/dostmt.c +++ b/cpp/ql/test/successor-tests/dostmt/dostmt.c @@ -1,38 +1,38 @@ -void always_false() { - do { - l1:; - } while(0); - l2:; -} - -void always_true_1() { - do { - l1:; - break; - } while(1); - l2:; -} - -void always_true_2() { - do { - l1:; - break; - l2:; - } while(1); - l3:; -} - -void always_true_3() { - do { - l1:; - } while(1); - l2:; -} - -void normal() { - int i = 0; - do { - ++i; - } while(i < 10); - l:; -} +void always_false() { + do { + l1:; + } while(0); + l2:; +} + +void always_true_1() { + do { + l1:; + break; + } while(1); + l2:; +} + +void always_true_2() { + do { + l1:; + break; + l2:; + } while(1); + l3:; +} + +void always_true_3() { + do { + l1:; + } while(1); + l2:; +} + +void normal() { + int i = 0; + do { + ++i; + } while(i < 10); + l:; +} diff --git a/cpp/ql/test/successor-tests/enum/enum.c b/cpp/ql/test/successor-tests/enum/enum.c index dd5be9ec595..4e714c7c940 100644 --- a/cpp/ql/test/successor-tests/enum/enum.c +++ b/cpp/ql/test/successor-tests/enum/enum.c @@ -1,7 +1,7 @@ -enum { - a = 1 + 1 -}; - -int f() { - return a; -} +enum { + a = 1 + 1 +}; + +int f() { + return a; +} diff --git a/cpp/ql/test/successor-tests/exceptionhandler/ellipsisexceptionhandler/ellipsisexceptionhandler.cpp b/cpp/ql/test/successor-tests/exceptionhandler/ellipsisexceptionhandler/ellipsisexceptionhandler.cpp index 8c6f2a7cb39..97666c3bf85 100644 --- a/cpp/ql/test/successor-tests/exceptionhandler/ellipsisexceptionhandler/ellipsisexceptionhandler.cpp +++ b/cpp/ql/test/successor-tests/exceptionhandler/ellipsisexceptionhandler/ellipsisexceptionhandler.cpp @@ -1,17 +1,17 @@ -void f() { - try { - try { - throw 1; - } catch (int i) { - } catch (...) { - } - } catch (int j) { - } -} - -void g(bool condition) { - try { - if (condition) throw 1; - } catch (...) { - } -} +void f() { + try { + try { + throw 1; + } catch (int i) { + } catch (...) { + } + } catch (int j) { + } +} + +void g(bool condition) { + try { + if (condition) throw 1; + } catch (...) { + } +} diff --git a/cpp/ql/test/successor-tests/exceptionhandler/exceptionhandler/exceptionhandler.cpp b/cpp/ql/test/successor-tests/exceptionhandler/exceptionhandler/exceptionhandler.cpp index e5818c89125..66c20661fd1 100644 --- a/cpp/ql/test/successor-tests/exceptionhandler/exceptionhandler/exceptionhandler.cpp +++ b/cpp/ql/test/successor-tests/exceptionhandler/exceptionhandler/exceptionhandler.cpp @@ -1,22 +1,22 @@ -class C { }; -class D { }; - -void g() { - throw 1; -} - -void f() { - try { - try { - g(); - throw 2; -l: - } catch (int) { - 4; - } - } catch (C) { - 5; - } catch (D) { - 6; - } -} +class C { }; +class D { }; + +void g() { + throw 1; +} + +void f() { + try { + try { + g(); + throw 2; +l: + } catch (int) { + 4; + } + } catch (C) { + 5; + } catch (D) { + 6; + } +} diff --git a/cpp/ql/test/successor-tests/exprstmt/exprstmt.c b/cpp/ql/test/successor-tests/exprstmt/exprstmt.c index 745dee0c47d..a0ce2659424 100644 --- a/cpp/ql/test/successor-tests/exprstmt/exprstmt.c +++ b/cpp/ql/test/successor-tests/exprstmt/exprstmt.c @@ -1,4 +1,4 @@ -void f() { - 1; - ; -} +void f() { + 1; + ; +} diff --git a/cpp/ql/test/successor-tests/fieldaccessexpr/constmemberaccess/constmemberaccess.cpp b/cpp/ql/test/successor-tests/fieldaccessexpr/constmemberaccess/constmemberaccess.cpp index 74445da5a99..9a75ab5b2e9 100644 --- a/cpp/ql/test/successor-tests/fieldaccessexpr/constmemberaccess/constmemberaccess.cpp +++ b/cpp/ql/test/successor-tests/fieldaccessexpr/constmemberaccess/constmemberaccess.cpp @@ -1,10 +1,10 @@ -class C { - public: - int x; -}; - -void f() { - C *c; - int i; - i = c->x; +class C { + public: + int x; +}; + +void f() { + C *c; + int i; + i = c->x; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/fieldaccessexpr/fieldaccess/fieldaccess.cpp b/cpp/ql/test/successor-tests/fieldaccessexpr/fieldaccess/fieldaccess.cpp index 74445da5a99..9a75ab5b2e9 100644 --- a/cpp/ql/test/successor-tests/fieldaccessexpr/fieldaccess/fieldaccess.cpp +++ b/cpp/ql/test/successor-tests/fieldaccessexpr/fieldaccess/fieldaccess.cpp @@ -1,10 +1,10 @@ -class C { - public: - int x; -}; - -void f() { - C *c; - int i; - i = c->x; +class C { + public: + int x; +}; + +void f() { + C *c; + int i; + i = c->x; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/forstmt/forstmt/forstmt.cpp b/cpp/ql/test/successor-tests/forstmt/forstmt/forstmt.cpp index 2ccbd6b3f54..917ccb0bbfd 100644 --- a/cpp/ql/test/successor-tests/forstmt/forstmt/forstmt.cpp +++ b/cpp/ql/test/successor-tests/forstmt/forstmt/forstmt.cpp @@ -1,21 +1,21 @@ -void f1() { - for (int i = 0; i < 10; i++) { - l1: - } - ; -} - -void f2() { - for (int i = 0; false; i++) { // true edge pruned - } -} - -void f3() { - for (int i = 0; true; i++) { // false edge pruned - } -} - -void f4() { - for (int i = 0; i < 0; i++) { // true edge pruned - } +void f1() { + for (int i = 0; i < 10; i++) { + l1: + } + ; +} + +void f2() { + for (int i = 0; false; i++) { // true edge pruned + } +} + +void f3() { + for (int i = 0; true; i++) { // false edge pruned + } +} + +void f4() { + for (int i = 0; i < 0; i++) { // true edge pruned + } } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt.cpp b/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt.cpp index e5257a9db53..d0587d8e85b 100644 --- a/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt.cpp +++ b/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt.cpp @@ -1,38 +1,38 @@ -void always_false() { - for(;0;) { - l1:; - } - l2:; -} - -void always_true_1() { - for(;1;) { - l1:; - break; - } - l2:; -} - -void always_true_2() { - for(;1;) { - l1:; - if(0) break; - if(1) break; - l2:; - } - l3:; -} - -void always_true_3() { - for(;1;) { - l1:; - } - l2:; -} - -void normal(int x, int y) { - for(;x < y;) { - x = y; - } - l:; -} +void always_false() { + for(;0;) { + l1:; + } + l2:; +} + +void always_true_1() { + for(;1;) { + l1:; + break; + } + l2:; +} + +void always_true_2() { + for(;1;) { + l1:; + if(0) break; + if(1) break; + l2:; + } + l3:; +} + +void always_true_3() { + for(;1;) { + l1:; + } + l2:; +} + +void normal(int x, int y) { + for(;x < y;) { + x = y; + } + l:; +} diff --git a/cpp/ql/test/successor-tests/forstmt/tinyforstmt/tinyforstmt.c b/cpp/ql/test/successor-tests/forstmt/tinyforstmt/tinyforstmt.c index 129e2b279b5..cbb6465ab7b 100644 --- a/cpp/ql/test/successor-tests/forstmt/tinyforstmt/tinyforstmt.c +++ b/cpp/ql/test/successor-tests/forstmt/tinyforstmt/tinyforstmt.c @@ -1,5 +1,5 @@ -void f() { - for (;;) { - ; - } -} +void f() { + for (;;) { + ; + } +} diff --git a/cpp/ql/test/successor-tests/gotostmt/gotostmt.c b/cpp/ql/test/successor-tests/gotostmt/gotostmt.c index 318e26caf69..4a5e44f4b00 100644 --- a/cpp/ql/test/successor-tests/gotostmt/gotostmt.c +++ b/cpp/ql/test/successor-tests/gotostmt/gotostmt.c @@ -1,5 +1,5 @@ -void v() { - goto label; - ; -label: -} +void v() { + goto label; + ; +label: +} diff --git a/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt.c b/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt.c index 618b67dc789..c21e213c8c7 100644 --- a/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt.c +++ b/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt.c @@ -1,45 +1,45 @@ -void always_false_1() { - if(0) { - l1:; - } - else { - l2:; - } - l3:; -} - -void always_false_2() { - if(0) - l1:; - else - l2:; - l3:; -} - -void always_true_1() { - if(1) { - l1:; - } - else { - l2:; - } - l3:; -} - -void always_true_2() { - if(1) - l1:; - else - l2:; - l3:; -} - -void normal(int x, int y) { - if(x == y) { - l1:; - } - else { - l2:; - } - l3:; -} +void always_false_1() { + if(0) { + l1:; + } + else { + l2:; + } + l3:; +} + +void always_false_2() { + if(0) + l1:; + else + l2:; + l3:; +} + +void always_true_1() { + if(1) { + l1:; + } + else { + l2:; + } + l3:; +} + +void always_true_2() { + if(1) + l1:; + else + l2:; + l3:; +} + +void normal(int x, int y) { + if(x == y) { + l1:; + } + else { + l2:; + } + l3:; +} diff --git a/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt.c b/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt.c index a98a1bfffe7..cf8c969277d 100644 --- a/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt.c +++ b/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt.c @@ -1,32 +1,32 @@ -void always_false_1() { - if(0) { - l1:; - } - l2:; -} - -void always_false_2() { - if(0) - l1:; - l2:; -} - -void always_true_1() { - if(1) { - l1:; - } - l2:; -} - -void always_true_2() { - if(1) - l1:; - l2:; -} - -void normal(int x, int y) { - if(x == y) { - l1:; - } - l2:; -} +void always_false_1() { + if(0) { + l1:; + } + l2:; +} + +void always_false_2() { + if(0) + l1:; + l2:; +} + +void always_true_1() { + if(1) { + l1:; + } + l2:; +} + +void always_true_2() { + if(1) + l1:; + l2:; +} + +void normal(int x, int y) { + if(x == y) { + l1:; + } + l2:; +} diff --git a/cpp/ql/test/successor-tests/initializer/aggregateinitializer/aggregateinitializer.c b/cpp/ql/test/successor-tests/initializer/aggregateinitializer/aggregateinitializer.c index 2c665328a18..463bd49e0a0 100644 --- a/cpp/ql/test/successor-tests/initializer/aggregateinitializer/aggregateinitializer.c +++ b/cpp/ql/test/successor-tests/initializer/aggregateinitializer/aggregateinitializer.c @@ -1,4 +1,4 @@ -void f() { - int a, b, c, d; - int x[] = { a + b, c - d }; -} +void f() { + int a, b, c, d; + int x[] = { a + b, c - d }; +} diff --git a/cpp/ql/test/successor-tests/initializer/constructorinitializer/constructorinitializer.cpp b/cpp/ql/test/successor-tests/initializer/constructorinitializer/constructorinitializer.cpp index adb3460317b..ce43dedf6ed 100644 --- a/cpp/ql/test/successor-tests/initializer/constructorinitializer/constructorinitializer.cpp +++ b/cpp/ql/test/successor-tests/initializer/constructorinitializer/constructorinitializer.cpp @@ -1,9 +1,9 @@ -class C { - public: - C(int x, int y); -}; - -void f() { - int i, j, k, l; - C c(i + j, k - l); -} +class C { + public: + C(int x, int y); +}; + +void f() { + int i, j, k, l; + C c(i + j, k - l); +} diff --git a/cpp/ql/test/successor-tests/initializer/initializer/initializer.c b/cpp/ql/test/successor-tests/initializer/initializer/initializer.c index 40204e94bf9..5cd9949f4c3 100644 --- a/cpp/ql/test/successor-tests/initializer/initializer/initializer.c +++ b/cpp/ql/test/successor-tests/initializer/initializer/initializer.c @@ -1,4 +1,4 @@ -void f() { - int a, b; - int i = a + b; +void f() { + int a, b; + int i = a + b; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/initializer/parameterinitializer/parameterinitializer.cpp b/cpp/ql/test/successor-tests/initializer/parameterinitializer/parameterinitializer.cpp index 35ffb855f8a..d132cd810a0 100644 --- a/cpp/ql/test/successor-tests/initializer/parameterinitializer/parameterinitializer.cpp +++ b/cpp/ql/test/successor-tests/initializer/parameterinitializer/parameterinitializer.cpp @@ -1,31 +1,31 @@ -void printf(char *format, ...); - -int g(void) { - return 5; -} - -void f(int i = g()) { - printf("Got %d\n", i); -} - -class c { -public: - c(int j = g()) {}; - - void method(int k = g()) {}; -}; - -int main(void) { - f(3); - f(); - f(4); - f(); - - { - c my_c; - - my_c.method(); - } - - return 0; -} +void printf(char *format, ...); + +int g(void) { + return 5; +} + +void f(int i = g()) { + printf("Got %d\n", i); +} + +class c { +public: + c(int j = g()) {}; + + void method(int k = g()) {}; +}; + +int main(void) { + f(3); + f(); + f(4); + f(); + + { + c my_c; + + my_c.method(); + } + + return 0; +} diff --git a/cpp/ql/test/successor-tests/landexpr/landexpr.c b/cpp/ql/test/successor-tests/landexpr/landexpr.c index 90e62d1b58f..98fa0a23c6d 100644 --- a/cpp/ql/test/successor-tests/landexpr/landexpr.c +++ b/cpp/ql/test/successor-tests/landexpr/landexpr.c @@ -1,6 +1,6 @@ -void f() { - int a, b; - if (a && b) { - } - ; +void f() { + int a, b; + if (a && b) { + } + ; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/lorexpr/lorexpr.c b/cpp/ql/test/successor-tests/lorexpr/lorexpr.c index 81e88d1ca27..d03d89760b6 100644 --- a/cpp/ql/test/successor-tests/lorexpr/lorexpr.c +++ b/cpp/ql/test/successor-tests/lorexpr/lorexpr.c @@ -1,6 +1,6 @@ -void f() { - int a, b; - if (a || b) { - } - ; +void f() { + int a, b; + if (a || b) { + } + ; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/ltrbinopexpr/ltrbinopexpr.c b/cpp/ql/test/successor-tests/ltrbinopexpr/ltrbinopexpr.c index ad88c668f0f..cf093d36531 100644 --- a/cpp/ql/test/successor-tests/ltrbinopexpr/ltrbinopexpr.c +++ b/cpp/ql/test/successor-tests/ltrbinopexpr/ltrbinopexpr.c @@ -1,43 +1,43 @@ -void f() { - int i, j; - int* p, q; - - i + j; - i - j; - i * j; - i / j; - i % j; - - p + i; - p - i; - //q - p; - - i << j; - i >> j; - - i & j; - i | j; - i ^ j; - i == j; - i != j; - i > j; - i < j; - i >= j; - i <= j; - - i += j; - i -= j; - i *= j; - i /= j; - i %= j; - i <<= j; - i >>= j; - i &= j; - i |= j; - i ^= j; - - p += i; - p -= i; - - i, j; -} +void f() { + int i, j; + int* p, q; + + i + j; + i - j; + i * j; + i / j; + i % j; + + p + i; + p - i; + //q - p; + + i << j; + i >> j; + + i & j; + i | j; + i ^ j; + i == j; + i != j; + i > j; + i < j; + i >= j; + i <= j; + + i += j; + i -= j; + i *= j; + i /= j; + i %= j; + i <<= j; + i >>= j; + i &= j; + i |= j; + i ^= j; + + p += i; + p -= i; + + i, j; +} diff --git a/cpp/ql/test/successor-tests/newexpr/defconstructornewexpr/defconstructornewexpr.cpp b/cpp/ql/test/successor-tests/newexpr/defconstructornewexpr/defconstructornewexpr.cpp index b97b4c65383..0a51afb3b83 100644 --- a/cpp/ql/test/successor-tests/newexpr/defconstructornewexpr/defconstructornewexpr.cpp +++ b/cpp/ql/test/successor-tests/newexpr/defconstructornewexpr/defconstructornewexpr.cpp @@ -1,6 +1,6 @@ -class C { }; - -void f() { - new C; - return; +class C { }; + +void f() { + new C; + return; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/newexpr/newexpr/newexpr.cpp b/cpp/ql/test/successor-tests/newexpr/newexpr/newexpr.cpp index cf27d3fea04..1060bfa898f 100644 --- a/cpp/ql/test/successor-tests/newexpr/newexpr/newexpr.cpp +++ b/cpp/ql/test/successor-tests/newexpr/newexpr/newexpr.cpp @@ -1,9 +1,9 @@ -class C { - public: - C(int i, int j); -}; - -void f() { - int a, b, c, d; - new C(a + b, c - d); -} +class C { + public: + C(int i, int j); +}; + +void f() { + int a, b, c, d; + new C(a + b, c - d); +} diff --git a/cpp/ql/test/successor-tests/questionexpr/questionexpr.c b/cpp/ql/test/successor-tests/questionexpr/questionexpr.c index d77accad443..aeb257d9a61 100644 --- a/cpp/ql/test/successor-tests/questionexpr/questionexpr.c +++ b/cpp/ql/test/successor-tests/questionexpr/questionexpr.c @@ -1,4 +1,4 @@ -void f() { - int a, b, c, d, x; - x = a == b ? c + b : d - b; +void f() { + int a, b, c, d, x; + x = a == b ? c + b : d - b; } \ No newline at end of file diff --git a/cpp/ql/test/successor-tests/returnstmt/returnstmt.c b/cpp/ql/test/successor-tests/returnstmt/returnstmt.c index e0383f5f336..f32c0632728 100644 --- a/cpp/ql/test/successor-tests/returnstmt/returnstmt.c +++ b/cpp/ql/test/successor-tests/returnstmt/returnstmt.c @@ -1,10 +1,10 @@ - -void return_void() { - return; - ; -} - -int return_int() { - return 1; - ; -} + +void return_void() { + return; + ; +} + +int return_int() { + return 1; + ; +} diff --git a/cpp/ql/test/successor-tests/staticlocals/staticlocals/staticlocals.cpp b/cpp/ql/test/successor-tests/staticlocals/staticlocals/staticlocals.cpp index 4420d4d05f6..f13e2fa9583 100644 --- a/cpp/ql/test/successor-tests/staticlocals/staticlocals/staticlocals.cpp +++ b/cpp/ql/test/successor-tests/staticlocals/staticlocals/staticlocals.cpp @@ -1,13 +1,13 @@ -int g() { - return 1; -} - -int h() { - return 1; -} - -void f() { - static int i = g(), j = h(); - static int k = g(); - ; -} +int g() { + return 1; +} + +int h() { + return 1; +} + +void f() { + static int i = g(), j = h(); + static int k = g(); + ; +} diff --git a/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/revsubscriptexpr.c b/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/revsubscriptexpr.c index 0850bf62ccf..f68a5bad0d9 100644 --- a/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/revsubscriptexpr.c +++ b/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/revsubscriptexpr.c @@ -1,5 +1,5 @@ -void g() { - double x[5]; - int i, a, b; - i = (a + b)[x]; -} +void g() { + double x[5]; + int i, a, b; + i = (a + b)[x]; +} diff --git a/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/subscriptexpr.c b/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/subscriptexpr.c index 22bed0c1afb..1a98c810aa7 100644 --- a/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/subscriptexpr.c +++ b/cpp/ql/test/successor-tests/subscriptexpr/subscriptexpr/subscriptexpr.c @@ -1,5 +1,5 @@ -void f() { - double x[5]; - int i, a, b; - i = x[a + b]; -} +void f() { + double x[5]; + int i, a, b; + i = x[a + b]; +} diff --git a/cpp/ql/test/successor-tests/switchstmt/nodefaultswitchstmt/nodefaultswitchstmt.c b/cpp/ql/test/successor-tests/switchstmt/nodefaultswitchstmt/nodefaultswitchstmt.c index f12cd7d3620..bdd18c622e6 100644 --- a/cpp/ql/test/successor-tests/switchstmt/nodefaultswitchstmt/nodefaultswitchstmt.c +++ b/cpp/ql/test/successor-tests/switchstmt/nodefaultswitchstmt/nodefaultswitchstmt.c @@ -1,7 +1,7 @@ -void f(int x) { - switch (x) { - case 1: - case 2: - } - ; -} +void f(int x) { + switch (x) { + case 1: + case 2: + } + ; +} diff --git a/cpp/ql/test/successor-tests/switchstmt/switchstmt/switchstmt.c b/cpp/ql/test/successor-tests/switchstmt/switchstmt/switchstmt.c index 4f618a21e20..32be6e43b68 100644 --- a/cpp/ql/test/successor-tests/switchstmt/switchstmt/switchstmt.c +++ b/cpp/ql/test/successor-tests/switchstmt/switchstmt/switchstmt.c @@ -1,8 +1,8 @@ -void f(int x) { - switch (x) { - case 1: - case 2: - default: - } - ; -} +void f(int x) { + switch (x) { + case 1: + case 2: + default: + } + ; +} diff --git a/cpp/ql/test/successor-tests/unaryopexpr/unaryopexpr.c b/cpp/ql/test/successor-tests/unaryopexpr/unaryopexpr.c index 0d2ce20ab44..625be3434ee 100644 --- a/cpp/ql/test/successor-tests/unaryopexpr/unaryopexpr.c +++ b/cpp/ql/test/successor-tests/unaryopexpr/unaryopexpr.c @@ -1,14 +1,14 @@ -void f() { - int i; - &i; - - -i; - //+i - ~i; - !i; - - i++; - i--; - ++i; - --i; -} +void f() { + int i; + &i; + + -i; + //+i + ~i; + !i; + + i++; + i--; + ++i; + --i; +} diff --git a/cpp/ql/test/successor-tests/whilestmt/whilestmt.c b/cpp/ql/test/successor-tests/whilestmt/whilestmt.c index 02af4089e76..9de843ba20a 100644 --- a/cpp/ql/test/successor-tests/whilestmt/whilestmt.c +++ b/cpp/ql/test/successor-tests/whilestmt/whilestmt.c @@ -1,45 +1,45 @@ -void always_false_1() { - while(0) { - l1:; - } - l2:; -} - -void always_false_2() { - int done = 1; - while(!done) { - done = 0; - } -} - -void always_true_1() { - while(1) { - l1:; - break; - } - l2:; -} - -void always_true_2() { - while(1) { - l1:; - break; - l2:; - } - l3:; -} - -void always_true_3() { - while(1) { - l1:; - } - l2:; -} - -void normal() { - int i = 0; - while(i < 10) { - ++i; - } - l:; -} +void always_false_1() { + while(0) { + l1:; + } + l2:; +} + +void always_false_2() { + int done = 1; + while(!done) { + done = 0; + } +} + +void always_true_1() { + while(1) { + l1:; + break; + } + l2:; +} + +void always_true_2() { + while(1) { + l1:; + break; + l2:; + } + l3:; +} + +void always_true_3() { + while(1) { + l1:; + } + l2:; +} + +void normal() { + int i = 0; + while(i < 10) { + ++i; + } + l:; +} From 26abf5d4a2a851b3a6b82e6e1f387dacaf80112a Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Thu, 20 Sep 2018 11:53:27 -0700 Subject: [PATCH 23/29] Force LF for basically everything. --- .editorconfig | 2 +- .gitattributes | 13 + change-notes/1.19/analysis-cpp.md | 40 +- cpp/ql/src/plugin.xml | 32 +- cpp/ql/src/tools/instantiate_templates.py | 274 +++--- csharp/ql/src/plugin.xml | 32 +- .../standalone/controlflow/ControlFlow.cs | 28 +- docs/ql-style-guide.md | 834 +++++++++--------- .../MissingParentBean.xml | 54 +- .../TooManyBeans.xml | 16 +- .../Refactoring Opportunities/UnusedBean.xml | 12 +- .../UselessPropertyOverride.xml | 46 +- .../AvoidAutowiring.xml | 24 +- .../DontUseConstructorArgIndex.xml | 24 +- .../ImportsFirst.xml | 52 +- .../NoBeanDescription.xml | 52 +- .../UseIdInsteadOfName.xml | 30 +- .../UseLocalRef.xml | 32 +- .../UseSetterInjection.java | 42 +- .../UseShortcutForms.xml | 76 +- .../MissingSetters.java | 18 +- .../MissingSetters.xml | 14 +- .../Arithmetic/BadAbsOfRandom.java | 34 +- .../Arithmetic/RandomUsedOnce.java | 22 +- .../Finalization/NullifiedSuperFinalize.java | 58 +- .../Frameworks/JUnit/BadSuiteMethod.java | 40 +- .../Frameworks/JUnit/TearDownNoSuper.java | 128 +-- .../Frameworks/JUnit/TestCaseNoTests.java | 54 +- .../I18N/MissingLocaleArgument.java | 26 +- .../IncorrectSerialVersionUID.java | 20 +- .../IncorrectSerializableMethods.java | 48 +- ...issingVoidConstructorOnExternalizable.java | 72 +- ...MissingVoidConstructorsOnSerializable.java | 82 +- .../NonSerializableComparator.java | 30 +- .../Serialization/NonSerializableField.java | 54 +- .../NonSerializableFieldTooGeneral.java | 58 +- .../NonSerializableInnerClass.java | 64 +- .../Serialization/ReadResolveObject.java | 78 +- .../TransientNotSerializable.java | 22 +- .../Dead Code/FinalizerNullsFields.java | 26 +- .../DroppedExceptions-comment.java | 16 +- .../DroppedExceptions-good.java | 18 +- .../DroppedExceptions-ignore.java | 8 +- .../CallsToRunFinalizersOnExit.java | 14 +- .../CallsToStringToString.java | 16 +- .../Undesirable Calls/DefaultToString.java | 40 +- .../Undesirable Calls/GarbageCollection.java | 28 +- .../Undesirable Calls/PrintLnArray.java | 46 +- java/ql/src/plugin.xml | 32 +- .../library-tests/comments/.gitattributes | 1 + .../library-tests/comments/TestWindows.java | 44 +- .../CloseReaderTest/CloseReaderTest.java | 50 +- .../LoopVarReadTest/LoopVarReadTest.java | 32 +- .../successors/SaveFileTest/SaveFileTest.java | 112 +-- .../successors/TestBreak/TestBreak.java | 172 ++-- .../successors/TestContinue/TestContinue.java | 118 +-- .../successors/TestFinally/TestFinally.java | 300 +++---- .../TestFinallyBreakContinue.java | 216 ++--- .../TestLoopBranch/TestLoopBranch.java | 238 ++--- .../successors/TestThrow/TestThrow.java | 270 +++--- .../successors/TestTryCatch/TestTryCatch.java | 88 +- .../AlertSuppression/.gitattributes | 1 + .../AlertSuppression/TestWindows.java | 56 +- javascript/ql/src/plugin.xml | 32 +- 64 files changed, 2313 insertions(+), 2298 deletions(-) create mode 100644 java/ql/test/library-tests/comments/.gitattributes create mode 100644 java/ql/test/query-tests/AlertSuppression/.gitattributes diff --git a/.editorconfig b/.editorconfig index 413e18ca658..268bd5a7ecb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,2 @@ -[*.{ql,qll,qlref,dbscheme,qhelp,html,js,mjs,ts,json,yml,c,cpp,h,hpp}] +[*] end_of_line = lf diff --git a/.gitattributes b/.gitattributes index d945c85a015..bd6bfa96bcc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,12 +16,25 @@ *.dbscheme eol=lf *.qhelp eol=lf *.html eol=lf +*.htm eol=lf +*.xhtml eol=lf +*.xhtm eol=lf *.js eol=lf *.mjs eol=lf *.ts eol=lf *.json eol=lf *.yml eol=lf +*.yaml eol=lf *.c eol=lf *.cpp eol=lf *.h eol=lf *.hpp eol=lf +*.md eol=lf +*.stats eol=lf +*.xml eol=lf +*.sh eol=lf +*.pl eol=lf +*.java eol=lf +*.cs eol=lf +*.py eol=lf +*.lua eol=lf diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md index 7fcf1fd234c..5a3340603c8 100644 --- a/change-notes/1.19/analysis-cpp.md +++ b/change-notes/1.19/analysis-cpp.md @@ -1,20 +1,20 @@ -# Improvements to C/C++ analysis - -## General improvements - -## New queries - -| **Query** | **Tags** | **Purpose** | -|-----------------------------|-----------|--------------------------------------------------------------------| -| *@name of query (Query ID)* | *Tags* |*Aim of the new query and whether it is enabled by default or not* | - -## Changes to existing queries - -| **Query** | **Expected impact** | **Change** | -|----------------------------|------------------------|------------------------------------------------------------------| -| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. | - - -## Changes to QL libraries - -* Added a hash consing library for structural comparison of expressions. +# Improvements to C/C++ analysis + +## General improvements + +## New queries + +| **Query** | **Tags** | **Purpose** | +|-----------------------------|-----------|--------------------------------------------------------------------| +| *@name of query (Query ID)* | *Tags* |*Aim of the new query and whether it is enabled by default or not* | + +## Changes to existing queries + +| **Query** | **Expected impact** | **Change** | +|----------------------------|------------------------|------------------------------------------------------------------| +| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. | + + +## Changes to QL libraries + +* Added a hash consing library for structural comparison of expressions. diff --git a/cpp/ql/src/plugin.xml b/cpp/ql/src/plugin.xml index e08a29947a6..d7036c7c347 100644 --- a/cpp/ql/src/plugin.xml +++ b/cpp/ql/src/plugin.xml @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/cpp/ql/src/tools/instantiate_templates.py b/cpp/ql/src/tools/instantiate_templates.py index 0beeeed20d8..d549a85f82d 100644 --- a/cpp/ql/src/tools/instantiate_templates.py +++ b/cpp/ql/src/tools/instantiate_templates.py @@ -1,137 +1,137 @@ -import sys -import os.path -import glob -import re -import json - -BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$") -END_TEMPLATE = re.compile(r"^\*/\s*$") - -def expand_template_params(args, param_arg_map): - '''Given a list of template arguments that may reference template parameters - of the current template, return a new list of template arguments with each - parameter use replaced with the appropriate fully-qualified argument for - that parameter.''' - result = [] - for arg in args: - if arg in param_arg_map: - result.append(param_arg_map[arg]) - else: - result.append(arg) - - return result - -def find_instantiation(module, args, templates): - '''Given a template module and a set of template arguments, find the module - name of the instantiation of that module with those arguments.''' - template = templates[module] - for instantiation in template["template_def"]["instantiations"]: - if instantiation["args"] == args: - return instantiation["name"] - return None - -def instantiate_template(template, instantiation, root, templates): - '''Create a single instantiation of a template.''' - template_def = template["template_def"] - output_components = instantiation["name"].split(".") - output_path = root - for component in output_components: - output_path = os.path.join(output_path, component) - output_path = output_path + ".qll" - with open(output_path, "w") as output: - output.write( -""" -/* - * THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'. - * DO NOT EDIT MANUALLY. - */ - -""" % (template["name"].replace(".", "/") + ".qllt") - ) - param_arg_map = {} - for param_index in range(len(template_def["params"])): - param = template_def["params"][param_index] - arg = instantiation["args"][param_index] - output.write("private import %s as %s // Template parameter\n" % (arg, param)) - param_arg_map[param] = arg - for import_record in template_def["imports"]: - if "access" in import_record: - output.write(import_record["access"] + " ") - imported_module = find_instantiation(import_record["module"], - expand_template_params(import_record["args"], param_arg_map), templates) - output.write("import %s // %s<%s>\n" % - ( - imported_module, - import_record["module"], - ", ".join(import_record["args"]) - ) - ) - - output.writelines(template_def["body_lines"]) - -def generate_instantiations(template, root, templates): - '''Create a .qll source file for each instantiation of the specified template.''' - template_def = template["template_def"] - if "instantiations" in template_def: - for instantiation in template_def["instantiations"]: - instantiate_template(template, instantiation, root, templates) - -def read_template(template_path, module_name): - '''Read a .qllt template file from template_path, using module_name as the - fully qualified name of the module.''' - with open(template_path) as input: - in_template = False - template_text = "" - template_def = None - body_lines = [] - for line in iter(input): - if in_template: - if END_TEMPLATE.match(line): - template_def = json.loads(template_text) - in_template = False - else: - template_text += line - else: - if BEGIN_TEMPLATE.match(line) and not template_def: - in_template = True - else: - body_lines.append(line) - - if template_def: - template_def["body_lines"] = body_lines - - result = { "name": module_name } - if template_def: - result["template_def"] = template_def - return result - -def module_name_from_path_impl(path): - (head, tail) = os.path.split(path) - if head == "": - return tail - else: - return module_name_from_path(head) + "." + tail - -def module_name_from_path(path): - '''Compute the fully qualified name of a module from the path of its .qll[t] - file. The path should be relative to the library root.''' - (module_root, ext) = os.path.splitext(path) - return module_name_from_path_impl(module_root) - -def main(): - templates = {} - - root = sys.argv[1] - for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True): - print(template_path) - module_name = module_name_from_path(os.path.relpath(template_path, root)) - print(module_name) - template = read_template(template_path, module_name) - templates[template["name"]] = template - - for name, template in templates.items(): - if "template_def" in template: - generate_instantiations(template, root, templates) - -if __name__ == "__main__": - main() +import sys +import os.path +import glob +import re +import json + +BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$") +END_TEMPLATE = re.compile(r"^\*/\s*$") + +def expand_template_params(args, param_arg_map): + '''Given a list of template arguments that may reference template parameters + of the current template, return a new list of template arguments with each + parameter use replaced with the appropriate fully-qualified argument for + that parameter.''' + result = [] + for arg in args: + if arg in param_arg_map: + result.append(param_arg_map[arg]) + else: + result.append(arg) + + return result + +def find_instantiation(module, args, templates): + '''Given a template module and a set of template arguments, find the module + name of the instantiation of that module with those arguments.''' + template = templates[module] + for instantiation in template["template_def"]["instantiations"]: + if instantiation["args"] == args: + return instantiation["name"] + return None + +def instantiate_template(template, instantiation, root, templates): + '''Create a single instantiation of a template.''' + template_def = template["template_def"] + output_components = instantiation["name"].split(".") + output_path = root + for component in output_components: + output_path = os.path.join(output_path, component) + output_path = output_path + ".qll" + with open(output_path, "w") as output: + output.write( +""" +/* + * THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'. + * DO NOT EDIT MANUALLY. + */ + +""" % (template["name"].replace(".", "/") + ".qllt") + ) + param_arg_map = {} + for param_index in range(len(template_def["params"])): + param = template_def["params"][param_index] + arg = instantiation["args"][param_index] + output.write("private import %s as %s // Template parameter\n" % (arg, param)) + param_arg_map[param] = arg + for import_record in template_def["imports"]: + if "access" in import_record: + output.write(import_record["access"] + " ") + imported_module = find_instantiation(import_record["module"], + expand_template_params(import_record["args"], param_arg_map), templates) + output.write("import %s // %s<%s>\n" % + ( + imported_module, + import_record["module"], + ", ".join(import_record["args"]) + ) + ) + + output.writelines(template_def["body_lines"]) + +def generate_instantiations(template, root, templates): + '''Create a .qll source file for each instantiation of the specified template.''' + template_def = template["template_def"] + if "instantiations" in template_def: + for instantiation in template_def["instantiations"]: + instantiate_template(template, instantiation, root, templates) + +def read_template(template_path, module_name): + '''Read a .qllt template file from template_path, using module_name as the + fully qualified name of the module.''' + with open(template_path) as input: + in_template = False + template_text = "" + template_def = None + body_lines = [] + for line in iter(input): + if in_template: + if END_TEMPLATE.match(line): + template_def = json.loads(template_text) + in_template = False + else: + template_text += line + else: + if BEGIN_TEMPLATE.match(line) and not template_def: + in_template = True + else: + body_lines.append(line) + + if template_def: + template_def["body_lines"] = body_lines + + result = { "name": module_name } + if template_def: + result["template_def"] = template_def + return result + +def module_name_from_path_impl(path): + (head, tail) = os.path.split(path) + if head == "": + return tail + else: + return module_name_from_path(head) + "." + tail + +def module_name_from_path(path): + '''Compute the fully qualified name of a module from the path of its .qll[t] + file. The path should be relative to the library root.''' + (module_root, ext) = os.path.splitext(path) + return module_name_from_path_impl(module_root) + +def main(): + templates = {} + + root = sys.argv[1] + for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True): + print(template_path) + module_name = module_name_from_path(os.path.relpath(template_path, root)) + print(module_name) + template = read_template(template_path, module_name) + templates[template["name"]] = template + + for name, template in templates.items(): + if "template_def" in template: + generate_instantiations(template, root, templates) + +if __name__ == "__main__": + main() diff --git a/csharp/ql/src/plugin.xml b/csharp/ql/src/plugin.xml index f44185688ff..532f6c121ad 100644 --- a/csharp/ql/src/plugin.xml +++ b/csharp/ql/src/plugin.xml @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/csharp/ql/test/library-tests/standalone/controlflow/ControlFlow.cs b/csharp/ql/test/library-tests/standalone/controlflow/ControlFlow.cs index 56a6e5121cb..1dedc955c33 100644 --- a/csharp/ql/test/library-tests/standalone/controlflow/ControlFlow.cs +++ b/csharp/ql/test/library-tests/standalone/controlflow/ControlFlow.cs @@ -1,14 +1,14 @@ -// semmle-extractor-options: --standalone - -using System; - -class Cfg -{ - void F() - { - var v = new InvalidType(); - Debug.Assert(v.a.b, "This is true"); - - new CounterCreationData() { CounterHelp = string.Empty, CounterType = v.Type }; - } -} +// semmle-extractor-options: --standalone + +using System; + +class Cfg +{ + void F() + { + var v = new InvalidType(); + Debug.Assert(v.a.b, "This is true"); + + new CounterCreationData() { CounterHelp = string.Empty, CounterType = v.Type }; + } +} diff --git a/docs/ql-style-guide.md b/docs/ql-style-guide.md index ad30770944d..2e2f8eb39f7 100644 --- a/docs/ql-style-guide.md +++ b/docs/ql-style-guide.md @@ -1,417 +1,417 @@ -# QL Style Guide - -## Introduction - -This document describes how to format the QL 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. - -Words in *italic* are defined in the [Glossary](#glossary). - -## Indentation -1. *Always* use 2 spaces for indentation. -1. *Always* indent: - - The *body* of a module, newtype, class or predicate - - The second and subsequent lines after you use a line break to split a long line - - The *body* of a `from`, `where` or `select` clause where it spans multiple lines - - The *body* of a *quantifier* that spans multiple lines - - -### Examples - -```ql -module Helpers { - /** ... */ - class X ... { - /** ... */ - int getNumberOfChildren () { - result = count(int child | - exists(this.getChild(child)) - ) - } - } -} -``` - -```ql -from Call c, string reason -where isDeprecated(c, reason) -select c, "This call to '$@' is deprecated because " + reason + ".", - c.getTarget(), c.getTarget().getName() -``` - -## Line breaks -1. Use UNIX line endings. -1. Lines *must not* exceed 100 characters. -1. Long lines *should* be split with a line break, and the following lines *must* be indented one level until the next "regular" line break. -1. There *should* be a single blank line: - - Between the file documentation and the first `import` - - Before each declaration, except for the first declaration in a *body* - - Before the `from`-`where`-`select` section in a query file -1. *Avoid* two or more adjacent blank lines. -1. There *must* be a new line after the *annotations* `cached`, `pragma`, `language` and `bindingset`. Other *annotations* do not have a new line. -1. There *should not* be additional blank lines within a predicate. -1. There *may* be a new line: - - Immediately after the `from`, `where` or `select` keywords in a query. - - Immediately after `if`, `then`, or `else` keywords. The `then` and `else` parts *should* be consistent. -1. *Avoid* other line breaks in declarations, other than to break long lines. -1. When operands of *binary operators* span two lines, the operator *should* be placed at the end of the first line. - -### Examples - -```ql -cached -private int getNumberOfParameters() { - ... -} -``` - -```ql -predicate methodStats(string qualifiedName, string name, - int numberOfParameters, int numberOfStatements, int numberOfExpressions, - int linesOfCode, int nestingDepth, int numberOfBranches) { - ... -} -``` - -```ql -from Method main -where main.getName() = "Main" -select main, "This is the program entry point." -``` - -```ql -from Method main -where - main.getName() = "Main" and - main.getNumberOfParameters() = 0 -select main, "Main method has no parameters." -``` - -```ql - if x.isPublic() - then result = "public" - else result = "private" -``` - -```ql - if x.isPublic() then - result = "public" - else - result = "private" -``` - -```ql - if - x.isPublic() - then - result = "public" - else - result = "private" -``` - -## Braces -1. Braces follow [Stroustrup](https://en.wikipedia.org/wiki/Indentation_style#Variant:_Stroustrup) style. The opening `{` *must* be placed at the end of the preceding line. -1. The closing `}` *must* be placed on its own line, indented to the outer level, or be on the same line as the opening `{`. -1. Braces of empty blocks *may* be placed on a single line, with a single space separating the braces. -1. Short predicates, not exceeding the maximum line width, *may* be placed on a single line, with a space following the opening brace and preceding the closing brace. - -### Examples - -```ql -class ThrowException extends ThrowExpr { - Foo() { - this.getTarget() instanceof ExceptionClass - } - - override string toString() { result = "Throw Exception" } -} -``` - -## Spaces -1. There *must* be a space or line break: - - Surrounding each `=` and `|` - - After each `,` -1. There *should* be a space or line break: - - Surrounding each *binary operator*, which *must* be balanced - - Surrounding `..` in a range - - Exceptions to this may be made to save space or to improve readability. -1. *Avoid* other spaces, for example: - - After a *quantifier/aggregation* keyword - - After the predicate name in a *call* - - Inside brackets used for *calls*, single-line quantifiers, and parenthesised formulas - - Surrounding a `.` - - Inside the opening or closing `[ ]` in a range expression - - Inside casts `a.(X)` -1. *Avoid* multiple spaces, except for indentation, and *avoid* additional indentation to align formulas, parameters or arguments. -1. *Do not* put whitespace on blank lines, or trailing on the end of a line. -1. *Do not* use tabs. - - -### Examples - -```ql -cached -private predicate foo(Expr e, Expr p) { - exists(int n | - n in [0 .. 1] | - e = p.getChild(n + 1) - ) -} -``` - -## Naming -1. Use [PascalCase](http://wiki.c2.com/?PascalCase) for: - - `class` names - - `module` names - - `newtype` names -1. Use [camelCase](https://en.wikipedia.org/wiki/Camel_case) for: - - Predicate names - - Variable names -1. Newtype predicate names *should* begin with `T`. -1. Predicates that have a result *should* be named `get...` -1. Predicates that can return multiple results *should* be named `getA...` or `getAn...` -1. Predicates that don't have a result or parameters *should* be named `is...` or `has...` -1. *Avoid* underscores in names. -1. *Avoid* short or single-letter names for classes, predicates and fields. -1. Short or single letter names for parameters and *quantifiers* *may* be used provided that they are sufficiently clear. -1. Use names as they are used in the target-language specification. -1. Use American English. - -### Examples - -```ql -/** ... */ -predicate calls(Callable caller, Callable callee) { - ... -} -``` - -```ql -/** ... */ -class Type extends ... { - /** ... */ - string getName() { ... } - - /** ... */ - predicate declares(Member m) { ... } - - /** ... */ - predicate isGeneric() { ... } - - /** ... */ - Type getTypeParameter(int n) { ... } - - /** ... */ - Type getATypeParameter() { ... } -} -``` - -## Documentation - -General requirements: - -1. Documentation *must* adhere to the [QLDoc specification](https://help.semmle.com/QL/QLDocSpecification.html). -1. Use `/** ... */` for documentation, even for single line comments. -1. For single-line documentation, the `/**` and `*/` are written on the same line as the comment. -1. For multi-line documentation, the `/**` and `*/` are written on separate lines. There is a `*` preceding each comment line, aligned on the first `*`. -1. Use full sentences, with capital letters and full stops. -1. Use American English. -1. Documentation comments *should* be appropriate for users of the code. -1. Documentation for maintainers of the code *must* use normal comments. - -Documentation for specific items: - -1. Public declarations *must* be documented. -1. Non-public declarations *should* be documented. -1. Declarations in query files *should* be documented. -1. Library files (`.qll` files) *should* be have a documentation comment at the top of the file. -1. Query files, except for tests, *must* have a QLDoc query documentation comment at the top of the file. -1. Predicates that do not have a result *should* be documented `/** Holds if ... */` -1. Predicates that have a result *should* be documented `/** Gets ... */` -1. All predicate parameters *should* be referred to in the predicate documentation. -1. Reference names, such as types and parameters, using backticks `` ` ``. -1. Give examples of code in the target language, enclosed in ```` ``` ```` or `` ` ``. -1. Classes *should* be documented in the singular, for example `/* An expression. */` -1. Where a class denotes a generic concept with subclasses, list those subclasses. -1. Declarations that are deprecated *should* be documented as `DEPRECATED: ...` -1. Declarations that are for internal use *should* be documented as `INTERNAL: Do not use`. - -### Examples - -```ql -/** Provides logic for determining constant expressions. */ -``` - -```ql -/** - * Holds if the qualifier of this call has type `qualifierType`. - * `isExactType` indicates whether the type is exact, that is, whether - * the qualifier is guaranteed not to be a subtype of `qualifierType`. - */ -``` -```ql -/** - * A delegate declaration, for example - * ``` - * delegate void Logger(string text); - * ``` - */ -class Delegate extends ... -``` - -```ql -/** - * An element that can be called. - * - * Either a method (`Method`), a constructor (`Constructor`), a destructor - * (`Destructor`), an operator (`Operator`), an accessor (`Accessor`), - * an anonymous function (`AnonymousFunctionExpr`), or a local function - * (`LocalFunction`). - */ -class Callable extends ... -``` - -```ql -/** DEPRECATED: Use `getAnExpr()` instead. */ -deprecated Expr getInitializer() -``` - -```ql -/** - * INTERNAL: Do not use. - */ -``` - -## Formulas -1. *Prefer* one *conjunct* per line. -1. Write the `and` at the end of the line. This also applies in `where` clauses. -1. *Prefer* to write the `or` keyword on its own line. -1. The `or` keyword *may* be written at the end of a line, or within a line, provided that it has no unparenthesised `and` operands. -1. Single-line formulas *may* be used in order to save space or add clarity, particularly in the *body* of a *quantifier/aggregation*. -1. *Always* use brackets to clarify the precedence of: - - `implies` - - `if`-`then`-`else` -1. Parenthesised formulas *can* be written: - - Within a single line. There *should not* be an additional space following the opening parenthesis or preceding the closing parenthesis. - - Spanning multiple lines. The opening parenthesis *should* be placed at the end of the preceding line, the body should be indented one level, and the closing bracket should be placed on a new line at the outer indentation. -1. *Quantifiers/aggregations* *can* be written: - - Within a single line. In this case, there is no space to the inside of the parentheses, or after the quantifier keyword. - - Across multiple lines. In this case, type declarations are on the same line as the quantifier, the `|` *may* be at the end of the line, or *may* be on its own line, and the body of the quantifier *must* be indented one level. The closing `)` is written on a new line, at the outer indentation. -1. `if`-`then`-`else` *can* be written: - - On a single line - - With the *body* after the `if`/`then`/`else` keyword - - With the *body* indented on the next line - - *Always* parenthesise the `else` part if it is a compound formula. -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`. - -### Examples - -```ql - argumentType.isImplicitlyConvertibleTo(parameterType) - or - argumentType instanceof NullType and - result.getParameter(i).isOut() and - parameterType instanceof SimpleType - or - reflectionOrDynamicArg(argumentType, parameterType) -``` - -```ql - this.getName() = "Finalize" and not exists(this.getAParameter()) -``` - -```ql - e1.getType() instanceof BoolType and ( - b1 = true - or - b1 = false - ) and ( - b2 = true - or - b2 = false - ) -``` - -```ql - if e1 instanceof BitwiseOrExpr or e1 instanceof LogicalOrExpr then ( - impliesSub(e1.(BinaryOperation).getAnOperand(), e2, b1, b2) and - b1 = false - ) else ( - e1.getType() instanceof BoolType and - e1 = e2 and - b1 = b2 and - (b1 = true or b1 = false) - ) -``` - -```ql - (x instanceof Exception implies x.isPublic()) and y instanceof Exception -``` - -```ql - x instanceof Exception implies (x.isPublic() and y instanceof Exception) -``` - -```ql - exists(Type arg | arg = this.getAChild() | arg instanceof TypeParameter) -``` - -```ql - exists(Type qualifierType | - this.hasNonExactQualifierType(qualifierType) | - result = getANonExactQualifierSubType(qualifierType) - ) -``` - -```ql - methods = count(Method m | t = m.getDeclaringType() and not ilc(m)) -``` - -```ql - if n = 0 then result = 1 else result = n * f(n - 1) -``` - -```ql - if n = 0 - then result = 1 - else result = n * f(n - 1) -``` - -```ql - if - n = 0 - then - result = 1 - else - result = n * f(n - 1) -``` - -```ql - if exists(this.getContainingType()) then ( - result = "A nested class" and - parentName = this.getContainingType().getFullyQualifiedName() - ) else ( - result = parentName + "." + this.getName() and - parentName = this.getNamespace().getFullyQualifiedName() - ) -``` - -## Glossary - -| Phrase | Meaning | -|-------------|----------| -| *[annotation](https://help.semmle.com/QL/QLLanguageSpecification.html#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/QLLanguageSpecification.html#conjunctions)* | A formula that is an operand to an `and`. | -| *declaration* | A class, module, predicate, field or newtype. | -| *[disjunct](https://help.semmle.com/QL/QLLanguageSpecification.html#disjunctions)* | A formula that is an operand to an `or`. | -| *[formula](https://help.semmle.com/QL/QLLanguageSpecification.html#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/QLLanguageSpecification.html#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*. | +# QL Style Guide + +## Introduction + +This document describes how to format the QL 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. + +Words in *italic* are defined in the [Glossary](#glossary). + +## Indentation +1. *Always* use 2 spaces for indentation. +1. *Always* indent: + - The *body* of a module, newtype, class or predicate + - The second and subsequent lines after you use a line break to split a long line + - The *body* of a `from`, `where` or `select` clause where it spans multiple lines + - The *body* of a *quantifier* that spans multiple lines + + +### Examples + +```ql +module Helpers { + /** ... */ + class X ... { + /** ... */ + int getNumberOfChildren () { + result = count(int child | + exists(this.getChild(child)) + ) + } + } +} +``` + +```ql +from Call c, string reason +where isDeprecated(c, reason) +select c, "This call to '$@' is deprecated because " + reason + ".", + c.getTarget(), c.getTarget().getName() +``` + +## Line breaks +1. Use UNIX line endings. +1. Lines *must not* exceed 100 characters. +1. Long lines *should* be split with a line break, and the following lines *must* be indented one level until the next "regular" line break. +1. There *should* be a single blank line: + - Between the file documentation and the first `import` + - Before each declaration, except for the first declaration in a *body* + - Before the `from`-`where`-`select` section in a query file +1. *Avoid* two or more adjacent blank lines. +1. There *must* be a new line after the *annotations* `cached`, `pragma`, `language` and `bindingset`. Other *annotations* do not have a new line. +1. There *should not* be additional blank lines within a predicate. +1. There *may* be a new line: + - Immediately after the `from`, `where` or `select` keywords in a query. + - Immediately after `if`, `then`, or `else` keywords. The `then` and `else` parts *should* be consistent. +1. *Avoid* other line breaks in declarations, other than to break long lines. +1. When operands of *binary operators* span two lines, the operator *should* be placed at the end of the first line. + +### Examples + +```ql +cached +private int getNumberOfParameters() { + ... +} +``` + +```ql +predicate methodStats(string qualifiedName, string name, + int numberOfParameters, int numberOfStatements, int numberOfExpressions, + int linesOfCode, int nestingDepth, int numberOfBranches) { + ... +} +``` + +```ql +from Method main +where main.getName() = "Main" +select main, "This is the program entry point." +``` + +```ql +from Method main +where + main.getName() = "Main" and + main.getNumberOfParameters() = 0 +select main, "Main method has no parameters." +``` + +```ql + if x.isPublic() + then result = "public" + else result = "private" +``` + +```ql + if x.isPublic() then + result = "public" + else + result = "private" +``` + +```ql + if + x.isPublic() + then + result = "public" + else + result = "private" +``` + +## Braces +1. Braces follow [Stroustrup](https://en.wikipedia.org/wiki/Indentation_style#Variant:_Stroustrup) style. The opening `{` *must* be placed at the end of the preceding line. +1. The closing `}` *must* be placed on its own line, indented to the outer level, or be on the same line as the opening `{`. +1. Braces of empty blocks *may* be placed on a single line, with a single space separating the braces. +1. Short predicates, not exceeding the maximum line width, *may* be placed on a single line, with a space following the opening brace and preceding the closing brace. + +### Examples + +```ql +class ThrowException extends ThrowExpr { + Foo() { + this.getTarget() instanceof ExceptionClass + } + + override string toString() { result = "Throw Exception" } +} +``` + +## Spaces +1. There *must* be a space or line break: + - Surrounding each `=` and `|` + - After each `,` +1. There *should* be a space or line break: + - Surrounding each *binary operator*, which *must* be balanced + - Surrounding `..` in a range + - Exceptions to this may be made to save space or to improve readability. +1. *Avoid* other spaces, for example: + - After a *quantifier/aggregation* keyword + - After the predicate name in a *call* + - Inside brackets used for *calls*, single-line quantifiers, and parenthesised formulas + - Surrounding a `.` + - Inside the opening or closing `[ ]` in a range expression + - Inside casts `a.(X)` +1. *Avoid* multiple spaces, except for indentation, and *avoid* additional indentation to align formulas, parameters or arguments. +1. *Do not* put whitespace on blank lines, or trailing on the end of a line. +1. *Do not* use tabs. + + +### Examples + +```ql +cached +private predicate foo(Expr e, Expr p) { + exists(int n | + n in [0 .. 1] | + e = p.getChild(n + 1) + ) +} +``` + +## Naming +1. Use [PascalCase](http://wiki.c2.com/?PascalCase) for: + - `class` names + - `module` names + - `newtype` names +1. Use [camelCase](https://en.wikipedia.org/wiki/Camel_case) for: + - Predicate names + - Variable names +1. Newtype predicate names *should* begin with `T`. +1. Predicates that have a result *should* be named `get...` +1. Predicates that can return multiple results *should* be named `getA...` or `getAn...` +1. Predicates that don't have a result or parameters *should* be named `is...` or `has...` +1. *Avoid* underscores in names. +1. *Avoid* short or single-letter names for classes, predicates and fields. +1. Short or single letter names for parameters and *quantifiers* *may* be used provided that they are sufficiently clear. +1. Use names as they are used in the target-language specification. +1. Use American English. + +### Examples + +```ql +/** ... */ +predicate calls(Callable caller, Callable callee) { + ... +} +``` + +```ql +/** ... */ +class Type extends ... { + /** ... */ + string getName() { ... } + + /** ... */ + predicate declares(Member m) { ... } + + /** ... */ + predicate isGeneric() { ... } + + /** ... */ + Type getTypeParameter(int n) { ... } + + /** ... */ + Type getATypeParameter() { ... } +} +``` + +## Documentation + +General requirements: + +1. Documentation *must* adhere to the [QLDoc specification](https://help.semmle.com/QL/QLDocSpecification.html). +1. Use `/** ... */` for documentation, even for single line comments. +1. For single-line documentation, the `/**` and `*/` are written on the same line as the comment. +1. For multi-line documentation, the `/**` and `*/` are written on separate lines. There is a `*` preceding each comment line, aligned on the first `*`. +1. Use full sentences, with capital letters and full stops. +1. Use American English. +1. Documentation comments *should* be appropriate for users of the code. +1. Documentation for maintainers of the code *must* use normal comments. + +Documentation for specific items: + +1. Public declarations *must* be documented. +1. Non-public declarations *should* be documented. +1. Declarations in query files *should* be documented. +1. Library files (`.qll` files) *should* be have a documentation comment at the top of the file. +1. Query files, except for tests, *must* have a QLDoc query documentation comment at the top of the file. +1. Predicates that do not have a result *should* be documented `/** Holds if ... */` +1. Predicates that have a result *should* be documented `/** Gets ... */` +1. All predicate parameters *should* be referred to in the predicate documentation. +1. Reference names, such as types and parameters, using backticks `` ` ``. +1. Give examples of code in the target language, enclosed in ```` ``` ```` or `` ` ``. +1. Classes *should* be documented in the singular, for example `/* An expression. */` +1. Where a class denotes a generic concept with subclasses, list those subclasses. +1. Declarations that are deprecated *should* be documented as `DEPRECATED: ...` +1. Declarations that are for internal use *should* be documented as `INTERNAL: Do not use`. + +### Examples + +```ql +/** Provides logic for determining constant expressions. */ +``` + +```ql +/** + * Holds if the qualifier of this call has type `qualifierType`. + * `isExactType` indicates whether the type is exact, that is, whether + * the qualifier is guaranteed not to be a subtype of `qualifierType`. + */ +``` +```ql +/** + * A delegate declaration, for example + * ``` + * delegate void Logger(string text); + * ``` + */ +class Delegate extends ... +``` + +```ql +/** + * An element that can be called. + * + * Either a method (`Method`), a constructor (`Constructor`), a destructor + * (`Destructor`), an operator (`Operator`), an accessor (`Accessor`), + * an anonymous function (`AnonymousFunctionExpr`), or a local function + * (`LocalFunction`). + */ +class Callable extends ... +``` + +```ql +/** DEPRECATED: Use `getAnExpr()` instead. */ +deprecated Expr getInitializer() +``` + +```ql +/** + * INTERNAL: Do not use. + */ +``` + +## Formulas +1. *Prefer* one *conjunct* per line. +1. Write the `and` at the end of the line. This also applies in `where` clauses. +1. *Prefer* to write the `or` keyword on its own line. +1. The `or` keyword *may* be written at the end of a line, or within a line, provided that it has no unparenthesised `and` operands. +1. Single-line formulas *may* be used in order to save space or add clarity, particularly in the *body* of a *quantifier/aggregation*. +1. *Always* use brackets to clarify the precedence of: + - `implies` + - `if`-`then`-`else` +1. Parenthesised formulas *can* be written: + - Within a single line. There *should not* be an additional space following the opening parenthesis or preceding the closing parenthesis. + - Spanning multiple lines. The opening parenthesis *should* be placed at the end of the preceding line, the body should be indented one level, and the closing bracket should be placed on a new line at the outer indentation. +1. *Quantifiers/aggregations* *can* be written: + - Within a single line. In this case, there is no space to the inside of the parentheses, or after the quantifier keyword. + - Across multiple lines. In this case, type declarations are on the same line as the quantifier, the `|` *may* be at the end of the line, or *may* be on its own line, and the body of the quantifier *must* be indented one level. The closing `)` is written on a new line, at the outer indentation. +1. `if`-`then`-`else` *can* be written: + - On a single line + - With the *body* after the `if`/`then`/`else` keyword + - With the *body* indented on the next line + - *Always* parenthesise the `else` part if it is a compound formula. +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`. + +### Examples + +```ql + argumentType.isImplicitlyConvertibleTo(parameterType) + or + argumentType instanceof NullType and + result.getParameter(i).isOut() and + parameterType instanceof SimpleType + or + reflectionOrDynamicArg(argumentType, parameterType) +``` + +```ql + this.getName() = "Finalize" and not exists(this.getAParameter()) +``` + +```ql + e1.getType() instanceof BoolType and ( + b1 = true + or + b1 = false + ) and ( + b2 = true + or + b2 = false + ) +``` + +```ql + if e1 instanceof BitwiseOrExpr or e1 instanceof LogicalOrExpr then ( + impliesSub(e1.(BinaryOperation).getAnOperand(), e2, b1, b2) and + b1 = false + ) else ( + e1.getType() instanceof BoolType and + e1 = e2 and + b1 = b2 and + (b1 = true or b1 = false) + ) +``` + +```ql + (x instanceof Exception implies x.isPublic()) and y instanceof Exception +``` + +```ql + x instanceof Exception implies (x.isPublic() and y instanceof Exception) +``` + +```ql + exists(Type arg | arg = this.getAChild() | arg instanceof TypeParameter) +``` + +```ql + exists(Type qualifierType | + this.hasNonExactQualifierType(qualifierType) | + result = getANonExactQualifierSubType(qualifierType) + ) +``` + +```ql + methods = count(Method m | t = m.getDeclaringType() and not ilc(m)) +``` + +```ql + if n = 0 then result = 1 else result = n * f(n - 1) +``` + +```ql + if n = 0 + then result = 1 + else result = n * f(n - 1) +``` + +```ql + if + n = 0 + then + result = 1 + else + result = n * f(n - 1) +``` + +```ql + if exists(this.getContainingType()) then ( + result = "A nested class" and + parentName = this.getContainingType().getFullyQualifiedName() + ) else ( + result = parentName + "." + this.getName() and + parentName = this.getNamespace().getFullyQualifiedName() + ) +``` + +## Glossary + +| Phrase | Meaning | +|-------------|----------| +| *[annotation](https://help.semmle.com/QL/QLLanguageSpecification.html#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/QLLanguageSpecification.html#conjunctions)* | A formula that is an operand to an `and`. | +| *declaration* | A class, module, predicate, field or newtype. | +| *[disjunct](https://help.semmle.com/QL/QLLanguageSpecification.html#disjunctions)* | A formula that is an operand to an `or`. | +| *[formula](https://help.semmle.com/QL/QLLanguageSpecification.html#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/QLLanguageSpecification.html#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*. | diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.xml b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.xml index 9e7554e5254..6ed09e2920e 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.xml +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.xml @@ -1,28 +1,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.xml b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.xml index bd8b0ad7da1..0361ff562c0 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.xml +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.xml @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.xml b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.xml index e40477b83c8..39ef911a3e6 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.xml +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.xml @@ -1,6 +1,6 @@ - - - - - - + + + + + + diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.xml b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.xml index 9337a0f045d..9a8cceaf3dc 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.xml +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.xml @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.xml index e7f707bdb65..2a10a0be651 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.xml @@ -1,13 +1,13 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.xml index 3e14a36dbce..92560855a7c 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.xml @@ -1,13 +1,13 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.xml index 739e375f28c..1199bb4de0e 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.xml @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.xml index 438d11b4449..7d6af942ca4 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.xml @@ -1,27 +1,27 @@ - - - - This file configures the various service beans. - - - - - - This bean defines base properties common to the service beans - - ... - - - - ... - - - - ... - + + + + This file configures the various service beans. + + + + + + This bean defines base properties common to the service beans + + ... + + + + ... + + + + ... + \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.xml index af75a2d37dd..f6121793781 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.xml @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.xml index b2dcdea2119..5b6256ee52c 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.java b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.java index d5cf0de1ea6..784b8ff9262 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.java +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.java @@ -1,22 +1,22 @@ -// Class for bean 'chart1' -public class WrongChartMaker { - private AxisRenderer axisRenderer = new DefaultAxisRenderer(); - private TrendRenderer trendRenderer = new DefaultTrendRenderer(); - - public WrongChartMaker() {} - - // Each combination of the optional parameters must be represented by a constructor. - public WrongChartMaker(AxisRenderer customAxisRenderer) { - this.axisRenderer = customAxisRenderer; - } - - public WrongChartMaker(TrendRenderer customTrendRenderer) { - this.trendRenderer = customTrendRenderer; - } - - public WrongChartMaker(AxisRenderer customAxisRenderer, - TrendRenderer customTrendRenderer) { - this.axisRenderer = customAxisRenderer; - this.trendRenderer = customTrendRenderer; - } +// Class for bean 'chart1' +public class WrongChartMaker { + private AxisRenderer axisRenderer = new DefaultAxisRenderer(); + private TrendRenderer trendRenderer = new DefaultTrendRenderer(); + + public WrongChartMaker() {} + + // Each combination of the optional parameters must be represented by a constructor. + public WrongChartMaker(AxisRenderer customAxisRenderer) { + this.axisRenderer = customAxisRenderer; + } + + public WrongChartMaker(TrendRenderer customTrendRenderer) { + this.trendRenderer = customTrendRenderer; + } + + public WrongChartMaker(AxisRenderer customAxisRenderer, + TrendRenderer customTrendRenderer) { + this.axisRenderer = customAxisRenderer; + this.trendRenderer = customTrendRenderer; + } } \ No newline at end of file diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.xml b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.xml index 703e67ffe93..0f6afa629f6 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.xml +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.xml @@ -1,38 +1,38 @@ - - - - main_service_registry - - - Top-level registry for services - - - - - - orderService - - com.foo.bar.OrderService - - - - billingService - - com.foo.bar.BillingService - - - - - - - - - - - - - - - - - + + + + main_service_registry + + + Top-level registry for services + + + + + + orderService + + com.foo.bar.OrderService + + + + billingService + + com.foo.bar.BillingService + + + + + + + + + + + + + + + + + diff --git a/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.java b/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.java index 6a310cfb758..9541f489ea6 100644 --- a/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.java +++ b/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.java @@ -1,9 +1,9 @@ -// bean class -public class ContentService { - private TransactionHelper helper; - - // This method does not match the property in the bean file. - public void setHelper(TransactionHelper helper) { - this.helper = helper; - } -} +// bean class +public class ContentService { + private TransactionHelper helper; + + // This method does not match the property in the bean file. + public void setHelper(TransactionHelper helper) { + this.helper = helper; + } +} diff --git a/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.xml b/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.xml index 9a4ac59115c..42a6b51ca02 100644 --- a/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.xml +++ b/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.xml @@ -1,7 +1,7 @@ - - - - - - + + + + + + diff --git a/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.java b/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.java index 96ab5134a36..ea5aa657ba0 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.java +++ b/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.java @@ -1,17 +1,17 @@ -public static void main(String args[]) { - Random r = new Random(); - - // BAD: 'mayBeNegativeInt' is negative if - // 'nextInt()' returns 'Integer.MIN_VALUE'. - int mayBeNegativeInt = Math.abs(r.nextInt()); - - // GOOD: 'nonNegativeInt' is always a value between 0 (inclusive) - // and Integer.MAX_VALUE (exclusive). - int nonNegativeInt = r.nextInt(Integer.MAX_VALUE); - - // GOOD: When 'nextInt' returns a negative number increment the returned value. - int nextInt = r.nextInt(); - if(nextInt < 0) - nextInt++; - int nonNegativeInt = Math.abs(nextInt); -} +public static void main(String args[]) { + Random r = new Random(); + + // BAD: 'mayBeNegativeInt' is negative if + // 'nextInt()' returns 'Integer.MIN_VALUE'. + int mayBeNegativeInt = Math.abs(r.nextInt()); + + // GOOD: 'nonNegativeInt' is always a value between 0 (inclusive) + // and Integer.MAX_VALUE (exclusive). + int nonNegativeInt = r.nextInt(Integer.MAX_VALUE); + + // GOOD: When 'nextInt' returns a negative number increment the returned value. + int nextInt = r.nextInt(); + if(nextInt < 0) + nextInt++; + int nonNegativeInt = Math.abs(nextInt); +} diff --git a/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.java b/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.java index 63eaedb7717..bb1886a80fe 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.java +++ b/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.java @@ -1,12 +1,12 @@ -public static void main(String args[]) { - // BAD: A new 'Random' object is created every time - // a pseudo-random integer is required. - int notReallyRandom = new Random().nextInt(); - int notReallyRandom2 = new Random().nextInt(); - - // GOOD: The same 'Random' object is used to generate - // two pseudo-random integers. - Random r = new Random(); - int random1 = r.nextInt(); - int random2 = r.nextInt(); +public static void main(String args[]) { + // BAD: A new 'Random' object is created every time + // a pseudo-random integer is required. + int notReallyRandom = new Random().nextInt(); + int notReallyRandom2 = new Random().nextInt(); + + // GOOD: The same 'Random' object is used to generate + // two pseudo-random integers. + Random r = new Random(); + int random1 = r.nextInt(); + int random2 = r.nextInt(); } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.java b/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.java index ddd6d5c7f4f..811e3cdcac6 100644 --- a/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.java +++ b/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.java @@ -1,30 +1,30 @@ -class LocalCache { - private Collection localResources; - - //... - - protected void finalize() throws Throwable { - for (NativeResource r : localResources) { - r.dispose(); - } - }; -} - -class WrongCache extends LocalCache { - //... - @Override - protected void finalize() throws Throwable { - // BAD: Empty 'finalize', which does not call 'super.finalize'. - // Native resources in LocalCache are not disposed of. - } -} - -class RightCache extends LocalCache { - //... - @Override - protected void finalize() throws Throwable { - // GOOD: 'finalize' calls 'super.finalize'. - // Native resources in LocalCache are disposed of. - super.finalize(); - } +class LocalCache { + private Collection localResources; + + //... + + protected void finalize() throws Throwable { + for (NativeResource r : localResources) { + r.dispose(); + } + }; +} + +class WrongCache extends LocalCache { + //... + @Override + protected void finalize() throws Throwable { + // BAD: Empty 'finalize', which does not call 'super.finalize'. + // Native resources in LocalCache are not disposed of. + } +} + +class RightCache extends LocalCache { + //... + @Override + protected void finalize() throws Throwable { + // GOOD: 'finalize' calls 'super.finalize'. + // Native resources in LocalCache are disposed of. + super.finalize(); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.java b/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.java index 2cc578bfff7..9b17c5faf0c 100644 --- a/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.java +++ b/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.java @@ -1,21 +1,21 @@ -public class BadSuiteMethod extends TestCase { - // BAD: JUnit 3.8 does not detect the following method as a 'suite' method. - // The method should be public, static, and return 'junit.framework.Test' - // or one of its subtypes. - static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new MyTests("testEquals")); - suite.addTest(new MyTests("testNotEquals")); - return suite; - } -} - -public class CorrectSuiteMethod extends TestCase { - // GOOD: JUnit 3.8 correctly detects the following method as a 'suite' method. - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new MyTests("testEquals")); - suite.addTest(new MyTests("testNotEquals")); - return suite; - } +public class BadSuiteMethod extends TestCase { + // BAD: JUnit 3.8 does not detect the following method as a 'suite' method. + // The method should be public, static, and return 'junit.framework.Test' + // or one of its subtypes. + static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(new MyTests("testEquals")); + suite.addTest(new MyTests("testNotEquals")); + return suite; + } +} + +public class CorrectSuiteMethod extends TestCase { + // GOOD: JUnit 3.8 correctly detects the following method as a 'suite' method. + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(new MyTests("testEquals")); + suite.addTest(new MyTests("testNotEquals")); + return suite; + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.java b/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.java index d05d4f16326..2a7ebea4d78 100644 --- a/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.java +++ b/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.java @@ -1,65 +1,65 @@ -// Abstract class that initializes then shuts down the -// framework after each set of tests -abstract class FrameworkTestCase extends TestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - Framework.init(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - Framework.shutdown(); - } -} - -// The following classes extend 'FrameworkTestCase' to reuse the -// 'setUp' and 'tearDown' methods of the framework. - -public class TearDownNoSuper extends FrameworkTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testFramework() { - //... - } - - public void testFramework2() { - //... - } - - @Override - protected void tearDown() throws Exception { - // BAD: Does not call 'super.tearDown'. May cause later tests to fail - // when they try to re-initialize an already initialized framework. - // Even if the framework allows re-initialization, it may maintain the - // internal state, which could affect the results of succeeding tests. - System.out.println("Tests complete"); - } -} - -public class TearDownSuper extends FrameworkTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testFramework() { - //... - } - - public void testFramework2() { - //... - } - - @Override - protected void tearDown() throws Exception { - // GOOD: Correctly calls 'super.tearDown' to shut down the - // framework. - System.out.println("Tests complete"); - super.tearDown(); - } +// Abstract class that initializes then shuts down the +// framework after each set of tests +abstract class FrameworkTestCase extends TestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + Framework.init(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + Framework.shutdown(); + } +} + +// The following classes extend 'FrameworkTestCase' to reuse the +// 'setUp' and 'tearDown' methods of the framework. + +public class TearDownNoSuper extends FrameworkTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testFramework() { + //... + } + + public void testFramework2() { + //... + } + + @Override + protected void tearDown() throws Exception { + // BAD: Does not call 'super.tearDown'. May cause later tests to fail + // when they try to re-initialize an already initialized framework. + // Even if the framework allows re-initialization, it may maintain the + // internal state, which could affect the results of succeeding tests. + System.out.println("Tests complete"); + } +} + +public class TearDownSuper extends FrameworkTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testFramework() { + //... + } + + public void testFramework2() { + //... + } + + @Override + protected void tearDown() throws Exception { + // GOOD: Correctly calls 'super.tearDown' to shut down the + // framework. + System.out.println("Tests complete"); + super.tearDown(); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.java b/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.java index d9ea2cb651d..9c6b6f403de 100644 --- a/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.java +++ b/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.java @@ -1,28 +1,28 @@ -// BAD: This test case class does not have any valid JUnit 3.8 test methods. -public class TestCaseNoTests38 extends TestCase { - // This is not a test case because it does not start with 'test'. - public void simpleTest() { - //... - } - - // This is not a test case because it takes two parameters. - public void testNotEquals(int i, int j) { - assertEquals(i != j, true); - } - - // This is recognized as a test, but causes JUnit to fail - // when run because it is not public. - void testEquals() { - //... - } -} - -// GOOD: This test case class correctly declares test methods. -public class MyTests extends TestCase { - public void testEquals() { - assertEquals(1, 1); - } - public void testNotEquals() { - assertFalse(1 == 2); - } +// BAD: This test case class does not have any valid JUnit 3.8 test methods. +public class TestCaseNoTests38 extends TestCase { + // This is not a test case because it does not start with 'test'. + public void simpleTest() { + //... + } + + // This is not a test case because it takes two parameters. + public void testNotEquals(int i, int j) { + assertEquals(i != j, true); + } + + // This is recognized as a test, but causes JUnit to fail + // when run because it is not public. + void testEquals() { + //... + } +} + +// GOOD: This test case class correctly declares test methods. +public class MyTests extends TestCase { + public void testEquals() { + assertEquals(1, 1); + } + public void testNotEquals() { + assertFalse(1 == 2); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.java b/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.java index 741bc708905..382c80c209a 100644 --- a/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.java +++ b/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.java @@ -1,14 +1,14 @@ -public static void main(String args[]) { - String phrase = "I miss my home in Mississippi."; - - // AVOID: Calling 'toLowerCase()' or 'toUpperCase()' - // produces different results depending on what the default locale is. - System.out.println(phrase.toUpperCase()); - System.out.println(phrase.toLowerCase()); - - // GOOD: Explicitly setting the locale when calling 'toLowerCase()' or - // 'toUpperCase()' ensures that the resulting string is - // English, regardless of the default locale. - System.out.println(phrase.toLowerCase(Locale.ENGLISH)); - System.out.println(phrase.toUpperCase(Locale.ENGLISH)); +public static void main(String args[]) { + String phrase = "I miss my home in Mississippi."; + + // AVOID: Calling 'toLowerCase()' or 'toUpperCase()' + // produces different results depending on what the default locale is. + System.out.println(phrase.toUpperCase()); + System.out.println(phrase.toLowerCase()); + + // GOOD: Explicitly setting the locale when calling 'toLowerCase()' or + // 'toUpperCase()' ensures that the resulting string is + // English, regardless of the default locale. + System.out.println(phrase.toLowerCase(Locale.ENGLISH)); + System.out.println(phrase.toUpperCase(Locale.ENGLISH)); } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.java b/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.java index 91ee7d116cd..eaf9e459780 100644 --- a/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.java +++ b/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.java @@ -1,11 +1,11 @@ -class WrongNote implements Serializable { - // BAD: serialVersionUID must be static, final, and 'long' - private static final int serialVersionUID = 1; - - //... -} - -class Note implements Serializable { - // GOOD: serialVersionUID is of the correct type - private static final long serialVersionUID = 1L; +class WrongNote implements Serializable { + // BAD: serialVersionUID must be static, final, and 'long' + private static final int serialVersionUID = 1; + + //... +} + +class Note implements Serializable { + // GOOD: serialVersionUID is of the correct type + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.java b/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.java index 33599f15e25..57fd8a64cc2 100644 --- a/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.java +++ b/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.java @@ -1,25 +1,25 @@ -class WrongNetRequest implements Serializable { - // BAD: Does not match the exact signature required for a custom - // deserialization protocol. Will not be called during deserialization. - void readObject(ObjectInputStream in) { - //... - } - - // BAD: Does not match the exact signature required for a custom - // serialization protocol. Will not be called during serialization. - protected void writeObject(ObjectOutputStream out) { - //... - } -} - -class NetRequest implements Serializable { - // GOOD: Signature for a custom deserialization implementation. - private void readObject(ObjectInputStream in) { - //... - } - - // GOOD: Signature for a custom serialization implementation. - private void writeObject(ObjectOutputStream out) { - //... - } +class WrongNetRequest implements Serializable { + // BAD: Does not match the exact signature required for a custom + // deserialization protocol. Will not be called during deserialization. + void readObject(ObjectInputStream in) { + //... + } + + // BAD: Does not match the exact signature required for a custom + // serialization protocol. Will not be called during serialization. + protected void writeObject(ObjectOutputStream out) { + //... + } +} + +class NetRequest implements Serializable { + // GOOD: Signature for a custom deserialization implementation. + private void readObject(ObjectInputStream in) { + //... + } + + // GOOD: Signature for a custom serialization implementation. + private void writeObject(ObjectOutputStream out) { + //... + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.java b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.java index fc297ce1788..24c8d634d21 100644 --- a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.java +++ b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.java @@ -1,37 +1,37 @@ -class WrongMemo implements Externalizable { - private String memo; - - // BAD: No public no-argument constructor is defined. Deserializing this object - // causes an 'InvalidClassException'. - - public WrongMemo(String memo) { - this.memo = memo; - } - - public void writeExternal(ObjectOutput arg0) throws IOException { - //... - } - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - //... - } -} - -class Memo implements Externalizable { - private String memo; - - // GOOD: Declare a public no-argument constructor, which is used by the - // serialization framework when the object is deserialized. - public Memo() { - } - - public Memo(String memo) { - this.memo = memo; - } - - public void writeExternal(ObjectOutput out) throws IOException { - //... - } - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - //... - } +class WrongMemo implements Externalizable { + private String memo; + + // BAD: No public no-argument constructor is defined. Deserializing this object + // causes an 'InvalidClassException'. + + public WrongMemo(String memo) { + this.memo = memo; + } + + public void writeExternal(ObjectOutput arg0) throws IOException { + //... + } + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + //... + } +} + +class Memo implements Externalizable { + private String memo; + + // GOOD: Declare a public no-argument constructor, which is used by the + // serialization framework when the object is deserialized. + public Memo() { + } + + public Memo(String memo) { + this.memo = memo; + } + + public void writeExternal(ObjectOutput out) throws IOException { + //... + } + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + //... + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.java b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.java index d9161f38710..fea0087ba4f 100644 --- a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.java +++ b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.java @@ -1,42 +1,42 @@ -class WrongItem { - private String name; - - // BAD: This class does not have a no-argument constructor, and throws an - // 'InvalidClassException' at runtime. - - public WrongItem(String name) { - this.name = name; - } -} - -class WrongSubItem extends WrongItem implements Serializable { - public WrongSubItem() { - super(null); - } - - public WrongSubItem(String name) { - super(name); - } -} - -class Item { - private String name; - - // GOOD: This class declares a no-argument constructor, which allows serializable - // subclasses to be deserialized without error. - public Item() {} - - public Item(String name) { - this.name = name; - } -} - -class SubItem extends Item implements Serializable { - public SubItem() { - super(null); - } - - public SubItem(String name) { - super(name); - } +class WrongItem { + private String name; + + // BAD: This class does not have a no-argument constructor, and throws an + // 'InvalidClassException' at runtime. + + public WrongItem(String name) { + this.name = name; + } +} + +class WrongSubItem extends WrongItem implements Serializable { + public WrongSubItem() { + super(null); + } + + public WrongSubItem(String name) { + super(name); + } +} + +class Item { + private String name; + + // GOOD: This class declares a no-argument constructor, which allows serializable + // subclasses to be deserialized without error. + public Item() {} + + public Item(String name) { + this.name = name; + } +} + +class SubItem extends Item implements Serializable { + public SubItem() { + super(null); + } + + public SubItem(String name) { + super(name); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.java b/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.java index 1617440e762..d2d758bcebc 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.java +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.java @@ -1,16 +1,16 @@ -// BAD: This is not serializable, and throws a 'java.io.NotSerializableException' -// when used in a serializable sorted collection. -class WrongComparator implements Comparator { - public int compare(String o1, String o2) { - return o1.compareTo(o2); - } -} - -// GOOD: This is serializable, and can be used in collections that are meant to be serialized. -class StringComparator implements Comparator, Serializable { - private static final long serialVersionUID = -5972458403679726498L; - - public int compare(String arg0, String arg1) { - return arg0.compareTo(arg1); - } +// BAD: This is not serializable, and throws a 'java.io.NotSerializableException' +// when used in a serializable sorted collection. +class WrongComparator implements Comparator { + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } +} + +// GOOD: This is serializable, and can be used in collections that are meant to be serialized. +class StringComparator implements Comparator, Serializable { + private static final long serialVersionUID = -5972458403679726498L; + + public int compare(String arg0, String arg1) { + return arg0.compareTo(arg1); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.java b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.java index 999e0dc207a..10821b8d785 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.java +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.java @@ -1,27 +1,27 @@ -class DerivedFactors { // Class that contains derived values computed from entries in a - private Number efficiency; // performance record - private Number costPerItem; - private Number profitPerItem; - ... -} - -class WrongPerformanceRecord implements Serializable { - private String unitId; - private Number dailyThroughput; - private Number dailyCost; - private DerivedFactors factors; // BAD: 'DerivedFactors' is not serializable - // but is in a serializable class. This - // causes a 'java.io.NotSerializableException' - // when 'WrongPerformanceRecord' is serialized. - ... -} - -class PerformanceRecord implements Serializable { - private String unitId; - private Number dailyThroughput; - private Number dailyCost; - transient private DerivedFactors factors; // GOOD: 'DerivedFactors' is declared - // 'transient' so it does not contribute to the - // serializable state of 'PerformanceRecord'. - ... -} +class DerivedFactors { // Class that contains derived values computed from entries in a + private Number efficiency; // performance record + private Number costPerItem; + private Number profitPerItem; + ... +} + +class WrongPerformanceRecord implements Serializable { + private String unitId; + private Number dailyThroughput; + private Number dailyCost; + private DerivedFactors factors; // BAD: 'DerivedFactors' is not serializable + // but is in a serializable class. This + // causes a 'java.io.NotSerializableException' + // when 'WrongPerformanceRecord' is serialized. + ... +} + +class PerformanceRecord implements Serializable { + private String unitId; + private Number dailyThroughput; + private Number dailyCost; + transient private DerivedFactors factors; // GOOD: 'DerivedFactors' is declared + // 'transient' so it does not contribute to the + // serializable state of 'PerformanceRecord'. + ... +} diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableFieldTooGeneral.java b/java/ql/src/Likely Bugs/Serialization/NonSerializableFieldTooGeneral.java index b2d51cf73e8..1a4a5cc04ca 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableFieldTooGeneral.java +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableFieldTooGeneral.java @@ -1,29 +1,29 @@ -class WrongPair implements Serializable{ - private final L left; // BAD - private final R right; // BAD: L and R are not guaranteed to be serializable - - public WrongPair(L left, R right){ ... } - - ... -} - -class Pair implements Serializable{ - private final L left; // GOOD: L and R must implement Serializable - private final R right; - - public Pair(L left, R right){ ... } - - ... -} - -class WrongEvent implements Serializable{ - private Object eventData; // BAD: Type is too general. - - public WrongEvent(Object eventData){ ... } -} - -class Event implements Serializable{ - private Serializable eventData; // GOOD: Force the user to supply only serializable data - - public Event(Serializable eventData){ ... } -} +class WrongPair implements Serializable{ + private final L left; // BAD + private final R right; // BAD: L and R are not guaranteed to be serializable + + public WrongPair(L left, R right){ ... } + + ... +} + +class Pair implements Serializable{ + private final L left; // GOOD: L and R must implement Serializable + private final R right; + + public Pair(L left, R right){ ... } + + ... +} + +class WrongEvent implements Serializable{ + private Object eventData; // BAD: Type is too general. + + public WrongEvent(Object eventData){ ... } +} + +class Event implements Serializable{ + private Serializable eventData; // GOOD: Force the user to supply only serializable data + + public Event(Serializable eventData){ ... } +} diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.java b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.java index d2d44110812..e9a66f56a4a 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.java +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.java @@ -1,33 +1,33 @@ -class NonSerializableServer { - - // BAD: The following class is serializable, but the enclosing class - // 'NonSerializableServer' is not. Serializing an instance of 'WrongSession' - // causes a 'java.io.NotSerializableException'. - class WrongSession implements Serializable { - private static final long serialVersionUID = 8970783971992397218L; - private int id; - private String user; - - WrongSession(int id, String user) { /*...*/ } - } - - public WrongSession getNewSession(String user) { - return new WrongSession(newId(), user); - } -} - -class Server { - - // GOOD: The following class can be correctly serialized because it is static. - static class Session implements Serializable { - private static final long serialVersionUID = 1065454318648105638L; - private int id; - private String user; - - Session(int id, String user) { /*...*/ } - } - - public Session getNewSession(String user) { - return new Session(newId(), user); - } +class NonSerializableServer { + + // BAD: The following class is serializable, but the enclosing class + // 'NonSerializableServer' is not. Serializing an instance of 'WrongSession' + // causes a 'java.io.NotSerializableException'. + class WrongSession implements Serializable { + private static final long serialVersionUID = 8970783971992397218L; + private int id; + private String user; + + WrongSession(int id, String user) { /*...*/ } + } + + public WrongSession getNewSession(String user) { + return new WrongSession(newId(), user); + } +} + +class Server { + + // GOOD: The following class can be correctly serialized because it is static. + static class Session implements Serializable { + private static final long serialVersionUID = 1065454318648105638L; + private int id; + private String user; + + Session(int id, String user) { /*...*/ } + } + + public Session getNewSession(String user) { + return new Session(newId(), user); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.java b/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.java index cba64daf49c..25057e1ecf2 100644 --- a/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.java +++ b/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.java @@ -1,40 +1,40 @@ -class FalseSingleton implements Serializable { - private static final long serialVersionUID = -7480651116825504381L; - private static FalseSingleton instance; - - private FalseSingleton() {} - - public static FalseSingleton getInstance() { - if (instance == null) { - instance = new FalseSingleton(); - } - return instance; - } - - // BAD: Signature of 'readResolve' does not match the exact signature that is expected - // (that is, it does not return 'java.lang.Object'). - public FalseSingleton readResolve() throws ObjectStreamException { - return FalseSingleton.getInstance(); - } -} - -class Singleton implements Serializable { - private static final long serialVersionUID = -7480651116825504381L; - private static Singleton instance; - - private Singleton() {} - - public static Singleton getInstance() { - if (instance == null) { - instance = new Singleton(); - } - return instance; - } - - // GOOD: Signature of 'readResolve' matches the exact signature that is expected. - // It replaces the singleton that is read from a stream with an instance of 'Singleton', - // instead of creating a new singleton. - private Object readResolve() throws ObjectStreamException { - return Singleton.getInstance(); - } +class FalseSingleton implements Serializable { + private static final long serialVersionUID = -7480651116825504381L; + private static FalseSingleton instance; + + private FalseSingleton() {} + + public static FalseSingleton getInstance() { + if (instance == null) { + instance = new FalseSingleton(); + } + return instance; + } + + // BAD: Signature of 'readResolve' does not match the exact signature that is expected + // (that is, it does not return 'java.lang.Object'). + public FalseSingleton readResolve() throws ObjectStreamException { + return FalseSingleton.getInstance(); + } +} + +class Singleton implements Serializable { + private static final long serialVersionUID = -7480651116825504381L; + private static Singleton instance; + + private Singleton() {} + + public static Singleton getInstance() { + if (instance == null) { + instance = new Singleton(); + } + return instance; + } + + // GOOD: Signature of 'readResolve' matches the exact signature that is expected. + // It replaces the singleton that is read from a stream with an instance of 'Singleton', + // instead of creating a new singleton. + private Object readResolve() throws ObjectStreamException { + return Singleton.getInstance(); + } } \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.java b/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.java index 783ed4f4181..3025f29bd5e 100644 --- a/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.java +++ b/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.java @@ -1,12 +1,12 @@ -class State { - // The 'transient' modifier has no effect here because - // the 'State' class does not implement 'Serializable'. - private transient int[] stateData; -} - -class PersistentState implements Serializable { - private int[] stateData; - // The 'transient' modifier indicates that this field is not part of - // the persistent state and should therefore not be serialized. - private transient int[] cachedComputedData; +class State { + // The 'transient' modifier has no effect here because + // the 'State' class does not implement 'Serializable'. + private transient int[] stateData; +} + +class PersistentState implements Serializable { + private int[] stateData; + // The 'transient' modifier indicates that this field is not part of + // the persistent state and should therefore not be serialized. + private transient int[] cachedComputedData; } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.java b/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.java index d55d76f835f..7213d78104b 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.java +++ b/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.java @@ -1,14 +1,14 @@ -class FinalizedClass { - Object o = new Object(); - String s = "abcdefg"; - Integer i = Integer.valueOf(2); - - @Override - protected void finalize() throws Throwable { - super.finalize(); - //No need to nullify fields - this.o = null; - this.s = null; - this.i = null; - } +class FinalizedClass { + Object o = new Object(); + String s = "abcdefg"; + Integer i = Integer.valueOf(2); + + @Override + protected void finalize() throws Throwable { + super.finalize(); + //No need to nullify fields + this.o = null; + this.s = null; + this.i = null; + } } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-comment.java b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-comment.java index a71288df47d..75f45e61ffc 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-comment.java +++ b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-comment.java @@ -1,9 +1,9 @@ -synchronized void waitIfAutoSyncScheduled() { - try { - while (isAutoSyncScheduled) { - this.wait(1000); - } - } catch (InterruptedException e) { - // Expected exception. The file cannot be synchronized yet. - } +synchronized void waitIfAutoSyncScheduled() { + try { + while (isAutoSyncScheduled) { + this.wait(1000); + } + } catch (InterruptedException e) { + // Expected exception. The file cannot be synchronized yet. + } } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-good.java b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-good.java index 0085f15c2db..4aeb0f464c9 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-good.java +++ b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-good.java @@ -1,10 +1,10 @@ -// Exception is passed to 'ignore' method with a comment -synchronized void waitIfAutoSyncScheduled() { - try { - while (isAutoSyncScheduled) { - this.wait(1000); - } - } catch (InterruptedException e) { - Exceptions.ignore(e, "Expected exception. The file cannot be synchronized yet."); - } +// Exception is passed to 'ignore' method with a comment +synchronized void waitIfAutoSyncScheduled() { + try { + while (isAutoSyncScheduled) { + this.wait(1000); + } + } catch (InterruptedException e) { + Exceptions.ignore(e, "Expected exception. The file cannot be synchronized yet."); + } } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-ignore.java b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-ignore.java index 6985620e530..266105c45c2 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-ignore.java +++ b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions-ignore.java @@ -1,5 +1,5 @@ -// 'ignore' method. This method does nothing, but can be called -// to document the reason why the exception can be ignored. -public static void ignore(Throwable e, String message) { - +// 'ignore' method. This method does nothing, but can be called +// to document the reason why the exception can be ignored. +public static void ignore(Throwable e, String message) { + } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.java b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.java index 06655aa8c1f..0a7ec51c920 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.java +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.java @@ -1,8 +1,8 @@ -void main() { - // ... - // BAD: Call to 'runFinalizersOnExit' forces execution of all finalizers on termination of - // the runtime, which can cause live objects to transition to an invalid state. - // Avoid using this method (and finalizers in general). - System.runFinalizersOnExit(true); - // ... +void main() { + // ... + // BAD: Call to 'runFinalizersOnExit' forces execution of all finalizers on termination of + // the runtime, which can cause live objects to transition to an invalid state. + // Avoid using this method (and finalizers in general). + System.runFinalizersOnExit(true); + // ... } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.java b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.java index 2fb4df11283..476ac9d49f5 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.java +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.java @@ -1,9 +1,9 @@ -public static void main(String args[]) { - String name = "John Doe"; - - // BAD: Unnecessary call to 'toString' on 'name' - System.out.println("Hi, my name is " + name.toString()); - - // GOOD: No call to 'toString' on 'name' - System.out.println("Hi, my name is " + name); +public static void main(String args[]) { + String name = "John Doe"; + + // BAD: Unnecessary call to 'toString' on 'name' + System.out.println("Hi, my name is " + name.toString()); + + // GOOD: No call to 'toString' on 'name' + System.out.println("Hi, my name is " + name); } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.java b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.java index 2cff927b157..7363006363c 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.java +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.java @@ -1,21 +1,21 @@ -// This class does not have a 'toString' method, so 'java.lang.Object.toString' -// is used when the class is converted to a string. -class WrongPerson { - private String name; - private Date birthDate; - - public WrongPerson(String name, Date birthDate) { - this.name =name; - this.birthDate = birthDate; - } -} - -public static void main(String args[]) throws Exception { - DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); - WrongPerson wp = new WrongPerson("Robert Van Winkle", dateFormatter.parse("1967-10-31")); - - // BAD: The following statement implicitly calls 'Object.toString', - // which returns something similar to: - // WrongPerson@4383f74d - System.out.println(wp); +// This class does not have a 'toString' method, so 'java.lang.Object.toString' +// is used when the class is converted to a string. +class WrongPerson { + private String name; + private Date birthDate; + + public WrongPerson(String name, Date birthDate) { + this.name =name; + this.birthDate = birthDate; + } +} + +public static void main(String args[]) throws Exception { + DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); + WrongPerson wp = new WrongPerson("Robert Van Winkle", dateFormatter.parse("1967-10-31")); + + // BAD: The following statement implicitly calls 'Object.toString', + // which returns something similar to: + // WrongPerson@4383f74d + System.out.println(wp); } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.java b/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.java index 47c881dbf20..16d0f46fe09 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.java +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.java @@ -1,15 +1,15 @@ -class RequestHandler extends Thread { - private boolean isRunning; - private Connection conn = new Connection(); - - public void run() { - while (isRunning) { - Request req = conn.getRequest(); - // Process the request ... - - System.gc(); // This call may cause a garbage collection after each request. - // This will likely reduce the throughput of the RequestHandler - // because the JVM spends time on unnecessary garbage collection passes. - } - } +class RequestHandler extends Thread { + private boolean isRunning; + private Connection conn = new Connection(); + + public void run() { + while (isRunning) { + Request req = conn.getRequest(); + // Process the request ... + + System.gc(); // This call may cause a garbage collection after each request. + // This will likely reduce the throughput of the RequestHandler + // because the JVM spends time on unnecessary garbage collection passes. + } + } } \ No newline at end of file diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.java b/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.java index 78f1221829a..5ef908a23e8 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.java +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.java @@ -1,24 +1,24 @@ -public static void main(String args[]) { - String[] words = {"Who", "is", "John", "Galt"}; - String[][] wordMatrix = {{"There", "is"}, {"no", "spoon"}}; - - // BAD: This implicitly uses 'Object.toString' to convert the contents - // of 'words[]', and prints out something similar to: - // [Ljava.lang.String;@459189e1 - System.out.println(words); - - // GOOD: 'Arrays.toString' calls 'toString' on - // each of the array's elements. The statement prints out: - // [Who, is, John, Galt] - System.out.println(Arrays.toString(words)); - - // ALMOST RIGHT: This calls 'toString' on each of the multi-dimensional - // array's elements. However, because the elements are arrays, the statement - // prints out something similar to: - // [[Ljava.lang.String;@55f33675, [Ljava.lang.String;@527c6768]] - System.out.println(Arrays.toString(wordMatrix)); - - // GOOD: This properly prints out the contents of the multi-dimensional array: - // [[There, is], [no, spoon]] - System.out.println(Arrays.deepToString(wordMatrix)); +public static void main(String args[]) { + String[] words = {"Who", "is", "John", "Galt"}; + String[][] wordMatrix = {{"There", "is"}, {"no", "spoon"}}; + + // BAD: This implicitly uses 'Object.toString' to convert the contents + // of 'words[]', and prints out something similar to: + // [Ljava.lang.String;@459189e1 + System.out.println(words); + + // GOOD: 'Arrays.toString' calls 'toString' on + // each of the array's elements. The statement prints out: + // [Who, is, John, Galt] + System.out.println(Arrays.toString(words)); + + // ALMOST RIGHT: This calls 'toString' on each of the multi-dimensional + // array's elements. However, because the elements are arrays, the statement + // prints out something similar to: + // [[Ljava.lang.String;@55f33675, [Ljava.lang.String;@527c6768]] + System.out.println(Arrays.toString(wordMatrix)); + + // GOOD: This properly prints out the contents of the multi-dimensional array: + // [[There, is], [no, spoon]] + System.out.println(Arrays.deepToString(wordMatrix)); } \ No newline at end of file diff --git a/java/ql/src/plugin.xml b/java/ql/src/plugin.xml index ff451072779..e129a194b56 100644 --- a/java/ql/src/plugin.xml +++ b/java/ql/src/plugin.xml @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/java/ql/test/library-tests/comments/.gitattributes b/java/ql/test/library-tests/comments/.gitattributes new file mode 100644 index 00000000000..1dd1b58fd4a --- /dev/null +++ b/java/ql/test/library-tests/comments/.gitattributes @@ -0,0 +1 @@ +TestWindows.java eol=crlf diff --git a/java/ql/test/library-tests/comments/TestWindows.java b/java/ql/test/library-tests/comments/TestWindows.java index cdefc327c5b..2409adeed8f 100644 --- a/java/ql/test/library-tests/comments/TestWindows.java +++ b/java/ql/test/library-tests/comments/TestWindows.java @@ -1,22 +1,22 @@ -/** - * A JavaDoc comment - * with multiple lines. - */ -class TestWindows { - /** A JavaDoc comment with a single line. */ - void m() { - // a single-line comment - // another single-line comment - } - - /* A block comment - * with multiple lines. - */ - - /* A block comment with a single line. */ - - // an end-of-line comment with a spurious trailing comment marker */ - // an end-of-line comment with trailing whitespace - //an end-of-line comment without a leading space - void test() {} // an end-of-line comment with preceding code -} +/** + * A JavaDoc comment + * with multiple lines. + */ +class TestWindows { + /** A JavaDoc comment with a single line. */ + void m() { + // a single-line comment + // another single-line comment + } + + /* A block comment + * with multiple lines. + */ + + /* A block comment with a single line. */ + + // an end-of-line comment with a spurious trailing comment marker */ + // an end-of-line comment with trailing whitespace + //an end-of-line comment without a leading space + void test() {} // an end-of-line comment with preceding code +} diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/CloseReaderTest.java b/java/ql/test/library-tests/successors/CloseReaderTest/CloseReaderTest.java index f466bb26518..ab52205adf2 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/CloseReaderTest.java +++ b/java/ql/test/library-tests/successors/CloseReaderTest/CloseReaderTest.java @@ -1,25 +1,25 @@ -package successors; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; - -public class CloseReaderTest { - public static String readPassword(File keyFile) - { - // TODO: use Console.readPassword() when it's available. - System.out.print("Enter password for " + keyFile - + " (password will not be hidden): "); - System.out.flush(); - BufferedReader stdin = new BufferedReader(new InputStreamReader( - System.in)); - try - { - return stdin.readLine(); - } catch (IOException ex) - { - return null; - } - } -} +package successors; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; + +public class CloseReaderTest { + public static String readPassword(File keyFile) + { + // TODO: use Console.readPassword() when it's available. + System.out.print("Enter password for " + keyFile + + " (password will not be hidden): "); + System.out.flush(); + BufferedReader stdin = new BufferedReader(new InputStreamReader( + System.in)); + try + { + return stdin.readLine(); + } catch (IOException ex) + { + return null; + } + } +} diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/LoopVarReadTest.java b/java/ql/test/library-tests/successors/LoopVarReadTest/LoopVarReadTest.java index 6f8d45e8438..c0a6d9bba4c 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/LoopVarReadTest.java +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/LoopVarReadTest.java @@ -1,16 +1,16 @@ -package successors; - -public class LoopVarReadTest { - public static void testLoop() - { - int x = 2; - for (int y = 0; y < 10; y += x) - { - System.out.println("Foo"); - } - - int q = 10; - - System.out.println("foo"); - } -} +package successors; + +public class LoopVarReadTest { + public static void testLoop() + { + int x = 2; + for (int y = 0; y < 10; y += x) + { + System.out.println("Foo"); + } + + int q = 10; + + System.out.println("foo"); + } +} diff --git a/java/ql/test/library-tests/successors/SaveFileTest/SaveFileTest.java b/java/ql/test/library-tests/successors/SaveFileTest/SaveFileTest.java index 02b4b46cdb2..f07bf930f41 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/SaveFileTest.java +++ b/java/ql/test/library-tests/successors/SaveFileTest/SaveFileTest.java @@ -1,56 +1,56 @@ -package successors; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - - -public class SaveFileTest { - public void saveFile(String path, String contentType, - long size, InputStream is) throws FileNotFoundException, - IOException - { - - String savePath = path; - if (path.startsWith("/")) - { - savePath = path.substring(1); - } - - // make sure uploads area exists for this weblog - File dirPath = new File("foo"); - File saveFile = new File(dirPath.getAbsolutePath() + File.separator - + savePath); - - byte[] buffer = new byte[8192]; - int bytesRead = 0; - OutputStream bos = null; - try - { - bos = new FileOutputStream(saveFile); - while ((bytesRead = is.read(buffer, 0, 8192)) != -1) - { - bos.write(buffer, 0, bytesRead); - } - - System.out.println("The file has been written to [" - + saveFile.getAbsolutePath() + "]"); - } catch (Exception e) - { - throw new IOException("ERROR uploading file", e); - } finally - { - try - { - bos.flush(); - bos.close(); - } catch (Exception ignored) - { - } - } - - } -} +package successors; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + + +public class SaveFileTest { + public void saveFile(String path, String contentType, + long size, InputStream is) throws FileNotFoundException, + IOException + { + + String savePath = path; + if (path.startsWith("/")) + { + savePath = path.substring(1); + } + + // make sure uploads area exists for this weblog + File dirPath = new File("foo"); + File saveFile = new File(dirPath.getAbsolutePath() + File.separator + + savePath); + + byte[] buffer = new byte[8192]; + int bytesRead = 0; + OutputStream bos = null; + try + { + bos = new FileOutputStream(saveFile); + while ((bytesRead = is.read(buffer, 0, 8192)) != -1) + { + bos.write(buffer, 0, bytesRead); + } + + System.out.println("The file has been written to [" + + saveFile.getAbsolutePath() + "]"); + } catch (Exception e) + { + throw new IOException("ERROR uploading file", e); + } finally + { + try + { + bos.flush(); + bos.close(); + } catch (Exception ignored) + { + } + } + + } +} diff --git a/java/ql/test/library-tests/successors/TestBreak/TestBreak.java b/java/ql/test/library-tests/successors/TestBreak/TestBreak.java index e9bfc8aecf7..c4663bb21f3 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestBreak.java +++ b/java/ql/test/library-tests/successors/TestBreak/TestBreak.java @@ -1,86 +1,86 @@ -package successors; - -public class TestBreak { - public void f() - { - //loop breaks - a: - for (;;) - { - int x = 1; - x = x + 1; - if (x == 1) - { - break; - } else - { - for (int q : new int[20]) - { - if (q == 1) - { - break; - } else - { - break a; - } - } - } - } - int y = 12; - while (true) - { - if (y == 1) - { - break; - } else - { - do - { - if (y == 2) - { - break; - } - y = y + 2; - } while (y == 1); - y = 12; - } - } - y = 13; - - //switch breaks - int x =12; - switch (x) - { - case 1: - x = x + 1; - y = y + 1; - case 2: - x = x + 2; - y = y + 2; - break; - case 3: - case 4: - x = x + 3; - y = y + 4; - break; - case 5: - case 6: - x = x + 5; - y = y + 6; - default: - x = y; - y = x; - } - - //no default - switch(x) - { - case 1: - x = 1; - break; - case 2: - x = 2; - break; - } - } -} +package successors; + +public class TestBreak { + public void f() + { + //loop breaks + a: + for (;;) + { + int x = 1; + x = x + 1; + if (x == 1) + { + break; + } else + { + for (int q : new int[20]) + { + if (q == 1) + { + break; + } else + { + break a; + } + } + } + } + int y = 12; + while (true) + { + if (y == 1) + { + break; + } else + { + do + { + if (y == 2) + { + break; + } + y = y + 2; + } while (y == 1); + y = 12; + } + } + y = 13; + + //switch breaks + int x =12; + switch (x) + { + case 1: + x = x + 1; + y = y + 1; + case 2: + x = x + 2; + y = y + 2; + break; + case 3: + case 4: + x = x + 3; + y = y + 4; + break; + case 5: + case 6: + x = x + 5; + y = y + 6; + default: + x = y; + y = x; + } + + //no default + switch(x) + { + case 1: + x = 1; + break; + case 2: + x = 2; + break; + } + } +} diff --git a/java/ql/test/library-tests/successors/TestContinue/TestContinue.java b/java/ql/test/library-tests/successors/TestContinue/TestContinue.java index 5a0042b3540..77e94e5c7ec 100644 --- a/java/ql/test/library-tests/successors/TestContinue/TestContinue.java +++ b/java/ql/test/library-tests/successors/TestContinue/TestContinue.java @@ -1,59 +1,59 @@ -package successors; - -public class TestContinue { - public void f() - { - //loop breaks - a: - for (int p = 0; p < 10;) - { - int x = 1; - x = x + 1; - if (x == 1) - { - continue; - } else - { - for (int q : new int[20]) - { - if (q == 1) - { - continue; - } else if (q == 2) - { - continue a; - } - q = 12; - } - } - } - int y = 12; - while (y != 13) - { - if (y == 1) - { - continue; - } else - { - do - { - if (y == 2) - { - continue; - } - y = y + 2; - } while (y == 1); - y = 12; - } - y = 15; - } - y = 13; - while (y != 12) - { - if (y != 6) - continue; - else - break; - } - } -} +package successors; + +public class TestContinue { + public void f() + { + //loop breaks + a: + for (int p = 0; p < 10;) + { + int x = 1; + x = x + 1; + if (x == 1) + { + continue; + } else + { + for (int q : new int[20]) + { + if (q == 1) + { + continue; + } else if (q == 2) + { + continue a; + } + q = 12; + } + } + } + int y = 12; + while (y != 13) + { + if (y == 1) + { + continue; + } else + { + do + { + if (y == 2) + { + continue; + } + y = y + 2; + } while (y == 1); + y = 12; + } + y = 15; + } + y = 13; + while (y != 12) + { + if (y != 6) + continue; + else + break; + } + } +} diff --git a/java/ql/test/library-tests/successors/TestFinally/TestFinally.java b/java/ql/test/library-tests/successors/TestFinally/TestFinally.java index 19f67f64a9a..51398bc7b8a 100644 --- a/java/ql/test/library-tests/successors/TestFinally/TestFinally.java +++ b/java/ql/test/library-tests/successors/TestFinally/TestFinally.java @@ -1,150 +1,150 @@ -package successors; - -public class TestFinally { - public void f() - { - int z = 12; - try - { - try - { - System.out.println("Try1"); - if (z == 1) - { - return; - } - try - { - System.out.println("Try1"); - if (z == 1) - { - return; - } - System.out.println("Try2"); - } catch (Exception ex) - { - System.out.println("Exception"); - if (z == 1) - { - return; - } - } finally - { - System.out.println("Finally"); - if (z == 1) - { - return; - } - System.out.println("Finally2"); - } - System.out.println("Try2"); - } catch (Exception ex) - { - System.out.println("Exception"); - try - { - System.out.println("Try1"); - if (z == 1) - { - return; - } - System.out.println("Try2"); - } catch (Exception ex2) - { - System.out.println("Exception"); - if (z == 1) - { - return; - } - } finally - { - System.out.println("Finally"); - if (z == 1) - { - return; - } - System.out.println("Finally2"); - } - if (z == 1) - { - return; - } - } finally - { - System.out.println("Finally"); - if (z == 1) - { - return; - } - System.out.println("Finally2"); - } - System.out.println("Foo"); - int y = 12 + 3; - System.out.println("Bar"); - y = y + 1; - return; - } catch (Exception e) - { - try - { - System.out.println("Try1"); - if (z == 1) - { - return; - } - System.out.println("Try2"); - } catch (Exception ex) - { - System.out.println("Exception"); - if (z == 1) - { - return; - } - } finally - { - System.out.println("Finally"); - if (z == 1) - { - return; - } - System.out.println("Finally2"); - } - int x = 1; - System.out.println("Error: " + e); - x = x + 1; - } finally - { - int y = 12; - System.out.println("Finally"); - y = y + 1; - } - z = z + 1; - - try - { - System.out.println("Try1"); - if (z == 1) - { - return; - } - System.out.println("Try2"); - } catch (Exception ex) - { - System.out.println("Exception"); - if (z == 1) - { - return; - } - } finally - { - System.out.println("Finally"); - if (z == 1) - { - return; - } - System.out.println("Finally2"); - } - - z = z + 2; - } -} +package successors; + +public class TestFinally { + public void f() + { + int z = 12; + try + { + try + { + System.out.println("Try1"); + if (z == 1) + { + return; + } + try + { + System.out.println("Try1"); + if (z == 1) + { + return; + } + System.out.println("Try2"); + } catch (Exception ex) + { + System.out.println("Exception"); + if (z == 1) + { + return; + } + } finally + { + System.out.println("Finally"); + if (z == 1) + { + return; + } + System.out.println("Finally2"); + } + System.out.println("Try2"); + } catch (Exception ex) + { + System.out.println("Exception"); + try + { + System.out.println("Try1"); + if (z == 1) + { + return; + } + System.out.println("Try2"); + } catch (Exception ex2) + { + System.out.println("Exception"); + if (z == 1) + { + return; + } + } finally + { + System.out.println("Finally"); + if (z == 1) + { + return; + } + System.out.println("Finally2"); + } + if (z == 1) + { + return; + } + } finally + { + System.out.println("Finally"); + if (z == 1) + { + return; + } + System.out.println("Finally2"); + } + System.out.println("Foo"); + int y = 12 + 3; + System.out.println("Bar"); + y = y + 1; + return; + } catch (Exception e) + { + try + { + System.out.println("Try1"); + if (z == 1) + { + return; + } + System.out.println("Try2"); + } catch (Exception ex) + { + System.out.println("Exception"); + if (z == 1) + { + return; + } + } finally + { + System.out.println("Finally"); + if (z == 1) + { + return; + } + System.out.println("Finally2"); + } + int x = 1; + System.out.println("Error: " + e); + x = x + 1; + } finally + { + int y = 12; + System.out.println("Finally"); + y = y + 1; + } + z = z + 1; + + try + { + System.out.println("Try1"); + if (z == 1) + { + return; + } + System.out.println("Try2"); + } catch (Exception ex) + { + System.out.println("Exception"); + if (z == 1) + { + return; + } + } finally + { + System.out.println("Finally"); + if (z == 1) + { + return; + } + System.out.println("Finally2"); + } + + z = z + 2; + } +} diff --git a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestFinallyBreakContinue.java b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestFinallyBreakContinue.java index 480713f60d0..04b232a4ba3 100644 --- a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestFinallyBreakContinue.java +++ b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestFinallyBreakContinue.java @@ -1,108 +1,108 @@ -package successors; - -public class TestFinallyBreakContinue { - public void f() - { - int x = 1; - a: - for (;;) - { - try - { - if (x == 1) - { - break; - } else - { - continue; - } - } catch (Exception e) - { - if (x == 1) - { - break; - } else - { - continue; - } - } finally - { - System.out.println("finally"); - } - } - - while (true) - { - try - { - try - { - if (x == 1) - { - break; - } else - { - continue; - } - } catch (Exception e) - { - if (x == 1) - { - break; - } else - { - continue; - } - } finally - { - System.out.println("finally"); - } - } catch (Exception e) - { - System.out.println("Exception"); - } finally - { - System.out.println("finally"); - } - } - - b: - do - { - try - { - for (int i : new int[20]) - { - try - { - if (x == 1) - { - break; - } else - { - continue; - } - } catch (Exception e) - { - if (x == 1) - { - break b; - } else - { - continue b; - } - } finally - { - System.out.println("finally"); - } - } - } catch (Exception e) - { - System.out.println("Exception"); - } finally - { - System.out.println("finally"); - } - } while (true); - } -} +package successors; + +public class TestFinallyBreakContinue { + public void f() + { + int x = 1; + a: + for (;;) + { + try + { + if (x == 1) + { + break; + } else + { + continue; + } + } catch (Exception e) + { + if (x == 1) + { + break; + } else + { + continue; + } + } finally + { + System.out.println("finally"); + } + } + + while (true) + { + try + { + try + { + if (x == 1) + { + break; + } else + { + continue; + } + } catch (Exception e) + { + if (x == 1) + { + break; + } else + { + continue; + } + } finally + { + System.out.println("finally"); + } + } catch (Exception e) + { + System.out.println("Exception"); + } finally + { + System.out.println("finally"); + } + } + + b: + do + { + try + { + for (int i : new int[20]) + { + try + { + if (x == 1) + { + break; + } else + { + continue; + } + } catch (Exception e) + { + if (x == 1) + { + break b; + } else + { + continue b; + } + } finally + { + System.out.println("finally"); + } + } + } catch (Exception e) + { + System.out.println("Exception"); + } finally + { + System.out.println("finally"); + } + } while (true); + } +} diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/TestLoopBranch.java b/java/ql/test/library-tests/successors/TestLoopBranch/TestLoopBranch.java index 60906547952..058a9d40275 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/TestLoopBranch.java +++ b/java/ql/test/library-tests/successors/TestLoopBranch/TestLoopBranch.java @@ -1,120 +1,120 @@ -package successors; - -public class TestLoopBranch { - int xx = 12; - int yy = 13; - - public void f() - { - int x = 1; - int y = 2; - System.out.println("foo"); - - do - { - System.out.println("bar"); - System.out.println("foobar"); - } while (x == 2); - - { - System.out.println("shazam"); - System.out.println("boogie"); - } - - while (x == 1) - { - System.out.println("wonderland"); - System.out.println("shodan"); - x = x + 1; - } - - for (int i = 0; i < 10; i++) - { - System.out.println("rapture"); - y = x - 2; - } - - ; - ; - - for (int j : new int[20]) - { - System.out.println("Zero : " + j); - j = j + x; - } - - if (y == -1) - { - System.out.println("i squared"); - } - - if (x == 42) - { - System.out.println("rat"); - x = 6 * 9; - } else - { - System.out.println("arr"); - x = y * x; - return; - } - - switch (x) - { - case 1: - x = x + 1; - y = y + 1; - case 2: - x = x + 2; - y = y + 2; - break; - case 3: - case 4: - x = x + 3; - y = y + 4; - break; - case 5: - case 6: - x = x + 5; - y = y + 6; - default: - x = y; - y = x; - } - - //no default - switch(x) - { - case 1: - x = 1; - break; - case 2: - x = 2; - break; - } - - Comparable b = new Comparable() { - @Override - public int compareTo(String o) - { - return 0; - } - }; - b.compareTo("Foo"); - - x = x + y; - return; - } - - public TestLoopBranch() - { - xx = 33; - yy = 44; - } - - public TestLoopBranch(int i) - { - xx = i; - yy = i; - } +package successors; + +public class TestLoopBranch { + int xx = 12; + int yy = 13; + + public void f() + { + int x = 1; + int y = 2; + System.out.println("foo"); + + do + { + System.out.println("bar"); + System.out.println("foobar"); + } while (x == 2); + + { + System.out.println("shazam"); + System.out.println("boogie"); + } + + while (x == 1) + { + System.out.println("wonderland"); + System.out.println("shodan"); + x = x + 1; + } + + for (int i = 0; i < 10; i++) + { + System.out.println("rapture"); + y = x - 2; + } + + ; + ; + + for (int j : new int[20]) + { + System.out.println("Zero : " + j); + j = j + x; + } + + if (y == -1) + { + System.out.println("i squared"); + } + + if (x == 42) + { + System.out.println("rat"); + x = 6 * 9; + } else + { + System.out.println("arr"); + x = y * x; + return; + } + + switch (x) + { + case 1: + x = x + 1; + y = y + 1; + case 2: + x = x + 2; + y = y + 2; + break; + case 3: + case 4: + x = x + 3; + y = y + 4; + break; + case 5: + case 6: + x = x + 5; + y = y + 6; + default: + x = y; + y = x; + } + + //no default + switch(x) + { + case 1: + x = 1; + break; + case 2: + x = 2; + break; + } + + Comparable b = new Comparable() { + @Override + public int compareTo(String o) + { + return 0; + } + }; + b.compareTo("Foo"); + + x = x + y; + return; + } + + public TestLoopBranch() + { + xx = 33; + yy = 44; + } + + public TestLoopBranch(int i) + { + xx = i; + yy = i; + } } \ No newline at end of file diff --git a/java/ql/test/library-tests/successors/TestThrow/TestThrow.java b/java/ql/test/library-tests/successors/TestThrow/TestThrow.java index 78df2a3595f..58098fc6505 100644 --- a/java/ql/test/library-tests/successors/TestThrow/TestThrow.java +++ b/java/ql/test/library-tests/successors/TestThrow/TestThrow.java @@ -1,135 +1,135 @@ -package successors; - -import java.io.IOException; -import java.security.InvalidParameterException; - -public class TestThrow { - private TestThrow() throws IOException - { - } - - private void thrower() throws InvalidParameterException - { - } - - public void f() throws Exception - { - int z = 0; - try - { - throw new RuntimeException(); - } catch (RuntimeException e) - { - z = 1; - } catch (Exception e) - { - z = 2; - } - - z = -1; - - try - { - if (z == 1) - { - throw new RuntimeException(); - } else if (z == 2) - { - throw new Exception(); - } else if (z == 3) - { - new TestThrow(); - } else - { - thrower(); - } - } catch (RuntimeException e) - { - z = 1; - } finally - { - z = 2; - } - - z = -1; - - try - { - if (z == 1) - { - throw new Exception(); - } - else if (z == 2) - { - new TestThrow(); - } else - { - thrower(); - } - } catch (RuntimeException e) - { - z = 1; - } - - z = -1; - - try - { - if (z == 1) - throw new Exception(); - } finally - { - z = 1; - } - - try - { - try - { - if (z == 1) - { - throw new Exception(); - } else if (z == 2) - { - throw new RuntimeException(); - } else - { - throw new IOException("Foo bar", null); - } - } catch (RuntimeException e) - { - z = 1; - } - try - { - z = -2; - } finally - { - if (z == 1) - { - throw new Exception(); - } else if (z == 2) - { - throw new RuntimeException(); - } else if (z == 3) - { - throw new IOException("Foo bar", null); - } - } - } catch (IOException e) - { - z = 2; - } - finally - { - z = 3; - } - - if (z == 1) - { - throw new Exception(); - } - - z = -1; - } -} +package successors; + +import java.io.IOException; +import java.security.InvalidParameterException; + +public class TestThrow { + private TestThrow() throws IOException + { + } + + private void thrower() throws InvalidParameterException + { + } + + public void f() throws Exception + { + int z = 0; + try + { + throw new RuntimeException(); + } catch (RuntimeException e) + { + z = 1; + } catch (Exception e) + { + z = 2; + } + + z = -1; + + try + { + if (z == 1) + { + throw new RuntimeException(); + } else if (z == 2) + { + throw new Exception(); + } else if (z == 3) + { + new TestThrow(); + } else + { + thrower(); + } + } catch (RuntimeException e) + { + z = 1; + } finally + { + z = 2; + } + + z = -1; + + try + { + if (z == 1) + { + throw new Exception(); + } + else if (z == 2) + { + new TestThrow(); + } else + { + thrower(); + } + } catch (RuntimeException e) + { + z = 1; + } + + z = -1; + + try + { + if (z == 1) + throw new Exception(); + } finally + { + z = 1; + } + + try + { + try + { + if (z == 1) + { + throw new Exception(); + } else if (z == 2) + { + throw new RuntimeException(); + } else + { + throw new IOException("Foo bar", null); + } + } catch (RuntimeException e) + { + z = 1; + } + try + { + z = -2; + } finally + { + if (z == 1) + { + throw new Exception(); + } else if (z == 2) + { + throw new RuntimeException(); + } else if (z == 3) + { + throw new IOException("Foo bar", null); + } + } + } catch (IOException e) + { + z = 2; + } + finally + { + z = 3; + } + + if (z == 1) + { + throw new Exception(); + } + + z = -1; + } +} diff --git a/java/ql/test/library-tests/successors/TestTryCatch/TestTryCatch.java b/java/ql/test/library-tests/successors/TestTryCatch/TestTryCatch.java index 38b320ae8e1..09466051023 100644 --- a/java/ql/test/library-tests/successors/TestTryCatch/TestTryCatch.java +++ b/java/ql/test/library-tests/successors/TestTryCatch/TestTryCatch.java @@ -1,44 +1,44 @@ -package successors; - -public class TestTryCatch { - public void f() - { - try - { - System.out.println("Foo"); - int y = 12 + 3; - System.out.println("Bar"); - y = y + 1; - } catch (Exception e) - { - int x = 1; - System.out.println("Error: " + e); - x = x + 1; - return; - } finally - { - int y = 12; - System.out.println("Finally"); - y = y + 1; - } - int z = 12; - z = z + 1; - - for (int q = 0; q < 10; q++) - { - try - { - System.out.println("Foo"); - int y = 12 + 3; - System.out.println("Bar"); - y = y + 1; - } catch (RuntimeException e) - { - int x = 1; - System.out.println("Error: " + e); - x = x + 1; - } - } - z = z + 2; - } -} +package successors; + +public class TestTryCatch { + public void f() + { + try + { + System.out.println("Foo"); + int y = 12 + 3; + System.out.println("Bar"); + y = y + 1; + } catch (Exception e) + { + int x = 1; + System.out.println("Error: " + e); + x = x + 1; + return; + } finally + { + int y = 12; + System.out.println("Finally"); + y = y + 1; + } + int z = 12; + z = z + 1; + + for (int q = 0; q < 10; q++) + { + try + { + System.out.println("Foo"); + int y = 12 + 3; + System.out.println("Bar"); + y = y + 1; + } catch (RuntimeException e) + { + int x = 1; + System.out.println("Error: " + e); + x = x + 1; + } + } + z = z + 2; + } +} diff --git a/java/ql/test/query-tests/AlertSuppression/.gitattributes b/java/ql/test/query-tests/AlertSuppression/.gitattributes new file mode 100644 index 00000000000..1dd1b58fd4a --- /dev/null +++ b/java/ql/test/query-tests/AlertSuppression/.gitattributes @@ -0,0 +1 @@ +TestWindows.java eol=crlf diff --git a/java/ql/test/query-tests/AlertSuppression/TestWindows.java b/java/ql/test/query-tests/AlertSuppression/TestWindows.java index da2539a3083..07845e3c0a5 100644 --- a/java/ql/test/query-tests/AlertSuppression/TestWindows.java +++ b/java/ql/test/query-tests/AlertSuppression/TestWindows.java @@ -1,28 +1,28 @@ -class TestWindows {} // lgtm -// lgtm[java/confusing-method-name] -// lgtm[java/confusing-method-name, java/non-short-circuit-evaluation] -// lgtm[@tag:exceptions] -// lgtm[@tag:exceptions,java/confusing-method-name] -// lgtm[@expires:2017-06-11] -// lgtm[java/confusing-method-name] does not seem confusing despite alert by lgtm -// lgtm: blah blah -// lgtm blah blah #falsepositive -//lgtm [java/confusing-method-name] -/* lgtm */ -// lgtm[] -// lgtmfoo -//lgtm -// lgtm -// lgtm [java/confusing-method-name] -// foolgtm[java/confusing-method-name] -// foolgtm -// foo; lgtm -// foo; lgtm[java/confusing-method-name] -// foo lgtm -// foo lgtm[java/confusing-method-name] -// foo lgtm bar -// foo lgtm[java/confusing-method-name] bar -// LGTM! -// LGTM[java/confusing-method-name] -//lgtm[java/confusing-method-name] and lgtm[java/non-short-circuit-evaluation] -//lgtm[java/confusing-method-name]; lgtm +class TestWindows {} // lgtm +// lgtm[java/confusing-method-name] +// lgtm[java/confusing-method-name, java/non-short-circuit-evaluation] +// lgtm[@tag:exceptions] +// lgtm[@tag:exceptions,java/confusing-method-name] +// lgtm[@expires:2017-06-11] +// lgtm[java/confusing-method-name] does not seem confusing despite alert by lgtm +// lgtm: blah blah +// lgtm blah blah #falsepositive +//lgtm [java/confusing-method-name] +/* lgtm */ +// lgtm[] +// lgtmfoo +//lgtm +// lgtm +// lgtm [java/confusing-method-name] +// foolgtm[java/confusing-method-name] +// foolgtm +// foo; lgtm +// foo; lgtm[java/confusing-method-name] +// foo lgtm +// foo lgtm[java/confusing-method-name] +// foo lgtm bar +// foo lgtm[java/confusing-method-name] bar +// LGTM! +// LGTM[java/confusing-method-name] +//lgtm[java/confusing-method-name] and lgtm[java/non-short-circuit-evaluation] +//lgtm[java/confusing-method-name]; lgtm diff --git a/javascript/ql/src/plugin.xml b/javascript/ql/src/plugin.xml index 206533511dc..19bcfc22249 100644 --- a/javascript/ql/src/plugin.xml +++ b/javascript/ql/src/plugin.xml @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + From 1f36f5552fe908ac774b7c684639208d94713e03 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Fri, 21 Sep 2018 07:50:03 -0700 Subject: [PATCH 24/29] Normalize all text files to LF Use `* text=auto eol=lf` --- .editorconfig | 4 +- .gitattributes | 73 ++++++++++--------- cpp/config/suites/security/cwe-120 | 26 +++---- cpp/config/suites/security/cwe-121 | 6 +- cpp/config/suites/security/cwe-131 | 14 ++-- cpp/config/suites/security/cwe-134 | 26 +++---- cpp/ql/test/.project | 24 +++--- cpp/ql/test/library-tests/exprs_cast/options | 2 +- .../library-tests/typename/typename.expected | 8 +- .../library-tests/types/__wchar_t/options | 2 +- .../types/integral_types_ms/options | 2 +- .../types/wchar_t_typedef/options | 2 +- .../AlertSuppression/.gitattributes | 2 +- .../Unused Entities/UnusedIncludes/g | 2 +- .../test/query-tests/Critical/NewFree/options | 2 +- csharp/ql/test/.project | 24 +++--- .../library-tests/assemblies/Assembly1.cs_ | 40 +++++----- .../library-tests/assemblies/Assembly2.cs_ | 46 ++++++------ .../generics/Generics20.expected | 2 +- .../library-tests/tokens/Tokens1.expected | 6 +- .../ReadOnlyContainer.expected | 20 ++--- .../src/.settings/org.eclipse.jdt.core.prefs | 14 ++-- .../library-tests/comments/.gitattributes | 2 +- .../AlertSuppression/.gitattributes | 2 +- .../test/library-tests/Lines/.gitattributes | 4 +- 25 files changed, 178 insertions(+), 177 deletions(-) diff --git a/.editorconfig b/.editorconfig index 268bd5a7ecb..270106b1fac 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,2 @@ -[*] -end_of_line = lf +[*] +end_of_line = lf diff --git a/.gitattributes b/.gitattributes index bd6bfa96bcc..779c409b1c6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,40 +1,41 @@ -# The following file types will be normalized to LF line endings in the Git -# database, and will keep those LF line endings in the working tree even on -# Windows. Any other files will have whatever line endings they had when they -# were committed. If you add new entries below, you should renormalize the -# affected files by running the following from the root of this repo (requires -# Git 2.16 or greater): +# Text files will be normalized to LF line endings in the Git database, and will keep those LF line +# endings in the working tree even on Windows. If you make changes below, you should renormalize the +# affected files by running the following from the root of this repo (requires Git 2.16 or greater): # # git add --renormalize . # git status [just to show what files were renormalized] # git commit -m "Normalize line endings" -# -# Also, please update .editorconfig to handle any new entries as well. -*.ql eol=lf -*.qll eol=lf -*.qlref eol=lf -*.dbscheme eol=lf -*.qhelp eol=lf -*.html eol=lf -*.htm eol=lf -*.xhtml eol=lf -*.xhtm eol=lf -*.js eol=lf -*.mjs eol=lf -*.ts eol=lf -*.json eol=lf -*.yml eol=lf -*.yaml eol=lf -*.c eol=lf -*.cpp eol=lf -*.h eol=lf -*.hpp eol=lf -*.md eol=lf -*.stats eol=lf -*.xml eol=lf -*.sh eol=lf -*.pl eol=lf -*.java eol=lf -*.cs eol=lf -*.py eol=lf -*.lua eol=lf + +# Anything Git auto-detects as text gets normalized and checked out as LF +* text=auto eol=lf + +# Explicitly set a bunch of known extensions to text, in case auto detection gets confused. +*.ql text +*.qll text +*.qlref text +*.dbscheme text +*.qhelp text +*.html text +*.htm text +*.xhtml text +*.xhtm text +*.js text +*.mjs text +*.ts text +*.json text +*.yml text +*.yaml text +*.c text +*.cpp text +*.h text +*.hpp text +*.md text +*.stats text +*.xml text +*.sh text +*.pl text +*.java text +*.cs text +*.py text +*.lua text +*.expected text diff --git a/cpp/config/suites/security/cwe-120 b/cpp/config/suites/security/cwe-120 index 0343041d79e..483958868eb 100644 --- a/cpp/config/suites/security/cwe-120 +++ b/cpp/config/suites/security/cwe-120 @@ -1,13 +1,13 @@ -# CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') -+ semmlecode-cpp-queries/Security/CWE/CWE-120/UnboundedWrite.ql: /CWE/CWE-120 - @name Unbounded write (CWE-120) -+ semmlecode-cpp-queries/Security/CWE/CWE-120/BadlyBoundedWrite.ql: /CWE/CWE-120 - @name Badly bounded write (CWE-120) -+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWrite.ql: /CWE/CWE-120 - @name Potentially overrunning write (CWE-120) -+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWriteFloat.ql: /CWE/CWE-120 - @name Potentially overrunning write with float to string conversion (CWE-120) -+ semmlecode-cpp-queries/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql: /CWE/CWE-120 - @name Array offset used before range check (CWE-120) -+ semmlecode-cpp-queries/Likely Bugs/Memory Management/UnsafeUseOfStrcat.ql: /CWE/CWE-120 - @name Potentially unsafe use of strcat (CWE-120) +# CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') ++ semmlecode-cpp-queries/Security/CWE/CWE-120/UnboundedWrite.ql: /CWE/CWE-120 + @name Unbounded write (CWE-120) ++ semmlecode-cpp-queries/Security/CWE/CWE-120/BadlyBoundedWrite.ql: /CWE/CWE-120 + @name Badly bounded write (CWE-120) ++ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWrite.ql: /CWE/CWE-120 + @name Potentially overrunning write (CWE-120) ++ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWriteFloat.ql: /CWE/CWE-120 + @name Potentially overrunning write with float to string conversion (CWE-120) ++ semmlecode-cpp-queries/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql: /CWE/CWE-120 + @name Array offset used before range check (CWE-120) ++ semmlecode-cpp-queries/Likely Bugs/Memory Management/UnsafeUseOfStrcat.ql: /CWE/CWE-120 + @name Potentially unsafe use of strcat (CWE-120) diff --git a/cpp/config/suites/security/cwe-121 b/cpp/config/suites/security/cwe-121 index c9f922d8c55..66c4da6b08d 100644 --- a/cpp/config/suites/security/cwe-121 +++ b/cpp/config/suites/security/cwe-121 @@ -1,3 +1,3 @@ -# CWE-121: Stack-based Buffer Overflow -+ semmlecode-cpp-queries/Security/CWE/CWE-121/UnterminatedVarargsCall.ql: /CWE/CWE-121 - @name Unterminated variadic call (CWE-121) +# CWE-121: Stack-based Buffer Overflow ++ semmlecode-cpp-queries/Security/CWE/CWE-121/UnterminatedVarargsCall.ql: /CWE/CWE-121 + @name Unterminated variadic call (CWE-121) diff --git a/cpp/config/suites/security/cwe-131 b/cpp/config/suites/security/cwe-131 index ae675145902..5bbdf081b86 100644 --- a/cpp/config/suites/security/cwe-131 +++ b/cpp/config/suites/security/cwe-131 @@ -1,7 +1,7 @@ -# CWE-131: Incorrect Calculation of Buffer Size -+ semmlecode-cpp-queries/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql: /CWE/CWE-131 - @name No space for zero terminator (CWE-131) -+ semmlecode-cpp-queries/Critical/SizeCheck.ql: /CWE/CWE-131 - @name Not enough memory allocated for pointer type (CWE-131) -+ semmlecode-cpp-queries/Critical/SizeCheck2.ql: /CWE/CWE-131 - @name Not enough memory allocated for array of pointer type (CWE-131) +# CWE-131: Incorrect Calculation of Buffer Size ++ semmlecode-cpp-queries/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql: /CWE/CWE-131 + @name No space for zero terminator (CWE-131) ++ semmlecode-cpp-queries/Critical/SizeCheck.ql: /CWE/CWE-131 + @name Not enough memory allocated for pointer type (CWE-131) ++ semmlecode-cpp-queries/Critical/SizeCheck2.ql: /CWE/CWE-131 + @name Not enough memory allocated for array of pointer type (CWE-131) diff --git a/cpp/config/suites/security/cwe-134 b/cpp/config/suites/security/cwe-134 index b6c1d5411a5..060ebbfa70b 100644 --- a/cpp/config/suites/security/cwe-134 +++ b/cpp/config/suites/security/cwe-134 @@ -1,13 +1,13 @@ -# CWE-134: Uncontrolled Format String -+ semmlecode-cpp-queries/Likely Bugs/Format/NonConstantFormat.ql: /CWE/CWE-134 - @name Non-constant format string (CWE-134) -# This one runs out of memory. See ODASA-608. -#+ semmlecode-cpp-queries/PointsTo/TaintedFormatStrings.ql: /CWE/CWE-134 -+ semmlecode-cpp-queries/Likely Bugs/Format/WrongNumberOfFormatArguments.ql: /CWE/CWE-134 - @name Wrong number of arguments to formatting function (CWE-134) -+ semmlecode-cpp-queries/Likely Bugs/Format/WrongTypeFormatArguments.ql: /CWE/CWE-134 - @name Wrong type of arguments to formatting function (CWE-134) -+ semmlecode-cpp-queries/Security/CWE/CWE-134/UncontrolledFormatString.ql: /CWE/CWE-134 - @name Uncontrolled format string (CWE-134) -+ semmlecode-cpp-queries/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql: /CWE/CWE-134 - @name Uncontrolled format string (through global variable) (CWE-134) +# CWE-134: Uncontrolled Format String ++ semmlecode-cpp-queries/Likely Bugs/Format/NonConstantFormat.ql: /CWE/CWE-134 + @name Non-constant format string (CWE-134) +# This one runs out of memory. See ODASA-608. +#+ semmlecode-cpp-queries/PointsTo/TaintedFormatStrings.ql: /CWE/CWE-134 ++ semmlecode-cpp-queries/Likely Bugs/Format/WrongNumberOfFormatArguments.ql: /CWE/CWE-134 + @name Wrong number of arguments to formatting function (CWE-134) ++ semmlecode-cpp-queries/Likely Bugs/Format/WrongTypeFormatArguments.ql: /CWE/CWE-134 + @name Wrong type of arguments to formatting function (CWE-134) ++ semmlecode-cpp-queries/Security/CWE/CWE-134/UncontrolledFormatString.ql: /CWE/CWE-134 + @name Uncontrolled format string (CWE-134) ++ semmlecode-cpp-queries/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql: /CWE/CWE-134 + @name Uncontrolled format string (through global variable) (CWE-134) diff --git a/cpp/ql/test/.project b/cpp/ql/test/.project index 2dbe9983f8c..bff15d701e3 100644 --- a/cpp/ql/test/.project +++ b/cpp/ql/test/.project @@ -1,12 +1,12 @@ - - - semmlecode-cpp-tests - - - - - - - com.semmle.plugin.qdt.core.qlnature - - + + + semmlecode-cpp-tests + + + + + + + com.semmle.plugin.qdt.core.qlnature + + diff --git a/cpp/ql/test/library-tests/exprs_cast/options b/cpp/ql/test/library-tests/exprs_cast/options index 6158faf8d2f..d8db22a4bcb 100644 --- a/cpp/ql/test/library-tests/exprs_cast/options +++ b/cpp/ql/test/library-tests/exprs_cast/options @@ -1 +1 @@ -semmle-extractor-options: --edg --target --edg win64 +semmle-extractor-options: --edg --target --edg win64 diff --git a/cpp/ql/test/library-tests/typename/typename.expected b/cpp/ql/test/library-tests/typename/typename.expected index 09bff6e139e..31a76b90ab2 100644 --- a/cpp/ql/test/library-tests/typename/typename.expected +++ b/cpp/ql/test/library-tests/typename/typename.expected @@ -1,4 +1,4 @@ -| file://:0:0:0:0 | T | -| file://:0:0:0:0 | int | -| file://:0:0:0:0 | myClass | -| file://:0:0:0:0 | short | +| file://:0:0:0:0 | T | +| file://:0:0:0:0 | int | +| file://:0:0:0:0 | myClass | +| file://:0:0:0:0 | short | diff --git a/cpp/ql/test/library-tests/types/__wchar_t/options b/cpp/ql/test/library-tests/types/__wchar_t/options index 8ee3fcb9163..c3fc566fda2 100644 --- a/cpp/ql/test/library-tests/types/__wchar_t/options +++ b/cpp/ql/test/library-tests/types/__wchar_t/options @@ -1 +1 @@ -semmle-extractor-options: --microsoft +semmle-extractor-options: --microsoft diff --git a/cpp/ql/test/library-tests/types/integral_types_ms/options b/cpp/ql/test/library-tests/types/integral_types_ms/options index 3eadeb8d45a..668c53efd7d 100644 --- a/cpp/ql/test/library-tests/types/integral_types_ms/options +++ b/cpp/ql/test/library-tests/types/integral_types_ms/options @@ -1 +1 @@ -semmle-extractor-options: --microsoft --edg --target --edg win64 +semmle-extractor-options: --microsoft --edg --target --edg win64 diff --git a/cpp/ql/test/library-tests/types/wchar_t_typedef/options b/cpp/ql/test/library-tests/types/wchar_t_typedef/options index b1ef636d3e9..979872636a4 100644 --- a/cpp/ql/test/library-tests/types/wchar_t_typedef/options +++ b/cpp/ql/test/library-tests/types/wchar_t_typedef/options @@ -1 +1 @@ -semmle-extractor-options: --microsoft --edg --target --edg win32 +semmle-extractor-options: --microsoft --edg --target --edg win32 diff --git a/cpp/ql/test/query-tests/AlertSuppression/.gitattributes b/cpp/ql/test/query-tests/AlertSuppression/.gitattributes index 03feb5510a3..ba9355dd601 100644 --- a/cpp/ql/test/query-tests/AlertSuppression/.gitattributes +++ b/cpp/ql/test/query-tests/AlertSuppression/.gitattributes @@ -1 +1 @@ -tstWindows.c eol=crlf +tstWindows.c eol=crlf diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/g b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/g index c3076bdfb82..7d808bf9b83 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/g +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedIncludes/g @@ -1 +1 @@ -// g +// g diff --git a/cpp/ql/test/query-tests/Critical/NewFree/options b/cpp/ql/test/query-tests/Critical/NewFree/options index 8ee3fcb9163..c3fc566fda2 100644 --- a/cpp/ql/test/query-tests/Critical/NewFree/options +++ b/cpp/ql/test/query-tests/Critical/NewFree/options @@ -1 +1 @@ -semmle-extractor-options: --microsoft +semmle-extractor-options: --microsoft diff --git a/csharp/ql/test/.project b/csharp/ql/test/.project index 1fa51e991e3..941c2e784d4 100644 --- a/csharp/ql/test/.project +++ b/csharp/ql/test/.project @@ -1,12 +1,12 @@ - - - semmlecode-csharp-tests - - - - - - - com.semmle.plugin.qdt.core.qlnature - - + + + semmlecode-csharp-tests + + + + + + + com.semmle.plugin.qdt.core.qlnature + + diff --git a/csharp/ql/test/library-tests/assemblies/Assembly1.cs_ b/csharp/ql/test/library-tests/assemblies/Assembly1.cs_ index 1e3f1b8c64e..e8484c4c377 100644 --- a/csharp/ql/test/library-tests/assemblies/Assembly1.cs_ +++ b/csharp/ql/test/library-tests/assemblies/Assembly1.cs_ @@ -1,20 +1,20 @@ -using System; - -namespace Assembly2 -{ - public delegate int del2(int x); - - public class Class2 : Attribute - { - } - - public class Class3 : Attribute - { - public class Class4 - { - } - public class Class5 - { - } - } -} +using System; + +namespace Assembly2 +{ + public delegate int del2(int x); + + public class Class2 : Attribute + { + } + + public class Class3 : Attribute + { + public class Class4 + { + } + public class Class5 + { + } + } +} diff --git a/csharp/ql/test/library-tests/assemblies/Assembly2.cs_ b/csharp/ql/test/library-tests/assemblies/Assembly2.cs_ index 4606901a5de..4d04c87acf6 100644 --- a/csharp/ql/test/library-tests/assemblies/Assembly2.cs_ +++ b/csharp/ql/test/library-tests/assemblies/Assembly2.cs_ @@ -1,23 +1,23 @@ -using System; -using Assembly2; - -namespace Assembly1 -{ - [Class3()] - public delegate Class2 del1(Class3 c3); - - [Class3()] - public class Class1 - { - [Class2()] - static public Class2 a; - static public Class2 b() { return new Class2(); } - [Class3()] - static public Class3.Class4 c(Class3 x) { return new Class3.Class4(); } - [Class2()] - static public int d() { return 1; } - static public del2 e() { return f; } - static public int f(int x) { return x; } - static public Class3.Class5 g(Class3.Class5 x) { return x; } - } -} +using System; +using Assembly2; + +namespace Assembly1 +{ + [Class3()] + public delegate Class2 del1(Class3 c3); + + [Class3()] + public class Class1 + { + [Class2()] + static public Class2 a; + static public Class2 b() { return new Class2(); } + [Class3()] + static public Class3.Class4 c(Class3 x) { return new Class3.Class4(); } + [Class2()] + static public int d() { return 1; } + static public del2 e() { return f; } + static public int f(int x) { return x; } + static public Class3.Class5 g(Class3.Class5 x) { return x; } + } +} diff --git a/csharp/ql/test/library-tests/generics/Generics20.expected b/csharp/ql/test/library-tests/generics/Generics20.expected index 78af767cb72..2a4f078a25f 100755 --- a/csharp/ql/test/library-tests/generics/Generics20.expected +++ b/csharp/ql/test/library-tests/generics/Generics20.expected @@ -1 +1 @@ -| 1 | +| 1 | diff --git a/csharp/ql/test/library-tests/tokens/Tokens1.expected b/csharp/ql/test/library-tests/tokens/Tokens1.expected index 3956fb2ce93..0ed42634419 100644 --- a/csharp/ql/test/library-tests/tokens/Tokens1.expected +++ b/csharp/ql/test/library-tests/tokens/Tokens1.expected @@ -1,3 +1,3 @@ -| tokens.cs:5:15:5:17 | I1 | -| tokens.cs:10:12:10:14 | S1 | -| tokens.cs:14:11:14:13 | C1 | +| tokens.cs:5:15:5:17 | I1 | +| tokens.cs:10:12:10:14 | S1 | +| tokens.cs:14:11:14:13 | C1 | diff --git a/csharp/ql/test/query-tests/ReadOnlyContainer/ReadOnlyContainer.expected b/csharp/ql/test/query-tests/ReadOnlyContainer/ReadOnlyContainer.expected index 98b43cffc28..39e5f5e9628 100755 --- a/csharp/ql/test/query-tests/ReadOnlyContainer/ReadOnlyContainer.expected +++ b/csharp/ql/test/query-tests/ReadOnlyContainer/ReadOnlyContainer.expected @@ -1,11 +1,11 @@ -| ReadOnlyContainer.cs:9:16:9:17 | v1 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:13:13:13:14 | v2 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:30:16:30:17 | v3 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:55:13:55:14 | v4 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:76:13:76:14 | v5 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:82:13:82:14 | v6 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:88:13:88:14 | v7 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:91:13:91:14 | v8 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:96:13:96:14 | v9 | The contents of this container are never initialized. | -| ReadOnlyContainer.cs:99:13:99:15 | v10 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:9:16:9:17 | v1 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:13:13:13:14 | v2 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:30:16:30:17 | v3 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:55:13:55:14 | v4 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:76:13:76:14 | v5 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:82:13:82:14 | v6 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:88:13:88:14 | v7 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:91:13:91:14 | v8 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:96:13:96:14 | v9 | The contents of this container are never initialized. | +| ReadOnlyContainer.cs:99:13:99:15 | v10 | The contents of this container are never initialized. | | ReadOnlyContainer.cs:121:13:121:15 | v11 | The contents of this container are never initialized. | \ No newline at end of file diff --git a/java/ql/src/.settings/org.eclipse.jdt.core.prefs b/java/ql/src/.settings/org.eclipse.jdt.core.prefs index 860376bf985..b36152aea39 100644 --- a/java/ql/src/.settings/org.eclipse.jdt.core.prefs +++ b/java/ql/src/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ -#Tue Nov 04 11:42:37 GMT 2008 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 +#Tue Nov 04 11:42:37 GMT 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/java/ql/test/library-tests/comments/.gitattributes b/java/ql/test/library-tests/comments/.gitattributes index 1dd1b58fd4a..7ed66a396cf 100644 --- a/java/ql/test/library-tests/comments/.gitattributes +++ b/java/ql/test/library-tests/comments/.gitattributes @@ -1 +1 @@ -TestWindows.java eol=crlf +TestWindows.java eol=crlf diff --git a/java/ql/test/query-tests/AlertSuppression/.gitattributes b/java/ql/test/query-tests/AlertSuppression/.gitattributes index 1dd1b58fd4a..7ed66a396cf 100644 --- a/java/ql/test/query-tests/AlertSuppression/.gitattributes +++ b/java/ql/test/query-tests/AlertSuppression/.gitattributes @@ -1 +1 @@ -TestWindows.java eol=crlf +TestWindows.java eol=crlf diff --git a/javascript/ql/test/library-tests/Lines/.gitattributes b/javascript/ql/test/library-tests/Lines/.gitattributes index 4d67c9960a4..3ca67868c63 100644 --- a/javascript/ql/test/library-tests/Lines/.gitattributes +++ b/javascript/ql/test/library-tests/Lines/.gitattributes @@ -1,2 +1,2 @@ -# This file intentionally contains a mix of different line endings -tst1.js -text +# This file intentionally contains a mix of different line endings +tst1.js -text From 396d7ea928b737fa6829d45e5d2d45717606613d Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Fri, 21 Sep 2018 11:36:28 -0700 Subject: [PATCH 25/29] Mark several known binary extensions as `-text` --- .gitattributes | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitattributes b/.gitattributes index 779c409b1c6..626c5a297c8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -39,3 +39,10 @@ *.py text *.lua text *.expected text + +# Explicitly set a bunch of known extensions to binary, because Git < 2.10 will treat +# `* text=auto eol=lf` as `* text eol=lf` +*.png -text +*.jpg -text +*.jpeg -text +*.gif -text From 2b5d15082965ddfc5a79456cbb3aaad8a9f57b7d Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Mon, 24 Sep 2018 14:29:51 +0200 Subject: [PATCH 26/29] C++: Test for IntMultToLong on char-typed numbers --- .../Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c | 4 ++++ .../Arithmetic/IntMultToLong/IntMultToLong.expected | 1 + 2 files changed, 5 insertions(+) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c index 603fd50b774..4afd40f5839 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c @@ -88,3 +88,7 @@ void use_printf(float f, double d) // ^ there's a float -> double varargs promotion here, but it's unlikely that the author anticipates requiring a double printf("%f", d * d); // safe } + +size_t three_chars(unsigned char a, unsigned char b, unsigned char c) { + return a * b * c; // at most 16581375 [FALSE POSITIVE] +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected index 4a5edf21379..25cef782aee 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected @@ -7,3 +7,4 @@ | IntMultToLong.c:61:23:61:33 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:63:23:63:40 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:75:9:75:13 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'size_t'. | +| IntMultToLong.c:93:12:93:20 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'size_t'. | From 4d2e4c53f155ddff378df6e3235b3772d2c9faae Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Mon, 24 Sep 2018 14:30:44 +0200 Subject: [PATCH 27/29] C++: Suppress IntMultToLong alert on char --- cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql | 2 ++ .../Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c | 2 +- .../Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql index ac2bed3d6f9..4ab00c2d280 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql @@ -21,6 +21,7 @@ import semmle.code.cpp.controlflow.SSA /** * Holds if `e` is either: * - a constant + * - a char-typed expression, meaning it's a small number * - an array access to an array of constants * - flows from one of the above * In these cases the value of `e` is likely to be small and @@ -28,6 +29,7 @@ import semmle.code.cpp.controlflow.SSA */ predicate effectivelyConstant(Expr e) { e.isConstant() or + e.getType().getSize() <= 1 or e.(ArrayExpr).getArrayBase().getType().(ArrayType).getBaseType().isConst() or exists(SsaDefinition def, Variable v | def.getAUse(v) = e and diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c index 4afd40f5839..76ab0e83c59 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c @@ -90,5 +90,5 @@ void use_printf(float f, double d) } size_t three_chars(unsigned char a, unsigned char b, unsigned char c) { - return a * b * c; // at most 16581375 [FALSE POSITIVE] + return a * b * c; // at most 16581375 } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected index 25cef782aee..4a5edf21379 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected @@ -7,4 +7,3 @@ | IntMultToLong.c:61:23:61:33 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:63:23:63:40 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:75:9:75:13 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'size_t'. | -| IntMultToLong.c:93:12:93:20 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'size_t'. | From a56376a2df90b4c28335303779d9187f84818251 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Mon, 24 Sep 2018 14:31:19 +0200 Subject: [PATCH 28/29] C++: rename effectivelyConstant to likelySmall This reflects the existing QLDoc better and makes it more clear why it includes char-typed expressions. --- cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql index 4ab00c2d280..885039e9d58 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql @@ -27,13 +27,13 @@ import semmle.code.cpp.controlflow.SSA * In these cases the value of `e` is likely to be small and * controlled, so we consider it less likely to cause an overflow. */ -predicate effectivelyConstant(Expr e) { +predicate likelySmall(Expr e) { e.isConstant() or e.getType().getSize() <= 1 or e.(ArrayExpr).getArrayBase().getType().(ArrayType).getBaseType().isConst() or exists(SsaDefinition def, Variable v | def.getAUse(v) = e and - effectivelyConstant(def.getDefiningValue(v)) + likelySmall(def.getDefiningValue(v)) ) } @@ -58,7 +58,7 @@ int getEffectiveMulOperands(MulExpr me) { result = count(Expr op | op = getMulOperand*(me) and not op instanceof MulExpr and - not effectivelyConstant(op) + not likelySmall(op) ) } From c3b523cdc498f48a8e36fa285be86ea22c067398 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 24 Sep 2018 10:02:52 -0700 Subject: [PATCH 29/29] Fixing a missed reference to renamed file. --- cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp index d441e368b20..d5b949691f0 100644 --- a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.qhelp @@ -15,7 +15,7 @@

In the following example, HRESULT is used in a test expression incorrectly as it may yield an incorrect result.

- +

To fix this issue, use the FAILED macro in the test expression.