Verify #1485 Analysis of some apex classes cause a stackoverflow error

This commit is contained in:
Andreas Dangel
2016-05-20 20:10:01 +02:00
parent 426427e9f3
commit 501ef71e70
2 changed files with 163 additions and 11 deletions

View File

@@ -13,6 +13,7 @@ import java.io.StringWriter;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
@@ -94,21 +95,43 @@ public class ApexParserTest {
}
@Test
public void parsesRealWorldClasses() {
try {
File directory = new File("src/test/resources");
File[] fList = directory.listFiles();
public void parsesRealWorldClasses() throws Exception {
File directory = new File("src/test/resources");
File[] fList = directory.listFiles();
for (File file : fList) {
if (file.isFile() && file.getName().endsWith(".cls")) {
String sourceCode = FileUtils.readFileToString(file);
ApexNode<Compilation> rootNode = parse(sourceCode);
}
for (File file : fList) {
if (file.isFile() && file.getName().endsWith(".cls")) {
String sourceCode = FileUtils.readFileToString(file);
ApexNode<Compilation> rootNode = parse(sourceCode);
Assert.assertNotNull(rootNode);
}
} catch (IOException e) {
Assert.fail();
}
}
/**
* See bug #1485
* @see <a href="https://sourceforge.net/p/pmd/bugs/1485/">#1485</a>
*/
@Test
public void stackOverflowDuringClassParsing() throws Exception {
String source = IOUtils.toString(ApexParserTest.class.getResourceAsStream("StackOverflowClass.cls"));
ApexNode<Compilation> rootNode = parse(source);
Assert.assertNotNull(rootNode);
int count = visitPosition(rootNode, 0);
System.out.println("Nodes visited: " + count);
}
private int visitPosition(Node node, int count) {
int result = count + 1;
Assert.assertTrue(node.getBeginLine() > 0);
Assert.assertTrue(node.getBeginColumn() > 0);
Assert.assertTrue(node.getEndLine() > 0);
Assert.assertTrue(node.getEndColumn() > 0);
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
result = visitPosition(node.jjtGetChild(i), result);
}
return result;
}
// TEST HELPER

View File

@@ -0,0 +1,129 @@
public class SomeClass {
public static boolean field1 = false;
public static boolean field2 = false;
public static boolean field3 = false;
public static boolean field4 = false;
public static void onBeforeInsert(List<Object1__c> object1List){
onBeforeInsert_update1(object1List);
onBeforeInsert_update2(object1List);
}
public static void onAfterInsert(Map<Id, Object1__c> object1Map){
onAfterInsert_postSomething();
}
public static void onBeforeUpdate(Map<Id, Object1__c> oldObject1Map, Map<Id, Object1__c> newObject1Map){
onBeforeUpdate_update3(newObject1Map.values());
onBeforeUpdate_update4(newObject1Map.values());
}
public static void onAfterUpdate(Map<Id, Object1__c> oldObject1Map, Map<Id, Object1__c> newObject1Map){
onAfterUpdate_postSomething();
}
//----------- PRIVATE METHOD ----------
private static Set<Id> objectIds;
private static List<Item> itemList;
private static List<Object1__c> List1;
private static List<Object1__c> List2;
private static void onBeforeInsert_update2(List<Object1__c> object1List){
for(Object1__c object1 : object1List){
String s = Something.getSomething(object1.Name);
if((String)object1.get(s) != null){
object1.txt_ParentId__c = (String)object1.get(s);
}
}
}
private static void onBeforeInsert_update1(List<Object1__c> object1List){
updateSomething(object1List);
}
private static void onBeforeUpdate_update3(List<Object1__c> object1List){
for(Object1__c object1 : object1List){
String s = Something.getSomething(object1.Name);
if((String)object1.get(s) != null){
object1.txt_ParentId__c = (String)object1.get(s);
}
}
}
private static void onBeforeUpdate_update4(List<Object1__c> object1List){
updateSomething(object1List);
}
private static void onAfterInsert_postSomething(){
itemList = new List<Item>();
itemToSomething1();
itemToSomething2();
insert itemList;
}
private static void onAfterUpdate_postSomething(){
itemList = new List<Item>();
itemToSomething1();
itemToSomething2();
insert itemList;
}
//-------------- HELPER FUNCTION -----------------
private static void itemToSomething1(){
if(!List1.isEmpty()){
Map<Id, Object1__c> object1Map = new Map<Id, Object1__c>([SELECT Id, Name
FROM Object1__c
WHERE someId in: objectIds]);
for(Object1__c object1 : List1){
if(object1Map.get(object1.Id).Id != null && object1.Text != null){
Item post = new Item();
post.ParentId = object1Map.get(object1.Id).Id;
post.Body = "Something";
itemList.add(post);
}
}
}
}
private static void itemToSomething2(){
if(!List2.isEmpty()){
for(Object1__c object1 : List2){
if(object1.Text != null && object1.Id != null){
Item post = new Item();
post.ParentId = object1.Id;
post.Body = "Something";
itemList.add(post);
}
}
}
}
private static void updateSomething(List<Object1__c> object1List){
objectIds = new Set<Id>();
List1 = new List<Object1__c>();
List2 = new List<Object1__c>();
for(Object1__c object1 : object1List){
if(object1.isSomething && object1.Text != null){
objectIds.add(object1.Text);
List1.add(object1);
object1.isTrue = false;
object1.Date = System.now();
}
if(object1.isFalse){
List2.add(object1);
object1.isTrue = false;
object1.Date = System.now();
}
}
}
}