EngineYaml.java

1
package com.jsql.model.injection.engine.model;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.bean.database.Database;
5
import com.jsql.model.bean.database.Table;
6
import com.jsql.model.injection.strategy.blind.AbstractInjectionBit.BlindOperator;
7
import com.jsql.model.injection.engine.model.yaml.Method;
8
import com.jsql.model.injection.engine.model.yaml.ModelYaml;
9
import com.jsql.util.LogLevelUtil;
10
import com.jsql.util.StringUtil;
11
import org.apache.commons.codec.binary.Hex;
12
import org.apache.commons.lang3.RandomStringUtils;
13
import org.apache.commons.lang3.StringUtils;
14
import org.apache.logging.log4j.LogManager;
15
import org.apache.logging.log4j.Logger;
16
import org.yaml.snakeyaml.Yaml;
17
18
import java.net.URLEncoder;
19
import java.nio.charset.StandardCharsets;
20
import java.util.ArrayList;
21
import java.util.Collections;
22
import java.util.List;
23
import java.util.concurrent.ThreadLocalRandom;
24
import java.util.regex.Pattern;
25
26
import static com.jsql.model.accessible.DataAccess.*;
27
28
public class EngineYaml implements AbstractEngine {
29
    
30
    private static final Logger LOGGER = LogManager.getRootLogger();
31
32
    /**
33
     * SQL characters marking the end of the result of an injection.
34
     * Process stops when this schema is encountered:
35
     * <pre>SqLix01x03x03x07
36
     */
37
    public static final String LEAD_HEX = "0x53714c69";
38
    public static final String LEAD_PIPE = "Sq'||'Li";
39
    public static final String TRAIL_SQL = "%01%03%03%07";
40
    public static final String TRAIL_HEX = "0x01030307";
41
42
    /**
43
     * SQL character used between each table cells.
44
     * Expected schema of multiple table cells :
45
     * <pre>
46
     * %04[table cell]%05[number of occurrences]%04%06%04[table cell]%05[number of occurrences]%04
47
     */
48
    public static final String SEPARATOR_CELL_SQL = "%06";
49
    public static final String SEPARATOR_CELL_HEX = "0x06";
50
51
    public static final String ENCLOSE_VALUE_HEX = "0x04";
52
53
    /**
54
     * SQL character used between the table cell and the number of occurrence of the cell text.
55
     * Expected schema of a table cell data is
56
     * <pre>%04[table cell]%05[number of occurrences]%04
57
     */
58
    public static final String SEPARATOR_QTE_SQL = "%05";
59
    public static final String SEPARATOR_QTE_HEX = "0x05";
60
61
    /**
62
     * SQL character enclosing a table cell returned by injection.
63
     * It allows to detect the correct end of a table cell data during parsing.
64
     * Expected schema of a table cell data is
65
     * <pre>%04[table cell]%05[number of occurrences]%04
66
     */
67
    public static final String ENCLOSE_VALUE_SQL = "%04";
68
69
    public static final String CALIBRATOR_SQL = "a";
70
    public static final String CALIBRATOR_HEX = "0x61";
71
    
72
    public static final String FORMAT_INDEX = "1337%s7331";
73
74
    private static final String BINARY_MODE = "${binary.mode}";
75
    public static final String LIMIT = "${limit}";
76
    private static final String LIMIT_VALUE = "${limit.value}";
77
    private static final String RESULT_RANGE = "${result_range}";
78
    private static final String INDICE_UNIQUE = "${indice_unique}";
79
    private static final String CALIBRATOR = "${calibrator}";
80
    private static final String INDICES = "${indices}";
81
    public static final String INDICE = "${indice}";
82
    public static final String WINDOW_CHAR = "${window.char}";
83
    public static final String BLOCK_MULTIBIT = "${multibit.block}";
84
    public static final String WINDOW = "${window}";
85
    public static final String CAPACITY = "${capacity}";
86
    public static final String DEFAULT_CAPACITY = "65565";
87
    private static final String SLEEP_TIME = "${sleep_time}";
88
    private static final String BIT = "${bit}";
89
    private static final String MID_CHR = "${mid}";
90
    private static final String MID_INT = "${mid.int}";
91
    public static final String INJECTION = "${injection}";
92
    public static final String TEST = "${test}";
93
    public static final String FILEPATH_HEX = "${filepath.hex}";
94
    private static final String FIELDS = "${fields}";
95
    private static final String FIELD = "${field.value}";
96
    private static final String TABLE = "${table}";
97
    private static final String DATABASE = "${database}";
98
    private static final String TABLE_HEX = "${table.hex}";
99
    private static final String DATABASE_HEX = "${database.hex}";
100
    private static final String DNS_DOMAIN = "${dns.domain}";
101
    private static final String DNS_RANDOM = "${dns.random}";
102
103
    private final ModelYaml modelYaml;
104
    private final InjectionModel injectionModel;
105
    
106
    public EngineYaml(String fileYaml, InjectionModel injectionModel) {
107
        this.injectionModel = injectionModel;
108
        var yaml = new Yaml();
109
        this.modelYaml = yaml.loadAs(
110
            EngineYaml.class.getClassLoader().getResourceAsStream("engine/" + fileYaml),
111
            ModelYaml.class
112
        );
113
    }
114
115
    @Override
116
    public String sqlDatabases() {
117
        String sqlQuery = this.modelYaml.getResource().getSchema().getDatabase();
118
        
119 1 1. sqlDatabases : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().preferencesUtil().isDiosStrategy()) {
120 1 1. sqlDatabases : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getDatabase())) {
121
                sqlQuery = this.modelYaml.getResource().getDios().getDatabase();
122
            } else {
123
                LOGGER.log(
124
                    LogLevelUtil.CONSOLE_INFORM,
125
                    "Strategy [Dios] activated but database query is undefined for [{}], fallback to default",
126 1 1. lambda$sqlDatabases$0 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlDatabases$0 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
127
                );
128
            }
129 1 1. sqlDatabases : negated conditional → NO_COVERAGE
        } else if (this.injectionModel.getMediatorUtils().preferencesUtil().isZipStrategy()) {
130 1 1. sqlDatabases : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getDatabase())) {
131
                sqlQuery = this.modelYaml.getResource().getZip().getDatabase();
132
            } else {
133
                LOGGER.log(
134
                    LogLevelUtil.CONSOLE_INFORM,
135
                    "Strategy [Zip] activated but database query is undefined for [{}], fallback to default",
136 1 1. lambda$sqlDatabases$1 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlDatabases$1 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
137
                );
138
            }
139
        }
140 1 1. sqlDatabases : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlDatabases → NO_COVERAGE
        return sqlQuery;
141
    }
142
    
143
    @Override
144
    public String sqlTables(Database database) {
145
        String sqlQuery = this.modelYaml.getResource().getSchema().getTable();
146
        
147 1 1. sqlTables : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().preferencesUtil().isDiosStrategy()) {
148 1 1. sqlTables : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getTable())) {
149
                sqlQuery = this.modelYaml.getResource().getDios().getTable();
150
            } else {
151
                LOGGER.log(
152
                    LogLevelUtil.CONSOLE_INFORM,
153
                    "Strategy [Dios] activated but table query is undefined for [{}], fallback to default",
154 1 1. lambda$sqlTables$2 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlTables$2 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
155
                );
156
            }
157 1 1. sqlTables : negated conditional → NO_COVERAGE
        } else if (this.injectionModel.getMediatorUtils().preferencesUtil().isZipStrategy()) {
158 1 1. sqlTables : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getTable())) {
159
                sqlQuery = this.modelYaml.getResource().getZip().getTable();
160
            } else {
161
                LOGGER.log(
162
                    LogLevelUtil.CONSOLE_INFORM,
163
                    "Strategy [Zip] activated but table query is undefined for [{}], fallback to default",
164 1 1. lambda$sqlTables$3 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlTables$3 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
165
                );
166
            }
167
        }
168
        
169
        String databaseUtf8 = Hex.encodeHexString(database.toString().getBytes(StandardCharsets.UTF_8));
170 1 1. sqlTables : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTables → NO_COVERAGE
        return sqlQuery
171
            .replace(EngineYaml.DATABASE_HEX, databaseUtf8)
172
            .replace(EngineYaml.DATABASE, database.toString());
173
    }
174
175
    @Override
176
    public String sqlColumns(Table table) {
177
        String sqlQuery = this.modelYaml.getResource().getSchema().getColumn();
178
        
179 1 1. sqlColumns : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().preferencesUtil().isDiosStrategy()) {
180 1 1. sqlColumns : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getColumn())) {
181
                sqlQuery = this.modelYaml.getResource().getDios().getColumn();
182
            } else {
183
                LOGGER.log(
184
                    LogLevelUtil.CONSOLE_INFORM,
185
                    "Strategy [Dios] activated but column query is undefined for [{}], fallback to default",
186 1 1. lambda$sqlColumns$4 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlColumns$4 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
187
                );
188
            }
189 1 1. sqlColumns : negated conditional → NO_COVERAGE
        } else if (this.injectionModel.getMediatorUtils().preferencesUtil().isZipStrategy()) {
190 1 1. sqlColumns : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getColumn())) {
191
                sqlQuery = this.modelYaml.getResource().getZip().getColumn();
192
            } else {
193
                LOGGER.log(
194
                    LogLevelUtil.CONSOLE_INFORM,
195
                    "Strategy [Zip] activated but column query is undefined for [{}], fallback to default",
196 1 1. lambda$sqlColumns$5 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlColumns$5 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
197
                );
198
            }
199
        }
200
        
201
        String databaseUtf8 = Hex.encodeHexString(table.getParent().toString().getBytes(StandardCharsets.UTF_8));
202
        String tableUtf8 = Hex.encodeHexString(table.toString().getBytes(StandardCharsets.UTF_8));
203
        
204 1 1. sqlColumns : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlColumns → NO_COVERAGE
        return sqlQuery
205
            .replace(EngineYaml.DATABASE_HEX, databaseUtf8)
206
            .replace(EngineYaml.TABLE_HEX, tableUtf8)
207
            .replace(EngineYaml.DATABASE, table.getParent().toString())
208
            .replace(EngineYaml.TABLE, table.toString());
209
    }
210
211
    @Override
212
    public String sqlRows(String[] namesColumns, Database database, Table table) {
213
        String sqlField = this.modelYaml.getResource().getSchema().getRow().getFields().getField();
214
        String sqlConcatFields = this.modelYaml.getResource().getSchema().getRow().getFields().getConcat();
215
        String sqlQuery = this.modelYaml.getResource().getSchema().getRow().getQuery();
216
        
217 1 1. sqlRows : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().preferencesUtil().isDiosStrategy()) {
218 1 1. sqlRows : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getDatabase())) {
219
                sqlField = this.modelYaml.getResource().getDios().getRow().getFields().getField();
220
                sqlConcatFields = this.modelYaml.getResource().getDios().getRow().getFields().getConcat();
221
                sqlQuery = this.modelYaml.getResource().getDios().getRow().getQuery();
222
            } else {
223
                LOGGER.log(
224
                    LogLevelUtil.CONSOLE_INFORM,
225
                    "Strategy [Dios] activated but row query is undefined for [{}], fallback to default",
226 1 1. lambda$sqlRows$6 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlRows$6 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
227
                );
228
            }
229 1 1. sqlRows : negated conditional → NO_COVERAGE
        } else if (this.injectionModel.getMediatorUtils().preferencesUtil().isZipStrategy()) {
230 1 1. sqlRows : negated conditional → NO_COVERAGE
            if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getDatabase())) {
231
                sqlField = this.modelYaml.getResource().getZip().getRow().getFields().getField();
232
                sqlConcatFields = this.modelYaml.getResource().getZip().getRow().getFields().getConcat();
233
                sqlQuery = this.modelYaml.getResource().getZip().getRow().getQuery();
234
            } else {
235
                LOGGER.log(
236
                    LogLevelUtil.CONSOLE_INFORM,
237
                    "Strategy [Zip] activated but row query is undefined for [{}], fallback to default",
238 1 1. lambda$sqlRows$7 : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlRows$7 → NO_COVERAGE
                    () -> this.injectionModel.getMediatorEngine().getEngine()
239
                );
240
            }
241
        }
242
        
243
        var matcherSqlField = Pattern.compile("(?s)(.*)"+ Pattern.quote(EngineYaml.FIELD) +"(.*)").matcher(sqlField);
244
        String leadSqlField = StringUtils.EMPTY;
245
        String trailSqlField = StringUtils.EMPTY;
246
        
247 1 1. sqlRows : negated conditional → NO_COVERAGE
        if (matcherSqlField.find()) {
248
            leadSqlField = matcherSqlField.group(1);
249
            trailSqlField = matcherSqlField.group(2);
250
        }
251
        
252
        var namesColumnUtf8 = new String[namesColumns.length];
253 2 1. sqlRows : changed conditional boundary → NO_COVERAGE
2. sqlRows : negated conditional → NO_COVERAGE
        for (var i = 0 ; i < namesColumns.length ; i++) {
254
            namesColumnUtf8[i] = StringUtil.detectUtf8(namesColumns[i]);
255
            namesColumnUtf8[i] = URLEncoder.encode(namesColumnUtf8[i], StandardCharsets.UTF_8);
256
        }
257
        
258
        var nameDatabaseUtf8 = StringUtil.detectUtf8(database.toString());
259
        nameDatabaseUtf8 = URLEncoder.encode(nameDatabaseUtf8, StandardCharsets.UTF_8);
260
        
261
        var nameTableUtf8 = StringUtil.detectUtf8(table.toString());
262
        nameTableUtf8 = URLEncoder.encode(nameTableUtf8, StandardCharsets.UTF_8);
263
        
264 1 1. sqlRows : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlRows → NO_COVERAGE
        return sqlQuery.replace(
265
                EngineYaml.FIELDS,
266
                leadSqlField
267
                + String.join(
268
                    trailSqlField + sqlConcatFields + leadSqlField,
269
                    namesColumnUtf8
270
                )
271
                + trailSqlField
272
            )
273
            .replace(EngineYaml.DATABASE, nameDatabaseUtf8)
274
            .replace(EngineYaml.TABLE, nameTableUtf8);
275
    }
276
277
    @Override
278
    public String sqlTestBlindWithOperator(String check, BlindOperator blindOperator) {
279
        String replacement = this.getMode(blindOperator);
280 1 1. sqlTestBlindWithOperator : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTestBlindWithOperator → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getBlind()
281
            .replace(EngineYaml.BINARY_MODE, replacement)
282
            .replace(EngineYaml.TEST, check)
283
            .trim();  // trim spaces in '${binary.mode} ${test}' when no mode, not covered by cleanSql()
284
    }
285
286
    @Override
287
    public String sqlBlindBit(String inj, int indexChar, int bit, BlindOperator blindOperator) {
288
        String replacement = this.getMode(blindOperator);
289 1 1. sqlBlindBit : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlindBit → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getBlind()
290
            .replace(EngineYaml.BINARY_MODE, replacement)
291
            .replace(
292
                EngineYaml.TEST,
293
                this.modelYaml.getStrategy().getBinary().getTest().getBit()
294
                .replace(EngineYaml.INJECTION, inj)
295
                .replace(EngineYaml.WINDOW_CHAR, Integer.toString(indexChar))
296
                .replace(EngineYaml.BIT, Integer.toString(bit))
297
            )
298
            .trim();  // trim spaces in '${binary.mode} ${test}' when no mode, not covered by cleanSql()
299
    }
300
301
    @Override
302
    public String sqlBlindBin(String inj, int indexChar, int mid, BlindOperator blindOperator) {
303
        String replacement = this.getMode(blindOperator);
304 1 1. sqlBlindBin : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlindBin → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getBlind()
305
            .replace(EngineYaml.BINARY_MODE, replacement)
306
            .replace(
307
                EngineYaml.TEST,
308
                this.modelYaml.getStrategy().getBinary().getTest().getBin()
309
                .replace(EngineYaml.INJECTION, inj)
310
                .replace(EngineYaml.WINDOW_CHAR, Integer.toString(indexChar))
311
                .replace(
312
                    EngineYaml.MID_CHR,
313
                    StringUtil.toUrl(Character.toString((char) mid).replace("'", "''"))  // escape quote
314
                )
315
                .replace(EngineYaml.MID_INT, String.valueOf(mid))
316
            )
317
            .trim();  // trim spaces in '${binary.mode} ${test}' when no mode, not covered by cleanSql()
318
    }
319
320
    @Override
321
    public String sqlTestTimeWithOperator(String check, BlindOperator blindOperator) {
322
        String replacement = this.getMode(blindOperator);
323 1 1. sqlTestTimeWithOperator : negated conditional → NO_COVERAGE
        int countSleepTimeStrategy = this.injectionModel.getMediatorUtils().preferencesUtil().isLimitingSleepTimeStrategy()
324
            ? this.injectionModel.getMediatorUtils().preferencesUtil().countSleepTimeStrategy()
325
            : 5;
326 1 1. sqlTestTimeWithOperator : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTestTimeWithOperator → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTime()
327
            .replace(EngineYaml.BINARY_MODE, replacement)
328
            .replace(EngineYaml.TEST, check)
329
            .replace(EngineYaml.SLEEP_TIME, Long.toString(countSleepTimeStrategy))
330
            .trim();  // trim spaces in '${binary.mode} ${test}' when no mode, not covered by cleanSql()
331
    }
332
333
    @Override
334
    public String sqlTimeBit(String inj, int indexChar, int bit, BlindOperator blindOperator) {
335
        String replacement = this.getMode(blindOperator);
336 1 1. sqlTimeBit : negated conditional → NO_COVERAGE
        int countSleepTimeStrategy = this.injectionModel.getMediatorUtils().preferencesUtil().isLimitingSleepTimeStrategy()
337
            ? this.injectionModel.getMediatorUtils().preferencesUtil().countSleepTimeStrategy()
338
            : 5;
339 1 1. sqlTimeBit : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTimeBit → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTime()
340
            .replace(EngineYaml.BINARY_MODE, replacement)
341
            .replace(
342
                EngineYaml.TEST,
343
                this.modelYaml.getStrategy().getBinary().getTest()
344
                .getBit()
345
                .replace(EngineYaml.INJECTION, inj)
346
                .replace(EngineYaml.WINDOW_CHAR, Integer.toString(indexChar))
347
                .replace(EngineYaml.BIT, Integer.toString(bit))
348
            )
349
            .replace(EngineYaml.SLEEP_TIME, Long.toString(countSleepTimeStrategy))
350
            .trim();  // trim spaces in '${binary.mode} ${test}' when no mode, not covered by cleanSql()
351
    }
352
353
    private String getMode(BlindOperator blindOperator) {
354
        return switch (blindOperator) {
355
            case AND -> this.modelYaml.getStrategy().getBinary().getModeAnd();
356
            case OR -> this.modelYaml.getStrategy().getBinary().getModeOr();
357
            case STACK -> this.modelYaml.getStrategy().getBinary().getModeStack();
358
            default -> StringUtils.EMPTY;
359
        };
360
    }
361
362
    @Override
363
    public String sqlBlind(String sqlQuery, String startPosition, boolean isReport) {
364 1 1. sqlBlind : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlind → NO_COVERAGE
        return EngineYaml.replaceTags(
365
            this.getSlidingWindow(isReport)
366
            .replace(EngineYaml.INJECTION, sqlQuery)
367
            .replace(EngineYaml.WINDOW_CHAR, startPosition)
368
            .replace(EngineYaml.CAPACITY, EngineYaml.DEFAULT_CAPACITY)
369
        );
370
    }
371
372
    @Override
373
    public String sqlTime(String sqlQuery, String startPosition, boolean isReport) {
374 1 1. sqlTime : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTime → NO_COVERAGE
        return EngineYaml.replaceTags(
375
            this.getSlidingWindow(isReport)
376
            .replace(EngineYaml.INJECTION, sqlQuery)
377
            .replace(EngineYaml.WINDOW_CHAR, startPosition)
378
            .replace(EngineYaml.CAPACITY, EngineYaml.DEFAULT_CAPACITY)
379
        );
380
    }
381
382
    @Override
383
    public String sqlMultibit(String inj, int indexChar, int block){
384 1 1. sqlMultibit : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlMultibit → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getMultibit()
385
            .replace(EngineYaml.INJECTION, inj)
386
            .replace(EngineYaml.WINDOW_CHAR, Integer.toString(indexChar))
387
            .replace(EngineYaml.BLOCK_MULTIBIT, Integer.toString(block));
388
    }
389
390
    @Override
391
    public String sqlErrorCalibrator(Method errorMethod) {
392 1 1. sqlErrorCalibrator : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlErrorCalibrator → NO_COVERAGE
        return EngineYaml.replaceTags(
393
            errorMethod.getQuery()
394
            .replace(EngineYaml.WINDOW, this.modelYaml.getStrategy().getConfiguration().getSlidingWindow())
395
            .replace(EngineYaml.INJECTION, this.modelYaml.getStrategy().getConfiguration().getCalibrator())
396
            .replace(EngineYaml.WINDOW_CHAR, "1")
397
            .replace(EngineYaml.CAPACITY, Integer.toString(errorMethod.getCapacity()))
398
        );
399
    }
400
401
    @Override
402
    public String sqlErrorIndice(Method errorMethod) {
403
        var indexZeroToFind = "0";
404 1 1. sqlErrorIndice : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlErrorIndice → NO_COVERAGE
        return EngineYaml.replaceTags(
405
            errorMethod.getQuery()
406
            .replace(EngineYaml.WINDOW, this.modelYaml.getStrategy().getConfiguration().getSlidingWindow())
407
            .replace(EngineYaml.INJECTION, this.modelYaml.getStrategy().getConfiguration().getFailsafe().replace(EngineYaml.INDICE, indexZeroToFind))
408
            .replace(EngineYaml.WINDOW_CHAR, "1")
409
            .replace(EngineYaml.CAPACITY, Integer.toString(errorMethod.getCapacity()))
410
        );
411
    }
412
413
    @Override
414
    public String sqlError(String sqlQuery, String startPosition, int indexMethodError, boolean isReport) {
415 1 1. sqlError : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlError → NO_COVERAGE
        return EngineYaml.replaceTags(
416
            this.modelYaml.getStrategy().getError().getMethod().get(indexMethodError).getQuery()
417
            .replace(EngineYaml.WINDOW, this.getSlidingWindow(isReport))
418
            .replace(EngineYaml.INJECTION, sqlQuery)
419
            .replace(EngineYaml.WINDOW_CHAR, startPosition)
420
            .replace(
421
                EngineYaml.CAPACITY,
422
                Integer.toString(
423
                    this.modelYaml.getStrategy().getError()
424
                    .getMethod()
425
                    .get(indexMethodError)
426
                    .getCapacity()
427
                )
428
            )
429
        );
430
    }
431
432
    @Override
433
    public String sqlUnion(String sqlQuery, String startPosition, boolean isReport) {
434 1 1. sqlUnion : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlUnion → NO_COVERAGE
        return EngineYaml.replaceTags(
435
            this.getSlidingWindow(isReport)
436
            .replace(EngineYaml.INJECTION, sqlQuery)
437
            .replace(EngineYaml.WINDOW_CHAR, startPosition)
438
            .replace(EngineYaml.CAPACITY, this.injectionModel.getMediatorStrategy().getUnion().getPerformanceLength())
439
        );
440
    }
441
442
    @Override
443
    public String sqlDns(String sqlQuery, String startPosition, BlindOperator blindOperator, boolean isReport) {
444
        String replacement = this.getMode(blindOperator);
445
        String result = EngineYaml.replaceTags(
446
            this.modelYaml.getStrategy().getDns()
447
            .replace(EngineYaml.WINDOW, this.getSlidingWindow(isReport))
448
            .replace(EngineYaml.BINARY_MODE, replacement)
449
            .replace(EngineYaml.INJECTION, sqlQuery)
450
            .replace(EngineYaml.DNS_DOMAIN, this.injectionModel.getMediatorUtils().preferencesUtil().getDnsDomain())
451
            .replace(EngineYaml.WINDOW_CHAR, startPosition)
452
            .replace(EngineYaml.CAPACITY, EngineYaml.DEFAULT_CAPACITY)
453
        );
454 1 1. sqlDns : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlDns → NO_COVERAGE
        return Pattern.compile(Pattern.quote(EngineYaml.DNS_RANDOM))
455
            .matcher(result)
456 1 1. lambda$sqlDns$8 : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlDns$8 → NO_COVERAGE
            .replaceAll(m -> String.format("%03d", ThreadLocalRandom.current().nextInt(999)));
457
    }
458
459
    @Override
460
    public String sqlStack(String sqlQuery, String startPosition, boolean isReport) {
461 1 1. sqlStack : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlStack → NO_COVERAGE
        return this.modelYaml.getStrategy().getStack().replace(
462
            EngineYaml.WINDOW,
463
            EngineYaml.replaceTags(
464
                this.getSlidingWindow(isReport)
465
                .replace(EngineYaml.INJECTION, sqlQuery)
466
                .replace(EngineYaml.WINDOW_CHAR, startPosition)
467
                .replace(EngineYaml.CAPACITY, EngineYaml.DEFAULT_CAPACITY)
468
            )
469
        );
470
    }
471
472
    @Override
473
    public String sqlCapacity(String[] indexes) {
474
        String regexIndexes = String.join("|", indexes);
475
        String regexVisibleIndexesToFind = String.format(EngineYaml.FORMAT_INDEX, "(%s)");
476 1 1. sqlCapacity : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlCapacity → NO_COVERAGE
        return this.injectionModel.getMediatorStrategy().getSpecificUnion().getIndexesInUrl().replaceAll(
477
            String.format(regexVisibleIndexesToFind, regexIndexes),
478
            EngineYaml.replaceTags(
479
                this.modelYaml.getStrategy().getUnion().getCapacity()
480
                .replace(EngineYaml.CALIBRATOR, this.modelYaml.getStrategy().getConfiguration().getCalibrator())
481
                .replace(EngineYaml.INDICE, "$1")
482
            )
483
        );
484
    }
485
486
    @Override
487
    public String sqlIndices(Integer nbFields) {
488
        String replaceTag = StringUtils.EMPTY;
489
        List<String> fields = new ArrayList<>();
490
        var indice = 1;
491 2 1. sqlIndices : changed conditional boundary → NO_COVERAGE
2. sqlIndices : negated conditional → NO_COVERAGE
        for ( ; indice <= nbFields ; indice++) {
492
            String field = this.modelYaml.getStrategy().getConfiguration().getFailsafe().replace(EngineYaml.INDICE, Integer.toString(indice));
493
            fields.add(field);
494
            replaceTag = field;
495
        }
496 1 1. sqlIndices : Changed increment from -1 to 1 → NO_COVERAGE
        indice--;
497 1 1. sqlIndices : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlIndices → NO_COVERAGE
        return this.modelYaml.getStrategy().getUnion()
498
            .getIndices()
499
            .replace(
500
                EngineYaml.INDICES,
501
                String.join(",", fields.toArray(new String[0]))
502
            )
503
            .replace(EngineYaml.INDICE_UNIQUE, replaceTag)
504
            .replace(
505
                EngineYaml.RESULT_RANGE,
506
                String.join(",", Collections.nCopies(indice, "r"))
507
            );
508
    }
509
510
    @Override
511
    public String sqlLimit(Integer limitSqlResult) {
512
        var limitBoundary = 0;
513
        try {
514
            limitBoundary = Integer.parseInt(this.modelYaml.getStrategy().getConfiguration().getLimitBoundary());
515
        } catch (NumberFormatException e) {
516
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Incorrect Limit start index, force to 0");
517
        }
518 1 1. sqlLimit : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlLimit → NO_COVERAGE
        return this.modelYaml.getStrategy().getConfiguration()
519
            .getLimit()
520 1 1. sqlLimit : Replaced integer addition with subtraction → NO_COVERAGE
            .replace(EngineYaml.LIMIT_VALUE, Integer.toString(limitSqlResult + limitBoundary));
521
    }
522
    
523
    @Override
524
    public String fingerprintErrorsAsRegex() {
525 1 1. fingerprintErrorsAsRegex : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::fingerprintErrorsAsRegex → NO_COVERAGE
        return "(?si)"+ StringUtils.join(
526
            this.modelYaml.getStrategy().getConfiguration().getFingerprint()
527
            .getErrorMessage()
528
            .stream()
529 1 1. lambda$fingerprintErrorsAsRegex$9 : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::lambda$fingerprintErrorsAsRegex$9 → NO_COVERAGE
            .map(m -> ".*"+ m +".*")
530
            .toArray(),
531
            "|"
532
        );
533
    }
534
    
535
    public static String replaceTags(String sqlRequest) {
536 1 1. replaceTags : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::replaceTags → NO_COVERAGE
        return sqlRequest
537
            .replace("${enclose_value_sql}", EngineYaml.ENCLOSE_VALUE_SQL)
538
            .replace("${enclose_value_hex}", EngineYaml.ENCLOSE_VALUE_HEX)
539
            .replace("${separator_qte_sql}", EngineYaml.SEPARATOR_QTE_SQL)
540
            .replace("${separator_qte_hex}", EngineYaml.SEPARATOR_QTE_HEX)
541
            .replace("${separator_cell_sql}", EngineYaml.SEPARATOR_CELL_SQL)
542
            .replace("${separator_cell_hex}", EngineYaml.SEPARATOR_CELL_HEX)
543
            .replace("${calibrator_sql}", EngineYaml.CALIBRATOR_SQL)
544
            .replace("${calibrator_raw}", EngineYaml.CALIBRATOR_SQL.repeat(100))
545
            .replace("${calibrator_hex}", EngineYaml.CALIBRATOR_HEX)
546
            .replace("${trail_sql}", EngineYaml.TRAIL_SQL)
547
            .replace("${trail_hex}", EngineYaml.TRAIL_HEX)
548
            .replace("${lead}", LEAD)
549
            .replace("${lead_hex}", EngineYaml.LEAD_HEX)
550
            .replace("${lead_pipe}", EngineYaml.LEAD_PIPE);
551
    }
552
553
    /**
554
     * Get payload with sliding window except for vulnerability report
555
     */
556
    private String getSlidingWindow(boolean isReport) {
557 2 1. getSlidingWindow : negated conditional → NO_COVERAGE
2. getSlidingWindow : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::getSlidingWindow → NO_COVERAGE
        return isReport
558
            ? "(" + EngineYaml.INJECTION + ")"
559
            : this.modelYaml.getStrategy().getConfiguration().getSlidingWindow();
560
    }
561
    
562
    
563
    // Getter and setter
564
565
    @Override
566
    public String sqlInfos() {
567 1 1. sqlInfos : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlInfos → NO_COVERAGE
        return this.modelYaml.getResource().getInfo();
568
    }
569
570
    @Override
571
    public List<String> getFalsyBit() {
572 1 1. getFalsyBit : replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getFalsyBit → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTest().getFalsyBit();
573
    }
574
575
    @Override
576
    public List<String> getTruthyBit() {
577 1 1. getTruthyBit : replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getTruthyBit → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTest().getTruthyBit();
578
    }
579
580
    @Override
581
    public List<String> getFalsyBin() {
582 1 1. getFalsyBin : replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getFalsyBin → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTest().getFalsyBin();
583
    }
584
585
    @Override
586
    public List<String> getTruthyBin() {
587 1 1. getTruthyBin : replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getTruthyBin → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTest().getTruthyBin();
588
    }
589
590
    @Override
591
    public String sqlBlindConfirm() {
592 1 1. sqlBlindConfirm : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlindConfirm → NO_COVERAGE
        return this.modelYaml.getStrategy().getBinary().getTest().getInit();
593
    }
594
595
    @Override
596
    public String sqlOrderBy() {
597 1 1. sqlOrderBy : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlOrderBy → NO_COVERAGE
        return this.modelYaml.getStrategy().getUnion().getOrderBy();
598
    }
599
    
600
    @Override
601
    public String endingComment() {
602 1 1. endingComment : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().preferencesUtil().isUrlRandomSuffixDisabled()) {
603 1 1. endingComment : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::endingComment → NO_COVERAGE
            return this.modelYaml.getStrategy().getConfiguration().getEndingComment();
604
        } else {
605 1 1. endingComment : replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::endingComment → NO_COVERAGE
            return this.modelYaml.getStrategy().getConfiguration().getEndingComment()
606
                + RandomStringUtils.secure().nextAlphanumeric(4);  // Allows binary match fingerprinting on host errors
607
        }
608
    }
609
610
    @Override
611
    public ModelYaml getModelYaml() {
612 1 1. getModelYaml : replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::getModelYaml → KILLED
        return this.modelYaml;
613
    }
614
}

Mutations

119

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

120

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

126

1.1
Location : lambda$sqlDatabases$0
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlDatabases$0 → NO_COVERAGE

129

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

130

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

136

1.1
Location : lambda$sqlDatabases$1
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlDatabases$1 → NO_COVERAGE

140

1.1
Location : sqlDatabases
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlDatabases → NO_COVERAGE

147

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

148

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

154

1.1
Location : lambda$sqlTables$2
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlTables$2 → NO_COVERAGE

157

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

158

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

164

1.1
Location : lambda$sqlTables$3
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlTables$3 → NO_COVERAGE

170

1.1
Location : sqlTables
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTables → NO_COVERAGE

179

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

180

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

186

1.1
Location : lambda$sqlColumns$4
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlColumns$4 → NO_COVERAGE

189

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

190

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

196

1.1
Location : lambda$sqlColumns$5
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlColumns$5 → NO_COVERAGE

204

1.1
Location : sqlColumns
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlColumns → NO_COVERAGE

217

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

218

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

226

1.1
Location : lambda$sqlRows$6
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlRows$6 → NO_COVERAGE

229

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

230

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

238

1.1
Location : lambda$sqlRows$7
Killed by : none
replaced return value with null for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlRows$7 → NO_COVERAGE

247

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

253

1.1
Location : sqlRows
Killed by : none
changed conditional boundary → NO_COVERAGE

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

264

1.1
Location : sqlRows
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlRows → NO_COVERAGE

280

1.1
Location : sqlTestBlindWithOperator
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTestBlindWithOperator → NO_COVERAGE

289

1.1
Location : sqlBlindBit
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlindBit → NO_COVERAGE

304

1.1
Location : sqlBlindBin
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlindBin → NO_COVERAGE

323

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

326

1.1
Location : sqlTestTimeWithOperator
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTestTimeWithOperator → NO_COVERAGE

336

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

339

1.1
Location : sqlTimeBit
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTimeBit → NO_COVERAGE

364

1.1
Location : sqlBlind
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlind → NO_COVERAGE

374

1.1
Location : sqlTime
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlTime → NO_COVERAGE

384

1.1
Location : sqlMultibit
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlMultibit → NO_COVERAGE

392

1.1
Location : sqlErrorCalibrator
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlErrorCalibrator → NO_COVERAGE

404

1.1
Location : sqlErrorIndice
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlErrorIndice → NO_COVERAGE

415

1.1
Location : sqlError
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlError → NO_COVERAGE

434

1.1
Location : sqlUnion
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlUnion → NO_COVERAGE

454

1.1
Location : sqlDns
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlDns → NO_COVERAGE

456

1.1
Location : lambda$sqlDns$8
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::lambda$sqlDns$8 → NO_COVERAGE

461

1.1
Location : sqlStack
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlStack → NO_COVERAGE

476

1.1
Location : sqlCapacity
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlCapacity → NO_COVERAGE

491

1.1
Location : sqlIndices
Killed by : none
changed conditional boundary → NO_COVERAGE

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

496

1.1
Location : sqlIndices
Killed by : none
Changed increment from -1 to 1 → NO_COVERAGE

497

1.1
Location : sqlIndices
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlIndices → NO_COVERAGE

518

1.1
Location : sqlLimit
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlLimit → NO_COVERAGE

520

1.1
Location : sqlLimit
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

525

1.1
Location : fingerprintErrorsAsRegex
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::fingerprintErrorsAsRegex → NO_COVERAGE

529

1.1
Location : lambda$fingerprintErrorsAsRegex$9
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::lambda$fingerprintErrorsAsRegex$9 → NO_COVERAGE

536

1.1
Location : replaceTags
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::replaceTags → NO_COVERAGE

557

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

2.2
Location : getSlidingWindow
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::getSlidingWindow → NO_COVERAGE

567

1.1
Location : sqlInfos
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlInfos → NO_COVERAGE

572

1.1
Location : getFalsyBit
Killed by : none
replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getFalsyBit → NO_COVERAGE

577

1.1
Location : getTruthyBit
Killed by : none
replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getTruthyBit → NO_COVERAGE

582

1.1
Location : getFalsyBin
Killed by : none
replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getFalsyBin → NO_COVERAGE

587

1.1
Location : getTruthyBin
Killed by : none
replaced return value with Collections.emptyList for com/jsql/model/injection/engine/model/EngineYaml::getTruthyBin → NO_COVERAGE

592

1.1
Location : sqlBlindConfirm
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlBlindConfirm → NO_COVERAGE

597

1.1
Location : sqlOrderBy
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::sqlOrderBy → NO_COVERAGE

602

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

603

1.1
Location : endingComment
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::endingComment → NO_COVERAGE

605

1.1
Location : endingComment
Killed by : none
replaced return value with "" for com/jsql/model/injection/engine/model/EngineYaml::endingComment → NO_COVERAGE

612

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

Active mutators

Tests examined


Report generated by PIT 1.22.1