Skip to content
This repository was archived by the owner on Oct 15, 2020. It is now read-only.

Commit 7ca46ff

Browse files
authored
Revert new pass-based approach to fix smaller problems in peace (#220)
* Revert "Fix `runWithPreprocessorAndOutput` (#219)" This reverts commit 5826306. * Revert "Commented AST to CFG converter - functional version (#217)" This reverts commit 19fbee0. * Revert "Include `JumpTarget` nodes in the CFG (#216)" This reverts commit 9dc2098. * Revert "Pass-Based FuzzyC2Cpg (#214)" This reverts commit 3feb6c7.
1 parent 5826306 commit 7ca46ff

File tree

58 files changed

+5364
-912
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+5364
-912
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ organization := "io.shiftleft"
33
scalaVersion := "2.13.1"
44
enablePlugins(GitVersioning)
55

6-
val cpgVersion = "0.11.338"
6+
val cpgVersion = "0.11.334"
77
val antlrVersion = "4.7.2"
88

99
libraryDependencies ++= Seq(

fuzzyc2cpg.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
SCRIPT_ABS_PATH=$(readlink -f "$0")
44
SCRIPT_ABS_DIR=$(dirname $SCRIPT_ABS_PATH)
55

6-
$SCRIPT_ABS_DIR/target/universal/stage/bin/fuzzyc2cpg -J-XX:+UseG1GC -J-XX:CompressedClassSpaceSize=128m -J-XX:+UseStringDeduplication -Dlogback.configurationFile=$SCRIPT_ABS_DIR/config/logback.xml $@
6+
$SCRIPT_ABS_DIR/target/universal/stage/bin/fuzzyc2cpg -Dlogback.configurationFile=$SCRIPT_ABS_DIR/config/logback.xml $@

src/main/java/io/shiftleft/fuzzyc2cpg/ast/statements/jump/GotoStatement.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ public String getTargetName() {
1212
return getChild(0).getEscapedCodeStr();
1313
}
1414

15-
public String getEscapedCodeStr() {
16-
return "goto " + getTargetName() + ";";
17-
}
18-
1915
public void accept(ASTNodeVisitor visitor) {
2016
visitor.visit(this);
2117
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.shiftleft.fuzzyc2cpg.output.inmemory;
2+
3+
import io.shiftleft.codepropertygraph.Cpg;
4+
import io.shiftleft.codepropertygraph.cpgloading.ProtoCpgLoader;
5+
import io.shiftleft.fuzzyc2cpg.output.CpgOutputModule;
6+
import overflowdb.OdbConfig;
7+
import io.shiftleft.proto.cpg.Cpg.CpgStruct;
8+
9+
import java.util.LinkedList;
10+
import java.util.List;
11+
12+
public class OutputModule implements CpgOutputModule {
13+
14+
private LinkedList<CpgStruct.Builder> cpgBuilders;
15+
private Cpg cpg;
16+
17+
protected OutputModule() {
18+
this.cpgBuilders = new LinkedList<>();
19+
}
20+
21+
public Cpg getInternalGraph() {
22+
return cpg;
23+
}
24+
25+
@Override
26+
public void setOutputIdentifier(String identifier) { }
27+
28+
@Override
29+
public void persistCpg(CpgStruct.Builder cpg) {
30+
synchronized (cpgBuilders) {
31+
cpgBuilders.add(cpg);
32+
}
33+
}
34+
35+
public void persist() {
36+
CpgStruct.Builder mergedBuilder = CpgStruct.newBuilder();
37+
38+
cpgBuilders.forEach(builder -> {
39+
mergedBuilder.mergeFrom(builder.build());
40+
});
41+
42+
List<CpgStruct> list = new LinkedList<>();
43+
list.add(mergedBuilder.build());
44+
cpg = ProtoCpgLoader.loadFromListOfProtos(list, OdbConfig.withoutOverflow());
45+
}
46+
47+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.shiftleft.fuzzyc2cpg.output.inmemory;
2+
3+
import io.shiftleft.codepropertygraph.Cpg;
4+
import io.shiftleft.fuzzyc2cpg.output.CpgOutputModule;
5+
import io.shiftleft.fuzzyc2cpg.output.CpgOutputModuleFactory;
6+
7+
public class OutputModuleFactory implements CpgOutputModuleFactory {
8+
9+
private OutputModule outputModule;
10+
11+
@Override
12+
public CpgOutputModule create() {
13+
synchronized (this) {
14+
if (outputModule == null) {
15+
outputModule = new OutputModule();
16+
}
17+
}
18+
return outputModule;
19+
}
20+
21+
/**
22+
* An internal representation of the graph.
23+
*
24+
* @return the internally constructed graph
25+
*/
26+
public Cpg getInternalGraph() {
27+
return outputModule.getInternalGraph();
28+
}
29+
30+
@Override
31+
public void persist() {
32+
if (outputModule != null) {
33+
outputModule.persist();
34+
}
35+
}
36+
}
37+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package io.shiftleft.fuzzyc2cpg.output.protobuf;
2+
3+
import com.google.common.hash.HashFunction;
4+
import com.google.common.hash.Hasher;
5+
import com.google.common.hash.Hashing;
6+
import io.shiftleft.fuzzyc2cpg.output.CpgOutputModule;
7+
import io.shiftleft.proto.cpg.Cpg.CpgStruct;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import java.io.File;
12+
import java.io.FileOutputStream;
13+
import java.io.IOException;
14+
import java.nio.file.Files;
15+
import java.nio.file.Path;
16+
import java.nio.file.Paths;
17+
import java.util.concurrent.ThreadLocalRandom;
18+
19+
public class OutputModule implements CpgOutputModule {
20+
private final Logger logger = LoggerFactory.getLogger(getClass());
21+
22+
private final Path protoTempDir;
23+
private final boolean writeToDisk;
24+
25+
private String outputIdentifier;
26+
27+
public OutputModule(boolean writeToDisk,
28+
Path protoTempDir) {
29+
this.writeToDisk = writeToDisk;
30+
this.protoTempDir = protoTempDir;
31+
}
32+
33+
@Override
34+
public void setOutputIdentifier(String identifier) {
35+
outputIdentifier = identifier;
36+
}
37+
38+
/**
39+
* This is called for each code property graph. There is one
40+
* code property graph per method, and one graph for the overall
41+
* program structure.
42+
* */
43+
44+
@Override
45+
public void persistCpg(CpgStruct.Builder cpg) throws IOException {
46+
CpgStruct buildCpg = cpg.build();
47+
if (writeToDisk) {
48+
String outputFilename = getOutputFileName();
49+
try (FileOutputStream outStream = new FileOutputStream(outputFilename)) {
50+
buildCpg.writeTo(outStream);
51+
}
52+
}
53+
}
54+
55+
/**
56+
* The complete handling for an already existing file should not be necessary.
57+
* This was added as a last resort to not get incomplete cpgs.
58+
* In case we have a hash collision, the resulting cpg part file names will not
59+
* be identical over different java2cpg runs.
60+
*/
61+
private String getOutputFileName() {
62+
String outputFilename = null;
63+
int postfix = 0;
64+
boolean fileExists = true;
65+
int resolveAttemptCounter = 0;
66+
67+
while (fileExists && resolveAttemptCounter < 10) {
68+
outputFilename = generateOutputFilename(postfix);
69+
if (Files.exists(Paths.get(outputFilename))) {
70+
postfix = ThreadLocalRandom.current().nextInt(0, 100000);
71+
72+
logger.warn("Hash collision identifier={}, postfix={}." +
73+
" Retry with random postfix.", outputIdentifier, postfix);
74+
75+
resolveAttemptCounter++;
76+
} else {
77+
fileExists = false;
78+
}
79+
}
80+
81+
if (fileExists) {
82+
logger.error("Unable to resolve hash collision. Cpg will be incomplete");
83+
}
84+
85+
return outputFilename;
86+
}
87+
88+
private String generateOutputFilename(int postfix) {
89+
HashFunction hashFunction = Hashing.murmur3_128();
90+
91+
Hasher hasher = hashFunction.newHasher();
92+
hasher.putUnencodedChars(outputIdentifier);
93+
hasher.putInt(postfix);
94+
95+
String protoSuffix = ".bin";
96+
return protoTempDir.toString() + File.separator + hasher.hash() + protoSuffix;
97+
}
98+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package io.shiftleft.fuzzyc2cpg.output.protobuf;
2+
3+
import io.shiftleft.fuzzyc2cpg.output.CpgOutputModule;
4+
import io.shiftleft.fuzzyc2cpg.output.CpgOutputModuleFactory;
5+
import java.io.IOException;
6+
import java.nio.file.Files;
7+
import java.nio.file.Path;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
import org.apache.commons.io.FileUtils;
12+
13+
public class OutputModuleFactory implements CpgOutputModuleFactory {
14+
15+
private final List<OutputModule> outputModules = new ArrayList<>();
16+
private final boolean writeToDisk;
17+
private final Path protoTempDir;
18+
private final String outputFilename;
19+
20+
public OutputModuleFactory(String outputFilename,
21+
boolean writeToDisk) throws IOException {
22+
this.writeToDisk = writeToDisk;
23+
this.protoTempDir = Files.createTempDirectory("proto");
24+
this.outputFilename = outputFilename;
25+
}
26+
27+
@Override
28+
public CpgOutputModule create() {
29+
OutputModule outputModule = new OutputModule(writeToDisk, protoTempDir);
30+
synchronized (this) {
31+
outputModules.add(outputModule);
32+
}
33+
return outputModule;
34+
}
35+
36+
/**
37+
* Store collected CPGs into the output directory specified
38+
* for this output module.
39+
* Note: This method should be called only once all intermediate CPGs
40+
* have been processed and collected.
41+
* If the output module was configured to combine intermediate CPGs into a single
42+
* one, we will combine individual proto files.
43+
* */
44+
@Override
45+
public void persist() throws IOException {
46+
if (writeToDisk) {
47+
try {
48+
ThreadedZipper threadedZipper = new ThreadedZipper(protoTempDir, outputFilename);
49+
threadedZipper.start();
50+
// wait until the thread is finished
51+
// if we don't wait, the output folder
52+
// may be deleted and and we get null pointer
53+
threadedZipper.join();
54+
} catch (InterruptedException interruptedException) {
55+
throw new IOException(interruptedException);
56+
}
57+
}
58+
if (this.protoTempDir != null && Files.exists(this.protoTempDir)) {
59+
FileUtils.deleteDirectory(this.protoTempDir.toFile());
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)