From a00532595a391ed62251f4d00aa27feb2a336ca3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Mar 2013 20:17:45 +0100 Subject: [PATCH] pmd: fixed #1068 CPD fails on broken symbolic links --- pmd/etc/changelog.txt | 6 ++ .../java/net/sourceforge/pmd/cpd/CPD.java | 7 +- .../java/net/sourceforge/pmd/cpd/CPDTest.java | 71 +++++++++++++++++++ .../sourceforge/pmd/cpd/files/real-file.txt | 0 .../pmd/cpd/files/symlink-for-real-file.txt | 1 + .../files/this-is-a-broken-sym-link-for-test | 1 + 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 pmd/src/test/java/net/sourceforge/pmd/cpd/CPDTest.java create mode 100644 pmd/src/test/resources/net/sourceforge/pmd/cpd/files/real-file.txt create mode 120000 pmd/src/test/resources/net/sourceforge/pmd/cpd/files/symlink-for-real-file.txt create mode 120000 pmd/src/test/resources/net/sourceforge/pmd/cpd/files/this-is-a-broken-sym-link-for-test diff --git a/pmd/etc/changelog.txt b/pmd/etc/changelog.txt index 72febfb173..1d27e95408 100644 --- a/pmd/etc/changelog.txt +++ b/pmd/etc/changelog.txt @@ -1,3 +1,9 @@ +????? ??, 2013 - 5.0.3: + +Fixed bug 1068: CPD fails on broken symbolic links + + + February 3, 2013 - 5.0.2: Fixed bug 878: False positive: UnusedFormalParameter for abstract methods diff --git a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java index 64e7c0ec64..d3d5633837 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java +++ b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java @@ -93,11 +93,16 @@ public class CPD { current.add(signature); } - if (!file.getCanonicalPath().equals(new File(file.getAbsolutePath()).getCanonicalPath())) { + if (!file.getCanonicalPath().equals(file.getAbsolutePath())) { System.err.println("Skipping " + file + " since it appears to be a symlink"); return; } + if (!file.exists()) { + System.err.println("Skipping " + file + " since it doesn't exist (broken symlink?)"); + return; + } + listener.addedFile(fileCount, file); SourceCode sourceCode = configuration.sourceCodeFor(file); configuration.tokenizer().tokenize(sourceCode, tokens); diff --git a/pmd/src/test/java/net/sourceforge/pmd/cpd/CPDTest.java b/pmd/src/test/java/net/sourceforge/pmd/cpd/CPDTest.java new file mode 100644 index 0000000000..e8bd3de734 --- /dev/null +++ b/pmd/src/test/java/net/sourceforge/pmd/cpd/CPDTest.java @@ -0,0 +1,71 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package net.sourceforge.pmd.cpd; + +import java.io.File; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit test for {@link CPD} + */ +public class CPDTest { + + private static final String BASE_TEST_RESOURCE_PATH = "src/test/resources/net/sourceforge/pmd/cpd/files/"; + + private CPD cpd; + + @Before + public void setup() { + CPDConfiguration theConfiguration = new CPDConfiguration(new String[] {"--language", "java", + "--minimum-tokens", "10"}); + cpd = new CPD(theConfiguration); + } + + /** + * A broken symlink (which is basically a not existing file), should be skipped. + * @throws Exception any error + */ + @Test + public void testFileSectionWithBrokenSymlinks() throws Exception { + cpd.setCpdListener(new NoFileAssertListener(0)); + + cpd.add(new File(BASE_TEST_RESOURCE_PATH, "this-is-a-broken-sym-link-for-test")); + } + + /** + * A file should be added only once - even if it was found twice, because of a sym link. + * @throws Exception any error + */ + @Test + public void testFileAddedAsSymlinkAndReal() throws Exception { + cpd.setCpdListener(new NoFileAssertListener(1)); + + cpd.add(new File(BASE_TEST_RESOURCE_PATH, "real-file.txt")); + cpd.add(new File(BASE_TEST_RESOURCE_PATH, "symlink-for-real-file.txt")); + } + + /** + * Simple listener that fails, if to many files were added and not skipped. + */ + private static class NoFileAssertListener implements CPDListener { + private int maximumFilesAllowed; + private int files; + public NoFileAssertListener(int maximumFilesAllowed) { + this.maximumFilesAllowed = maximumFilesAllowed; + this.files = 0; + } + public void addedFile(int fileCount, File file) { + files++; + if (files > maximumFilesAllowed) { + Assert.fail("File was added! - " + file); + } + } + public void phaseUpdate(int phase) { + // not needed for this test + } + } +} diff --git a/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/real-file.txt b/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/real-file.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/symlink-for-real-file.txt b/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/symlink-for-real-file.txt new file mode 120000 index 0000000000..cf29a52983 --- /dev/null +++ b/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/symlink-for-real-file.txt @@ -0,0 +1 @@ +real-file.txt \ No newline at end of file diff --git a/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/this-is-a-broken-sym-link-for-test b/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/this-is-a-broken-sym-link-for-test new file mode 120000 index 0000000000..8d8e4d3769 --- /dev/null +++ b/pmd/src/test/resources/net/sourceforge/pmd/cpd/files/this-is-a-broken-sym-link-for-test @@ -0,0 +1 @@ +broken-sym-link \ No newline at end of file