[doc] [apex] Adjust externalInfoUrl properties to new site - Part 5
Note: I also took the chance to fix tab damage
This commit is contained in:
@ -20,7 +20,7 @@ import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
|||||||
*
|
*
|
||||||
* @author a.subramanian
|
* @author a.subramanian
|
||||||
*/
|
*/
|
||||||
public class ApexUnitTestClassShouldHaveAsserts extends AbstractApexUnitTestRule {
|
public class ApexUnitTestClassShouldHaveAssertsRule extends AbstractApexUnitTestRule {
|
||||||
|
|
||||||
private static final Set<String> ASSERT_METHODS = new HashSet<>();
|
private static final Set<String> ASSERT_METHODS = new HashSet<>();
|
||||||
|
|
@ -25,7 +25,7 @@ import apex.jorje.services.Version;
|
|||||||
*
|
*
|
||||||
* @author a.subramanian
|
* @author a.subramanian
|
||||||
*/
|
*/
|
||||||
public class ApexUnitTestShouldNotUseSeeAllDataTrue extends AbstractApexUnitTestRule {
|
public class ApexUnitTestShouldNotUseSeeAllDataTrueRule extends AbstractApexUnitTestRule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visit(final ASTUserClass node, final Object data) {
|
public Object visit(final ASTUserClass node, final Object data) {
|
@ -11,8 +11,8 @@
|
|||||||
<rule name="ApexUnitTestClassShouldHaveAsserts"
|
<rule name="ApexUnitTestClassShouldHaveAsserts"
|
||||||
since="5.5.1"
|
since="5.5.1"
|
||||||
message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()"
|
message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAsserts"
|
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAssertsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/apexunit.html#ApexUnitTestClassShouldHaveAsserts">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_apexunit.html#apexunittestclassshouldhaveasserts">
|
||||||
<description>
|
<description>
|
||||||
Apex unit tests should include at least one assertion. This makes the tests more robust, and using assert
|
Apex unit tests should include at least one assertion. This makes the tests more robust, and using assert
|
||||||
with messages provide the developer a clearer idea of what the test does.
|
with messages provide the developer a clearer idea of what the test does.
|
||||||
@ -35,8 +35,8 @@ public class Foo {
|
|||||||
<rule name="ApexUnitTestShouldNotUseSeeAllDataTrue"
|
<rule name="ApexUnitTestShouldNotUseSeeAllDataTrue"
|
||||||
since="5.5.1"
|
since="5.5.1"
|
||||||
message="Apex unit tests should not use @isTest(seeAllData = true)"
|
message="Apex unit tests should not use @isTest(seeAllData = true)"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrue"
|
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrueRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/apexunit.html#ApexUnitTestShouldNotUseSeeAllDataTrue">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_apexunit.html#apexunittestshouldnotuseseealldatatrue">
|
||||||
<description>
|
<description>
|
||||||
Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests.
|
Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests.
|
||||||
</description>
|
</description>
|
||||||
|
@ -13,7 +13,7 @@ The Braces ruleset contains rules regarding the use and placement of braces.
|
|||||||
since="5.6.0"
|
since="5.6.0"
|
||||||
message="Avoid using if statements without curly braces"
|
message="Avoid using if statements without curly braces"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#IfStmtsMustUseBraces">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#ifstmtsmustusebraces">
|
||||||
<description>
|
<description>
|
||||||
Avoid using if statements without using braces to surround the code block. If the code
|
Avoid using if statements without using braces to surround the code block. If the code
|
||||||
formatting or indentation is lost then it becomes difficult to separate the code being
|
formatting or indentation is lost then it becomes difficult to separate the code being
|
||||||
@ -23,23 +23,21 @@ controlled from the rest.
|
|||||||
<properties>
|
<properties>
|
||||||
<property name="xpath">
|
<property name="xpath">
|
||||||
<value>
|
<value>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
//IfBlockStatement/BlockStatement[@CurlyBrace='false']
|
//IfBlockStatement/BlockStatement[@CurlyBrace='false']
|
||||||
]]>
|
]]>
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
if (foo) // not recommended
|
if (foo) // not recommended
|
||||||
x++;
|
x++;
|
||||||
|
|
||||||
if (foo) { // preferred approach
|
if (foo) { // preferred approach
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
]]>
|
||||||
]]>
|
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
@ -48,7 +46,7 @@ if (foo) { // preferred approach
|
|||||||
since="5.6.0"
|
since="5.6.0"
|
||||||
message="Avoid using 'while' statements without curly braces"
|
message="Avoid using 'while' statements without curly braces"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#WhileLoopsMustUseBraces">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#whileloopsmustusebraces">
|
||||||
<description>
|
<description>
|
||||||
Avoid using 'while' statements without using braces to surround the code block. If the code
|
Avoid using 'while' statements without using braces to surround the code block. If the code
|
||||||
formatting or indentation is lost then it becomes difficult to separate the code being
|
formatting or indentation is lost then it becomes difficult to separate the code being
|
||||||
@ -81,7 +79,7 @@ while (true) { // preferred approach
|
|||||||
since="5.6.0"
|
since="5.6.0"
|
||||||
message="Avoid using 'if...else' statements without curly braces"
|
message="Avoid using 'if...else' statements without curly braces"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#IfElseStmtsMustUseBraces">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#ifelsestmtsmustusebraces">
|
||||||
<description>
|
<description>
|
||||||
Avoid using if..else statements without using surrounding braces. If the code formatting
|
Avoid using if..else statements without using surrounding braces. If the code formatting
|
||||||
or indentation is lost then it becomes difficult to separate the code being controlled
|
or indentation is lost then it becomes difficult to separate the code being controlled
|
||||||
@ -95,19 +93,19 @@ from the rest.
|
|||||||
//IfBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
|
//IfBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
|
||||||
|
|
|
|
||||||
//IfElseBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
|
//IfElseBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
|
||||||
]]>
|
]]>
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
// this is OK
|
// this is OK
|
||||||
if (foo) x++;
|
if (foo) x++;
|
||||||
|
|
||||||
// but this is not
|
// but this is not
|
||||||
if (foo)
|
if (foo)
|
||||||
x = x+1;
|
x = x+1;
|
||||||
else
|
else
|
||||||
x = x-1;
|
x = x-1;
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
@ -118,7 +116,7 @@ if (foo)
|
|||||||
since="5.6.0"
|
since="5.6.0"
|
||||||
message="Avoid using 'for' statements without curly braces"
|
message="Avoid using 'for' statements without curly braces"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#ForLoopsMustUseBraces">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#forloopsmustusebraces">
|
||||||
<description>
|
<description>
|
||||||
Avoid using 'for' statements without using surrounding braces. If the code formatting or
|
Avoid using 'for' statements without using surrounding braces. If the code formatting or
|
||||||
indentation is lost then it becomes difficult to separate the code being controlled
|
indentation is lost then it becomes difficult to separate the code being controlled
|
||||||
@ -128,11 +126,11 @@ from the rest.
|
|||||||
<properties>
|
<properties>
|
||||||
<property name="xpath">
|
<property name="xpath">
|
||||||
<value>
|
<value>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
//ForLoopStatement/BlockStatement[@CurlyBrace='false']
|
//ForLoopStatement/BlockStatement[@CurlyBrace='false']
|
||||||
|
|
|
|
||||||
//ForEachStatement/BlockStatement[@CurlyBrace='false']
|
//ForEachStatement/BlockStatement[@CurlyBrace='false']
|
||||||
]]>
|
]]>
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
|
@ -12,13 +12,14 @@ The Complexity ruleset contains rules that find problems related to code size or
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Deeply nested if..then statements are hard to read"
|
message="Deeply nested if..then statements are hard to read"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.AvoidDeeplyNestedIfStmtsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.AvoidDeeplyNestedIfStmtsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#AvoidDeeplyNestedIfStmts">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#avoiddeeplynestedifstmts">
|
||||||
<description>
|
<description>
|
||||||
Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
|
Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo {
|
<![CDATA[
|
||||||
|
public class Foo {
|
||||||
public void bar(Integer x, Integer y, Integer z) {
|
public void bar(Integer x, Integer y, Integer z) {
|
||||||
if (x>y) {
|
if (x>y) {
|
||||||
if (y>z) {
|
if (y>z) {
|
||||||
@ -37,20 +38,21 @@ Avoid creating deeply nested if-then statements since they are harder to read an
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Avoid long parameter lists."
|
message="Avoid long parameter lists."
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveParameterListRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveParameterListRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#ExcessiveParameterList">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#excessiveparameterlist">
|
||||||
<description>
|
<description>
|
||||||
Methods with numerous parameters are a challenge to maintain, especially if most of them share the
|
Methods with numerous parameters are a challenge to maintain, especially if most of them share the
|
||||||
same datatype. These situations usually denote the need for new objects to wrap the numerous parameters.
|
same datatype. These situations usually denote the need for new objects to wrap the numerous parameters.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[// too many arguments liable to be mixed up
|
<![CDATA[
|
||||||
|
// too many arguments liable to be mixed up
|
||||||
public void addPerson(int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) {
|
public void addPerson(int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
// preferred approach
|
// preferred approach
|
||||||
public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
|
public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
@ -60,7 +62,7 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Avoid really long classes."
|
message="Avoid really long classes."
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveClassLengthRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveClassLengthRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#ExcessiveClassLength">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#excessiveclasslength">
|
||||||
<description>
|
<description>
|
||||||
Excessive class file lengths are usually indications that the class may be burdened with excessive
|
Excessive class file lengths are usually indications that the class may be burdened with excessive
|
||||||
responsibilities that could be provided by external classes or functions. In breaking these methods
|
responsibilities that could be provided by external classes or functions. In breaking these methods
|
||||||
@ -68,7 +70,8 @@ apart the code becomes more managable and ripe for reuse.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo {
|
<![CDATA[
|
||||||
|
public class Foo {
|
||||||
public void bar1() {
|
public void bar1() {
|
||||||
// 1000 lines of code
|
// 1000 lines of code
|
||||||
}
|
}
|
||||||
@ -86,11 +89,11 @@ apart the code becomes more managable and ripe for reuse.
|
|||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="NcssMethodCount"
|
<rule name="NcssMethodCount"
|
||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="The method ''{0}()'' has an NCSS line count of {1}"
|
message="The method ''{0}()'' has an NCSS line count of {1}"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssMethodCountRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssMethodCountRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#NcssMethodCount">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#ncssmethodcount">
|
||||||
<description>
|
<description>
|
||||||
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
||||||
of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
||||||
@ -98,7 +101,8 @@ lines of code that are split are counted as one.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo extends Bar {
|
<![CDATA[
|
||||||
|
public class Foo extends Bar {
|
||||||
//this method only has 1 NCSS lines
|
//this method only has 1 NCSS lines
|
||||||
public Integer methd() {
|
public Integer methd() {
|
||||||
super.methd();
|
super.methd();
|
||||||
@ -112,11 +116,11 @@ lines of code that are split are counted as one.
|
|||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="NcssTypeCount"
|
<rule name="NcssTypeCount"
|
||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="The type has an NCSS line count of {0}"
|
message="The type has an NCSS line count of {0}"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssTypeCountRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssTypeCountRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#NcssTypeCount">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#ncsstypecount">
|
||||||
<description>
|
<description>
|
||||||
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
||||||
of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
||||||
@ -124,7 +128,8 @@ lines of code that are split are counted as one.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[//this class only has 6 NCSS lines
|
<![CDATA[
|
||||||
|
//this class only has 6 NCSS lines
|
||||||
public class Foo extends Bar {
|
public class Foo extends Bar {
|
||||||
public Foo() {
|
public Foo() {
|
||||||
super();
|
super();
|
||||||
@ -137,13 +142,14 @@ public class Foo extends Bar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example></rule>
|
</example>
|
||||||
|
</rule>
|
||||||
|
|
||||||
<rule name="NcssConstructorCount"
|
<rule name="NcssConstructorCount"
|
||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="The constructor has an NCSS line count of {0}"
|
message="The constructor has an NCSS line count of {0}"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssConstructorCountRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssConstructorCountRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#NcssConstructorCount">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#ncssconstructorcount">
|
||||||
<description>
|
<description>
|
||||||
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
|
||||||
of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm,
|
||||||
@ -151,7 +157,8 @@ lines of code that are split are counted as one.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo extends Bar {
|
<![CDATA[
|
||||||
|
public class Foo extends Bar {
|
||||||
//this constructor only has 1 NCSS lines
|
//this constructor only has 1 NCSS lines
|
||||||
public Foo() {
|
public Foo() {
|
||||||
super();
|
super();
|
||||||
@ -160,29 +167,28 @@ lines of code that are split are counted as one.
|
|||||||
|
|
||||||
|
|
||||||
super.foo();
|
super.foo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="StdCyclomaticComplexity"
|
<rule name="StdCyclomaticComplexity"
|
||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
|
message="The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.StdCyclomaticComplexityRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.StdCyclomaticComplexityRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#StdCyclomaticComplexity">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#stdcyclomaticcomplexity">
|
||||||
<description>
|
<description>
|
||||||
<![CDATA[
|
|
||||||
Complexity directly affects maintenance costs is determined by the number of decision points in a method
|
Complexity directly affects maintenance costs is determined by the number of decision points in a method
|
||||||
plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls.
|
plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls.
|
||||||
Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
|
Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
|
||||||
high complexity, and 11+ is very high complexity.
|
high complexity, and 11+ is very high complexity.
|
||||||
]]>
|
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[// This has a Cyclomatic Complexity = 12
|
<![CDATA[
|
||||||
public class Foo {
|
// This has a Cyclomatic Complexity = 12
|
||||||
|
public class Foo {
|
||||||
1 public void example() {
|
1 public void example() {
|
||||||
2 if (a == b || (c == d && e == f)) {
|
2 if (a == b || (c == d && e == f)) {
|
||||||
3 if (a1 == b1) {
|
3 if (a1 == b1) {
|
||||||
@ -216,8 +222,7 @@ high complexity, and 11+ is very high complexity.
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
@ -226,7 +231,7 @@ high complexity, and 11+ is very high complexity.
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Too many fields"
|
message="Too many fields"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.TooManyFieldsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.TooManyFieldsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#TooManyFields">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#toomanyfields">
|
||||||
<description>
|
<description>
|
||||||
Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields,
|
Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields,
|
||||||
possibly through grouping related fields in new objects. For example, a class with individual
|
possibly through grouping related fields in new objects. For example, a class with individual
|
||||||
@ -234,7 +239,8 @@ city/state/zip fields could park them within a single Address field.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Person {
|
<![CDATA[
|
||||||
|
public class Person {
|
||||||
// too many separate fields
|
// too many separate fields
|
||||||
int birthYear;
|
int birthYear;
|
||||||
int birthMonth;
|
int birthMonth;
|
||||||
@ -256,7 +262,7 @@ public class Person {
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="This class has a bunch of public methods and attributes"
|
message="This class has a bunch of public methods and attributes"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessivePublicCountRule"
|
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessivePublicCountRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#ExcessivePublicCount">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#excessivepubliccount">
|
||||||
<description>
|
<description>
|
||||||
Classes with large numbers of public methods and attributes require disproportionate testing efforts
|
Classes with large numbers of public methods and attributes require disproportionate testing efforts
|
||||||
since combinational side effects grow rapidly and increase risk. Refactoring these classes into
|
since combinational side effects grow rapidly and increase risk. Refactoring these classes into
|
||||||
@ -265,7 +271,8 @@ developed easily.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo {
|
<![CDATA[
|
||||||
|
public class Foo {
|
||||||
public String value;
|
public String value;
|
||||||
public Bar something;
|
public Bar something;
|
||||||
public Variable var;
|
public Variable var;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
since="6.0.0"
|
since="6.0.0"
|
||||||
class="net.sourceforge.pmd.lang.apex.metrics.rule.CyclomaticComplexityRule"
|
class="net.sourceforge.pmd.lang.apex.metrics.rule.CyclomaticComplexityRule"
|
||||||
metrics="true"
|
metrics="true"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/metrics.html#CyclomaticComplexity">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_metrics.html#cyclomaticcomplexity">
|
||||||
<description>
|
<description>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic
|
The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic
|
||||||
|
@ -12,13 +12,14 @@ The Performance ruleset contains a collection of good practices which should be
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Avoid Soql queries inside loops"
|
message="Avoid Soql queries inside loops"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidSoqlInLoopsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidSoqlInLoopsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/performance.html#AvoidSoqlInLoops">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_performance.html#avoidsoqlinloops">
|
||||||
<description>
|
<description>
|
||||||
New objects created within loops should be checked to see if they can created outside them and reused.
|
New objects created within loops should be checked to see if they can created outside them and reused.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Something {
|
<![CDATA[
|
||||||
|
public class Something {
|
||||||
public static void main( String as[] ) {
|
public static void main( String as[] ) {
|
||||||
for (Integer i = 0; i < 10; i++) {
|
for (Integer i = 0; i < 10; i++) {
|
||||||
List<Account> accounts = [SELECT Id FROM Account];
|
List<Account> accounts = [SELECT Id FROM Account];
|
||||||
@ -33,8 +34,10 @@ New objects created within loops should be checked to see if they can created ou
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Avoid DML statements inside loops"
|
message="Avoid DML statements inside loops"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidDmlStatementsInLoopsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidDmlStatementsInLoopsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/performance.html#AvoidDmlStatementsInLoops">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_performance.html#avoiddmlstatementsinloops">
|
||||||
<description>Avoid DML statements inside loops to avoid hitting the DML governor limit. Instead, try to batch up the data into a list and invoke your DML once on that list of data outside the loop.</description>
|
<description>
|
||||||
|
Avoid DML statements inside loops to avoid hitting the DML governor limit. Instead, try to batch up the data into a list and invoke your DML once on that list of data outside the loop.
|
||||||
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
@ -42,7 +45,7 @@ public class Something {
|
|||||||
public void foo() {
|
public void foo() {
|
||||||
for (Integer i = 0; i < 151; i++) {
|
for (Integer i = 0; i < 151; i++) {
|
||||||
Account account;
|
Account account;
|
||||||
...
|
// ...
|
||||||
insert account;
|
insert account;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,10 @@
|
|||||||
# BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
# BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
#
|
#
|
||||||
|
|
||||||
rulesets.filenames=rulesets/apex/complexity.xml,rulesets/apex/performance.xml,rulesets/apex/style.xml,rulesets/apex/apexunit.xml,rulesets/apex/security.xml,rulesets/apex/braces.xml
|
rulesets.filenames=\
|
||||||
|
rulesets/apex/apexunit.xml,\
|
||||||
|
rulesets/apex/braces.xml,\
|
||||||
|
rulesets/apex/complexity.xml,\
|
||||||
|
rulesets/apex/performance.xml,\
|
||||||
|
rulesets/apex/security.xml,\
|
||||||
|
rulesets/apex/style.xml
|
||||||
|
@ -3,95 +3,99 @@
|
|||||||
<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
|
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
These rules deal with different security problems that can occur within Apex.
|
These rules deal with different security problems that can occur within Apex.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<rule name="ApexSharingViolations" since="5.5.3"
|
<rule name="ApexSharingViolations"
|
||||||
|
since="5.5.3"
|
||||||
message="Apex classes should declare a sharing model if DML or SOQL/SOSL is used"
|
message="Apex classes should declare a sharing model if DML or SOQL/SOSL is used"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSharingViolationsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSharingViolationsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexSharingViolations">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexsharingviolations">
|
||||||
<description>
|
<description>
|
||||||
Detect classes declared without explicit sharing mode if DML methods are used. This
|
Detect classes declared without explicit sharing mode if DML methods are used. This
|
||||||
forces the developer to take access restrictions into account before modifying objects.
|
forces the developer to take access restrictions into account before modifying objects.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public without sharing class Foo {
|
public without sharing class Foo {
|
||||||
// DML operation here
|
// DML operation here
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexOpenRedirect" since="5.5.3"
|
<rule name="ApexOpenRedirect"
|
||||||
|
since="5.5.3"
|
||||||
message="Apex classes should safely redirect to a known location"
|
message="Apex classes should safely redirect to a known location"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexOpenRedirectRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexOpenRedirectRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexOpenRedirect">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexopenredirect">
|
||||||
<description>
|
<description>
|
||||||
Checks against redirects to user-controlled locations. This prevents attackers from
|
Checks against redirects to user-controlled locations. This prevents attackers from
|
||||||
redirecting users to phishing sites.
|
redirecting users to phishing sites.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public without sharing class Foo {
|
public without sharing class Foo {
|
||||||
String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param');
|
String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param');
|
||||||
PageReference page() {
|
PageReference page() {
|
||||||
return new PageReference(unsafeLocation);
|
return new PageReference(unsafeLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
<rule name="ApexInsecureEndpoint"
|
||||||
<rule name="ApexInsecureEndpoint" since="5.5.3"
|
since="5.5.3"
|
||||||
message="Apex callouts should use encrypted communication channels"
|
message="Apex callouts should use encrypted communication channels"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexInsecureEndpointRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexInsecureEndpointRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexInsecureEndpoint">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexinsecureendpoint">
|
||||||
<description>
|
<description>
|
||||||
Checks against accessing endpoints under plain **http**. You should always use
|
Checks against accessing endpoints under plain **http**. You should always use
|
||||||
**https** for security.
|
**https** for security.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public without sharing class Foo {
|
public without sharing class Foo {
|
||||||
void foo() {
|
void foo() {
|
||||||
HttpRequest req = new HttpRequest();
|
HttpRequest req = new HttpRequest();
|
||||||
req.setEndpoint('http://localhost:com');
|
req.setEndpoint('http://localhost:com');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexXSSFromURLParam" since="5.5.3"
|
<rule name="ApexXSSFromURLParam"
|
||||||
|
since="5.5.3"
|
||||||
message="Apex classes should escape/sanitize Strings obtained from URL parameters"
|
message="Apex classes should escape/sanitize Strings obtained from URL parameters"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromURLParamRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromURLParamRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexXSSFromURLParam">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexxssfromurlparam">
|
||||||
<description>
|
<description>
|
||||||
Makes sure that all values obtained from URL parameters are properly escaped / sanitized
|
Makes sure that all values obtained from URL parameters are properly escaped / sanitized
|
||||||
to avoid XSS attacks.
|
to avoid XSS attacks.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public without sharing class Foo {
|
public without sharing class Foo {
|
||||||
String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param');
|
String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param');
|
||||||
String usedLater = unescapedstring;
|
String usedLater = unescapedstring;
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
<rule name="ApexXSSFromEscapeFalse"
|
||||||
<rule name="ApexXSSFromEscapeFalse" since="5.5.3"
|
since="5.5.3"
|
||||||
message="Apex classes should escape Strings in error messages"
|
message="Apex classes should escape Strings in error messages"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromEscapeFalseRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromEscapeFalseRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexXSSFromEscapeFalse">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexxssfromescapefalse">
|
||||||
<description>
|
<description>
|
||||||
Reports on calls to `addError` with disabled escaping. The message passed to `addError`
|
Reports on calls to `addError` with disabled escaping. The message passed to `addError`
|
||||||
will be displayed directly to the user in the UI, making it prime ground for XSS
|
will be displayed directly to the user in the UI, making it prime ground for XSS
|
||||||
@ -99,47 +103,48 @@ attacks if unescaped.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public without sharing class Foo {
|
public without sharing class Foo {
|
||||||
Trigger.new[0].addError(vulnerableHTMLGoesHere, false);
|
Trigger.new[0].addError(vulnerableHTMLGoesHere, false);
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexBadCrypto" since="5.5.3"
|
<rule name="ApexBadCrypto"
|
||||||
|
since="5.5.3"
|
||||||
message="Apex classes should use random IV/key"
|
message="Apex classes should use random IV/key"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexBadCryptoRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexBadCryptoRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexBadCrypto">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexbadcrypto">
|
||||||
<description>
|
<description>
|
||||||
The rule makes sure you are using randomly generated IVs and keys for `Crypto` calls.
|
The rule makes sure you are using randomly generated IVs and keys for `Crypto` calls.
|
||||||
Hard-wiring these values greatly compromises the security of encrypted data.
|
Hard-wiring these values greatly compromises the security of encrypted data.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public without sharing class Foo {
|
public without sharing class Foo {
|
||||||
Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123');
|
Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123');
|
||||||
Blob hardCodedKey = Blob.valueOf('0000000000000000');
|
Blob hardCodedKey = Blob.valueOf('0000000000000000');
|
||||||
Blob data = Blob.valueOf('Data to be encrypted');
|
Blob data = Blob.valueOf('Data to be encrypted');
|
||||||
Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data);
|
Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data);
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
<rule name="ApexCSRF"
|
||||||
<rule name="ApexCSRF" since="5.5.3"
|
since="5.5.3"
|
||||||
message="Avoid making DML operations in Apex class constructor/init method"
|
message="Avoid making DML operations in Apex class constructor/init method"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCSRFRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCSRFRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexCSRF">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexcsrf">
|
||||||
<description>
|
<description>
|
||||||
Check to avoid making DML operations in Apex class constructor/init method. This prevents
|
Check to avoid making DML operations in Apex class constructor/init method. This prevents
|
||||||
modification of the database just by accessing a page.
|
modification of the database just by accessing a page.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public class Foo {
|
public class Foo {
|
||||||
public init() {
|
public init() {
|
||||||
insert data;
|
insert data;
|
||||||
@ -149,33 +154,35 @@ public class Foo {
|
|||||||
insert data;
|
insert data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexSOQLInjection" since="5.5.3"
|
<rule name="ApexSOQLInjection"
|
||||||
|
since="5.5.3"
|
||||||
message="Avoid untrusted/unescaped variables in DML query"
|
message="Avoid untrusted/unescaped variables in DML query"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSOQLInjectionRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSOQLInjectionRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexSOQLInjection">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexsoqlinjection">
|
||||||
<description>
|
<description>
|
||||||
Detects the usage of untrusted / unescaped variables in DML queries.
|
Detects the usage of untrusted / unescaped variables in DML queries.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public class Foo {
|
public class Foo {
|
||||||
public void test1(String t1) {
|
public void test1(String t1) {
|
||||||
Database.query('SELECT Id FROM Account' + t1);
|
Database.query('SELECT Id FROM Account' + t1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexCRUDViolation" since="5.5.3"
|
<rule name="ApexCRUDViolation"
|
||||||
|
since="5.5.3"
|
||||||
message="Validate CRUD permission before SOQL/DML operation"
|
message="Validate CRUD permission before SOQL/DML operation"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCRUDViolationRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCRUDViolationRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexCRUDViolationRule">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexcrudviolation">
|
||||||
<description>
|
<description>
|
||||||
The rule validates you are checking for access permissions before a SOQL/SOSL/DML operation.
|
The rule validates you are checking for access permissions before a SOQL/SOSL/DML operation.
|
||||||
Since Apex runs in system mode not having proper permissions checks results in escalation of
|
Since Apex runs in system mode not having proper permissions checks results in escalation of
|
||||||
@ -183,7 +190,7 @@ privilege and may produce runtime errors. This check forces you to handle such s
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public class Foo {
|
public class Foo {
|
||||||
public Contact foo(String status, String ID) {
|
public Contact foo(String status, String ID) {
|
||||||
Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID];
|
Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID];
|
||||||
@ -198,14 +205,15 @@ public class Foo {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexDangerousMethods" since="5.5.3"
|
<rule name="ApexDangerousMethods"
|
||||||
|
since="5.5.3"
|
||||||
message="Calling potentially dangerous method"
|
message="Calling potentially dangerous method"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexDangerousMethodsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexDangerousMethodsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexDangerousMethodsRule">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexdangerousmethods">
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
Checks against calling dangerous methods.
|
Checks against calling dangerous methods.
|
||||||
|
|
||||||
@ -215,23 +223,25 @@ For the time being, it reports:
|
|||||||
opens the door to several attacks and requires manual validation, which is unreliable.
|
opens the door to several attacks and requires manual validation, which is unreliable.
|
||||||
* Calling `System.debug` passing sensitive data as parameter, which could lead to exposure
|
* Calling `System.debug` passing sensitive data as parameter, which could lead to exposure
|
||||||
of private data.
|
of private data.
|
||||||
]]></description>
|
]]>
|
||||||
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public class Foo {
|
public class Foo {
|
||||||
public Foo() {
|
public Foo() {
|
||||||
Configuration.disableTriggerCRUDSecurity();
|
Configuration.disableTriggerCRUDSecurity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule name="ApexSuggestUsingNamedCred" since="5.5.3"
|
<rule name="ApexSuggestUsingNamedCred"
|
||||||
|
since="5.5.3"
|
||||||
message="Suggest named credentials for authentication"
|
message="Suggest named credentials for authentication"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSuggestUsingNamedCredRule"
|
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSuggestUsingNamedCredRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexSuggestUsingNamedCredRule">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexsuggestusingnamedcred">
|
||||||
<description><
|
For more information, you can check [this](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials.htm)
|
||||||
]]></description>
|
]]>
|
||||||
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
public class Foo {
|
public class Foo {
|
||||||
public void foo(String username, String password) {
|
public void foo(String username, String password) {
|
||||||
Blob headerValue = Blob.valueOf(username + ':' + password);
|
Blob headerValue = Blob.valueOf(username + ':' + password);
|
||||||
@ -261,5 +272,4 @@ public class Foo {
|
|||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
</ruleset>
|
</ruleset>
|
||||||
|
@ -12,7 +12,7 @@ The Style Ruleset contains rules regarding preferred usage of names and identifi
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="{0} variable {1} should begin with {2}"
|
message="{0} variable {1} should begin with {2}"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.style.VariableNamingConventionsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.style.VariableNamingConventionsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#VariableNamingConventions">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#variablenamingconventions">
|
||||||
<description>
|
<description>
|
||||||
A variable naming conventions rule - customize this to your liking. Currently, it
|
A variable naming conventions rule - customize this to your liking. Currently, it
|
||||||
checks for final variables that should be fully capitalized and non-final variables
|
checks for final variables that should be fully capitalized and non-final variables
|
||||||
@ -20,7 +20,8 @@ that should not include underscores.
|
|||||||
</description>
|
</description>
|
||||||
<priority>1</priority>
|
<priority>1</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo {
|
<![CDATA[
|
||||||
|
public class Foo {
|
||||||
public static final Integer MY_NUM = 0;
|
public static final Integer MY_NUM = 0;
|
||||||
public String myTest = '';
|
public String myTest = '';
|
||||||
DataModule dmTest = new DataModule();
|
DataModule dmTest = new DataModule();
|
||||||
@ -33,13 +34,14 @@ that should not include underscores.
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Method name does not begin with a lower case character."
|
message="Method name does not begin with a lower case character."
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.style.MethodNamingConventionsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.style.MethodNamingConventionsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#MethodNamingConventions">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#methodnamingconventions">
|
||||||
<description>
|
<description>
|
||||||
Method names should always begin with a lower case character, and should not contain underscores.
|
Method names should always begin with a lower case character, and should not contain underscores.
|
||||||
</description>
|
</description>
|
||||||
<priority>1</priority>
|
<priority>1</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo {
|
<![CDATA[
|
||||||
|
public class Foo {
|
||||||
public void fooStuff() {
|
public void fooStuff() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,13 +53,14 @@ Method names should always begin with a lower case character, and should not con
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Class names should begin with an uppercase character"
|
message="Class names should begin with an uppercase character"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.style.ClassNamingConventionsRule"
|
class="net.sourceforge.pmd.lang.apex.rule.style.ClassNamingConventionsRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#ClassNamingConventions">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#classnamingconventions">
|
||||||
<description>
|
<description>
|
||||||
Class names should always begin with an upper case character.
|
Class names should always begin with an upper case character.
|
||||||
</description>
|
</description>
|
||||||
<priority>1</priority>
|
<priority>1</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class Foo {}
|
<![CDATA[
|
||||||
|
public class Foo {}
|
||||||
]]>
|
]]>
|
||||||
</example>
|
</example>
|
||||||
</rule>
|
</rule>
|
||||||
@ -66,13 +69,14 @@ Class names should always begin with an upper case character.
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Classes should not have non-constructor methods with the same name as the class"
|
message="Classes should not have non-constructor methods with the same name as the class"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.style.MethodWithSameNameAsEnclosingClassRule"
|
class="net.sourceforge.pmd.lang.apex.rule.style.MethodWithSameNameAsEnclosingClassRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#MethodWithSameNameAsEnclosingClass">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#methodwithsamenameasenclosingclass">
|
||||||
<description>
|
<description>
|
||||||
Non-constructor methods should not have the same name as the enclosing class.
|
Non-constructor methods should not have the same name as the enclosing class.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[public class MyClass {
|
<![CDATA[
|
||||||
|
public class MyClass {
|
||||||
// this is OK because it is a constructor
|
// this is OK because it is a constructor
|
||||||
public MyClass() {}
|
public MyClass() {}
|
||||||
// this is bad because it is a method
|
// this is bad because it is a method
|
||||||
@ -86,7 +90,7 @@ Non-constructor methods should not have the same name as the enclosing class.
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Avoid logic in triggers"
|
message="Avoid logic in triggers"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.style.AvoidLogicInTriggerRule"
|
class="net.sourceforge.pmd.lang.apex.rule.style.AvoidLogicInTriggerRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#AvoidLogicInTrigger">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#avoidlogicintrigger">
|
||||||
<description>
|
<description>
|
||||||
As triggers do not allow methods like regular classes they are less flexible and suited to apply good encapsulation style.
|
As triggers do not allow methods like regular classes they are less flexible and suited to apply good encapsulation style.
|
||||||
Therefore delegate the triggers work to a regular class (often called Trigger handler class).
|
Therefore delegate the triggers work to a regular class (often called Trigger handler class).
|
||||||
@ -95,16 +99,17 @@ See more here: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[trigger Accounts on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
|
<![CDATA[
|
||||||
|
trigger Accounts on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
|
||||||
for(Account acc : Trigger.new) {
|
for(Account acc : Trigger.new) {
|
||||||
if(Trigger.isInsert) {
|
if(Trigger.isInsert) {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
...
|
// ...
|
||||||
|
|
||||||
if(Trigger.isDelete) {
|
if(Trigger.isDelete) {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,14 +121,15 @@ See more here: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex
|
|||||||
since="5.5.0"
|
since="5.5.0"
|
||||||
message="Avoid using global modifier"
|
message="Avoid using global modifier"
|
||||||
class="net.sourceforge.pmd.lang.apex.rule.style.AvoidGlobalModifierRule"
|
class="net.sourceforge.pmd.lang.apex.rule.style.AvoidGlobalModifierRule"
|
||||||
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#AvoidGlobalModifier">
|
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#avoidglobalmodifier">
|
||||||
<description>
|
<description>
|
||||||
Global classes should be avoided (especially in managed packages) as they can never be deleted or changed in signature. Always check twice if something needs to be global.
|
Global classes should be avoided (especially in managed packages) as they can never be deleted or changed in signature. Always check twice if something needs to be global.
|
||||||
Many interfaces (e.g. Batch) required global modifiers in the past but don't require this anymore. Don't lock yourself in.
|
Many interfaces (e.g. Batch) required global modifiers in the past but don't require this anymore. Don't lock yourself in.
|
||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<example>
|
<example>
|
||||||
<![CDATA[global class Unchangeable {
|
<![CDATA[
|
||||||
|
global class Unchangeable {
|
||||||
global UndeletableType unchangable(UndeletableType param) {
|
global UndeletableType unchangable(UndeletableType param) {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.sourceforge.pmd.lang.apex;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.AbstractRuleSetFactoryTest;
|
||||||
|
import net.sourceforge.pmd.lang.apex.rule.ApexXPathRule;
|
||||||
|
|
||||||
|
public class RuleSetFactoryTest extends AbstractRuleSetFactoryTest {
|
||||||
|
public RuleSetFactoryTest() {
|
||||||
|
super();
|
||||||
|
validXPathClassNames.add(ApexXPathRule.class.getName());
|
||||||
|
}
|
||||||
|
}
|
@ -17,10 +17,13 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.parsers.SAXParser;
|
import javax.xml.parsers.SAXParser;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
@ -49,6 +52,12 @@ public abstract class AbstractRuleSetFactoryTest {
|
|||||||
private static ValidateDefaultHandler validateDefaultHandlerDtd;
|
private static ValidateDefaultHandler validateDefaultHandlerDtd;
|
||||||
private static SAXParser saxParser;
|
private static SAXParser saxParser;
|
||||||
|
|
||||||
|
protected Set<String> validXPathClassNames = new HashSet<>();
|
||||||
|
|
||||||
|
public AbstractRuleSetFactoryTest() {
|
||||||
|
validXPathClassNames.add(XPathRule.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setups the XML parser with validation.
|
* Setups the XML parser with validation.
|
||||||
*
|
*
|
||||||
@ -134,7 +143,7 @@ public abstract class AbstractRuleSetFactoryTest {
|
|||||||
String expectedClassName = "net.sourceforge.pmd.lang." + language.getTerseName() + ".rule." + group
|
String expectedClassName = "net.sourceforge.pmd.lang." + language.getTerseName() + ".rule." + group
|
||||||
+ "." + rule.getName() + "Rule";
|
+ "." + rule.getName() + "Rule";
|
||||||
if (!rule.getRuleClass().equals(expectedClassName)
|
if (!rule.getRuleClass().equals(expectedClassName)
|
||||||
&& !rule.getRuleClass().equals(XPathRule.class.getName())) {
|
&& !validXPathClassNames.contains(rule.getRuleClass())) {
|
||||||
invalidClassName++;
|
invalidClassName++;
|
||||||
messages += "Rule " + fileName + "/" + rule.getName() + " seems to have an invalid 'class' value ("
|
messages += "Rule " + fileName + "/" + rule.getName() + " seems to have an invalid 'class' value ("
|
||||||
+ rule.getRuleClass() + "), it should be:" + expectedClassName + PMD.EOL;
|
+ rule.getRuleClass() + "), it should be:" + expectedClassName + PMD.EOL;
|
||||||
|
Reference in New Issue
Block a user