[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:
Andreas Dangel
2017-08-14 21:18:27 +02:00
parent 1aaf52f0b0
commit cfa4e15d54
12 changed files with 605 additions and 551 deletions

View File

@ -20,7 +20,7 @@ import net.sourceforge.pmd.lang.apex.ast.ApexNode;
*
* @author a.subramanian
*/
public class ApexUnitTestClassShouldHaveAsserts extends AbstractApexUnitTestRule {
public class ApexUnitTestClassShouldHaveAssertsRule extends AbstractApexUnitTestRule {
private static final Set<String> ASSERT_METHODS = new HashSet<>();

View File

@ -25,7 +25,7 @@ import apex.jorje.services.Version;
*
* @author a.subramanian
*/
public class ApexUnitTestShouldNotUseSeeAllDataTrue extends AbstractApexUnitTestRule {
public class ApexUnitTestShouldNotUseSeeAllDataTrueRule extends AbstractApexUnitTestRule {
@Override
public Object visit(final ASTUserClass node, final Object data) {

View File

@ -11,8 +11,8 @@
<rule name="ApexUnitTestClassShouldHaveAsserts"
since="5.5.1"
message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()"
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAsserts"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/apexunit.html#ApexUnitTestClassShouldHaveAsserts">
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAssertsRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_apexunit.html#apexunittestclassshouldhaveasserts">
<description>
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.
@ -35,8 +35,8 @@ public class Foo {
<rule name="ApexUnitTestShouldNotUseSeeAllDataTrue"
since="5.5.1"
message="Apex unit tests should not use @isTest(seeAllData = true)"
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrue"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/apexunit.html#ApexUnitTestShouldNotUseSeeAllDataTrue">
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrueRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_apexunit.html#apexunittestshouldnotuseseealldatatrue">
<description>
Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests.
</description>

View File

@ -13,7 +13,7 @@ The Braces ruleset contains rules regarding the use and placement of braces.
since="5.6.0"
message="Avoid using if statements without curly braces"
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>
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
@ -23,23 +23,21 @@ controlled from the rest.
<properties>
<property name="xpath">
<value>
<![CDATA[
<![CDATA[
//IfBlockStatement/BlockStatement[@CurlyBrace='false']
]]>
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
if (foo) // not recommended
x++;
if (foo) { // preferred approach
x++;
}
]]>
]]>
</example>
</rule>
@ -48,7 +46,7 @@ if (foo) { // preferred approach
since="5.6.0"
message="Avoid using 'while' statements without curly braces"
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>
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
@ -81,7 +79,7 @@ while (true) { // preferred approach
since="5.6.0"
message="Avoid using 'if...else' statements without curly braces"
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>
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
@ -95,19 +93,19 @@ from the rest.
//IfBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
|
//IfElseBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
]]>
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// this is OK
// this is OK
if (foo) x++;
// but this is not
// but this is not
if (foo)
x = x+1;
else
else
x = x-1;
]]>
</example>
@ -118,7 +116,7 @@ if (foo)
since="5.6.0"
message="Avoid using 'for' statements without curly braces"
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>
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
@ -128,11 +126,11 @@ from the rest.
<properties>
<property name="xpath">
<value>
<![CDATA[
<![CDATA[
//ForLoopStatement/BlockStatement[@CurlyBrace='false']
|
//ForEachStatement/BlockStatement[@CurlyBrace='false']
]]>
]]>
</value>
</property>
</properties>

View File

@ -12,13 +12,14 @@ The Complexity ruleset contains rules that find problems related to code size or
since="5.5.0"
message="Deeply nested if..then statements are hard to read"
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>
Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Foo {
<![CDATA[
public class Foo {
public void bar(Integer x, Integer y, Integer z) {
if (x>y) {
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"
message="Avoid long parameter lists."
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>
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.
</description>
<priority>3</priority>
<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) {
...
// ...
}
// preferred approach
public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
...
// ...
}
]]>
</example>
@ -60,7 +62,7 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
since="5.5.0"
message="Avoid really long classes."
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>
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
@ -68,7 +70,8 @@ apart the code becomes more managable and ripe for reuse.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Foo {
<![CDATA[
public class Foo {
public void bar1() {
// 1000 lines of code
}
@ -86,11 +89,11 @@ apart the code becomes more managable and ripe for reuse.
</example>
</rule>
<rule name="NcssMethodCount"
<rule name="NcssMethodCount"
since="5.5.0"
message="The method ''{0}()'' has an NCSS line count of {1}"
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>
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,
@ -98,7 +101,8 @@ lines of code that are split are counted as one.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Foo extends Bar {
<![CDATA[
public class Foo extends Bar {
//this method only has 1 NCSS lines
public Integer methd() {
super.methd();
@ -112,11 +116,11 @@ lines of code that are split are counted as one.
</example>
</rule>
<rule name="NcssTypeCount"
<rule name="NcssTypeCount"
since="5.5.0"
message="The type has an NCSS line count of {0}"
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>
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,
@ -124,7 +128,8 @@ lines of code that are split are counted as one.
</description>
<priority>3</priority>
<example>
<![CDATA[//this class only has 6 NCSS lines
<![CDATA[
//this class only has 6 NCSS lines
public class Foo extends Bar {
public Foo() {
super();
@ -137,13 +142,14 @@ public class Foo extends Bar {
}
}
]]>
</example></rule>
</example>
</rule>
<rule name="NcssConstructorCount"
<rule name="NcssConstructorCount"
since="5.5.0"
message="The constructor has an NCSS line count of {0}"
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>
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,
@ -151,7 +157,8 @@ lines of code that are split are counted as one.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Foo extends Bar {
<![CDATA[
public class Foo extends Bar {
//this constructor only has 1 NCSS lines
public Foo() {
super();
@ -160,29 +167,28 @@ lines of code that are split are counted as one.
super.foo();
}
}
}
]]>
</example>
</rule>
</rule>
<rule name="StdCyclomaticComplexity"
since="5.5.0"
message="The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
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>
<![CDATA[
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.
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.
]]>
</description>
<priority>3</priority>
<example>
<![CDATA[// This has a Cyclomatic Complexity = 12
public class Foo {
<![CDATA[
// This has a Cyclomatic Complexity = 12
public class Foo {
1 public void example() {
2 if (a == b || (c == d && e == f)) {
3 if (a1 == b1) {
@ -216,8 +222,7 @@ high complexity, and 11+ is very high complexity.
break;
}
}
}
}
}
]]>
</example>
</rule>
@ -226,7 +231,7 @@ high complexity, and 11+ is very high complexity.
since="5.5.0"
message="Too many fields"
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>
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
@ -234,7 +239,8 @@ city/state/zip fields could park them within a single Address field.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Person {
<![CDATA[
public class Person {
// too many separate fields
int birthYear;
int birthMonth;
@ -256,7 +262,7 @@ public class Person {
since="5.5.0"
message="This class has a bunch of public methods and attributes"
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>
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
@ -265,7 +271,8 @@ developed easily.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Foo {
<![CDATA[
public class Foo {
public String value;
public Bar something;
public Variable var;

View File

@ -14,7 +14,7 @@
since="6.0.0"
class="net.sourceforge.pmd.lang.apex.metrics.rule.CyclomaticComplexityRule"
metrics="true"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/metrics.html#CyclomaticComplexity">
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_metrics.html#cyclomaticcomplexity">
<description>
<![CDATA[
The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic

View File

@ -12,13 +12,14 @@ The Performance ruleset contains a collection of good practices which should be
since="5.5.0"
message="Avoid Soql queries inside loops"
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>
New objects created within loops should be checked to see if they can created outside them and reused.
</description>
<priority>3</priority>
<example>
<![CDATA[public class Something {
<![CDATA[
public class Something {
public static void main( String as[] ) {
for (Integer i = 0; i < 10; i++) {
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"
message="Avoid DML statements inside loops"
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidDmlStatementsInLoopsRule"
externalInfoUrl="${pmd.website.baseurl}/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>
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>
<priority>3</priority>
<example>
<![CDATA[
@ -42,7 +45,7 @@ public class Something {
public void foo() {
for (Integer i = 0; i < 151; i++) {
Account account;
...
// ...
insert account;
}
}

View File

@ -2,4 +2,10 @@
# 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

View File

@ -3,95 +3,99 @@
<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
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">
<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>
<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"
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>
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.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public without sharing class Foo {
// DML operation here
// DML operation here
}
]]>
]]>
</example>
</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"
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>
Checks against redirects to user-controlled locations. This prevents attackers from
redirecting users to phishing sites.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public without sharing class Foo {
String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param');
PageReference page() {
return new PageReference(unsafeLocation);
}
}
]]>
]]>
</example>
</rule>
<rule name="ApexInsecureEndpoint" since="5.5.3"
<rule name="ApexInsecureEndpoint"
since="5.5.3"
message="Apex callouts should use encrypted communication channels"
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>
Checks against accessing endpoints under plain **http**. You should always use
**https** for security.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public without sharing class Foo {
void foo() {
HttpRequest req = new HttpRequest();
req.setEndpoint('http://localhost:com');
}
}
]]>
]]>
</example>
</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"
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>
Makes sure that all values obtained from URL parameters are properly escaped / sanitized
to avoid XSS attacks.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public without sharing class Foo {
String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param');
String usedLater = unescapedstring;
}
]]>
]]>
</example>
</rule>
<rule name="ApexXSSFromEscapeFalse" since="5.5.3"
<rule name="ApexXSSFromEscapeFalse"
since="5.5.3"
message="Apex classes should escape Strings in error messages"
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>
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
@ -99,47 +103,48 @@ attacks if unescaped.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public without sharing class Foo {
Trigger.new[0].addError(vulnerableHTMLGoesHere, false);
}
]]>
]]>
</example>
</rule>
<rule name="ApexBadCrypto" since="5.5.3"
<rule name="ApexBadCrypto"
since="5.5.3"
message="Apex classes should use random IV/key"
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>
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.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public without sharing class Foo {
Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123');
Blob hardCodedKey = Blob.valueOf('0000000000000000');
Blob data = Blob.valueOf('Data to be encrypted');
Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data);
}
]]>
]]>
</example>
</rule>
<rule name="ApexCSRF" since="5.5.3"
<rule name="ApexCSRF"
since="5.5.3"
message="Avoid making DML operations in Apex class constructor/init method"
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>
Check to avoid making DML operations in Apex class constructor/init method. This prevents
modification of the database just by accessing a page.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public class Foo {
public init() {
insert data;
@ -149,33 +154,35 @@ public class Foo {
insert data;
}
}
]]>
]]>
</example>
</rule>
<rule name="ApexSOQLInjection" since="5.5.3"
<rule name="ApexSOQLInjection"
since="5.5.3"
message="Avoid untrusted/unescaped variables in DML query"
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>
Detects the usage of untrusted / unescaped variables in DML queries.
Detects the usage of untrusted / unescaped variables in DML queries.
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public class Foo {
public void test1(String t1) {
Database.query('SELECT Id FROM Account' + t1);
}
}
]]>
]]>
</example>
</rule>
<rule name="ApexCRUDViolation" since="5.5.3"
<rule name="ApexCRUDViolation"
since="5.5.3"
message="Validate CRUD permission before SOQL/DML operation"
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>
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
@ -183,7 +190,7 @@ privilege and may produce runtime errors. This check forces you to handle such s
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public class Foo {
public Contact foo(String status, String ID) {
Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID];
@ -198,14 +205,15 @@ public class Foo {
return c;
}
}
]]>
]]>
</example>
</rule>
<rule name="ApexDangerousMethods" since="5.5.3"
<rule name="ApexDangerousMethods"
since="5.5.3"
message="Calling potentially dangerous method"
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[
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.
* Calling `System.debug` passing sensitive data as parameter, which could lead to exposure
of private data.
]]></description>
]]>
</description>
<priority>3</priority>
<example>
<![CDATA[
<![CDATA[
public class Foo {
public Foo() {
Configuration.disableTriggerCRUDSecurity();
}
}
]]>
]]>
</example>
</rule>
<rule name="ApexSuggestUsingNamedCred" since="5.5.3"
<rule name="ApexSuggestUsingNamedCred"
since="5.5.3"
message="Suggest named credentials for authentication"
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><![CDATA[
Detects hardcoded credentials used in requests to an endpoint.
@ -246,10 +256,11 @@ You should refrain from hardcoding credentials:
Instead, you should use *Named Credentials* and a callout endpoint.
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>
<example>
<![CDATA[
<![CDATA[
public class Foo {
public void foo(String username, String password) {
Blob headerValue = Blob.valueOf(username + ':' + password);
@ -261,5 +272,4 @@ public class Foo {
</example>
</rule>
</ruleset>

View File

@ -12,7 +12,7 @@ The Style Ruleset contains rules regarding preferred usage of names and identifi
since="5.5.0"
message="{0} variable {1} should begin with {2}"
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>
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
@ -20,7 +20,8 @@ that should not include underscores.
</description>
<priority>1</priority>
<example>
<![CDATA[public class Foo {
<![CDATA[
public class Foo {
public static final Integer MY_NUM = 0;
public String myTest = '';
DataModule dmTest = new DataModule();
@ -33,13 +34,14 @@ that should not include underscores.
since="5.5.0"
message="Method name does not begin with a lower case character."
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>
Method names should always begin with a lower case character, and should not contain underscores.
</description>
<priority>1</priority>
<example>
<![CDATA[public class Foo {
<![CDATA[
public class Foo {
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"
message="Class names should begin with an uppercase character"
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>
Class names should always begin with an upper case character.
</description>
<priority>1</priority>
<example>
<![CDATA[public class Foo {}
<![CDATA[
public class Foo {}
]]>
</example>
</rule>
@ -66,13 +69,14 @@ Class names should always begin with an upper case character.
since="5.5.0"
message="Classes should not have non-constructor methods with the same name as the class"
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>
Non-constructor methods should not have the same name as the enclosing class.
</description>
<priority>3</priority>
<example>
<![CDATA[public class MyClass {
<![CDATA[
public class MyClass {
// this is OK because it is a constructor
public MyClass() {}
// 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"
message="Avoid logic in triggers"
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>
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).
@ -95,16 +99,17 @@ See more here: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex
</description>
<priority>3</priority>
<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) {
if(Trigger.isInsert) {
...
// ...
}
...
// ...
if(Trigger.isDelete) {
...
// ...
}
}
}
@ -116,14 +121,15 @@ See more here: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex
since="5.5.0"
message="Avoid using global modifier"
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>
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.
</description>
<priority>3</priority>
<example>
<![CDATA[global class Unchangeable {
<![CDATA[
global class Unchangeable {
global UndeletableType unchangable(UndeletableType param) {
// ...
}

View File

@ -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());
}
}

View File

@ -17,10 +17,13 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
@ -49,6 +52,12 @@ public abstract class AbstractRuleSetFactoryTest {
private static ValidateDefaultHandler validateDefaultHandlerDtd;
private static SAXParser saxParser;
protected Set<String> validXPathClassNames = new HashSet<>();
public AbstractRuleSetFactoryTest() {
validXPathClassNames.add(XPathRule.class.getName());
}
/**
* Setups the XML parser with validation.
*
@ -134,7 +143,7 @@ public abstract class AbstractRuleSetFactoryTest {
String expectedClassName = "net.sourceforge.pmd.lang." + language.getTerseName() + ".rule." + group
+ "." + rule.getName() + "Rule";
if (!rule.getRuleClass().equals(expectedClassName)
&& !rule.getRuleClass().equals(XPathRule.class.getName())) {
&& !validXPathClassNames.contains(rule.getRuleClass())) {
invalidClassName++;
messages += "Rule " + fileName + "/" + rule.getName() + " seems to have an invalid 'class' value ("
+ rule.getRuleClass() + "), it should be:" + expectedClassName + PMD.EOL;