Skip to content

Commit 330a2c3

Browse files
authored
Merge pull request #1653 from ivangalkin/try_1651
CxxIssuesReportSensor: use realPath as part of path normalization
2 parents a0b0f45 + 1960b41 commit 330a2c3

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

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

Lines changed: 61 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,68 @@ 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 '{}', exception '{}'",
149+
sensorContext.module().key(), sensorContext.fileSystem().baseDir(), path, e);
150+
}
151+
return null;
152+
}
153+
154+
// if the real path is equal to the given one - skip search; we already
155+
// tried such path
156+
//
157+
// IMPORTANT: don't use Path::equals(), since it's dependent on a file-system.
158+
// SonarQube plugin API works with string paths, so the equality of strings
159+
// is important
160+
final String realPathString = realPath.toString();
161+
if (absolutePath.toString().equals(realPathString)) {
162+
return null;
163+
}
164+
165+
return sensorContext.fileSystem()
166+
.inputFile(sensorContext.fileSystem().predicates().hasAbsolutePath(realPathString));
167+
}
168+
138169
public InputFile getInputFileIfInProject(SensorContext sensorContext, String path) {
139170
if (notFoundFiles.contains(path)) {
140171
return null;
141172
}
142-
final InputFile inputFile = sensorContext.fileSystem().inputFile(sensorContext.
143-
fileSystem().predicates().hasPath(path));
173+
174+
// 1. try the most generic search predicate first; usually it's the right
175+
// one
176+
InputFile inputFile = sensorContext.fileSystem()
177+
.inputFile(sensorContext.fileSystem().predicates().hasPath(path));
178+
179+
// 2. if there was nothing found, try to normalize the path by means of
180+
// Path::toRealPath(). This helps if some 3rd party tools obfuscate the
181+
// paths. E.g. the MS VC compiler tends to transform file paths to the lower
182+
// case in its logs.
183+
//
184+
// IMPORTANT: SQ plugin API allows creation of NewIssue only on locations,
185+
// which belong to the module. This internal check is performed by means
186+
// of comparison of the paths. The paths which are managed by the framework
187+
// (the reference paths) are NOT stored in the canonical form.
188+
// E.g. the plugin API neither resolves symbolic links nor performs
189+
// case-insensitive path normalization (could be relevant on Windows)
190+
//
191+
// Normalization by means of File::getCanonicalFile() or Path::toRealPath()
192+
// can produce paths, which don't pass the mentioned check. E.g. resolution
193+
// of symbolic links or letter case transformation
194+
// might lead to the paths, which don't belong to the module's base
195+
// directory (at least not in terms of parent-child semantic). This is the
196+
// reason why we should avoid the resolution of symbolic links and not use
197+
// the Path::toRealPath() as the only search predicate.
198+
199+
if (inputFile == null) {
200+
inputFile = getInputFileTryRealPath(sensorContext, path);
201+
}
202+
144203
if (inputFile == null) {
145204
LOG.warn("Cannot find the file '{}' in module '{}' base dir '{}', skipping violations.",
146205
path, sensorContext.module().key(), sensorContext.fileSystem().baseDir());

0 commit comments

Comments
 (0)