Skip to content

Commit

Permalink
CxxIssuesReportSensor: use realPath as part of path normalization
Browse files Browse the repository at this point in the history
* introduce the fallback for the lookup of `InputFile`s:
  try it with the Path::realPath()

resolves SonarOpenCommunity#1651
  • Loading branch information
ivangalkin committed Jan 5, 2019
1 parent a0b0f45 commit 8d2c035
Showing 1 changed file with 49 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
package org.sonar.cxx.sensors.utils;

import java.io.File;
import java.io.IOException;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -135,12 +138,56 @@ public void saveUniqueViolation(SensorContext sensorContext, CxxReportIssue issu
}
}

private InputFile getInputFileTryRealPath(SensorContext sensorContext, String path) {
final Path absolutePath = sensorContext.fileSystem().baseDir().toPath().resolve(path);
Path realPath;
try {
realPath = absolutePath.toRealPath(LinkOption.NOFOLLOW_LINKS);
} catch (IOException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Unable to get the real path: module {}, baseDir {}, path {}", sensorContext.module().key(),
sensorContext.fileSystem().baseDir(), path);
}
return null;
}
return sensorContext.fileSystem()
.inputFile(sensorContext.fileSystem().predicates().hasAbsolutePath(realPath.toString()));
}

public InputFile getInputFileIfInProject(SensorContext sensorContext, String path) {
if (notFoundFiles.contains(path)) {
return null;
}
final InputFile inputFile = sensorContext.fileSystem().inputFile(sensorContext.
fileSystem().predicates().hasPath(path));

// 1. try the most generic search predicate first; usually it's the right
// one
InputFile inputFile = sensorContext.fileSystem()
.inputFile(sensorContext.fileSystem().predicates().hasPath(path));

// 2. if there was nothing found, try to normalize the path by means of
// Path::toRealPath(). This helps if some 3rd party tools obfuscate the
// paths. E.g. the MS VC compiler tends to transform file paths to the lower
// case in its logs.
//
// IMPORTANT: SQ plugin API allows creation of NewIssue only on locations,
// which belong to the module. This internal check is performed by means
// of comparison of the paths. The paths which are managed by the framework
// (the reference paths) are NOT stored in the canonical form.
// E.g. the plugin API neither resolves symbolic links nor performs
// case-insensitive path normalization (could be relevant on Windows)
//
// Normalization by means of File::getCanonicalFile() or Path::toRealPath()
// can produce paths, which don't pass the mentioned check. E.g. resolution
// of symbolic links or letter case transformation
// might lead to the paths, which don't belong to the module's base
// directory (at least not in terms of parent-child semantic). This is the
// reason why we should avoid the resolution of symbolic links and not use
// the Path::toRealPath() as the only search predicate.

if (inputFile == null) {
inputFile = getInputFileTryRealPath(sensorContext, path);
}

if (inputFile == null) {
LOG.warn("Cannot find the file '{}' in module '{}' base dir '{}', skipping violations.",
path, sensorContext.module().key(), sensorContext.fileSystem().baseDir());
Expand Down

0 comments on commit 8d2c035

Please sign in to comment.