InjectionModel.java

1
/*******************************************************************************
2
 * Copyhacked (H) 2012-2025.
3
 * This program and the accompanying materials
4
 * are made available under no term at all, use it like
5
 * you want, but share and discuss it
6
 * every time possible with every body.
7
 * 
8
 * Contributors:
9
 *      ron190 at ymail dot com - initial implementation
10
 ******************************************************************************/
11
package com.jsql.model;
12
13
import com.jsql.model.accessible.DataAccess;
14
import com.jsql.model.accessible.ResourceAccess;
15
import com.jsql.view.subscriber.Seal;
16
import com.jsql.model.exception.JSqlException;
17
import com.jsql.model.exception.JSqlRuntimeException;
18
import com.jsql.model.injection.method.AbstractMethodInjection;
19
import com.jsql.model.injection.method.MediatorMethod;
20
import com.jsql.model.injection.strategy.MediatorStrategy;
21
import com.jsql.model.injection.strategy.blind.callable.AbstractCallableBit;
22
import com.jsql.model.injection.engine.MediatorEngine;
23
import com.jsql.model.injection.engine.model.EngineYaml;
24
import com.jsql.util.*;
25
import com.jsql.util.GitUtil.ShowOnConsole;
26
import org.apache.commons.lang3.StringUtils;
27
import org.apache.logging.log4j.LogManager;
28
import org.apache.logging.log4j.Logger;
29
30
import javax.swing.*;
31
import java.awt.*;
32
import java.io.IOException;
33
import java.io.Serializable;
34
import java.net.*;
35
import java.net.http.HttpRequest;
36
import java.net.http.HttpRequest.BodyPublishers;
37
import java.net.http.HttpRequest.Builder;
38
import java.net.http.HttpResponse;
39
import java.net.http.HttpResponse.BodyHandlers;
40
import java.nio.charset.StandardCharsets;
41
import java.text.DecimalFormat;
42
import java.time.Duration;
43
import java.util.AbstractMap.SimpleEntry;
44
import java.util.Map;
45
import java.util.regex.Matcher;
46
import java.util.stream.Collectors;
47
import java.util.stream.Stream;
48
49
/**
50
 * Model class of MVC pattern for processing SQL injection automatically.<br>
51
 * Different views can be attached to this observable, like Swing or command line, in order to separate
52
 * the functional job from the graphical processing.<br>
53
 * The Model has a specific database engine and strategy which run an automatic injection to get name of
54
 * databases, tables, columns and values, and it can also retrieve resources like files and shell.<br>
55
 * Tasks are run in multi-threads in general to speed the process.
56
 */
57
public class InjectionModel extends AbstractModelObservable implements Serializable {
58
    
59
    private static final Logger LOGGER = LogManager.getRootLogger();
60
    
61
    private final transient MediatorEngine mediatorEngine = new MediatorEngine(this);
62
    private final transient MediatorMethod mediatorMethod = new MediatorMethod(this);
63
    private final transient DataAccess dataAccess = new DataAccess(this);
64
    private final transient ResourceAccess resourceAccess = new ResourceAccess(this);
65
    private final transient PropertiesUtil propertiesUtil = new PropertiesUtil();
66
    private final transient MediatorUtils mediatorUtils;
67
    private final transient MediatorStrategy mediatorStrategy;
68
69
    public static final String STAR = "*";
70
    public static final String BR = "<br>&#10;";
71
72
    /**
73
     * initialUrl transformed to a correct injection url.
74
     */
75
    private String analysisReport = StringUtils.EMPTY;
76
77
    /**
78
     * Allow to directly start an injection after a failed one
79
     * without asking the user 'Start a new injection?'.
80
     */
81
    private boolean shouldErasePreviousInjection = false;
82
    private boolean isScanning = false;
83
84
    public InjectionModel() {
85
        this.mediatorStrategy = new MediatorStrategy(this);
86
        this.mediatorUtils = new MediatorUtils(
87
            this.propertiesUtil,
88
            new ConnectionUtil(this),
89
            new AuthenticationUtil(),
90
            new GitUtil(this),
91
            new HeaderUtil(this),
92
            new ParameterUtil(this),
93
            new ExceptionUtil(this),
94
            new SoapUtil(this),
95
            new MultipartUtil(this),
96
            new CookiesUtil(this),
97
            new JsonUtil(this),
98
            new PreferencesUtil(),
99
            new ProxyUtil(),
100
            new ThreadUtil(this),
101
            new TamperingUtil(),
102
            new UserAgentUtil(),
103
            new CsrfUtil(this),
104
            new DigestUtil(this),
105
            new FormUtil(this),
106
            new CertificateUtil()
107
        );
108
    }
109
110
    /**
111
     * Reset each injection attributes: Database metadata, General Thread status, Strategy.
112
     */
113
    public void resetModel() {
114 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getTime().setApplicable(false);
115 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getBlindBin().setApplicable(false);
116 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getBlindBit().setApplicable(false);
117 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getMultibit().setApplicable(false);
118 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getDns().setApplicable(false);
119 1 1. resetModel : removed call to com/jsql/model/injection/strategy/StrategyError::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getError().setApplicable(false);
120 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getStack().setApplicable(false);
121 1 1. resetModel : removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE
        this.mediatorStrategy.getUnion().setApplicable(false);
122 1 1. resetModel : removed call to com/jsql/model/injection/strategy/MediatorStrategy::setStrategy → NO_COVERAGE
        this.mediatorStrategy.setStrategy(null);
123
124 1 1. resetModel : removed call to com/jsql/model/injection/strategy/StrategyUnion::setVisibleIndex → NO_COVERAGE
        this.mediatorStrategy.getSpecificUnion().setVisibleIndex(null);
125 1 1. resetModel : removed call to com/jsql/model/injection/strategy/StrategyUnion::setIndexesInUrl → NO_COVERAGE
        this.mediatorStrategy.getSpecificUnion().setIndexesInUrl(StringUtils.EMPTY);
126
127
        this.analysisReport = StringUtils.EMPTY;
128
        this.isStoppedByUser = false;
129
        this.shouldErasePreviousInjection = false;
130
131 1 1. resetModel : removed call to com/jsql/util/CsrfUtil::setTokenCsrf → NO_COVERAGE
        this.mediatorUtils.csrfUtil().setTokenCsrf(null);
132 1 1. resetModel : removed call to com/jsql/util/DigestUtil::setTokenDigest → NO_COVERAGE
        this.mediatorUtils.digestUtil().setTokenDigest(null);
133 1 1. resetModel : removed call to com/jsql/util/ThreadUtil::reset → NO_COVERAGE
        this.mediatorUtils.threadUtil().reset();
134
    }
135
136
    /**
137
     * Prepare the injection process, can be interrupted by the user (via shouldStopAll).
138
     * Erase all attributes eventually defined in a previous injection.
139
     * Run by Scan, Standard and TU.
140
     */
141
    public void beginInjection() {
142 1 1. beginInjection : removed call to com/jsql/model/InjectionModel::resetModel → NO_COVERAGE
        this.resetModel();
143
        try {
144 1 1. beginInjection : negated conditional → NO_COVERAGE
            if (this.mediatorUtils.proxyUtil().isNotLive(ShowOnConsole.YES)) {
145
                return;
146
            }
147
            LOGGER.log(
148
                LogLevelUtil.CONSOLE_INFORM,
149
                "{}: {}",
150 1 1. lambda$beginInjection$0 : replaced return value with null for com/jsql/model/InjectionModel::lambda$beginInjection$0 → NO_COVERAGE
                () -> I18nUtil.valueByKey("LOG_START_INJECTION"),
151 1 1. lambda$beginInjection$1 : replaced return value with null for com/jsql/model/InjectionModel::lambda$beginInjection$1 → NO_COVERAGE
                () -> this.mediatorUtils.connectionUtil().getUrlByUser()
152
            );
153
            
154
            // Check general integrity if user's parameters
155 1 1. beginInjection : removed call to com/jsql/util/ParameterUtil::checkParametersFormat → NO_COVERAGE
            this.mediatorUtils.parameterUtil().checkParametersFormat();
156 1 1. beginInjection : removed call to com/jsql/util/ConnectionUtil::testConnection → NO_COVERAGE
            this.mediatorUtils.connectionUtil().testConnection();
157
158
            // TODO Check all path params URL segments
159
            boolean hasFoundInjection = this.mediatorMethod.getQuery().testParameters(false);
160
            hasFoundInjection = this.mediatorUtils.multipartUtil().testParameters(hasFoundInjection);
161
            hasFoundInjection = this.mediatorUtils.soapUtil().testParameters(hasFoundInjection);
162
            hasFoundInjection = this.mediatorMethod.getRequest().testParameters(hasFoundInjection);
163
            hasFoundInjection = this.mediatorMethod.getHeader().testParameters(hasFoundInjection);
164
            hasFoundInjection = this.mediatorUtils.cookiesUtil().testParameters(hasFoundInjection);
165
166 2 1. beginInjection : negated conditional → NO_COVERAGE
2. beginInjection : negated conditional → NO_COVERAGE
            if (hasFoundInjection && !this.isScanning) {
167 1 1. beginInjection : negated conditional → NO_COVERAGE
                if (!this.getMediatorUtils().preferencesUtil().isNotShowingVulnReport()) {
168 1 1. beginInjection : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
                    this.sendToViews(new Seal.CreateAnalysisReport(this.analysisReport));
169
                }
170 1 1. beginInjection : negated conditional → NO_COVERAGE
                if (this.getMediatorUtils().preferencesUtil().isZipStrategy()) {
171
                    LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Using Zip mode for reduced query size");
172 1 1. beginInjection : negated conditional → NO_COVERAGE
                } else if (this.getMediatorUtils().preferencesUtil().isDiosStrategy()) {
173
                    LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Using Dump In One Shot strategy for single query dump");
174
                }
175 1 1. beginInjection : negated conditional → NO_COVERAGE
                if (!this.mediatorUtils.preferencesUtil().isNotInjectingMetadata()) {
176 1 1. beginInjection : removed call to com/jsql/model/accessible/DataAccess::getDatabaseInfos → NO_COVERAGE
                    this.dataAccess.getDatabaseInfos();
177
                }
178
                this.dataAccess.listDatabases();
179
            }
180
            
181
            LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, () -> I18nUtil.valueByKey("LOG_DONE"));
182
            this.shouldErasePreviousInjection = true;
183
        } catch (InterruptedException e) {
184
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
185 1 1. beginInjection : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
186
        } catch (JSqlRuntimeException | JSqlException | IOException e) {  // Catch expected exceptions only
187
            LOGGER.log(
188
                LogLevelUtil.CONSOLE_ERROR,
189
                "Interruption: {}",
190 1 1. beginInjection : negated conditional → NO_COVERAGE
                e.getMessage() == null ? InjectionModel.getImplicitReason(e) : e.getMessage()
191
            );
192
        } finally {
193 1 1. beginInjection : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.sendToViews(new Seal.EndPreparation());
194
        }
195
    }
196
    
197
    public static String getImplicitReason(Throwable e) {
198
        String message = e.getClass().getSimpleName();
199 1 1. getImplicitReason : negated conditional → NO_COVERAGE
        if (e.getMessage() != null) {
200
            message += ": "+ e.getMessage();
201
        }
202 2 1. getImplicitReason : negated conditional → NO_COVERAGE
2. getImplicitReason : negated conditional → NO_COVERAGE
        if (e.getCause() != null && !e.equals(e.getCause())) {
203
            message += " > "+ InjectionModel.getImplicitReason(e.getCause());
204
        }
205 1 1. getImplicitReason : replaced return value with "" for com/jsql/model/InjectionModel::getImplicitReason → NO_COVERAGE
        return message;
206
    }
207
    
208
    /**
209
     * Run an HTTP connection to the web server.
210
     * @param dataInjection SQL query
211
     * @return source code of current page
212
     */
213
    @Override
214
    public String inject(
215
        String dataInjection,
216
        boolean isUsingIndex,
217
        String metadataInjectionProcess,
218
        AbstractCallableBit<?> callableBoolean,
219
        boolean isReport
220
    ) {
221
        // Temporary url, we go from "select 1,2,3,4..." to "select 1,([complex query]),2...", but keep initial url
222
        String urlInjection = this.mediatorUtils.connectionUtil().getUrlBase();
223
        urlInjection = this.mediatorStrategy.buildPath(urlInjection, isUsingIndex, dataInjection);
224
        urlInjection = StringUtil.cleanSql(urlInjection.trim());
225
226
        URL urlObject;
227
        String urlInjectionFixed;
228
        try {
229
            urlInjectionFixed = this.initQueryString(
230
                isUsingIndex,
231
                urlInjection,
232
                dataInjection
233
            );
234
            urlObject = new URI(urlInjectionFixed).toURL();
235
        } catch (MalformedURLException | URISyntaxException e) {
236
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, String.format("Incorrect Query Url: %s", e.getMessage()));
237
            return StringUtils.EMPTY;
238
        }
239
240
        String pageSource = StringUtils.EMPTY;
241
        
242
        // Define the connection
243
        try {
244
            var httpRequestBuilder = HttpRequest.newBuilder()
245
                .uri(URI.create(urlObject.toString()))
246
                .setHeader(HeaderUtil.CONTENT_TYPE_REQUEST, "text/plain")
247
                .timeout(Duration.ofSeconds(15));
248
            
249 1 1. inject : removed call to com/jsql/util/CsrfUtil::addHeaderToken → NO_COVERAGE
            this.mediatorUtils.csrfUtil().addHeaderToken(httpRequestBuilder);
250 1 1. inject : removed call to com/jsql/util/DigestUtil::addHeaderToken → NO_COVERAGE
            this.mediatorUtils.digestUtil().addHeaderToken(httpRequestBuilder);
251 1 1. inject : removed call to com/jsql/util/ConnectionUtil::setCustomUserAgent → NO_COVERAGE
            this.mediatorUtils.connectionUtil().setCustomUserAgent(httpRequestBuilder);
252
253
            String body = this.initRequest(isUsingIndex, dataInjection, httpRequestBuilder);
254 1 1. inject : removed call to com/jsql/model/InjectionModel::initHeader → NO_COVERAGE
            this.initHeader(isUsingIndex, dataInjection, httpRequestBuilder);
255
            
256
            var httpRequest = httpRequestBuilder.build();
257 1 1. inject : negated conditional → NO_COVERAGE
            if (isReport) {
258
                Color colorReport = UIManager.getColor("TextArea.inactiveForeground");
259
                String report = InjectionModel.BR + StringUtil.formatReport(colorReport, "Method: ") + httpRequest.method();
260
                report += InjectionModel.BR + StringUtil.formatReport(colorReport, "Path: ") + httpRequest.uri().getPath();
261 1 1. inject : negated conditional → NO_COVERAGE
                if (httpRequest.uri().getQuery() != null) {
262
                    report += InjectionModel.BR + StringUtil.formatReport(colorReport, "Query: ") + httpRequest.uri().getQuery();
263
                }
264
                if (
265 1 1. inject : negated conditional → NO_COVERAGE
                    !(this.mediatorUtils.parameterUtil().getListRequest().isEmpty()
266 1 1. inject : negated conditional → NO_COVERAGE
                    && this.mediatorUtils.csrfUtil().getTokenCsrf() == null)
267
                ) {
268
                    report += InjectionModel.BR + StringUtil.formatReport(colorReport, "Body: ") + body;
269
                }
270
                report += InjectionModel.BR 
271
                    + StringUtil.formatReport(colorReport, "Header: ") 
272
                    + httpRequest.headers().map().entrySet().stream()
273
                    .map(entry -> 
274 1 1. lambda$inject$3 : replaced return value with "" for com/jsql/model/InjectionModel::lambda$inject$3 → NO_COVERAGE
                        String.format("%s: %s", entry.getKey(), 
275
                        String.join(StringUtils.EMPTY, entry.getValue()))
276
                    )
277
                    .collect(Collectors.joining(InjectionModel.BR));
278 1 1. inject : replaced return value with "" for com/jsql/model/InjectionModel::inject → NO_COVERAGE
                return report;
279
            }
280
            
281
            HttpResponse<String> response = this.getMediatorUtils().connectionUtil().getHttpClient().build().send(
282
                httpRequestBuilder.build(),
283
                BodyHandlers.ofString()
284
            );
285 1 1. inject : negated conditional → NO_COVERAGE
            if (this.mediatorUtils.parameterUtil().isRequestSoap()) {
286
                // Invalid XML control chars like \x04 requires urlencoding from server
287
                pageSource = URLDecoder.decode(response.body(), StandardCharsets.UTF_8);
288
                pageSource = StringUtil.fromHtml(pageSource);
289
            } else {
290
                pageSource = response.body();
291
            }
292
293
            Map<String, String> headersResponse = ConnectionUtil.getHeadersMap(response);
294
            int sizeHeaders = headersResponse.keySet()
295
                .stream()
296 2 1. lambda$inject$4 : Replaced integer addition with subtraction → NO_COVERAGE
2. lambda$inject$4 : replaced Integer return value with 0 for com/jsql/model/InjectionModel::lambda$inject$4 → NO_COVERAGE
                .map(key -> headersResponse.get(key).length() + key.length())
297
                .mapToInt(Integer::intValue)
298
                .sum();
299 2 1. inject : Replaced float division with multiplication → NO_COVERAGE
2. inject : Replaced integer addition with subtraction → NO_COVERAGE
            float size = (float) (pageSource.length() + sizeHeaders) / 1024;
300
            var decimalFormat = new DecimalFormat("0.000");
301
302
            String pageSourceFixed = pageSource
303
                .replaceAll("("+ EngineYaml.CALIBRATOR_SQL +"){60,}", "$1...")  // Remove ranges of # created by calibration
304
                .replaceAll("(jIyM){60,}", "$1...");  // Remove batch of chars created by Dios
305
306
            // Send data to Views
307 1 1. inject : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.sendToViews(new Seal.MessageHeader(
308
                urlInjectionFixed,
309
                body,
310
                ConnectionUtil.getHeadersMap(httpRequest.headers()),
311
                headersResponse,
312
                pageSourceFixed,
313
                decimalFormat.format(size),
314
                this.mediatorStrategy.getMeta(),
315
                metadataInjectionProcess,
316
                callableBoolean
317
            ));
318
        } catch (IOException e) {
319
            LOGGER.log(
320
                LogLevelUtil.CONSOLE_ERROR,
321
                String.format("Error during connection: %s", e.getMessage())
322
            );
323
        } catch (InterruptedException e) {
324
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
325 1 1. inject : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
326
        }
327
328 1 1. inject : replaced return value with "" for com/jsql/model/InjectionModel::inject → NO_COVERAGE
        return pageSource;
329
    }
330
331
    private String initQueryString(boolean isUsingIndex, String urlInjection, String dataInjection) {
332
        String urlInjectionFixed = urlInjection;
333
        if (
334 1 1. initQueryString : negated conditional → NO_COVERAGE
            this.mediatorUtils.parameterUtil().getListQueryString().isEmpty()
335 1 1. initQueryString : negated conditional → NO_COVERAGE
            && !this.mediatorUtils.preferencesUtil().isProcessingCsrf()
336
        ) {
337 1 1. initQueryString : replaced return value with "" for com/jsql/model/InjectionModel::initQueryString → NO_COVERAGE
            return urlInjectionFixed;
338
        }
339
            
340
        // URL without query string like Request and Header can receive
341
        // new params from <form> parsing, in that case add the '?' to URL
342 1 1. initQueryString : negated conditional → NO_COVERAGE
        if (!urlInjectionFixed.contains("?")) {
343
            urlInjectionFixed += "?";
344
        }
345
        urlInjectionFixed += this.buildQuery(
346
            this.mediatorMethod.getQuery(),
347
            this.mediatorUtils.parameterUtil().getQueryStringFromEntries(),
348
            isUsingIndex,
349
            dataInjection
350
        );
351 1 1. initQueryString : replaced return value with "" for com/jsql/model/InjectionModel::initQueryString → NO_COVERAGE
        return this.mediatorUtils.csrfUtil().addQueryStringToken(urlInjectionFixed);
352
    }
353
354
    private void initHeader(boolean isUsingIndex, String dataInjection, Builder httpRequest) {
355 1 1. initHeader : negated conditional → NO_COVERAGE
        if (!this.mediatorUtils.parameterUtil().getListHeader().isEmpty()) {
356
            Stream.of(
357
                this.buildQuery(
358
                    this.mediatorMethod.getHeader(),
359
                    this.mediatorUtils.parameterUtil().getHeaderFromEntries(),
360
                    isUsingIndex,
361
                    dataInjection
362
                )
363
                .split("\\\\r\\\\n")
364
            )
365 1 1. initHeader : removed call to java/util/stream/Stream::forEach → NO_COVERAGE
            .forEach(header -> {
366 1 1. lambda$initHeader$5 : negated conditional → NO_COVERAGE
                if (header.split(":").length == 2) {
367
                    try {  // TODO Should not catch, rethrow or use runtime exception
368 1 1. lambda$initHeader$5 : removed call to com/jsql/util/HeaderUtil::sanitizeHeaders → NO_COVERAGE
                        HeaderUtil.sanitizeHeaders(
369
                            httpRequest,
370
                            new SimpleEntry<>(
371
                                header.split(":")[0],
372
                                header.split(":")[1]
373
                            )
374
                        );
375
                    } catch (JSqlException e) {
376
                        LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Headers sanitizing issue caught already during connection, ignoring", e);
377
                    }
378
                }
379
            });
380
        }
381
    }
382
383
    private String initRequest(boolean isUsingIndex, String dataInjection, Builder httpRequest) {
384
        if (
385 1 1. initRequest : negated conditional → NO_COVERAGE
            this.mediatorUtils.parameterUtil().getListRequest().isEmpty()
386 1 1. initRequest : negated conditional → NO_COVERAGE
            && this.mediatorUtils.csrfUtil().getTokenCsrf() == null
387
        ) {
388 1 1. initRequest : replaced return value with "" for com/jsql/model/InjectionModel::initRequest → NO_COVERAGE
            return dataInjection;
389
        }
390
            
391
        // Set connection method
392
        // Active for query string injection too, in that case inject query string still with altered method
393
        
394 1 1. initRequest : negated conditional → NO_COVERAGE
        if (this.mediatorUtils.parameterUtil().isRequestSoap()) {
395
            httpRequest.setHeader(HeaderUtil.CONTENT_TYPE_REQUEST, "text/xml");
396
        } else {
397
            httpRequest.setHeader(HeaderUtil.CONTENT_TYPE_REQUEST, "application/x-www-form-urlencoded");
398
        }
399
400
        var body = new StringBuilder();
401 1 1. initRequest : removed call to com/jsql/util/CsrfUtil::addRequestToken → NO_COVERAGE
        this.mediatorUtils.csrfUtil().addRequestToken(body);
402
            
403 1 1. initRequest : negated conditional → NO_COVERAGE
        if (this.mediatorUtils.connectionUtil().getTypeRequest().matches("PUT|POST")) {
404 1 1. initRequest : negated conditional → NO_COVERAGE
            if (this.mediatorUtils.parameterUtil().isRequestSoap()) {
405
                body.append(
406
                    this.buildQuery(
407
                        this.mediatorMethod.getRequest(),
408
                        this.mediatorUtils.parameterUtil().getRawRequest(),
409
                        isUsingIndex,
410
                        dataInjection
411
                    )
412
                    // Invalid XML characters in recent Spring version
413
                    // Server needs to urldecode, or stop using out of range chars
414
                    .replace("\u0001", "&#01;")
415
                    .replace("\u0003", "&#03;")
416
                    .replace("\u0004", "&#04;")
417
                    .replace("\u0005", "&#05;")
418
                    .replace("\u0006", "&#06;")
419
                    .replace("\u0007", "&#07;")
420
                    .replace("+", "%2B")  // Prevent replace '+' into 'space' on server side urldecode
421
                );
422
            } else {
423
                body.append(
424
                    this.buildQuery(
425
                        this.mediatorMethod.getRequest(),
426
                        this.mediatorUtils.parameterUtil().getRequestFromEntries(),
427
                        isUsingIndex,
428
                        dataInjection
429
                    )
430
                );
431
            }
432
        }
433
        
434
        var bodyPublisher = BodyPublishers.ofString(body.toString());
435
        httpRequest.method(
436
            this.mediatorUtils.connectionUtil().getTypeRequest(),
437
            bodyPublisher
438
        );
439 1 1. initRequest : replaced return value with "" for com/jsql/model/InjectionModel::initRequest → NO_COVERAGE
        return body.toString();
440
    }
441
    
442
    private String buildQuery(AbstractMethodInjection methodInjection, String paramLead, boolean isUsingIndex, String sqlTrail) {
443
        String query;
444
        String paramLeadFixed = paramLead.replace(
445
            InjectionModel.STAR,
446
            TamperingUtil.TAG_OPENED + InjectionModel.STAR + TamperingUtil.TAG_CLOSED
447
        );
448
        if (
449
            // No parameter transformation if method is not selected by user
450 1 1. buildQuery : negated conditional → NO_COVERAGE
            this.mediatorUtils.connectionUtil().getMethodInjection() != methodInjection
451
            // No parameter transformation if injection point in URL
452 1 1. buildQuery : negated conditional → NO_COVERAGE
            || this.mediatorUtils.connectionUtil().getUrlBase().contains(InjectionModel.STAR)
453
        ) {
454
            query = paramLeadFixed;  // Just pass parameters without any transformation
455
        } else if (
456
            // If method is selected by user and URL does not contain injection point
457
            // but parameters contain an injection point
458
            // then replace injection point by SQL expression in this parameter
459 1 1. buildQuery : negated conditional → NO_COVERAGE
            paramLeadFixed.contains(InjectionModel.STAR)
460
        ) {
461
            query = this.initStarInjection(paramLeadFixed, isUsingIndex, sqlTrail);
462
        } else {
463
            query = this.initRawInjection(paramLeadFixed, isUsingIndex, sqlTrail);
464
        }
465
        query = this.cleanQuery(methodInjection, query);  // Remove comments except empty /**/
466
        // Add empty comments with space=>/**/
467 1 1. buildQuery : negated conditional → NO_COVERAGE
        if (this.mediatorUtils.connectionUtil().getMethodInjection() == methodInjection) {
468
            query = this.mediatorUtils.tamperingUtil().tamper(query);
469
        }
470 1 1. buildQuery : replaced return value with "" for com/jsql/model/InjectionModel::buildQuery → NO_COVERAGE
        return this.applyEncoding(methodInjection, query);
471
    }
472
473
    private String initRawInjection(String paramLead, boolean isUsingIndex, String sqlTrail) {
474
        String query;
475
        // Method is selected by user and there's no injection point
476 1 1. initRawInjection : negated conditional → NO_COVERAGE
        if (!isUsingIndex) {
477
            // Several SQL expressions does not use indexes in SELECT,
478
            // like Boolean, Error, Shell and search for character insertion,
479
            // in that case concat SQL expression to the end of param.
480
            query = paramLead + sqlTrail;
481
        } else {
482
            // Concat indexes found for Union strategy to params
483
            // and use visible Index for injection
484
            query = paramLead + this.getMediatorStrategy().getSpecificUnion().getIndexesInUrl().replaceAll(
485
                String.format(EngineYaml.FORMAT_INDEX, this.mediatorStrategy.getSpecificUnion().getVisibleIndex()),
486
                // Oracle column often contains $, which is reserved for regex.
487
                // => need to be escape with quoteReplacement()
488
                Matcher.quoteReplacement(sqlTrail)
489
            );
490
        }
491
        // Add ending line comment by engine
492 1 1. initRawInjection : replaced return value with "" for com/jsql/model/InjectionModel::initRawInjection → NO_COVERAGE
        return query + this.mediatorEngine.getEngine().instance().endingComment();
493
    }
494
495
    private String initStarInjection(String paramLead, boolean isUsingIndex, String sqlTrail) {
496
        String query;
497
        // Several SQL expressions does not use indexes in SELECT,
498
        // like Boolean, Error, Shell and search for character insertion,
499
        // in that case replace injection point by SQL expression.
500
        // Injection point is always at the end?
501 1 1. initStarInjection : negated conditional → NO_COVERAGE
        if (!isUsingIndex) {
502
            query = paramLead.replace(
503
                InjectionModel.STAR,
504
                sqlTrail + this.mediatorEngine.getEngine().instance().endingComment()
505
            );
506
        } else {
507
            // Replace injection point by indexes found for Union strategy
508
            // and use visible Index for injection
509
            query = paramLead.replace(
510
                InjectionModel.STAR,
511
                this.mediatorStrategy.getSpecificUnion().getIndexesInUrl().replace(
512
                    String.format(EngineYaml.FORMAT_INDEX, this.mediatorStrategy.getSpecificUnion().getVisibleIndex()),
513
                    sqlTrail
514
                )
515
                + this.mediatorEngine.getEngine().instance().endingComment()
516
            );
517
        }
518 1 1. initStarInjection : replaced return value with "" for com/jsql/model/InjectionModel::initStarInjection → NO_COVERAGE
        return query;
519
    }
520
521
    /**
522
     * Dependency:
523
     * - Tamper space=>comment
524
     */
525
    private String cleanQuery(AbstractMethodInjection methodInjection, String query) {
526
        String queryFixed = query;
527
        if (
528 1 1. cleanQuery : negated conditional → NO_COVERAGE
            methodInjection == this.mediatorMethod.getRequest()
529
            && (
530 1 1. cleanQuery : negated conditional → NO_COVERAGE
                this.mediatorUtils.parameterUtil().isRequestSoap()
531 1 1. cleanQuery : negated conditional → NO_COVERAGE
                || this.mediatorUtils.parameterUtil().isMultipartRequest()
532
            )
533
        ) {
534
            queryFixed = StringUtil.removeSqlComment(queryFixed)
535
                .replace("+", " ")
536
                .replace("%2b", "+")  // Failsafe
537
                .replace("%23", "#");  // End comment
538 1 1. cleanQuery : negated conditional → NO_COVERAGE
            if (this.mediatorUtils.parameterUtil().isMultipartRequest()) {
539
                // restore linefeed from textfield
540
                queryFixed = queryFixed.replaceAll("(?s)\\\\n", "\r\n");
541
            }
542
        } else {
543
            queryFixed = StringUtil.cleanSql(queryFixed);
544
        }
545 1 1. cleanQuery : replaced return value with "" for com/jsql/model/InjectionModel::cleanQuery → NO_COVERAGE
        return queryFixed;
546
    }
547
548
    private String applyEncoding(AbstractMethodInjection methodInjection, String query) {
549
        String queryFixed = query;
550 1 1. applyEncoding : negated conditional → NO_COVERAGE
        if (!this.mediatorUtils.parameterUtil().isRequestSoap()) {
551 1 1. applyEncoding : negated conditional → NO_COVERAGE
            if (methodInjection == this.mediatorMethod.getQuery()) {
552
                // URL encode each character because no query parameter context
553 1 1. applyEncoding : negated conditional → NO_COVERAGE
                if (!this.mediatorUtils.preferencesUtil().isUrlEncodingDisabled()) {
554
                    queryFixed = queryFixed.replace("'", "%27");
555
                    queryFixed = queryFixed.replace("(", "%28");
556
                    queryFixed = queryFixed.replace(")", "%29");
557
                    queryFixed = queryFixed.replace("{", "%7b");
558
                    queryFixed = queryFixed.replace("[", "%5b");
559
                    queryFixed = queryFixed.replace("]", "%5d");
560
                    queryFixed = queryFixed.replace("}", "%7d");
561
                    queryFixed = queryFixed.replace(">", "%3e");
562
                    queryFixed = queryFixed.replace("<", "%3c");
563
                    queryFixed = queryFixed.replace("?", "%3f");
564
                    queryFixed = queryFixed.replace("_", "%5f");
565
                    queryFixed = queryFixed.replace(",", "%2c");
566
                }
567
                // HTTP forbidden characters
568
                queryFixed = queryFixed.replace(StringUtils.SPACE, "+");
569
                queryFixed = queryFixed.replace("`", "%60");  // from `${database}`.`${table}`
570
                queryFixed = queryFixed.replace("\"", "%22");
571
                queryFixed = queryFixed.replace("|", "%7c");
572
                queryFixed = queryFixed.replace("\\", "%5c");
573 1 1. applyEncoding : negated conditional → NO_COVERAGE
            } else if (methodInjection != this.mediatorMethod.getRequest()) {
574
                // For cookies in Spring (confirmed, covered by integration tests)
575
                queryFixed = queryFixed.replace("+", "%20");
576
                queryFixed = queryFixed.replace(",", "%2c");
577
                try {  // fix #95709: IllegalArgumentException on decode()
578
                    queryFixed = URLDecoder.decode(queryFixed, StandardCharsets.UTF_8);
579
                } catch (IllegalArgumentException e) {
580
                    LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Incorrect values in [{}], please check the parameters", methodInjection.name());
581
                    throw new JSqlRuntimeException(e);
582
                }
583
            }
584
        }
585 1 1. applyEncoding : replaced return value with "" for com/jsql/model/InjectionModel::applyEncoding → NO_COVERAGE
        return queryFixed;
586
    }
587
    
588
    /**
589
     * Display source code in console.
590
     * @param message Error message
591
     * @param source Text to display in console
592
     */
593
    public void sendResponseFromSite(String message, String source) {
594
        LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "{}, response from site:", message);
595
        LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ">>>{}", source);
596
    }
597
    
598
    
599
    // Getters and setters
600
601
    public boolean shouldErasePreviousInjection() {
602 2 1. shouldErasePreviousInjection : replaced boolean return with false for com/jsql/model/InjectionModel::shouldErasePreviousInjection → NO_COVERAGE
2. shouldErasePreviousInjection : replaced boolean return with true for com/jsql/model/InjectionModel::shouldErasePreviousInjection → NO_COVERAGE
        return this.shouldErasePreviousInjection;
603
    }
604
605
    public void setIsScanning(boolean isScanning) {
606
        this.isScanning = isScanning;
607
    }
608
609
    public PropertiesUtil getPropertiesUtil() {
610 1 1. getPropertiesUtil : replaced return value with null for com/jsql/model/InjectionModel::getPropertiesUtil → NO_COVERAGE
        return this.propertiesUtil;
611
    }
612
613
    public MediatorUtils getMediatorUtils() {
614 1 1. getMediatorUtils : replaced return value with null for com/jsql/model/InjectionModel::getMediatorUtils → KILLED
        return this.mediatorUtils;
615
    }
616
617
    public MediatorEngine getMediatorEngine() {
618 1 1. getMediatorEngine : replaced return value with null for com/jsql/model/InjectionModel::getMediatorEngine → KILLED
        return this.mediatorEngine;
619
    }
620
621
    public MediatorMethod getMediatorMethod() {
622 1 1. getMediatorMethod : replaced return value with null for com/jsql/model/InjectionModel::getMediatorMethod → KILLED
        return this.mediatorMethod;
623
    }
624
625
    public DataAccess getDataAccess() {
626 1 1. getDataAccess : replaced return value with null for com/jsql/model/InjectionModel::getDataAccess → NO_COVERAGE
        return this.dataAccess;
627
    }
628
629
    public ResourceAccess getResourceAccess() {
630 1 1. getResourceAccess : replaced return value with null for com/jsql/model/InjectionModel::getResourceAccess → NO_COVERAGE
        return this.resourceAccess;
631
    }
632
633
    public MediatorStrategy getMediatorStrategy() {
634 1 1. getMediatorStrategy : replaced return value with null for com/jsql/model/InjectionModel::getMediatorStrategy → KILLED
        return this.mediatorStrategy;
635
    }
636
637
    public void appendAnalysisReport(String analysisReport) {
638 1 1. appendAnalysisReport : removed call to com/jsql/model/InjectionModel::appendAnalysisReport → NO_COVERAGE
        this.appendAnalysisReport(analysisReport, false);
639
    }
640
641
    public void appendAnalysisReport(String analysisReport, boolean isInit) {
642 1 1. appendAnalysisReport : negated conditional → NO_COVERAGE
        this.analysisReport += (isInit ? StringUtils.EMPTY : "<br>&#10;<br>&#10;") + analysisReport;
643
    }
644
}

Mutations

114

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

115

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

116

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

117

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

118

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

119

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyError::setApplicable → NO_COVERAGE

120

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

121

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/AbstractStrategy::setApplicable → NO_COVERAGE

122

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/MediatorStrategy::setStrategy → NO_COVERAGE

124

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyUnion::setVisibleIndex → NO_COVERAGE

125

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyUnion::setIndexesInUrl → NO_COVERAGE

131

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/util/CsrfUtil::setTokenCsrf → NO_COVERAGE

132

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/util/DigestUtil::setTokenDigest → NO_COVERAGE

133

1.1
Location : resetModel
Killed by : none
removed call to com/jsql/util/ThreadUtil::reset → NO_COVERAGE

142

1.1
Location : beginInjection
Killed by : none
removed call to com/jsql/model/InjectionModel::resetModel → NO_COVERAGE

144

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

150

1.1
Location : lambda$beginInjection$0
Killed by : none
replaced return value with null for com/jsql/model/InjectionModel::lambda$beginInjection$0 → NO_COVERAGE

151

1.1
Location : lambda$beginInjection$1
Killed by : none
replaced return value with null for com/jsql/model/InjectionModel::lambda$beginInjection$1 → NO_COVERAGE

155

1.1
Location : beginInjection
Killed by : none
removed call to com/jsql/util/ParameterUtil::checkParametersFormat → NO_COVERAGE

156

1.1
Location : beginInjection
Killed by : none
removed call to com/jsql/util/ConnectionUtil::testConnection → NO_COVERAGE

166

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

167

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

168

1.1
Location : beginInjection
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

170

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

172

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

175

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

176

1.1
Location : beginInjection
Killed by : none
removed call to com/jsql/model/accessible/DataAccess::getDatabaseInfos → NO_COVERAGE

185

1.1
Location : beginInjection
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

190

1.1
Location : beginInjection
Killed by : none
negated conditional → NO_COVERAGE

193

1.1
Location : beginInjection
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

199

1.1
Location : getImplicitReason
Killed by : none
negated conditional → NO_COVERAGE

202

1.1
Location : getImplicitReason
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : getImplicitReason
Killed by : none
negated conditional → NO_COVERAGE

205

1.1
Location : getImplicitReason
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::getImplicitReason → NO_COVERAGE

249

1.1
Location : inject
Killed by : none
removed call to com/jsql/util/CsrfUtil::addHeaderToken → NO_COVERAGE

250

1.1
Location : inject
Killed by : none
removed call to com/jsql/util/DigestUtil::addHeaderToken → NO_COVERAGE

251

1.1
Location : inject
Killed by : none
removed call to com/jsql/util/ConnectionUtil::setCustomUserAgent → NO_COVERAGE

254

1.1
Location : inject
Killed by : none
removed call to com/jsql/model/InjectionModel::initHeader → NO_COVERAGE

257

1.1
Location : inject
Killed by : none
negated conditional → NO_COVERAGE

261

1.1
Location : inject
Killed by : none
negated conditional → NO_COVERAGE

265

1.1
Location : inject
Killed by : none
negated conditional → NO_COVERAGE

266

1.1
Location : inject
Killed by : none
negated conditional → NO_COVERAGE

274

1.1
Location : lambda$inject$3
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::lambda$inject$3 → NO_COVERAGE

278

1.1
Location : inject
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::inject → NO_COVERAGE

285

1.1
Location : inject
Killed by : none
negated conditional → NO_COVERAGE

296

1.1
Location : lambda$inject$4
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : lambda$inject$4
Killed by : none
replaced Integer return value with 0 for com/jsql/model/InjectionModel::lambda$inject$4 → NO_COVERAGE

299

1.1
Location : inject
Killed by : none
Replaced float division with multiplication → NO_COVERAGE

2.2
Location : inject
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

307

1.1
Location : inject
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

325

1.1
Location : inject
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

328

1.1
Location : inject
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::inject → NO_COVERAGE

334

1.1
Location : initQueryString
Killed by : none
negated conditional → NO_COVERAGE

335

1.1
Location : initQueryString
Killed by : none
negated conditional → NO_COVERAGE

337

1.1
Location : initQueryString
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::initQueryString → NO_COVERAGE

342

1.1
Location : initQueryString
Killed by : none
negated conditional → NO_COVERAGE

351

1.1
Location : initQueryString
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::initQueryString → NO_COVERAGE

355

1.1
Location : initHeader
Killed by : none
negated conditional → NO_COVERAGE

365

1.1
Location : initHeader
Killed by : none
removed call to java/util/stream/Stream::forEach → NO_COVERAGE

366

1.1
Location : lambda$initHeader$5
Killed by : none
negated conditional → NO_COVERAGE

368

1.1
Location : lambda$initHeader$5
Killed by : none
removed call to com/jsql/util/HeaderUtil::sanitizeHeaders → NO_COVERAGE

385

1.1
Location : initRequest
Killed by : none
negated conditional → NO_COVERAGE

386

1.1
Location : initRequest
Killed by : none
negated conditional → NO_COVERAGE

388

1.1
Location : initRequest
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::initRequest → NO_COVERAGE

394

1.1
Location : initRequest
Killed by : none
negated conditional → NO_COVERAGE

401

1.1
Location : initRequest
Killed by : none
removed call to com/jsql/util/CsrfUtil::addRequestToken → NO_COVERAGE

403

1.1
Location : initRequest
Killed by : none
negated conditional → NO_COVERAGE

404

1.1
Location : initRequest
Killed by : none
negated conditional → NO_COVERAGE

439

1.1
Location : initRequest
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::initRequest → NO_COVERAGE

450

1.1
Location : buildQuery
Killed by : none
negated conditional → NO_COVERAGE

452

1.1
Location : buildQuery
Killed by : none
negated conditional → NO_COVERAGE

459

1.1
Location : buildQuery
Killed by : none
negated conditional → NO_COVERAGE

467

1.1
Location : buildQuery
Killed by : none
negated conditional → NO_COVERAGE

470

1.1
Location : buildQuery
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::buildQuery → NO_COVERAGE

476

1.1
Location : initRawInjection
Killed by : none
negated conditional → NO_COVERAGE

492

1.1
Location : initRawInjection
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::initRawInjection → NO_COVERAGE

501

1.1
Location : initStarInjection
Killed by : none
negated conditional → NO_COVERAGE

518

1.1
Location : initStarInjection
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::initStarInjection → NO_COVERAGE

528

1.1
Location : cleanQuery
Killed by : none
negated conditional → NO_COVERAGE

530

1.1
Location : cleanQuery
Killed by : none
negated conditional → NO_COVERAGE

531

1.1
Location : cleanQuery
Killed by : none
negated conditional → NO_COVERAGE

538

1.1
Location : cleanQuery
Killed by : none
negated conditional → NO_COVERAGE

545

1.1
Location : cleanQuery
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::cleanQuery → NO_COVERAGE

550

1.1
Location : applyEncoding
Killed by : none
negated conditional → NO_COVERAGE

551

1.1
Location : applyEncoding
Killed by : none
negated conditional → NO_COVERAGE

553

1.1
Location : applyEncoding
Killed by : none
negated conditional → NO_COVERAGE

573

1.1
Location : applyEncoding
Killed by : none
negated conditional → NO_COVERAGE

585

1.1
Location : applyEncoding
Killed by : none
replaced return value with "" for com/jsql/model/InjectionModel::applyEncoding → NO_COVERAGE

602

1.1
Location : shouldErasePreviousInjection
Killed by : none
replaced boolean return with false for com/jsql/model/InjectionModel::shouldErasePreviousInjection → NO_COVERAGE

2.2
Location : shouldErasePreviousInjection
Killed by : none
replaced boolean return with true for com/jsql/model/InjectionModel::shouldErasePreviousInjection → NO_COVERAGE

610

1.1
Location : getPropertiesUtil
Killed by : none
replaced return value with null for com/jsql/model/InjectionModel::getPropertiesUtil → NO_COVERAGE

614

1.1
Location : getMediatorUtils
Killed by : ParameterUtilSpock.[engine:spock]/[spec:ParameterUtilSpock]/[feature:$spock_feature_0_2]
replaced return value with null for com/jsql/model/InjectionModel::getMediatorUtils → KILLED

618

1.1
Location : getMediatorEngine
Killed by : ParameterUtilSpock.[engine:spock]/[spec:ParameterUtilSpock]/[feature:$spock_feature_0_2]
replaced return value with null for com/jsql/model/InjectionModel::getMediatorEngine → KILLED

622

1.1
Location : getMediatorMethod
Killed by : ParameterUtilSpock.[engine:spock]/[spec:ParameterUtilSpock]/[feature:$spock_feature_0_1]
replaced return value with null for com/jsql/model/InjectionModel::getMediatorMethod → KILLED

626

1.1
Location : getDataAccess
Killed by : none
replaced return value with null for com/jsql/model/InjectionModel::getDataAccess → NO_COVERAGE

630

1.1
Location : getResourceAccess
Killed by : none
replaced return value with null for com/jsql/model/InjectionModel::getResourceAccess → NO_COVERAGE

634

1.1
Location : getMediatorStrategy
Killed by : ParameterUtilSpock.[engine:spock]/[spec:ParameterUtilSpock]/[feature:$spock_feature_0_2]
replaced return value with null for com/jsql/model/InjectionModel::getMediatorStrategy → KILLED

638

1.1
Location : appendAnalysisReport
Killed by : none
removed call to com/jsql/model/InjectionModel::appendAnalysisReport → NO_COVERAGE

642

1.1
Location : appendAnalysisReport
Killed by : none
negated conditional → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.22.1