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