1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! Turn a `file:` URI into the path drep was asked to check.
//!
//! Split from `parsers.rs` because it is a URI decoder rather than a diagnostic
//! reader: SARIF is the only format that mandates a URI, but the decoding is
//! the spec's rather than checkstyle's, so it belongs beside the other
//! encoding rules rather than among the per-tool parsers.
//!
//! Decoding is complete before the path leaves here. `check` looks a finding's
//! absolute path up in a table to rewrite it back to the path the user typed,
//! and a half-decoded URI matches nothing in that table, so the finding keeps a
//! location no file has.
/// `file:/abs/path` and `file:///abs/path` both name a local path. drep matches
/// findings against the paths it was asked to check, so a finding left under a
/// URI is filed against a path that matches nothing and is silently dropped.
///
/// The path is percent-decoded because producers encode it: checkstyle's
/// SarifLogger maps a space to `%20` and a quote to `%22`, and a spec-compliant
/// producer percent-encodes everything reserved. Left encoded, the finding's
/// path never matches the file drep was asked to check.
pub
/// `file:/C:/repo/Sample.java` is how a Windows producer names a local path.
/// RFC 8089 requires the path component to begin with `/`, so the drive letter
/// arrives one slash deeper than the path it denotes. Left in place that slash
/// makes the path drive-relative rather than absolute, so it matches nothing in
/// the absolute-path table `check` uses to rewrite a finding back to the path
/// the user asked about, and every Windows checkstyle finding keeps a location
/// no file has.
///
/// Applied on every platform rather than under `cfg(windows)`: a `cfg`-gated
/// twin is invisible to the mutation gate, and a first component that is a bare
/// ASCII letter followed by a colon is not a path any Unix producer emits.
///
/// Four named conditions rather than one slice pattern, for the reason
/// `percent_decode` writes `hi * 16 + lo` below: cargo-mutants does not mutate
/// match patterns, so `matches!(path.as_bytes(), [b'/', d, b':', ..])` states
/// the same rule while making every part of it invisible to the gate. Written
/// this way it carries five mutable operators, and the fixture table in
/// `sarif_parser_keeps_paths_that_only_look_like_a_drive` has one row per
/// operator to discriminate them.
/// Decode RFC 3986 `%HH` sequences byte-wise. Anything that is not a valid
/// triplet passes through verbatim, and malformed UTF-8 at the end of decoding
/// degrades lossily rather than failing the finding. checkstyle encodes only
/// the space and the quote, so a literal `%20` *in* a filename is ambiguous
/// with an encoded one at the source; decoding is the better wrong there,
/// because spaces in paths are common and `%20` in a name is not.