1 | package com.jsql.util; | |
2 | ||
3 | import com.jsql.model.InjectionModel; | |
4 | import com.jsql.util.bruter.HashUtil; | |
5 | import org.apache.commons.lang3.exception.ExceptionUtils; | |
6 | import org.apache.logging.log4j.Level; | |
7 | import org.apache.logging.log4j.LogManager; | |
8 | import org.apache.logging.log4j.Logger; | |
9 | ||
10 | import javax.swing.*; | |
11 | import java.lang.reflect.InvocationTargetException; | |
12 | import java.nio.charset.StandardCharsets; | |
13 | import java.security.MessageDigest; | |
14 | import java.security.NoSuchAlgorithmException; | |
15 | import java.util.Set; | |
16 | import java.util.concurrent.CopyOnWriteArraySet; | |
17 | ||
18 | /** | |
19 | * Utility class managing exception reporting to GitHub. | |
20 | */ | |
21 | public class ExceptionUtil { | |
22 | | |
23 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
24 | | |
25 | private final InjectionModel injectionModel; | |
26 | | |
27 | private final Set<String> exceptionsMd5Cached = new CopyOnWriteArraySet<>(); | |
28 | | |
29 | public ExceptionUtil(InjectionModel injectionModel) { | |
30 | | |
31 | this.injectionModel = injectionModel; | |
32 | } | |
33 | | |
34 | /** | |
35 | * Handler class processing errors on top of the JVM in order to send | |
36 | * a report to GitHub automatically. | |
37 | */ | |
38 | public class ExceptionHandler implements Thread.UncaughtExceptionHandler { | |
39 | ||
40 | @Override | |
41 | public void uncaughtException(Thread thread, Throwable throwable) { | |
42 | | |
43 | LOGGER.log( | |
44 | LogLevelUtil.CONSOLE_JAVA, | |
45 |
1
1. lambda$uncaughtException$0 : replaced return value with null for com/jsql/util/ExceptionUtil$ExceptionHandler::lambda$uncaughtException$0 → NO_COVERAGE |
() -> String.format("Unhandled Exception on %s", thread.getName()), |
46 | throwable | |
47 | ); | |
48 | ||
49 | // Display to stdout | |
50 | LOGGER.log( | |
51 | Level.ERROR, | |
52 |
1
1. lambda$uncaughtException$1 : replaced return value with null for com/jsql/util/ExceptionUtil$ExceptionHandler::lambda$uncaughtException$1 → NO_COVERAGE |
() -> String.format("Unhandled Exception on %s", thread.getName()), |
53 | throwable | |
54 | ); | |
55 | ||
56 | // Report #214: ignore if OutOfMemoryError: Java heap space | |
57 | if ( | |
58 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
ExceptionUtil.this.injectionModel.getMediatorUtils().getPreferencesUtil().isReportingBugs() |
59 |
2
1. uncaughtException : negated conditional → NO_COVERAGE 2. uncaughtException : negated conditional → NO_COVERAGE |
&& ExceptionUtils.getStackTrace(throwable).contains("com.jsql") |
60 | && !(throwable instanceof OutOfMemoryError) | |
61 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
&& !ExceptionUtils.getStackTrace(throwable).contains("OutOfMemoryError") // when implicit |
62 | ) { | |
63 | ||
64 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
if (ExceptionUtils.getStackTrace(throwable).contains("Could not initialize class java.awt.Toolkit")) { |
65 | ||
66 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "System libraries are missing, please use a proper Java runtime instead of headless runtime"); | |
67 | return; | |
68 | ||
69 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
} else if (ExceptionUtils.getStackTrace(throwable).contains("Could not initialize class sun.awt.X11.XToolkit")) { |
70 | ||
71 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "System libraries are missing or wrong DISPLAY variable, please verify your settings"); | |
72 | return; | |
73 | } | |
74 | ||
75 | try { | |
76 | var md = MessageDigest.getInstance("Md5"); | |
77 | ||
78 | String stackTrace = ExceptionUtils.getStackTrace(throwable).trim(); | |
79 | var passwordString = String.valueOf(stackTrace.toCharArray()); | |
80 | ||
81 | byte[] passwordByte = passwordString.getBytes(StandardCharsets.UTF_8); | |
82 |
1
1. uncaughtException : removed call to java/security/MessageDigest::update → NO_COVERAGE |
md.update(passwordByte, 0, passwordByte.length); |
83 | ||
84 | byte[] encodedPassword = md.digest(); | |
85 | ||
86 | var md5Exception = HashUtil.digestToHexString(encodedPassword); | |
87 | ||
88 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
if (!ExceptionUtil.this.exceptionsMd5Cached.contains(md5Exception)) { |
89 | ||
90 | ExceptionUtil.this.exceptionsMd5Cached.add(md5Exception); | |
91 |
1
1. uncaughtException : removed call to com/jsql/util/GitUtil::sendUnhandledException → NO_COVERAGE |
ExceptionUtil.this.injectionModel.getMediatorUtils().getGitUtil().sendUnhandledException( |
92 | thread.getName(), | |
93 | throwable | |
94 | ); | |
95 | } | |
96 | } catch (NoSuchAlgorithmException e) { | |
97 | LOGGER.log(LogLevelUtil.IGNORE, e); | |
98 | } | |
99 | } | |
100 | } | |
101 | } | |
102 | | |
103 | /** | |
104 | * Add the error reporting mechanism on top of the JVM in order to | |
105 | * intercept and process the error to GitHub. | |
106 | */ | |
107 | public void setUncaughtExceptionHandler() { | |
108 | | |
109 | // Regular Exception | |
110 |
1
1. setUncaughtExceptionHandler : removed call to java/lang/Thread::setDefaultUncaughtExceptionHandler → NO_COVERAGE |
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler()); |
111 | ||
112 | // Event dispatching thread Exception | |
113 | try { | |
114 |
1
1. setUncaughtExceptionHandler : removed call to javax/swing/SwingUtilities::invokeAndWait → NO_COVERAGE |
SwingUtilities.invokeAndWait(() -> |
115 | // We are in the event dispatching thread | |
116 |
1
1. lambda$setUncaughtExceptionHandler$0 : removed call to java/lang/Thread::setUncaughtExceptionHandler → NO_COVERAGE |
Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler()) |
117 | ); | |
118 | } catch (InvocationTargetException | InterruptedException e) { | |
119 | | |
120 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
121 |
1
1. setUncaughtExceptionHandler : removed call to java/lang/Thread::interrupt → NO_COVERAGE |
Thread.currentThread().interrupt(); |
122 | } | |
123 | } | |
124 | } | |
Mutations | ||
45 |
1.1 |
|
52 |
1.1 |
|
58 |
1.1 |
|
59 |
1.1 2.2 |
|
61 |
1.1 |
|
64 |
1.1 |
|
69 |
1.1 |
|
82 |
1.1 |
|
88 |
1.1 |
|
91 |
1.1 |
|
110 |
1.1 |
|
114 |
1.1 |
|
116 |
1.1 |
|
121 |
1.1 |