Skip to content

Commit 8d2c035

Browse files
committed
CxxIssuesReportSensor: use realPath as part of path normalization
* introduce the fallback for the lookup of `InputFile`s: try it with the Path::realPath() resolves #1651
1 parent a0b0f45 commit 8d2c035

File tree

1 file changed

+49
-2
lines changed

1 file changed

+49
-2
lines changed

cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxIssuesReportSensor.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
package org.sonar.cxx.sensors.utils;
2121

2222
import java.io.File;
23+
import java.io.IOException;
24+
import java.nio.file.LinkOption;
25+
import java.nio.file.Path;
2326
import java.util.ArrayList;
2427
import java.util.HashMap;
2528
import java.util.HashSet;
@@ -135,12 +138,56 @@ public void saveUniqueViolation(SensorContext sensorContext, CxxReportIssue issu
135138
}
136139
}
137140

141+
private InputFile getInputFileTryRealPath(SensorContext sensorContext, String path) {
142+
final Path absolutePath = sensorContext.fileSystem().baseDir().toPath().resolve(path);
143+
Path realPath;
144+
try {
145+
realPath = absolutePath.toRealPath(LinkOption.NOFOLLOW_LINKS);
146+
} catch (IOException e) {
147+
if (LOG.isDebugEnabled()) {
148+
LOG.debug("Unable to get the real path: module {}, baseDir {}, path {}", sensorContext.module().key(),
149+
sensorContext.fileSystem().baseDir(), path);
150+
}
151+
return null;
152+
}
153+
return sensorContext.fileSystem()
154+
.inputFile(sensorContext.fileSystem().predicates().hasAbsolutePath(realPath.toString()));
155+
}
156+
138157
public InputFile getInputFileIfInProject(SensorContext sensorContext, String path) {
139158
if (notFoundFiles.contains(path)) {
140159
return null;
141160
}
142-
final InputFile inputFile = sensorContext.fileSystem().inputFile(sensorContext.
143-
fileSystem().predicates().hasPath(path));
161+
162+
// 1. try the most generic search predicate first; usually it's the right
163+
// one
164+
InputFile inputFile = sensorContext.fileSystem()
165+
.inputFile(sensorContext.fileSystem().predicates().hasPath(path));
166+
167+
// 2. if there was nothing found, try to normalize the path by means of
168+
// Path::toRealPath(). This helps if some 3rd party tools obfuscate the
169+
// paths. E.g. the MS VC compiler tends to transform file paths to the lower
170+
// case in its logs.
171+
//
172+
// IMPORTANT: SQ plugin API allows creation of NewIssue only on locations,
173+
// which belong to the module. This internal check is performed by means
174+
// of comparison of the paths. The paths which are managed by the framework
175+
// (the reference paths) are NOT stored in the canonical form.
176+
// E.g. the plugin API neither resolves symbolic links nor performs
177+
// case-insensitive path normalization (could be relevant on Windows)
178+
//
179+
// Normalization by means of File::getCanonicalFile() or Path::toRealPath()
180+
// can produce paths, which don't pass the mentioned check. E.g. resolution
181+
// of symbolic links or letter case transformation
182+
// might lead to the paths, which don't belong to the module's base
183+
// directory (at least not in terms of parent-child semantic). This is the
184+
// reason why we should avoid the resolution of symbolic links and not use
185+
// the Path::toRealPath() as the only search predicate.
186+
187+
if (inputFile == null) {
188+
inputFile = getInputFileTryRealPath(sensorContext, path);
189+
}
190+
144191
if (inputFile == null) {
145192
LOG.warn("Cannot find the file '{}' in module '{}' base dir '{}', skipping violations.",
146193
path, sensorContext.module().key(), sensorContext.fileSystem().baseDir());

0 commit comments

Comments
 (0)