CallableFile.java

1
package com.jsql.model.accessible;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.exception.AbstractSlidingException;
5
import com.jsql.model.exception.InjectionFailureException;
6
import com.jsql.model.exception.LoopDetectedSlidingException;
7
import com.jsql.model.exception.StoppedByUserSlidingException;
8
import com.jsql.model.injection.vendor.model.Vendor;
9
import com.jsql.model.suspendable.SuspendableGetRows;
10
import com.jsql.util.LogLevelUtil;
11
import org.apache.commons.lang3.StringUtils;
12
import org.apache.logging.log4j.LogManager;
13
import org.apache.logging.log4j.Logger;
14
15
import java.util.AbstractMap;
16
import java.util.HashMap;
17
import java.util.Map;
18
import java.util.concurrent.Callable;
19
20
/**
21
 * Thread unit to read source of a file by SQL injection.
22
 * User can interrupt the process and get a partial result of the file content.
23
 */
24
public class CallableFile implements Callable<CallableFile> {
25
    
26
    private static final Logger LOGGER = LogManager.getRootLogger();
27
    public static final String REQUIRE_STACK = "Read file requirement: stack query";
28
29
    /**
30
     * Path to the file to read.
31
     */
32
    private final String pathFile;
33
34
    /**
35
     * Source of file.
36
     */
37
    private String sourceFile = StringUtils.EMPTY;
38
    
39
    /**
40
     * Suspendable task that reads lines of the file by injection.
41
     */
42
    private final SuspendableGetRows suspendableReadFile;
43
44
    private final InjectionModel injectionModel;
45
    
46
    /**
47
     * Create Callable to read a file.
48
     */
49
    public CallableFile(String pathFile, InjectionModel injectionModel) {
50
        this.pathFile = pathFile;
51
        this.injectionModel= injectionModel;
52
        this.suspendableReadFile = new SuspendableGetRows(injectionModel);
53
    }
54
55
    @FunctionalInterface
56
    private interface Readable {
57
        String call() throws AbstractSlidingException;
58
    }
59
60
    /**
61
     * Read a file on the server using SQL injection.
62
     * Get partial result if user interrupts the process.
63
     */
64
    @Override
65
    public CallableFile call() throws Exception {
66
        Map<Vendor, Readable> mapVendorReadable = new HashMap<>();
67 1 1. lambda$call$0 : replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$0 → NO_COVERAGE
        mapVendorReadable.put(this.injectionModel.getMediatorVendor().getMysql(), () -> this.injectionModel.getResourceAccess().getExploitMysql().getRead(this.pathFile));
68 1 1. lambda$call$1 : replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$1 → NO_COVERAGE
        mapVendorReadable.put(this.injectionModel.getMediatorVendor().getH2(), () -> this.injectionModel.getResourceAccess().getExploitH2().getRead(this.pathFile));
69 1 1. lambda$call$2 : replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$2 → NO_COVERAGE
        mapVendorReadable.put(this.injectionModel.getMediatorVendor().getSqlite(), () -> this.injectionModel.getResourceAccess().getExploitSqlite().getRead(this.pathFile));
70 1 1. lambda$call$3 : replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$3 → NO_COVERAGE
        mapVendorReadable.put(this.injectionModel.getMediatorVendor().getDerby(), () -> this.injectionModel.getResourceAccess().getExploitDerby().getRead(this.pathFile));
71 1 1. lambda$call$4 : replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$4 → NO_COVERAGE
        mapVendorReadable.put(this.injectionModel.getMediatorVendor().getHsqldb(), () -> this.injectionModel.getResourceAccess().getExploitHsqldb().getRead(this.pathFile));
72 1 1. lambda$call$5 : replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$5 → NO_COVERAGE
        mapVendorReadable.put(this.injectionModel.getMediatorVendor().getPostgres(), () -> this.injectionModel.getResourceAccess().getExploitPostgres().getRead(this.pathFile));
73
74
        Readable readable = mapVendorReadable.entrySet().stream()
75 2 1. lambda$call$6 : replaced boolean return with true for com/jsql/model/accessible/CallableFile::lambda$call$6 → NO_COVERAGE
2. lambda$call$6 : negated conditional → NO_COVERAGE
            .filter(entry -> this.injectionModel.getMediatorVendor().getVendor() == entry.getKey())
76
            .findFirst()
77
            .orElse(new AbstractMap.SimpleEntry<>(null, () -> {
78
                LOGGER.log(
79
                    LogLevelUtil.CONSOLE_DEFAULT,
80
                    "Read file not implemented for [{}], share a working example to GitHub to speed up release",
81
                    this.injectionModel.getMediatorVendor().getVendor()
82
                );
83
                return StringUtils.EMPTY;
84
            }))
85
            .getValue();
86
87
        String resultToParse = StringUtils.EMPTY;
88
        try {
89
            resultToParse = readable.call();
90
        } catch (InjectionFailureException e) {
91
            // Usually thrown if File does not exist
92
            LOGGER.log(LogLevelUtil.IGNORE, e);
93
        } catch (LoopDetectedSlidingException | StoppedByUserSlidingException e) {
94 1 1. call : negated conditional → NO_COVERAGE
            if (StringUtils.isNotEmpty(e.getSlidingWindowAllRows())) {  // Get partial source
95
                resultToParse = e.getSlidingWindowAllRows();
96 1 1. call : negated conditional → NO_COVERAGE
            } else if (StringUtils.isNotEmpty(e.getSlidingWindowCurrentRows())) {
97
                resultToParse = e.getSlidingWindowCurrentRows();
98
            }
99
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e);
100
        }
101
102
        this.sourceFile = resultToParse;
103 1 1. call : replaced return value with null for com/jsql/model/accessible/CallableFile::call → NO_COVERAGE
        return this;
104
    }
105
106
107
    // Getters
108
    
109
    public String getPathFile() {
110 1 1. getPathFile : replaced return value with "" for com/jsql/model/accessible/CallableFile::getPathFile → NO_COVERAGE
        return this.pathFile;
111
    }
112
113
    public String getSourceFile() {
114 1 1. getSourceFile : replaced return value with "" for com/jsql/model/accessible/CallableFile::getSourceFile → NO_COVERAGE
        return this.sourceFile;
115
    }
116
117
    public SuspendableGetRows getSuspendableReadFile() {
118 1 1. getSuspendableReadFile : replaced return value with null for com/jsql/model/accessible/CallableFile::getSuspendableReadFile → NO_COVERAGE
        return this.suspendableReadFile;
119
    }
120
}

Mutations

67

1.1
Location : lambda$call$0
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$0 → NO_COVERAGE

68

1.1
Location : lambda$call$1
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$1 → NO_COVERAGE

69

1.1
Location : lambda$call$2
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$2 → NO_COVERAGE

70

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

71

1.1
Location : lambda$call$4
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$4 → NO_COVERAGE

72

1.1
Location : lambda$call$5
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::lambda$call$5 → NO_COVERAGE

75

1.1
Location : lambda$call$6
Killed by : none
replaced boolean return with true for com/jsql/model/accessible/CallableFile::lambda$call$6 → NO_COVERAGE

2.2
Location : lambda$call$6
Killed by : none
negated conditional → NO_COVERAGE

94

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

96

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

103

1.1
Location : call
Killed by : none
replaced return value with null for com/jsql/model/accessible/CallableFile::call → NO_COVERAGE

110

1.1
Location : getPathFile
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::getPathFile → NO_COVERAGE

114

1.1
Location : getSourceFile
Killed by : none
replaced return value with "" for com/jsql/model/accessible/CallableFile::getSourceFile → NO_COVERAGE

118

1.1
Location : getSuspendableReadFile
Killed by : none
replaced return value with null for com/jsql/model/accessible/CallableFile::getSuspendableReadFile → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.1