aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2017-04-07 14:20:09 +0200
committerdbmeneses <duarte.meneses@sonarsource.com>2017-04-11 16:12:42 +0200
commit6782a76dcf2e42fea32116a22d1c3ecb8d2975fa (patch)
tree1d80043f01606755615444d2db54246918c034c6 /sonar-scanner-engine
parentaffd68df75848af9d3355a563c48a69a231b8853 (diff)
downloadsonarqube-6782a76dcf2e42fea32116a22d1c3ecb8d2975fa.tar.gz
sonarqube-6782a76dcf2e42fea32116a22d1c3ecb8d2975fa.zip
SONAR-6100 Improve support of binary files and/or files with different encoding
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java132
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java40
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java34
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java95
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java50
-rw-r--r--sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt6
-rw-r--r--sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt4
8 files changed, 300 insertions, 64 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java
new file mode 100644
index 00000000000..ae6aa5532da
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java
@@ -0,0 +1,132 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.scan.filesystem;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import javax.annotation.CheckForNull;
+
+import org.apache.commons.io.ByteOrderMark;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.BOMInputStream;
+
+public class CharsetDetector {
+ private static final int BYTES_TO_DECODE = 512;
+ private Path filePath;
+ private BOMInputStream stream;
+ private Charset detectedCharset;
+ private Charset defaultEncoding;
+
+ public CharsetDetector(Path filePath, Charset defaultEncoding) {
+ this.filePath = filePath;
+ this.defaultEncoding = defaultEncoding;
+ }
+
+ public boolean run() {
+ try {
+ stream = createInputStream(filePath);
+ if (detectBOM()) {
+ return true;
+ }
+
+ return detectCharset();
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to read file " + filePath.toAbsolutePath().toString(), e);
+ }
+ }
+
+ @CheckForNull
+ public Charset charset() {
+ assertRun();
+ return detectedCharset;
+ }
+
+ public InputStream inputStream() {
+ assertRun();
+ return stream;
+ }
+
+ private static BOMInputStream createInputStream(Path path) throws IOException {
+ BufferedInputStream bufferedStream = new BufferedInputStream(Files.newInputStream(path));
+ return new BOMInputStream(bufferedStream, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE,
+ ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
+ }
+
+ private boolean detectBOM() throws IOException {
+ String charsetName = stream.getBOMCharsetName();
+ if (charsetName != null) {
+ detectedCharset = Charset.forName(charsetName);
+ return true;
+ }
+ return false;
+ }
+
+ @CheckForNull
+ private boolean detectCharset() throws IOException {
+ stream.mark(BYTES_TO_DECODE);
+ byte[] buf = new byte[BYTES_TO_DECODE];
+ int len = IOUtils.read(stream, buf, 0, BYTES_TO_DECODE);
+ stream.reset();
+
+ Set<Charset> charsets = new LinkedHashSet<>();
+ charsets.add(defaultEncoding);
+ charsets.add(StandardCharsets.UTF_8);
+ charsets.add(Charset.defaultCharset());
+
+ for (Charset c : charsets) {
+ if (tryDecode(buf, len, c)) {
+ detectedCharset = c;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean tryDecode(byte[] bytes, int len, Charset charset) throws IOException {
+ CharsetDecoder decoder = charset.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPORT)
+ .onUnmappableCharacter(CodingErrorAction.REPORT);
+
+ try {
+ decoder.decode(ByteBuffer.wrap(bytes, 0, len));
+ } catch (CharacterCodingException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private void assertRun() {
+ if (stream == null) {
+ throw new IllegalStateException("Charset detection did not run");
+ }
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
index c04483cc784..f8b796688f7 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
@@ -19,14 +19,8 @@
*/
package org.sonar.scanner.scan.filesystem;
-import com.google.common.annotations.VisibleForTesting;
-
-import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,6 +31,8 @@ import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.fs.internal.Metadata;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
+import com.google.common.annotations.VisibleForTesting;
+
class MetadataGenerator {
private static final Logger LOG = LoggerFactory.getLogger(MetadataGenerator.class);
@VisibleForTesting
@@ -62,10 +58,13 @@ class MetadataGenerator {
* It is an expensive computation, reading the entire file.
*/
public void setMetadata(final DefaultInputFile inputFile, Charset defaultEncoding) {
+ CharsetDetector detector = new CharsetDetector(inputFile.path(), defaultEncoding);
try {
- Charset charset = detectCharset(inputFile.path(), defaultEncoding);
+ detector.run();
+ Charset charset = detector.charset();
+ InputStream is = detector.inputStream();
inputFile.setCharset(charset);
- Metadata metadata = fileMetadata.readMetadata(inputFile.file(), charset, exclusionsScanner.createCharHandlerFor(inputFile.key()));
+ Metadata metadata = fileMetadata.readMetadata(is, charset, inputFile.absolutePath(), exclusionsScanner.createCharHandlerFor(inputFile.key()));
inputFile.setMetadata(metadata);
inputFile.setStatus(statusDetection.status(inputModule.definition().getKeyWithBranch(), inputFile.relativePath(), metadata.hash()));
LOG.debug("'{}' generated metadata {} with charset '{}'", inputFile.relativePath(), inputFile.type() == Type.TEST ? "as test " : "", charset);
@@ -74,29 +73,4 @@ class MetadataGenerator {
}
}
- /**
- * @return charset detected from BOM in given file or given defaultCharset
- * @throws IllegalStateException if an I/O error occurs
- */
- private static Charset detectCharset(Path path, Charset defaultCharset) {
- try (InputStream inputStream = Files.newInputStream(path)) {
- byte[] bom = new byte[4];
- int n = inputStream.read(bom, 0, bom.length);
- if ((n >= 3) && (bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
- return StandardCharsets.UTF_8;
- } else if ((n >= 4) && (bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
- return UTF_32BE;
- } else if ((n >= 4) && (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
- return UTF_32LE;
- } else if ((n >= 2) && (bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
- return StandardCharsets.UTF_16BE;
- } else if ((n >= 2) && (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
- return StandardCharsets.UTF_16LE;
- } else {
- return defaultCharset;
- }
- } catch (IOException e) {
- throw new IllegalStateException("Unable to read file " + path.toAbsolutePath().toString(), e);
- }
- }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
index 37c2b957b65..e3a322e6938 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
@@ -31,7 +31,9 @@ import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsRegexpScanner;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader.DoubleRegexpMatcher;
+import java.io.IOException;
import java.net.URISyntaxException;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
@@ -72,10 +74,11 @@ public class IssueExclusionsRegexpScannerTest {
javaFile = "org.sonar.test.MyFile";
regexpScanner = new IssueExclusionsRegexpScanner(javaFile, allFilePatterns, blockPatterns, patternMatcher);
}
-
+
@Test
- public void shouldDetectPatternLastLine() throws URISyntaxException {
- fileMetadata.readMetadata(getResource("file-with-single-regexp-last-line.txt").toFile(), UTF_8, regexpScanner);
+ public void shouldDetectPatternLastLine() throws URISyntaxException, IOException {
+ Path filePath = getResource("file-with-single-regexp-last-line.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
verifyNoMoreInteractions(patternMatcher);
@@ -83,13 +86,16 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldDoNothing() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-no-regexp.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-no-regexp.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
+
verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeFile() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-single-regexp.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-single-regexp.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
verifyNoMoreInteractions(patternMatcher);
@@ -97,7 +103,8 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldAddPatternToExcludeFileEvenIfAlsoDoubleRegexps() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-single-regexp-and-double-regexp.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-single-regexp-and-double-regexp.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(5, 26));
@@ -108,7 +115,8 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldAddPatternToExcludeLines() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-double-regexp.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-double-regexp.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 25));
@@ -118,7 +126,8 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldAddPatternToExcludeLinesTillTheEnd() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-double-regexp-unfinished.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-double-regexp-unfinished.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 34));
@@ -128,7 +137,8 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldAddPatternToExcludeSeveralLineRanges() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-double-regexp-twice.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-double-regexp-twice.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 25));
@@ -139,7 +149,8 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldAddPatternToExcludeLinesWithWrongOrder() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-double-regexp-wrong-order.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-double-regexp-wrong-order.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(25, 35));
@@ -149,7 +160,8 @@ public class IssueExclusionsRegexpScannerTest {
@Test
public void shouldAddPatternToExcludeLinesWithMess() throws Exception {
- fileMetadata.readMetadata(getResource("file-with-double-regexp-mess.txt").toFile(), UTF_8, regexpScanner);
+ Path filePath = getResource("file-with-double-regexp-mess.txt");
+ fileMetadata.readMetadata(Files.newInputStream(filePath), UTF_8, filePath.toString(), regexpScanner);
Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 29));
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java
index f2f783a6bb3..b0465a5ce40 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java
@@ -21,6 +21,8 @@ package org.sonar.scanner.issue.tracking;
import java.io.File;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
@@ -59,6 +61,7 @@ public class SourceHashHolderTest {
ioFile = temp.newFile();
when(file.file()).thenReturn(ioFile);
when(file.path()).thenReturn(ioFile.toPath());
+ when(file.inputStream()).thenAnswer(i -> Files.newInputStream(ioFile.toPath()));
when(file.lines()).thenReturn(1);
when(file.charset()).thenReturn(StandardCharsets.UTF_8);
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java
new file mode 100644
index 00000000000..167e362201c
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/CharsetDetectorTest.java
@@ -0,0 +1,95 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.scan.filesystem;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Random;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+public class CharsetDetectorTest {
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void should_detect_charset_from_BOM() {
+ Path basedir = Paths.get("src/test/resources/org/sonar/scanner/scan/filesystem/");
+
+ assertThat(detectCharset(basedir.resolve("without_BOM.txt"), StandardCharsets.US_ASCII)).isEqualTo(StandardCharsets.US_ASCII);
+ assertThat(detectCharset(basedir.resolve("UTF-8.txt"), StandardCharsets.US_ASCII)).isEqualTo(StandardCharsets.UTF_8);
+ assertThat(detectCharset(basedir.resolve("UTF-16BE.txt"), StandardCharsets.US_ASCII)).isEqualTo(StandardCharsets.UTF_16BE);
+ assertThat(detectCharset(basedir.resolve("UTF-16LE.txt"), StandardCharsets.US_ASCII)).isEqualTo(StandardCharsets.UTF_16LE);
+ assertThat(detectCharset(basedir.resolve("UTF-32BE.txt"), StandardCharsets.US_ASCII)).isEqualTo(MetadataGenerator.UTF_32BE);
+ assertThat(detectCharset(basedir.resolve("UTF-32LE.txt"), StandardCharsets.US_ASCII)).isEqualTo(MetadataGenerator.UTF_32LE);
+ }
+
+ @Test
+ public void always_try_utf8() throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8")) {
+ // UTF-16 can't read 1 byte only
+ writer.write("t");
+ }
+
+ Path filePath = temp.newFile().toPath();
+ Files.write(filePath, out.toByteArray());
+ assertThat(detectCharset(filePath, StandardCharsets.UTF_16)).isEqualByComparingTo(StandardCharsets.UTF_8);
+
+ }
+
+ @Test
+ public void fail_if_file_doesnt_exist() {
+ exception.expect(IllegalStateException.class);
+ exception.expectMessage("Unable to read file " + Paths.get("non_existing").toAbsolutePath());
+ detectCharset(Paths.get("non_existing"), StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void no_encoding_found() throws IOException {
+ Path filePath = temp.newFile().toPath();
+ byte[] b = new byte[512];
+ new Random().nextBytes(b);
+ Files.write(filePath, b);
+
+ CharsetDetector detector = new CharsetDetector(filePath, StandardCharsets.UTF_8);
+ assertThat(detector.run()).isFalse();
+ }
+
+ private Charset detectCharset(Path file, Charset defaultEncoding) {
+ CharsetDetector detector = new CharsetDetector(file, defaultEncoding);
+ assertThat(detector.run()).isTrue();
+ return detector.charset();
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
index 67b455a9986..c552cf75610 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.scanner.scan.filesystem;
+import static org.apache.commons.codec.digest.DigestUtils.md5Hex;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -69,29 +70,25 @@ public class MetadataGeneratorTest {
public void should_detect_charset_from_BOM() {
Path basedir = Paths.get("src/test/resources/org/sonar/scanner/scan/filesystem/");
- assertThat(createInputFileWithMetadata(generator, basedir, "without_BOM.txt").charset())
+ assertThat(createInputFileWithMetadata(basedir.resolve("without_BOM.txt")).charset())
.isEqualTo(StandardCharsets.US_ASCII);
- assertThat(createInputFileWithMetadata(generator, basedir, "UTF-8.txt").charset())
+ assertThat(createInputFileWithMetadata(basedir.resolve("UTF-8.txt")).charset())
.isEqualTo(StandardCharsets.UTF_8);
- assertThat(createInputFileWithMetadata(generator, basedir, "UTF-16BE.txt").charset())
+ assertThat(createInputFileWithMetadata(basedir.resolve("UTF-16BE.txt")).charset())
.isEqualTo(StandardCharsets.UTF_16BE);
- assertThat(createInputFileWithMetadata(generator, basedir, "UTF-16LE.txt").charset())
+ assertThat(createInputFileWithMetadata(basedir.resolve("UTF-16LE.txt")).charset())
.isEqualTo(StandardCharsets.UTF_16LE);
- assertThat(createInputFileWithMetadata(generator, basedir, "UTF-32BE.txt").charset())
+ assertThat(createInputFileWithMetadata(basedir.resolve("UTF-32BE.txt")).charset())
.isEqualTo(MetadataGenerator.UTF_32BE);
- assertThat(createInputFileWithMetadata(generator, basedir, "UTF-32LE.txt").charset())
+ assertThat(createInputFileWithMetadata(basedir.resolve("UTF-32LE.txt")).charset())
.isEqualTo(MetadataGenerator.UTF_32LE);
+ }
- try {
- createInputFileWithMetadata(generator, basedir, "non_existing");
- Assert.fail();
- } catch (IllegalStateException e) {
- assertThat(e.getMessage()).endsWith("Unable to read file " + basedir.resolve("non_existing").toAbsolutePath());
- assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
- }
+ private DefaultInputFile createInputFileWithMetadata(Path filePath) {
+ return createInputFileWithMetadata(filePath.getParent(), filePath.getFileName().toString());
}
- private DefaultInputFile createInputFileWithMetadata(MetadataGenerator generator, Path baseDir, String relativePath) {
+ private DefaultInputFile createInputFileWithMetadata(Path baseDir, String relativePath) {
DefaultInputFile inputFile = new TestInputFileBuilder("struts", relativePath)
.setModuleBaseDir(baseDir)
.build();
@@ -100,6 +97,29 @@ public class MetadataGeneratorTest {
}
@Test
+ public void start_with_bom() throws Exception {
+ Path tempFile = temp.newFile().toPath();
+ FileUtils.write(tempFile.toFile(), "\uFEFFfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true);
+
+ DefaultInputFile inputFile = createInputFileWithMetadata(tempFile);
+ assertThat(inputFile.lines()).isEqualTo(3);
+ assertThat(inputFile.nonBlankLines()).isEqualTo(3);
+ assertThat(inputFile.hash()).isEqualTo(md5Hex("foo\nbar\nbaz"));
+ assertThat(inputFile.originalLineOffsets()).containsOnly(0, 4, 9);
+ }
+
+ @Test
+ public void non_existing_file_should_throw_exception() {
+ try {
+ createInputFileWithMetadata(Paths.get(""), "non_existing");
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).endsWith("Unable to read file " + Paths.get("").resolve("non_existing").toAbsolutePath());
+ assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
+ }
+ }
+
+ @Test
public void complete_input_file() throws Exception {
// file system
Path baseDir = temp.newFolder().toPath();
@@ -111,7 +131,7 @@ public class MetadataGeneratorTest {
when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
.thenReturn(InputFile.Status.ADDED);
- InputFile inputFile = createInputFileWithMetadata(generator, baseDir, "src/main/java/foo/Bar.java");
+ InputFile inputFile = createInputFileWithMetadata(baseDir, "src/main/java/foo/Bar.java");
assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN);
assertThat(inputFile.file()).isEqualTo(srcFile.toFile());
diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt
index ef135ebc50c..88ad675955f 100644
--- a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt
+++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt
@@ -4,9 +4,6 @@ import com.google.common.collect.Sets;
import java.util.Set;
-/**
- * @SONAR-IGNORE-ALL
- */
public class LineRange {
int from, to;
@@ -30,4 +27,5 @@ public class LineRange {
return lines;
}
-} \ No newline at end of file
+}
+// @SONAR-IGNORE-ALL \ No newline at end of file
diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
index 88ad675955f..ea1e7b07e2d 100644
--- a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
+++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
@@ -4,6 +4,9 @@ import com.google.common.collect.Sets;
import java.util.Set;
+/**
+ * @SONAR-IGNORE-ALL
+ */
public class LineRange {
int from, to;
@@ -28,4 +31,3 @@ public class LineRange {
}
}
-// @SONAR-IGNORE-ALL \ No newline at end of file