2020import me .n1ar4 .jar .analyzer .engine .log .Logger ;
2121import me .n1ar4 .jar .analyzer .engine .utils .*;
2222import me .n1ar4 .jar .analyzer .entity .ClassFileEntity ;
23+ import me .n1ar4 .jar .analyzer .entity .JarEntity ;
2324import org .objectweb .asm .ClassReader ;
2425
2526import java .io .ByteArrayInputStream ;
2627import java .io .File ;
27- import java .io .FileNotFoundException ;
2828import java .io .FileOutputStream ;
29+ import java .io .IOException ;
2930import java .nio .file .Files ;
3031import java .nio .file .Path ;
3132import java .nio .file .Paths ;
@@ -44,7 +45,21 @@ public static void run(EngineConfig config) {
4445 callback = ProgressCallback .CONSOLE ;
4546 }
4647
47- // Clear corrupted files tracking
48+ // Clear all state for re-entrant safety
49+ AnalyzeEnv .classFileList .clear ();
50+ AnalyzeEnv .discoveredClasses .clear ();
51+ AnalyzeEnv .discoveredMethods .clear ();
52+ AnalyzeEnv .methodsInClassMap .clear ();
53+ AnalyzeEnv .classMap .clear ();
54+ AnalyzeEnv .methodMap .clear ();
55+ AnalyzeEnv .methodCalls .clear ();
56+ AnalyzeEnv .strMap .clear ();
57+ AnalyzeEnv .controllers .clear ();
58+ AnalyzeEnv .interceptors .clear ();
59+ AnalyzeEnv .servlets .clear ();
60+ AnalyzeEnv .filters .clear ();
61+ AnalyzeEnv .listeners .clear ();
62+ AnalyzeEnv .stringAnnoMap .clear ();
4863 AnalyzeEnv .corruptedFiles .clear ();
4964
5065 // Setup JarUtil with black/white list
@@ -78,7 +93,12 @@ public static void run(EngineConfig config) {
7893 if (s .toLowerCase ().endsWith (".jar" ) ||
7994 s .toLowerCase ().endsWith (".war" )) {
8095 DatabaseManager .saveJar (s );
81- jarIdMap .put (s , DatabaseManager .getJarId (s ).getJid ());
96+ JarEntity jarEntity = DatabaseManager .getJarId (s );
97+ if (jarEntity != null ) {
98+ jarIdMap .put (s , jarEntity .getJid ());
99+ } else {
100+ logger .error ("save jar failed, cannot get jar id: {}" , s );
101+ }
82102 }
83103 }
84104 cfs = CoreUtil .getAllClassesFromJars (files , jarIdMap );
@@ -94,7 +114,12 @@ public static void run(EngineConfig config) {
94114 callback .onStats ("totalJar" , String .valueOf (jarList .size ()));
95115 for (String s : jarList ) {
96116 DatabaseManager .saveJar (s );
97- jarIdMap .put (s , DatabaseManager .getJarId (s ).getJid ());
117+ JarEntity jarEntity = DatabaseManager .getJarId (s );
118+ if (jarEntity != null ) {
119+ jarIdMap .put (s , jarEntity .getJid ());
120+ } else {
121+ logger .error ("save jar failed, cannot get jar id: {}" , s );
122+ }
98123 }
99124 cfs = CoreUtil .getAllClassesFromJars (jarList , jarIdMap );
100125 }
@@ -103,35 +128,42 @@ public static void run(EngineConfig config) {
103128 for (ClassFileEntity cf : cfs ) {
104129 String className = cf .getClassName ();
105130 if (!fixClass ) {
106- int i = className .indexOf ("classes" );
107131 if (className .contains ("BOOT-INF" ) || className .contains ("WEB-INF" )) {
108- className = className .substring (i + 8 );
132+ int i = className .indexOf ("classes" );
133+ if (i >= 0 ) {
134+ className = className .substring (i + 8 );
135+ }
109136 }
110137 cf .setClassName (className );
111138 } else {
112139 Path parPath = Paths .get (EngineConst .tempDir );
113140 FixClassVisitor cv = new FixClassVisitor ();
141+ byte [] fileBytes = cf .getFile ();
142+ if (fileBytes == null ) {
143+ logger .error ("cannot read class file: {}" , cf .getClassName ());
144+ continue ;
145+ }
114146 try {
115- ClassReader cr = new ClassReader (cf . getFile () );
147+ ClassReader cr = new ClassReader (fileBytes );
116148 cr .accept (cv , EngineConst .AnalyzeASMOptions );
117149 } catch (IndexOutOfBoundsException e ) {
118- if (!StackMapFrameHandler .handleParseException (cf . getFile () , cv ,
150+ if (!StackMapFrameHandler .handleParseException (fileBytes , cv ,
119151 cf .getJarName () + "!" + cf .getClassName (),
120152 logger , "fix class name" , e )) {
121153 throw e ;
122154 }
123155 }
124156 Path path = parPath .resolve (Paths .get (cv .getName ()));
125157 File file = path .toFile ();
126- if (!file .getParentFile ().mkdirs ()) {
158+ if (!file .getParentFile ().exists () && ! file . getParentFile (). mkdirs ()) {
127159 logger .error ("fix class mkdirs error" );
128160 }
129161 className = file .getPath () + ".class" ;
130- try {
131- IOUtil . copy ( new ByteArrayInputStream ( cf . getFile ()),
132- new FileOutputStream ( className ) );
133- } catch (FileNotFoundException ignored ) {
134- logger .error ("fix path copy bytes error" );
162+ try ( ByteArrayInputStream bis = new ByteArrayInputStream ( fileBytes );
163+ FileOutputStream fos = new FileOutputStream ( className )) {
164+ IOUtil . copy ( bis , fos );
165+ } catch (IOException ex ) {
166+ logger .error ("fix path copy bytes error: {}" , ex . toString () );
135167 }
136168 cf .setClassName (className );
137169 cf .setPath (Paths .get (className ));
@@ -209,9 +241,14 @@ public static void run(EngineConfig config) {
209241
210242 for (ClassFileEntity file : AnalyzeEnv .classFileList ) {
211243 try {
244+ byte [] fileBytes = file .getFile ();
245+ if (fileBytes == null ) {
246+ logger .error ("cannot read class file for string analysis: {}" , file .getClassName ());
247+ continue ;
248+ }
212249 StringClassVisitor dcv = new StringClassVisitor (
213250 AnalyzeEnv .strMap , AnalyzeEnv .classMap , AnalyzeEnv .methodMap );
214- ClassReader cr = new ClassReader (file . getFile () );
251+ ClassReader cr = new ClassReader (fileBytes );
215252 cr .accept (dcv , EngineConst .AnalyzeASMOptions );
216253 } catch (IndexOutOfBoundsException e ) {
217254 if (!StackMapFrameHandler .handleParseException (file ,
@@ -272,6 +309,12 @@ public static void run(EngineConfig config) {
272309 AnalyzeEnv .methodMap .clear ();
273310 AnalyzeEnv .methodCalls .clear ();
274311 AnalyzeEnv .strMap .clear ();
312+ AnalyzeEnv .stringAnnoMap .clear ();
313+ AnalyzeEnv .interceptors .clear ();
314+ AnalyzeEnv .servlets .clear ();
315+ AnalyzeEnv .filters .clear ();
316+ AnalyzeEnv .listeners .clear ();
317+ AnalyzeEnv .corruptedFiles .clear ();
275318 if (!quickMode ) {
276319 if (AnalyzeEnv .inheritanceMap != null ) {
277320 AnalyzeEnv .inheritanceMap .getInheritanceMap ().clear ();
0 commit comments