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 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
if (ExceptionUtils.getStackTrace(throwable).contains("Could not initialize class java.awt.Toolkit")) { |
64 | ||
65 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "System libraries are missing, please use a proper Java runtime instead of headless runtime"); | |
66 | return; | |
67 | ||
68 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
} else if (ExceptionUtils.getStackTrace(throwable).contains("Could not initialize class sun.awt.X11.XToolkit")) { |
69 | ||
70 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "System libraries are missing or wrong DISPLAY variable, please verify your settings"); | |
71 | return; | |
72 | } | |
73 | ||
74 | try { | |
75 | var md = MessageDigest.getInstance("Md5"); | |
76 | ||
77 | String stackTrace = ExceptionUtils.getStackTrace(throwable).trim(); | |
78 | var passwordString = String.valueOf(stackTrace.toCharArray()); | |
79 | ||
80 | byte[] passwordByte = passwordString.getBytes(StandardCharsets.UTF_8); | |
81 |
1
1. uncaughtException : removed call to java/security/MessageDigest::update → NO_COVERAGE |
md.update(passwordByte, 0, passwordByte.length); |
82 | ||
83 | byte[] encodedPassword = md.digest(); | |
84 | ||
85 | var md5Exception = HashUtil.digestToHexString(encodedPassword); | |
86 | ||
87 |
1
1. uncaughtException : negated conditional → NO_COVERAGE |
if (!ExceptionUtil.this.exceptionsMd5Cached.contains(md5Exception)) { |
88 | ||
89 | ExceptionUtil.this.exceptionsMd5Cached.add(md5Exception); | |
90 |
1
1. uncaughtException : removed call to com/jsql/util/GitUtil::sendUnhandledException → NO_COVERAGE |
ExceptionUtil.this.injectionModel.getMediatorUtils().getGitUtil().sendUnhandledException( |
91 | thread.getName(), | |
92 | throwable | |
93 | ); | |
94 | } | |
95 | } catch (NoSuchAlgorithmException e) { | |
96 | LOGGER.log(LogLevelUtil.IGNORE, e); | |
97 | } | |
98 | } | |
99 | } | |
100 | } | |
101 | | |
102 | /** | |
103 | * Add the error reporting mechanism on top of the JVM in order to | |
104 | * intercept and process the error to GitHub. | |
105 | */ | |
106 | public void setUncaughtExceptionHandler() { | |
107 | | |
108 | // Regular Exception | |
109 |
1
1. setUncaughtExceptionHandler : removed call to java/lang/Thread::setDefaultUncaughtExceptionHandler → NO_COVERAGE |
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler()); |
110 | ||
111 | // Event dispatching thread Exception | |
112 | try { | |
113 |
1
1. setUncaughtExceptionHandler : removed call to javax/swing/SwingUtilities::invokeAndWait → NO_COVERAGE |
SwingUtilities.invokeAndWait(() -> |
114 | // We are in the event dispatching thread | |
115 |
1
1. lambda$setUncaughtExceptionHandler$0 : removed call to java/lang/Thread::setUncaughtExceptionHandler → NO_COVERAGE |
Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler()) |
116 | ); | |
117 | } catch (InvocationTargetException | InterruptedException e) { | |
118 | | |
119 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
120 |
1
1. setUncaughtExceptionHandler : removed call to java/lang/Thread::interrupt → NO_COVERAGE |
Thread.currentThread().interrupt(); |
121 | } | |
122 | } | |
123 | } | |
Mutations | ||
45 |
1.1 |
|
52 |
1.1 |
|
58 |
1.1 |
|
59 |
1.1 2.2 |
|
61 |
1.1 |
|
63 |
1.1 |
|
68 |
1.1 |
|
81 |
1.1 |
|
87 |
1.1 |
|
90 |
1.1 |
|
109 |
1.1 |
|
113 |
1.1 |
|
115 |
1.1 |
|
120 |
1.1 |