ReadBytes.java

1
package com.reallifedeveloper.tools;
2
3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.net.URI;
6
import java.net.URISyntaxException;
7
import java.net.URL;
8
import java.nio.charset.StandardCharsets;
9
10
import org.slf4j.Logger;
11
import org.slf4j.LoggerFactory;
12
13
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14
15
/**
16
 * Utility class to read a file and display the content as bytes.
17
 *
18
 * @author RealLifeDeveloper
19
 */
20
@SuppressFBWarnings(value = "URLCONNECTION_SSRF_FD", justification = "Use at your own risk")
21
public final class ReadBytes {
22
23
    private static final int BLOCK_SIZE = 16;
24
25
    private static final String NEWLINE = "\\R";
26
27
    private static final Logger LOG = LoggerFactory.getLogger(ReadBytes.class);
28
29
    /**
30
     * This is a utility class with only static methods, so we hide the only constructor.
31
     */
32
    private ReadBytes() {
33
    }
34
35
    /**
36
     * Main method to read bytes from a URL and log the result.
37
     *
38
     * @param args a string array that should contain one element, the URL to read from
39
     *
40
     * @throws IOException        if reading from the URL failed
41
     * @throws URISyntaxException if the provided URL is malformed
42
     */
43
    public static void main(String... args) throws IOException, URISyntaxException {
44 1 1. main : negated conditional → KILLED
        if (args.length != 1) {
45
            throw new IllegalArgumentException("Usage: java " + ReadBytes.class.getName() + " <url>");
46
        }
47
        URL url = new URI(args[0]).toURL();
48 1 1. main : removed call to com/reallifedeveloper/tools/ReadBytes::logBytesFromUrl → KILLED
        logBytesFromUrl(url);
49
    }
50
51
    /**
52
     * Reads bytes from the given URL and logs them at info level, both as hexadecimal byte values and as an ASCII string.
53
     *
54
     * @param url the URL to read from
55
     *
56
     * @throws IOException if reading from {@code url} failed
57
     */
58
    public static void logBytesFromUrl(URL url) throws IOException {
59 1 1. logBytesFromUrl : negated conditional → KILLED
        if (url == null) {
60
            throw new IllegalArgumentException("url must not be null");
61
        }
62
        byte[] data = new byte[BLOCK_SIZE];
63
        try (InputStream in = url.openConnection().getInputStream()) {
64
            int bytesRead;
65 1 1. logBytesFromUrl : negated conditional → KILLED
            while ((bytesRead = in.read(data)) != -1) {
66 1 1. logBytesFromUrl : removed call to com/reallifedeveloper/tools/ReadBytes::logBytes → KILLED
                logBytes(data, bytesRead);
67
            }
68
        }
69
    }
70
71
    @SuppressFBWarnings(value = "CRLF_INJECTION_LOGS", justification = "The string is being sanitized replacing line break with space")
72
    private static void logBytes(byte[] data, int n) {
73
        StringBuilder sb = new StringBuilder();
74 2 1. logBytes : changed conditional boundary → KILLED
2. logBytes : negated conditional → KILLED
        for (int i = 0; i < n; i++) {
75
            byte b = data[i];
76
            sb.append(String.format("%02X ", b));
77
        }
78 2 1. logBytes : negated conditional → SURVIVED
2. logBytes : changed conditional boundary → SURVIVED
        if (n < BLOCK_SIZE) {
79 2 1. logBytes : negated conditional → RUN_ERROR
2. logBytes : changed conditional boundary → SURVIVED
            for (int i = n; i < BLOCK_SIZE; i++) {
80
                sb.append("   ");
81
            }
82
        }
83
        sb.append(": ").append(new String(data, StandardCharsets.US_ASCII).replaceAll(NEWLINE, " "));
84
        LOG.info(sb.toString());
85
    }
86
}

Mutations

44

1.1
Location : main
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:main()]
negated conditional → KILLED

48

1.1
Location : main
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:main()]
removed call to com/reallifedeveloper/tools/ReadBytes::logBytesFromUrl → KILLED

59

1.1
Location : logBytesFromUrl
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:logBytesFromNullUrl()]
negated conditional → KILLED

65

1.1
Location : logBytesFromUrl
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:logBytesFromUrl()]
negated conditional → KILLED

66

1.1
Location : logBytesFromUrl
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:logBytesFromUrl()]
removed call to com/reallifedeveloper/tools/ReadBytes::logBytes → KILLED

74

1.1
Location : logBytes
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:logBytesFromUrl()]
changed conditional boundary → KILLED

2.2
Location : logBytes
Killed by : com.reallifedeveloper.tools.ReadBytesTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.ReadBytesTest]/[method:logBytesFromUrl()]
negated conditional → KILLED

78

1.1
Location : logBytes
Killed by : none
negated conditional → SURVIVED
Covering tests

2.2
Location : logBytes
Killed by : none
changed conditional boundary → SURVIVED Covering tests

79

1.1
Location : logBytes
Killed by : none
negated conditional → RUN_ERROR

2.2
Location : logBytes
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

Active mutators

Tests examined


Report generated by PIT 1.20.2