diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2017-04-07 14:20:09 +0200 |
---|---|---|
committer | dbmeneses <duarte.meneses@sonarsource.com> | 2017-04-11 16:12:42 +0200 |
commit | 6782a76dcf2e42fea32116a22d1c3ecb8d2975fa (patch) | |
tree | 1d80043f01606755615444d2db54246918c034c6 /sonar-scanner-engine | |
parent | affd68df75848af9d3355a563c48a69a231b8853 (diff) | |
download | sonarqube-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')
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 |