@@ -23,24 +23,35 @@ import java.io.InputStream
2323import scala .collection .mutable .{ HashMap , MultiMap , Set }
2424
2525import akka .actor .{ Actor , Stash }
26- import com .secdec .codepulse .data .bytecode .parse .MethodDeclarationListener
26+ import com .google .common .io .CharStreams
27+ import com .secdec .codepulse .data .bytecode .parse .ParseListener
2728import com .secdec .codepulse .data .bytecode .{ AsmVisitors , CodeForestBuilder , CodeTreeNodeKind }
2829import com .secdec .codepulse .data .jsp .{ JasperJspAdapter , JspAnalyzer }
2930import com .secdec .codepulse .data .model .{ MethodSignatureNode , SourceDataAccess , TreeNodeDataAccess , TreeNodeImporter }
3031import com .secdec .codepulse .data .storage .Storage
3132import com .secdec .codepulse .events .GeneralEventBus
3233import com .secdec .codepulse .input .pathnormalization .{ FilePath , NestedPath , PathNormalization }
3334import com .secdec .codepulse .input .{ CanProcessFile , LanguageProcessor }
35+ import com .secdec .codepulse .parsers .java9 .Java9Parser .CompilationUnitContext
3436import com .secdec .codepulse .parsers .java9 .{ Java9Lexer , Java9Parser }
3537import com .secdec .codepulse .processing .{ ProcessEnvelope , ProcessStatus }
3638import com .secdec .codepulse .processing .ProcessStatus .{ DataInputAvailable , ProcessDataAvailable }
3739import com .secdec .codepulse .util .SmartLoader .Success
3840import com .secdec .codepulse .util .SmartLoader
3941import org .apache .commons .io .FilenameUtils
4042import net .liftweb .common .Loggable
41- import org .antlr .v4 .runtime .CharStreams
42- import org .antlr .v4 .runtime .CommonTokenStream
43- import org .antlr .v4 .runtime .tree .ParseTreeWalker
43+ // import org.antlr.v4.runtime.CharStreams
44+ // import org.antlr.v4.runtime.CommonTokenStream
45+ // import org.antlr.v4.runtime.tree.ParseTreeWalker
46+ import org .apache .commons .io .input .CloseShieldInputStream
47+ import com .github .javaparser .JavaParser
48+ import com .github .javaparser .ParseException
49+ import com .github .javaparser .ast .body .MethodDeclaration
50+ import com .github .javaparser .ast .visitor .VoidVisitorAdapter
51+ import com .github .javaparser .ast .Node
52+ import com .github .javaparser .ast .body .ClassOrInterfaceDeclaration
53+ import com .github .javaparser .ast .CompilationUnit
54+ import com .github .javaparser .ast .PackageDeclaration
4455
4556class ByteCodeProcessor (eventBus : GeneralEventBus ) extends Actor with Stash with LanguageProcessor with Loggable {
4657 val group = " Classes"
@@ -97,6 +108,15 @@ class ByteCodeProcessor(eventBus: GeneralEventBus) extends Actor with Stash with
97108 })
98109 }
99110
111+ val sourceMethods = new HashMap [String , List [(String , Int )]]
112+ storage.readEntries(sourceType(" java" ) _) { (filename, entryPath, entry, contents) =>
113+ val methodsAndStarts = parseJava9(contents)
114+ sourceMethods.get(entry.getName()) match {
115+ case None => sourceMethods += (entry.getName() -> methodsAndStarts)
116+ case Some (entries) => sourceMethods += (entry.getName() -> (entries ::: methodsAndStarts))
117+ }
118+ }
119+
100120 def getPackageFromSig (sig : String ): String = {
101121 val packageContainer = sig.split(" ;" ).take(1 )
102122 val packagePart = packageContainer(0 ).split(" /" ).dropRight(1 )
@@ -118,8 +138,7 @@ class ByteCodeProcessor(eventBus: GeneralEventBus) extends Actor with Stash with
118138 if (! entry.isDirectory) {
119139 FilenameUtils .getExtension(entry.getName) match {
120140 case " class" =>
121- val methods = AsmVisitors .parseMethodsFromClass(contents)
122- val methodsAndStartLines = parseJava9(contents)
141+ val methods = AsmVisitors .parseMethodsFromClass(new CloseShieldInputStream (contents))
123142 for {
124143 (file, name, size, lineCount, methodStartLine) <- methods
125144 pkg = getPackageFromSig(name)
@@ -132,7 +151,15 @@ class ByteCodeProcessor(eventBus: GeneralEventBus) extends Actor with Stash with
132151 case Some (np) => authoritativePath(groupName, np).map (_.toString)
133152 case None => None
134153 }
135- treeNode <- builder.getOrAddMethod(groupName, name, size, authority, Option (lineCount), Option (methodStartLine))
154+ methodsAndStartLines = authority.flatMap(sourceMethods.get)
155+ startLine = methodsAndStartLines.flatMap { l =>
156+ val aName = name.split(" ;" ).take(1 )(0 )
157+ val potentials = l.filter { case (qualifiedName, line) => qualifiedName == name.split(" ;" ).take(1 )(0 ) }
158+ val selection = potentials.headOption.getOrElse(((" " , 0 )))
159+
160+ Some (selection._2)
161+ }
162+ treeNode <- builder.getOrAddMethod(groupName, name, size, authority, Option (lineCount), startLine)
136163 } {
137164 methodCorrelationsBuilder += (name -> treeNode.id)
138165 }
@@ -193,24 +220,60 @@ class ByteCodeProcessor(eventBus: GeneralEventBus) extends Actor with Stash with
193220 }
194221
195222 private def parseJava9 (contents : InputStream ): List [(String , Int )] = {
196- // contents to stream
197- val stream = CharStreams .fromStream(contents)
223+ def mkString (s1 : String , s2 : String , sep : String ): String = {
224+ if (s1.isEmpty) s2
225+ else if (s2.isEmpty) s1
226+ else s1 + sep + s2
227+ }
228+
229+ def getQualifiedClass (n : Node , s : String ): String = {
230+ n match {
231+ case m : MethodDeclaration => if (m.getParentNode().isPresent()) {
232+ getQualifiedClass(m.getParentNode().get(), s)
233+ } else {
234+ s
235+ }
236+ case c : ClassOrInterfaceDeclaration => if (c.getParentNode().isPresent()) {
237+ getQualifiedClass(c.getParentNode().get(), mkString(c.getName().toString, s, " $" ))// c.getName + "." + s)
238+ } else {
239+ s
240+ }
241+ case cu : CompilationUnit => if (cu.getPackageDeclaration().isPresent()) {
242+ getQualifiedClass(cu.getPackageDeclaration().get(), s)
243+ } else {
244+ s
245+ }
246+ case p : PackageDeclaration => mkString(p.getName().toString.replace(" ." , " /" ), s, " /" )// p.getName + "." + s
247+ }
248+ }
198249
199- // create lexer, token, and parser
200- val lexer = new Java9Lexer (stream)
201- val tokens = new CommonTokenStream (lexer)
202- val parser = new Java9Parser (tokens)
250+ var methodStarts = List [(String , Int )]()
203251
204- // read input
205- val ctx = parser.methodDeclaration()
252+ try {
253+ val sourceContent = new CloseShieldInputStream (contents)
254+ val cu = JavaParser .parse(sourceContent)
206255
207- // walk the tree, listening for what we need
208- val walker = new ParseTreeWalker ()
256+ val methodVisitor = new VoidVisitorAdapter [Void ] {
257+ override def visit (n : MethodDeclaration , arg : Void ): Unit = {
258+ super .visit(n, arg)
259+ System .out.println(getQualifiedClass(n, " " ) + " \t " + n.getName() + " \t " + n.getBegin())
209260
210- var methodStarts = List [(String , Int )]()
211- val listener = new MethodDeclarationListener ((method, start) => methodStarts = (method, start) :: methodStarts)
261+ val qualifiedName = mkString(getQualifiedClass(n, " " ), n.getName().toString, " ." )
262+ val startLine = if (n.getBegin().isPresent()) {
263+ val location = n.getBegin().get()
264+ location.line
265+ } else {
266+ 0
267+ }
212268
213- walker.walk(listener, ctx)
269+ methodStarts = (qualifiedName, startLine) :: methodStarts
270+ }
271+ }
272+
273+ cu.accept(methodVisitor, null )
274+ } catch {
275+ case ex : Exception => System .out.println(ex)
276+ }
214277
215278 methodStarts
216279 }
0 commit comments