From 4944177cc4a8a6b3467950bab061795e1c261813 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 7 May 2022 21:30:47 +0200 Subject: [PATCH 01/12] [core] Add missing methods to IOUtil as replacement for IOUtils --- .../java/net/sourceforge/pmd/util/IOUtil.java | 318 +++++++++++++++++- .../net/sourceforge/pmd/util/IOUtilTest.java | 258 ++++++++++++++ 2 files changed, 574 insertions(+), 2 deletions(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java index d4833987d1..791561bc7a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java @@ -7,21 +7,30 @@ package net.sourceforge.pmd.util; import java.io.BufferedReader; import java.io.Closeable; import java.io.File; +import java.io.FilterInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collection; import java.util.List; +import java.util.Objects; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.annotation.InternalApi; @@ -35,6 +44,8 @@ import net.sourceforge.pmd.annotation.InternalApi; @Deprecated public final class IOUtil { + private static final int BUFFER_SIZE = 8192; + private IOUtil() { } @@ -119,7 +130,7 @@ public final class IOUtil { public static void tryCloseClassLoader(ClassLoader classLoader) { if (classLoader instanceof Closeable) { - IOUtils.closeQuietly((Closeable) classLoader); + closeQuietly((Closeable) classLoader); } } @@ -169,4 +180,307 @@ public final class IOUtil { } } + public static void closeQuietly(Closeable closeable) { + try { + closeable.close(); + } catch (IOException ignored) { + // ignored + } + } + + public static byte[] toByteArray(InputStream stream) throws IOException { + byte[] result = new byte[0]; + byte[] buffer = new byte[BUFFER_SIZE]; + int count = stream.read(buffer); + while (count > -1) { + byte[] newResult = new byte[result.length + count]; + System.arraycopy(result, 0, newResult, 0, result.length); + System.arraycopy(buffer, 0, newResult, result.length, count); + result = newResult; + count = stream.read(buffer); + } + return result; + } + + public static long skipFully(InputStream stream, long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException(); + } + + long bytesToSkip = n; + byte[] buffer = new byte[(int) Math.min(BUFFER_SIZE, bytesToSkip)]; + while (bytesToSkip > 0) { + int count = stream.read(buffer, 0, (int) Math.min(BUFFER_SIZE, bytesToSkip)); + if (count < 0) { + // reached eof + break; + } + bytesToSkip -= count; + } + return n - bytesToSkip; + } + + public static String normalizePath(String path) { + Path path1 = Paths.get(path); + path1.isAbsolute(); + String normalized = path1.normalize().toString(); + if (normalized.contains("." + File.separator) || normalized.contains(".." + File.separator) || "".equals(normalized)) { + return null; + } + return normalized; + } + + public static boolean equalsNormalizedPaths(String path1, String path2) { + return Objects.equals(normalizePath(path1), normalizePath(path2)); + } + + public static String getFilenameExtension(String name) { + String filename = Paths.get(name).getFileName().toString(); + int dot = filename.lastIndexOf('.'); + if (dot > -1) { + return filename.substring(dot + 1); + } + return ""; + } + + public static String getFilenameBase(String name) { + String filename = Paths.get(name).getFileName().toString(); + int dot = filename.lastIndexOf('.'); + if (dot > -1) { + return filename.substring(0, dot); + } + return filename; + } + + public static void copy(InputStream from, OutputStream to) throws IOException { + byte[] buffer = new byte[BUFFER_SIZE]; + int count = from.read(buffer); + while (count > -1) { + to.write(buffer, 0, count); + count = from.read(buffer); + } + } + + public static void copy(Reader from, Writer to) throws IOException { + char[] buffer = new char[BUFFER_SIZE]; + int count = from.read(buffer); + while (count > -1) { + to.write(buffer, 0, count); + count = from.read(buffer); + } + } + + public static String readFileToString(File file) throws IOException { + return readFileToString(file, Charset.defaultCharset()); + } + + public static String readFileToString(File file, Charset charset) throws IOException { + byte[] bytes = Files.readAllBytes(file.toPath()); + return charset.decode(ByteBuffer.wrap(bytes)).toString(); + } + + public static String readToString(Reader reader) throws IOException { + StringBuilder sb = new StringBuilder(BUFFER_SIZE); + char[] buffer = new char[BUFFER_SIZE]; + int count = reader.read(buffer); + while (count > -1) { + sb.append(buffer, 0, count); + count = reader.read(buffer); + } + return sb.toString(); + } + + public static String readToString(InputStream stream, Charset charset) throws IOException { + byte[] bytes = toByteArray(stream); + return charset.decode(ByteBuffer.wrap(bytes)).toString(); + } + + public static InputStream fromReader(Reader reader) throws IOException { + class ReaderInputStream extends InputStream { + private final Reader reader; + private final CharBuffer charBuffer = CharBuffer.allocate(BUFFER_SIZE); + private final ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); + private final CharsetEncoder encoder; + + private boolean eof; + + ReaderInputStream(Reader reader) { + this.reader = reader; + encoder = Charset.defaultCharset().newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + charBuffer.clear(); + byteBuffer.clear(); + byteBuffer.flip(); // byte buffer is empty at the beginning, no bytes read yet + } + + @Override + public int read() throws IOException { + if (!byteBuffer.hasRemaining()) { + if (charBuffer.hasRemaining() && !eof) { + int count = reader.read(charBuffer); + eof = count == -1; + } + byteBuffer.clear(); + charBuffer.flip(); + encoder.encode(charBuffer, byteBuffer, eof); + byteBuffer.flip(); + charBuffer.flip(); + } + + if (byteBuffer.hasRemaining()) { + return byteBuffer.get(); + } + + return -1; + } + + @Override + public int available() throws IOException { + return byteBuffer.remaining(); + } + + @Override + public void close() throws IOException { + reader.close(); + } + } + + return new ReaderInputStream(reader); + } + + public static OutputStream fromWriter(Writer writer, String encoding) throws UnsupportedCharsetException { + class WriterOutputStream extends OutputStream { + private final Writer writer; + private final CharsetDecoder decoder; + private final ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); + private final CharBuffer charBuffer = CharBuffer.allocate(BUFFER_SIZE); + + WriterOutputStream(Writer writer, String encoding) throws UnsupportedCharsetException { + this.writer = writer; + Charset charset = Charset.forName(encoding); + decoder = charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + byteBuffer.clear(); + charBuffer.clear(); + } + + @Override + public void write(int b) throws IOException { + if (!byteBuffer.hasRemaining()) { + decodeByteBuffer(false); + } + byteBuffer.put((byte) b); + } + + @Override + public void flush() throws IOException { + decodeByteBuffer(false); + } + + private void decodeByteBuffer(boolean isClosing) throws IOException { + byteBuffer.flip(); + charBuffer.clear(); + decoder.decode(byteBuffer, charBuffer, isClosing); + writer.write(charBuffer.array(), 0, charBuffer.position()); + writer.flush(); + byteBuffer.compact(); + } + + @Override + public void close() throws IOException { + flush(); + decodeByteBuffer(true); + writer.close(); + } + } + + return new WriterOutputStream(writer, encoding); + } + + /** + *

+ * Input stream that skips an optional byte order mark at the beginning + * of the stream. Whether the stream had a byte order mark (encoded in either UTF-8, + * UTF-16LE or UTF-16BE) can be checked with {@link #hasBom()}. The corresponding + * charset can be retrieved with {@link #getBomCharsetName()}. + *

+ * + *

+ * If the stream didn't had a BOM, then no bytes are skipped. + *

+ */ + public static class BomAwareInputStream extends FilterInputStream { + + private byte[] begin; + int beginIndex; + + private String charset; + + public BomAwareInputStream(InputStream in) { + super(in); + begin = determineBom(); + } + + private byte[] determineBom() { + byte[] bytes = new byte[3]; + try { + int count = in.read(bytes); + if (count == 3 && bytes[0] == (byte) 0xef && bytes[1] == (byte) 0xbb && bytes[2] == (byte) 0xbf) { + charset = StandardCharsets.UTF_8.name(); + return new byte[0]; // skip all 3 bytes + } else if (count >= 2 && bytes[0] == (byte) 0xfe && bytes[1] == (byte) 0xff) { + charset = StandardCharsets.UTF_16BE.name(); + return new byte[] { bytes[2] }; + } else if (count >= 2 && bytes[0] == (byte) 0xff && bytes[1] == (byte) 0xfe) { + charset = StandardCharsets.UTF_16LE.name(); + return new byte[] { bytes[2] }; + } else if (count == 3) { + return bytes; + } + + if (count < 0) { + return new byte[0]; + } + + byte[] read = new byte[count]; + for (int i = 0; i < count; i++) { + read[i] = bytes[i]; + } + return read; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public int read() throws IOException { + if (beginIndex < begin.length) { + return begin[beginIndex++]; + } + return super.read(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (beginIndex < begin.length) { + int count = 0; + for (; count < len && beginIndex < begin.length; beginIndex++) { + b[off + count] = begin[beginIndex]; + count++; + } + return count; + } + return super.read(b, off, len); + } + + public boolean hasBom() { + return charset != null; + } + + public String getBomCharsetName() { + return charset; + } + } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java new file mode 100644 index 0000000000..35e772cfc9 --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java @@ -0,0 +1,258 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.commons.lang3.SystemUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.function.ThrowingRunnable; + +public class IOUtilTest { + + @Test + public void testReadAllBytes() throws IOException { + byte[] data = "12345".getBytes(StandardCharsets.UTF_8); + try (InputStream stream = new ByteArrayInputStream(data)) { + byte[] bytes = IOUtil.toByteArray(stream); + Assert.assertEquals(5, bytes.length); + Assert.assertArrayEquals(data, bytes); + } + } + + @Test + public void testToByteArrayResize() throws IOException { + int size = 8192 + 8192 + 10; + byte[] data = new byte[size]; + for (int i = 0; i < size; i++) { + data[i] = 'A'; + } + try (InputStream stream = new ByteArrayInputStream(data)) { + byte[] bytes = IOUtil.toByteArray(stream); + Assert.assertEquals(size, bytes.length); + Assert.assertArrayEquals(data, bytes); + } + } + + @Test + public void testSkipFully() throws IOException { + byte[] data = "12345".getBytes(StandardCharsets.UTF_8); + try (InputStream stream = new ByteArrayInputStream(data)) { + Assert.assertThrows(IllegalArgumentException.class, new ThrowingRunnable() { + @Override + public void run() throws Throwable { + IOUtil.skipFully(stream, -1); + } + }); + + Assert.assertEquals(3, IOUtil.skipFully(stream, 3)); + byte[] bytes = IOUtil.toByteArray(stream); + Assert.assertEquals(2, bytes.length); + Assert.assertArrayEquals("45".getBytes(StandardCharsets.UTF_8), bytes); + } + } + + @Test + public void testSkipFully2() throws IOException { + byte[] data = "12345".getBytes(StandardCharsets.UTF_8); + try (InputStream stream = new ByteArrayInputStream(data)) { + // skip more bytes than the stream contains + Assert.assertEquals(data.length, IOUtil.skipFully(stream, data.length + 1)); + byte[] bytes = IOUtil.toByteArray(stream); + Assert.assertEquals(0, bytes.length); + } + } + + @Test + public void testNormalizePath() { + Assert.assertEquals("ab/cd.txt", IOUtil.normalizePath("ab/ef/../cd.txt")); + Assert.assertEquals("/a.txt", IOUtil.normalizePath("/x/../../a.txt")); + Assert.assertEquals("/foo", IOUtil.normalizePath("//../foo")); + Assert.assertEquals("/foo", IOUtil.normalizePath("/foo//")); + Assert.assertEquals("/foo", IOUtil.normalizePath("/foo/./")); + Assert.assertEquals("/bar", IOUtil.normalizePath("/foo/../bar")); + Assert.assertEquals("/bar", IOUtil.normalizePath("/foo/../bar/")); + Assert.assertEquals("/baz", IOUtil.normalizePath("/foo/../bar/../baz")); + Assert.assertEquals("/foo/bar", IOUtil.normalizePath("//foo//./bar")); + Assert.assertEquals("foo", IOUtil.normalizePath("foo/bar/..")); + Assert.assertEquals("bar", IOUtil.normalizePath("foo/../bar")); + Assert.assertEquals("/foo/baz", IOUtil.normalizePath("//foo/bar/../baz")); + Assert.assertEquals("~/bar", IOUtil.normalizePath("~/foo/../bar/")); + Assert.assertEquals("/", IOUtil.normalizePath("/../")); + Assert.assertEquals("bar", IOUtil.normalizePath("~/../bar")); + Assert.assertEquals("bar", IOUtil.normalizePath("./bar")); + + Assert.assertNull(IOUtil.normalizePath("../foo")); + Assert.assertNull(IOUtil.normalizePath("foo/../../bar")); + Assert.assertNull(IOUtil.normalizePath(".")); + + Assert.assertTrue(IOUtil.equalsNormalizedPaths("foo/../bar", "bar/./")); + + if (SystemUtils.IS_OS_WINDOWS) { + Assert.assertEquals("C:\\bar", IOUtil.normalizePath("C:\\..\\bar")); + Assert.assertEquals("ab\\cd.txt", IOUtil.normalizePath("ab\\ef\\..\\cd.txt")); + Assert.assertEquals("C:\\ab\\cd.txt", IOUtil.normalizePath("C:\\ab\\ef\\..\\.\\cd.txt")); + Assert.assertNull(IOUtil.normalizePath("..\\foo")); + Assert.assertNull(IOUtil.normalizePath("foo\\..\\..\\bar")); + } + } + + @Test + public void testFilenameExtension() { + Assert.assertEquals("txt", IOUtil.getFilenameExtension("ab/cd.txt")); + Assert.assertEquals("txt", IOUtil.getFilenameExtension("ab.cd.txt")); + Assert.assertEquals("", IOUtil.getFilenameExtension("ab/cd")); + Assert.assertEquals("html", IOUtil.getFilenameExtension("cd.html")); + } + + @Test + public void testFilenameBase() { + Assert.assertEquals("cd", IOUtil.getFilenameBase("ab/cd.txt")); + Assert.assertEquals("ab.cd", IOUtil.getFilenameBase("ab.cd.txt")); + Assert.assertEquals("cd", IOUtil.getFilenameBase("ab/cd")); + } + + @Test + public void testBomAwareStream() throws IOException { + assertBomStream("No BOM".getBytes(StandardCharsets.UTF_8), "No BOM", null); + assertBomStream("\ufeffBOM".getBytes(StandardCharsets.UTF_8), "BOM", StandardCharsets.UTF_8.name()); + assertBomStream("\ufeffBOM".getBytes(StandardCharsets.UTF_16LE), "BOM", StandardCharsets.UTF_16LE.name()); + assertBomStream("\ufeffBOM".getBytes(StandardCharsets.UTF_16BE), "BOM", StandardCharsets.UTF_16BE.name()); + } + + private void assertBomStream(byte[] data, String expectedData, String expectedCharset) throws IOException { + try (IOUtil.BomAwareInputStream stream = new IOUtil.BomAwareInputStream(new ByteArrayInputStream(data))) { + if (expectedCharset != null) { + Assert.assertTrue(stream.hasBom()); + Assert.assertEquals(expectedCharset, stream.getBomCharsetName()); + Assert.assertEquals(expectedData, new String(IOUtil.toByteArray(stream), stream.getBomCharsetName())); + + } else { + Assert.assertFalse(stream.hasBom()); + Assert.assertNull(stream.getBomCharsetName()); + Assert.assertEquals(expectedData, new String(IOUtil.toByteArray(stream), StandardCharsets.UTF_8)); + } + } + } + + @Test + public void testOutputStreamFromWriter() throws IOException { + StringWriter writer = new StringWriter(); + try (OutputStream outputStream = IOUtil.fromWriter(writer, "UTF-8")) { + outputStream.write("abc".getBytes(StandardCharsets.UTF_8)); + } + Assert.assertEquals("abc", writer.toString()); + } + + @Test + public void testInputStreamFromReader() throws IOException { + try (InputStream inputStream = IOUtil.fromReader(new StringReader("abc"))) { + byte[] bytes = IOUtil.toByteArray(inputStream); + Assert.assertEquals("abc", new String(bytes, StandardCharsets.UTF_8)); + } + } + + @Test + public void testCopyStream() throws IOException { + int size = 8192 + 8192 + 10; + byte[] data = new byte[size]; + for (int i = 0; i < size; i++) { + data[i] = 'A'; + } + try (InputStream stream = new ByteArrayInputStream(data); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + IOUtil.copy(stream, out); + byte[] bytes = out.toByteArray(); + Assert.assertEquals(size, bytes.length); + Assert.assertArrayEquals(data, bytes); + } + } + + @Test + public void testCopyReader() throws IOException { + int size = 8192 + 8192 + 10; + char[] data = new char[size]; + for (int i = 0; i < size; i++) { + data[i] = 'A'; + } + try (Reader reader = new CharArrayReader(data); + StringWriter writer = new StringWriter()) { + IOUtil.copy(reader, writer); + char[] chars = writer.toString().toCharArray(); + Assert.assertEquals(size, chars.length); + Assert.assertArrayEquals(data, chars); + } + } + + @Test + public void testReadEmptyStream() throws IOException { + try (InputStream in = new ByteArrayInputStream(new byte[0])) { + byte[] bytes = IOUtil.toByteArray(in); + Assert.assertNotNull(bytes); + Assert.assertEquals(0, bytes.length); + } + } + + @Test + public void testCloseQuietly() { + class Stream extends InputStream { + private boolean closed = false; + + @Override + public int read() throws IOException { + return 0; + } + + @Override + public void close() throws IOException { + closed = true; + throw new IOException("test"); + } + + public boolean isClosed() { + return closed; + } + } + + Stream stream = new Stream(); + IOUtil.closeQuietly(stream); + Assert.assertTrue(stream.isClosed()); + } + + @Test + public void testReadFileToString() throws IOException { + String testString = "Test ABC"; + Path tempFile = Files.createTempFile("pmd", ".txt"); + Files.write(tempFile, testString.getBytes(Charset.defaultCharset())); + Assert.assertEquals(testString, IOUtil.readFileToString(tempFile.toFile())); + } + + @Test + public void testReadToString() throws IOException { + String testString = "testReadToString"; + Reader reader = new StringReader(testString); + Assert.assertEquals(testString, IOUtil.readToString(reader)); + } + + @Test + public void testReadStreamToString() throws IOException { + String testString = "testReadStreamToString"; + InputStream stream = new ByteArrayInputStream(testString.getBytes(StandardCharsets.UTF_8)); + Assert.assertEquals(testString, IOUtil.readToString(stream, StandardCharsets.UTF_8)); + } +} From 753cb49e403b71d683bc7bcc7104fd01cb813530 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 09:51:54 +0200 Subject: [PATCH 02/12] [all] Remove dependency to commons-io --- pmd-apex/pom.xml | 4 ---- pmd-core/pom.xml | 4 ---- pmd-dist/pom.xml | 4 ---- pmd-doc/pom.xml | 4 ---- pmd-java/pom.xml | 4 ---- pmd-javascript/pom.xml | 4 ---- pmd-lang-test/pom.xml | 4 ---- pmd-plsql/pom.xml | 4 ---- pmd-scala-modules/pmd-scala-common/pom.xml | 4 ---- pmd-test/pom.xml | 4 ---- pmd-xml/pom.xml | 4 ---- pom.xml | 5 ----- 12 files changed, 49 deletions(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 9c0e6b93a9..4b7786ff4e 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -58,10 +58,6 @@ pom - - commons-io - commons-io - org.apache.commons commons-lang3 diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index bd5ed97a91..bd60fcdfad 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -111,10 +111,6 @@ com.beust jcommander - - commons-io - commons-io - jaxen jaxen diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 66d4134964..58348f8bbf 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -236,10 +236,6 @@ - - commons-io - commons-io - org.apache.commons commons-lang3 diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index db23e84ae7..5fda1dc5b9 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -83,10 +83,6 @@ pmd-core ${project.version} - - commons-io - commons-io - org.apache.commons commons-lang3 diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index b85810aaeb..df12c9505f 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -127,10 +127,6 @@ org.ow2.asm asm - - commons-io - commons-io - org.apache.commons commons-lang3 diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index d4256cf9bc..d87540aceb 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -84,10 +84,6 @@ rhino 1.7.14 - - commons-io - commons-io - junit diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index c657cdd6b8..cbe2246ebd 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -81,10 +81,6 @@ org.apache.commons commons-lang3 - - commons-io - commons-io - - - commons-io - commons-io - 2.6 - org.apache.commons commons-lang3 From 2887fe3ae0e7cb573380142aa004d040b47f8877 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 09:52:13 +0200 Subject: [PATCH 03/12] [core] Replace IOUtils with IOUtil --- .../sourceforge/pmd/RuleSetFactoryCompatibility.java | 5 ++--- .../main/java/net/sourceforge/pmd/RuleSetWriter.java | 4 ++-- .../main/java/net/sourceforge/pmd/ant/Formatter.java | 6 +++--- .../sourceforge/pmd/cache/AbstractAnalysisCache.java | 5 ++--- .../java/net/sourceforge/pmd/cache/AnalysisResult.java | 6 ++---- .../pmd/cache/internal/RawFileFingerprinter.java | 4 ++-- .../src/main/java/net/sourceforge/pmd/cpd/CPD.java | 6 ++---- .../main/java/net/sourceforge/pmd/cpd/SourceCode.java | 10 ++++------ .../net/sourceforge/pmd/document/DocumentFile.java | 4 ++-- .../pmd/internal/util/FileCollectionUtil.java | 5 ++--- .../net/sourceforge/pmd/lang/document/NioTextFile.java | 5 ++--- .../pmd/processor/AbstractPMDProcessor.java | 4 ++-- .../sourceforge/pmd/renderers/AbstractRenderer.java | 4 +--- .../net/sourceforge/pmd/renderers/XMLRenderer.java | 4 ++-- .../main/java/net/sourceforge/pmd/util/FileFinder.java | 10 +++++++--- .../main/java/net/sourceforge/pmd/util/FileUtil.java | 3 +-- .../pmd/util/datasource/ReaderDataSource.java | 5 ++--- .../pmd/RuleSetFactoryCompatibilityTest.java | 10 +++++----- .../net/sourceforge/pmd/RuleSetReferenceIdTest.java | 10 +++++----- .../src/test/java/net/sourceforge/pmd/RuleSetTest.java | 4 ++-- .../test/java/net/sourceforge/pmd/ant/PMDTaskTest.java | 9 +++++---- .../test/java/net/sourceforge/pmd/cli/CoreCliTest.java | 4 ++-- .../java/net/sourceforge/pmd/cpd/CPDFilelistTest.java | 6 +++--- .../test/java/net/sourceforge/pmd/cpd/CpdXsltTest.java | 5 +++-- .../net/sourceforge/pmd/document/DocumentFileTest.java | 7 ++++--- .../net/sourceforge/pmd/junit/JavaUtilLoggingRule.java | 9 +++++++-- .../net/sourceforge/pmd/lang/DummyLanguageModule.java | 4 ++-- .../pmd/renderers/AbstractRendererTest.java | 4 ++-- .../sourceforge/pmd/renderers/JsonRendererTest.java | 4 ++-- .../sourceforge/pmd/renderers/SarifRendererTest.java | 5 ++--- .../net/sourceforge/pmd/renderers/XMLRendererTest.java | 4 ++-- .../sourceforge/pmd/renderers/YAHTMLRendererTest.java | 10 +++++----- .../pmd/util/treeexport/TreeExportCliTest.java | 4 ++-- .../sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt | 4 ++-- .../sourceforge/pmd/AbstractRuleSetFactoryTest.java | 4 ++-- 35 files changed, 97 insertions(+), 100 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java index 6ed1d189a4..2d4c1ab420 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetFactoryCompatibility.java @@ -16,9 +16,8 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.annotation.InternalApi; +import net.sourceforge.pmd.util.IOUtil; /** * Provides a simple filter mechanism to avoid failing to parse an old ruleset, @@ -116,7 +115,7 @@ public class RuleSetFactoryCompatibility { * @throws IOException if the stream couldn't be read */ public Reader filterRuleSetFile(InputStream stream) throws IOException { - byte[] bytes = IOUtils.toByteArray(stream); + byte[] bytes = IOUtil.toByteArray(stream); String encoding = determineEncoding(bytes); String ruleset = new String(bytes, encoding); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java index 97aa27ca45..07691f4e12 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleSetWriter.java @@ -22,7 +22,6 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import org.apache.commons.io.IOUtils; import org.w3c.dom.CDATASection; import org.w3c.dom.DOMException; import org.w3c.dom.Document; @@ -37,6 +36,7 @@ import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyDescriptorField; import net.sourceforge.pmd.properties.PropertyTypeId; +import net.sourceforge.pmd.util.IOUtil; /** * This class represents a way to serialize a RuleSet to an XML configuration @@ -62,7 +62,7 @@ public class RuleSetWriter { } public void close() { - IOUtils.closeQuietly(outputStream); + IOUtil.closeQuietly(outputStream); } public void write(RuleSet ruleSet) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ant/Formatter.java b/pmd-core/src/main/java/net/sourceforge/pmd/ant/Formatter.java index da031a0152..e248dc6f18 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ant/Formatter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ant/Formatter.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.reflect.MethodUtils; @@ -30,6 +29,7 @@ import net.sourceforge.pmd.Report; import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.renderers.Renderer; import net.sourceforge.pmd.renderers.RendererFactory; +import net.sourceforge.pmd.util.IOUtil; public class Formatter { @@ -187,8 +187,8 @@ public class Formatter { isOnError = false; } finally { if (isOnError) { - IOUtils.closeQuietly(output); - IOUtils.closeQuietly(writer); + IOUtil.closeQuietly(output); + IOUtil.closeQuietly(writer); } } return writer; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/AbstractAnalysisCache.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/AbstractAnalysisCache.java index 57568be50c..ce3b5056cf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/AbstractAnalysisCache.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/AbstractAnalysisCache.java @@ -23,8 +23,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.commons.io.FilenameUtils; - import net.sourceforge.pmd.PMDVersion; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleSets; @@ -35,6 +33,7 @@ import net.sourceforge.pmd.benchmark.TimedOperation; import net.sourceforge.pmd.benchmark.TimedOperationCategory; import net.sourceforge.pmd.cache.internal.ClasspathFingerprinter; import net.sourceforge.pmd.stat.Metric; +import net.sourceforge.pmd.util.IOUtil; /** * Abstract implementation of the analysis cache. Handles all operations, except for persistence. @@ -189,7 +188,7 @@ public abstract class AbstractAnalysisCache implements AnalysisCache { @Override public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { - String extension = FilenameUtils.getExtension(file.toString()); + String extension = IOUtil.getFilenameExtension(file.toString()); if ("jar".equalsIgnoreCase(extension)) { fileVisitor.visitFile(file, attrs); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/AnalysisResult.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/AnalysisResult.java index 0e5f5d9736..4fa7f0e0f6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/AnalysisResult.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/AnalysisResult.java @@ -13,10 +13,9 @@ import java.util.List; import java.util.zip.Adler32; import java.util.zip.CheckedInputStream; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.annotation.InternalApi; +import net.sourceforge.pmd.util.IOUtil; /** * The result of a single file analysis. @@ -45,8 +44,7 @@ public class AnalysisResult { new BufferedInputStream(Files.newInputStream(sourceFile.toPath())), new Adler32()); ) { // Just read it, the CheckedInputStream will update the checksum on it's own - IOUtils.skipFully(stream, sourceFile.length()); - + IOUtil.skipFully(stream, sourceFile.length()); return stream.getChecksum().getValue(); } catch (final IOException ignored) { // We don't really care, if it's unreadable diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java index 6f8854f09c..a183e69f09 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java @@ -14,7 +14,7 @@ import java.util.logging.Logger; import java.util.zip.CheckedInputStream; import java.util.zip.Checksum; -import org.apache.commons.io.IOUtils; +import net.sourceforge.pmd.util.IOUtil; /** * Base fingerprinter for raw files. @@ -40,7 +40,7 @@ public class RawFileFingerprinter implements ClasspathEntryFingerprinter { public void fingerprint(URL entry, Checksum checksum) throws IOException { try (CheckedInputStream inputStream = new CheckedInputStream(entry.openStream(), checksum)) { // Just read it, the CheckedInputStream will update the checksum on it's own - while (IOUtils.skip(inputStream, Long.MAX_VALUE) == Long.MAX_VALUE) { + while (IOUtil.skipFully(inputStream, Long.MAX_VALUE) == Long.MAX_VALUE) { // just loop } } catch (final FileNotFoundException ignored) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java index a18b4d2791..130791c123 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java @@ -17,11 +17,10 @@ import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.commons.io.FilenameUtils; - import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.ast.TokenMgrError; import net.sourceforge.pmd.util.FileFinder; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.database.DBMSMetadata; import net.sourceforge.pmd.util.database.DBURI; import net.sourceforge.pmd.util.database.SourceObject; @@ -93,8 +92,7 @@ public class CPD { current.add(signature); } - if (!FilenameUtils.equalsNormalizedOnSystem(file.getAbsoluteFile().getCanonicalPath(), - file.getAbsolutePath())) { + if (!IOUtil.equalsNormalizedPaths(file.getAbsoluteFile().getCanonicalPath(), file.getAbsolutePath())) { System.err.println("Skipping " + file + " since it appears to be a symlink"); return; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java index 99cf8f8829..b7ac55af7b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java @@ -14,8 +14,7 @@ import java.nio.file.Files; import java.util.ArrayList; import java.util.List; -import org.apache.commons.io.ByteOrderMark; -import org.apache.commons.io.input.BOMInputStream; +import net.sourceforge.pmd.util.IOUtil; public class SourceCode { @@ -112,11 +111,10 @@ public class SourceCode { @Override public Reader getReader() throws Exception { - BOMInputStream inputStream = new BOMInputStream(Files.newInputStream(file.toPath()), ByteOrderMark.UTF_8, - ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE); + IOUtil.BomAwareInputStream inputStream = new IOUtil.BomAwareInputStream(Files.newInputStream(file.toPath())); - if (inputStream.hasBOM()) { - encoding = inputStream.getBOMCharsetName(); + if (inputStream.hasBom()) { + encoding = inputStream.getBomCharsetName(); } return new InputStreamReader(inputStream, encoding); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/document/DocumentFile.java b/pmd-core/src/main/java/net/sourceforge/pmd/document/DocumentFile.java index 7c3e1640c0..0c1bae358a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/document/DocumentFile.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/document/DocumentFile.java @@ -21,7 +21,7 @@ import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.commons.io.IOUtils; +import net.sourceforge.pmd.util.IOUtil; /** * Implementation that handles a Document as a file in the filesystem and receives operations in a sorted manner @@ -159,7 +159,7 @@ public class DocumentFile implements Document, Closeable { } private void writeUntilEOF() throws IOException { - IOUtils.copy(reader, writer); + IOUtil.copy(reader, writer); } /* package-private */ List getLineToOffset() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java index 68e1ab16e1..e8041d3430 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java @@ -15,13 +15,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.lang.Language; import net.sourceforge.pmd.lang.document.FileCollector; import net.sourceforge.pmd.lang.document.TextFile; import net.sourceforge.pmd.util.FileUtil; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.database.DBMSMetadata; import net.sourceforge.pmd.util.database.DBURI; import net.sourceforge.pmd.util.database.SourceObject; @@ -157,7 +156,7 @@ public final class FileCollectionUtil { collector.getReporter().trace("Adding database source object {0}", falseFilePath); try (Reader sourceCode = dbmsMetadata.getSourceCode(sourceObject)) { - String source = IOUtils.toString(sourceCode); + String source = IOUtil.readToString(sourceCode); collector.addSourceFile(source, falseFilePath); } catch (SQLException ex) { collector.getReporter().warnEx("Cannot get SourceCode for {0} - skipping ...", diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java index 705ef530a7..c7d77e1de8 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java @@ -12,11 +12,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Objects; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.internal.util.AssertionUtil; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.datasource.DataSource; import net.sourceforge.pmd.util.datasource.FileDataSource; @@ -68,7 +67,7 @@ class NioTextFile implements TextFile { } try (BufferedReader br = Files.newBufferedReader(path, charset)) { - return IOUtils.toString(br); + return IOUtil.readToString(br); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java index 8da879721f..93a1487e0f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java @@ -11,7 +11,6 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.exception.ContextedRuntimeException; import net.sourceforge.pmd.PMDConfiguration; @@ -27,6 +26,7 @@ import net.sourceforge.pmd.benchmark.TimeTracker; import net.sourceforge.pmd.benchmark.TimedOperation; import net.sourceforge.pmd.benchmark.TimedOperationCategory; import net.sourceforge.pmd.renderers.Renderer; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.datasource.DataSource; /** @@ -151,7 +151,7 @@ public abstract class AbstractPMDProcessor { // in case we analyzed files within Zip Files/Jars, we need to close them after // the analysis is finished for (DataSource dataSource : files) { - IOUtils.closeQuietly(dataSource); + IOUtil.closeQuietly(dataSource); } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java index 88b69d2202..5ee89c4cc2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java @@ -9,8 +9,6 @@ import java.io.Writer; import java.util.Collections; import java.util.List; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.cli.PMDParameters; @@ -108,7 +106,7 @@ public abstract class AbstractRenderer extends AbstractPropertySource implements } catch (IOException e) { throw new IllegalStateException(e); } finally { - IOUtils.closeQuietly(writer); + IOUtil.closeQuietly(writer); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java index f9dfd96a72..e7adaa6426 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java @@ -21,13 +21,13 @@ import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import org.apache.commons.io.output.WriterOutputStream; import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.PMDVersion; import net.sourceforge.pmd.Report; import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.properties.StringProperty; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.StringUtil; /** @@ -256,7 +256,7 @@ public class XMLRenderer extends AbstractIncrementingRenderer { public void setWriter(final Writer writer) { String encoding = getProperty(ENCODING); // for backwards compatibility, create a OutputStream that writes to the writer. - this.stream = new WriterOutputStream(writer, encoding); + this.stream = IOUtil.fromWriter(writer, encoding); XMLOutputFactory outputFactory = XMLOutputFactory.newFactory(); try { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java index 874a004bcf..c632997409 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java @@ -8,10 +8,9 @@ import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; -import org.apache.commons.io.comparator.PathFileComparator; - import net.sourceforge.pmd.annotation.InternalApi; /** @@ -49,7 +48,12 @@ public class FileFinder { return; } - Arrays.sort(candidates, PathFileComparator.PATH_INSENSITIVE_COMPARATOR); + Arrays.sort(candidates, new Comparator() { + @Override + public int compare(File o1, File o2) { + return o1.getPath().compareToIgnoreCase(o2.getPath()); + } + }); for (File tmp : candidates) { if (tmp.isDirectory()) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileUtil.java index 7b2bd58d57..efb047050f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileUtil.java @@ -20,7 +20,6 @@ import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.annotation.InternalApi; @@ -181,7 +180,7 @@ public final class FileUtil { * @throws IOException if the file couldn't be read */ public static String readFilelist(File filelist) throws IOException { - String filePaths = FileUtils.readFileToString(filelist); + String filePaths = IOUtil.readFileToString(filelist); filePaths = StringUtils.trimToEmpty(filePaths); filePaths = filePaths.replaceAll("\\r?\\n", ","); filePaths = filePaths.replaceAll(",+", ","); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/ReaderDataSource.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/ReaderDataSource.java index ec21c09f4b..fe530ae40c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/ReaderDataSource.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/ReaderDataSource.java @@ -8,8 +8,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import org.apache.commons.io.input.ReaderInputStream; - +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.datasource.internal.AbstractDataSource; /** @@ -50,7 +49,7 @@ public class ReaderDataSource extends AbstractDataSource { */ @Override public InputStream getInputStream() throws IOException { - return new ReaderInputStream(reader); + return IOUtil.fromReader(reader); } /** diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryCompatibilityTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryCompatibilityTest.java index 7dfb6e1f09..b573c371f1 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryCompatibilityTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetFactoryCompatibilityTest.java @@ -9,10 +9,10 @@ import java.io.InputStream; import java.io.Reader; import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.ResourceLoader; public class RuleSetFactoryCompatibilityTest { @@ -48,7 +48,7 @@ public class RuleSetFactoryCompatibilityTest { InputStream stream = new ByteArrayInputStream(ruleset.getBytes(StandardCharsets.ISO_8859_1)); Reader filtered = rsfc.filterRuleSetFile(stream); - String out = IOUtils.toString(filtered); + String out = IOUtil.readToString(filtered); Assert.assertFalse(out.contains("notexisting.xml")); Assert.assertFalse(out.contains("OldDummyBasicMockRule")); @@ -90,7 +90,7 @@ public class RuleSetFactoryCompatibilityTest { InputStream stream = new ByteArrayInputStream(ruleset.getBytes(StandardCharsets.ISO_8859_1)); Reader filtered = rsfc.filterRuleSetFile(stream); - String out = IOUtils.toString(filtered); + String out = IOUtil.readToString(filtered); Assert.assertTrue(out.contains("OldDummyBasicMockRule")); } @@ -112,7 +112,7 @@ public class RuleSetFactoryCompatibilityTest { + " \n" + "\n"; InputStream stream = new ByteArrayInputStream(in.getBytes(StandardCharsets.ISO_8859_1)); Reader filtered = rsfc.filterRuleSetFile(stream); - String out = IOUtils.toString(filtered); + String out = IOUtil.readToString(filtered); Assert.assertFalse(out.contains("notexisting.xml")); Assert.assertTrue(out.contains("")); @@ -136,7 +136,7 @@ public class RuleSetFactoryCompatibilityTest { + " \n" + " \n" + "\n"; InputStream stream = new ByteArrayInputStream(in.getBytes(StandardCharsets.ISO_8859_1)); Reader filtered = rsfc.filterRuleSetFile(stream); - String out = IOUtils.toString(filtered); + String out = IOUtil.readToString(filtered); Assert.assertFalse(out.contains("OldNameOfBasicMockRule")); Assert.assertTrue(out.contains("")); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetReferenceIdTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetReferenceIdTest.java index 0914045572..fa48c86698 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetReferenceIdTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetReferenceIdTest.java @@ -22,9 +22,9 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Test; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.ResourceLoader; import com.github.tomakehurst.wiremock.junit.WireMockRule; @@ -123,7 +123,7 @@ public class RuleSetReferenceIdTest { assertRuleSetReferenceId(true, rulesetUrl, true, null, rulesetUrl, ruleSetReferenceId); try (InputStream inputStream = ruleSetReferenceId.getInputStream(new ResourceLoader())) { - String loaded = IOUtils.toString(inputStream, StandardCharsets.UTF_8); + String loaded = IOUtil.readToString(inputStream, StandardCharsets.UTF_8); assertEquals("xyz", loaded); } @@ -139,8 +139,8 @@ public class RuleSetReferenceIdTest { String path = "/profiles/export?format=pmd&language=java&name=Sonar%2520way"; String completePath = path + "/DummyBasicMockRule"; String hostpart = "http://localhost:" + wireMockRule.port(); - String basicRuleSet = IOUtils - .toString(RuleSetReferenceId.class.getResourceAsStream("/rulesets/dummy/basic.xml"), StandardCharsets.UTF_8); + String basicRuleSet = IOUtil + .readToString(RuleSetReferenceId.class.getResourceAsStream("/rulesets/dummy/basic.xml"), StandardCharsets.UTF_8); stubFor(head(urlEqualTo(completePath)).willReturn(aResponse().withStatus(404))); stubFor(head(urlEqualTo(path)).willReturn(aResponse().withStatus(200).withHeader("Content-type", "text/xml"))); @@ -152,7 +152,7 @@ public class RuleSetReferenceIdTest { ruleSetReferenceId); try (InputStream inputStream = ruleSetReferenceId.getInputStream(new ResourceLoader())) { - String loaded = IOUtils.toString(inputStream, StandardCharsets.UTF_8); + String loaded = IOUtil.readToString(inputStream, StandardCharsets.UTF_8); assertEquals(basicRuleSet, loaded); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java index 7c0f5c8813..14f4db1072 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java @@ -22,7 +22,6 @@ import java.util.Random; import java.util.Set; import java.util.regex.Pattern; -import org.apache.commons.io.FilenameUtils; import org.junit.Test; import net.sourceforge.pmd.Report.ProcessingError; @@ -35,6 +34,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.MockRule; import net.sourceforge.pmd.lang.rule.RuleReference; import net.sourceforge.pmd.util.CollectionUtil; +import net.sourceforge.pmd.util.IOUtil; public class RuleSetTest { @@ -582,7 +582,7 @@ public class RuleSetTest { assertTrue("Should be a RuntimeException", processingError.getError() instanceof RuntimeException); assertEquals("Wrong filename in processing error", "net.sourceforge.pmd.RuleSetTest/ruleExceptionShouldBeReported.java", - FilenameUtils.normalize(processingError.getFile(), true)); + IOUtil.normalizePath(processingError.getFile())); assertEquals("There should be a violation", 1, context.getReport().size()); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index 48acda9ba2..fba597a5f1 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -11,7 +11,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildFileRule; import org.junit.Assert; @@ -19,6 +18,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import net.sourceforge.pmd.util.IOUtil; + public class PMDTaskTest { @Rule @@ -74,7 +75,7 @@ public class PMDTaskTest { buildRule.executeTarget("testWithShortFilenames"); try (InputStream in = new FileInputStream("target/pmd-ant-test.txt")) { - String actual = IOUtils.toString(in, StandardCharsets.UTF_8); + String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); // remove any trailing newline actual = actual.replaceAll("\n|\r", ""); Assert.assertEquals("sample.dummy:0:\tSampleXPathRule:\tTest Rule 2", actual); @@ -87,11 +88,11 @@ public class PMDTaskTest { try (InputStream in = new FileInputStream("target/pmd-ant-xml.xml"); InputStream expectedStream = PMDTaskTest.class.getResourceAsStream("xml/expected-pmd-ant-xml.xml")) { - String actual = IOUtils.toString(in, StandardCharsets.UTF_8); + String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); actual = actual.replaceFirst("timestamp=\"[^\"]+\"", "timestamp=\"\""); actual = actual.replaceFirst("\\.xsd\" version=\"[^\"]+\"", ".xsd\" version=\"\""); - String expected = IOUtils.toString(expectedStream, StandardCharsets.UTF_8); + String expected = IOUtil.readToString(expectedStream, StandardCharsets.UTF_8); expected = expected.replaceFirst("timestamp=\"[^\"]+\"", "timestamp=\"\""); expected = expected.replaceFirst("\\.xsd\" version=\"[^\"]+\"", ".xsd\" version=\"\""); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 157caf975d..e8d19a0c36 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -20,7 +20,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.logging.Logger; -import org.apache.commons.io.IOUtils; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; @@ -33,6 +32,7 @@ import org.junit.rules.TemporaryFolder; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMD.StatusCode; import net.sourceforge.pmd.junit.JavaUtilLoggingRule; +import net.sourceforge.pmd.util.IOUtil; /** * @@ -131,7 +131,7 @@ public class CoreCliTest { runPmdSuccessfully("--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET, "--report-file", reportFile, "--debug"); assertTrue("Report file should have been created", Files.exists(reportFile)); - String reportText = IOUtils.toString(Files.newBufferedReader(reportFile, StandardCharsets.UTF_8)); + String reportText = IOUtil.readToString(Files.newBufferedReader(reportFile, StandardCharsets.UTF_8)); assertThat(reportText, not(containsStringIgnoringCase("error"))); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java index 5c21740f85..74604cc10a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java @@ -7,11 +7,11 @@ package net.sourceforge.pmd.cpd; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.nio.file.Paths; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.apache.commons.io.FilenameUtils; import org.junit.Test; public class CPDFilelistTest { @@ -28,7 +28,7 @@ public class CPDFilelistTest { assertEquals(2, paths.size()); Set simpleNames = new HashSet<>(); for (String path : paths) { - simpleNames.add(FilenameUtils.getName(path)); + simpleNames.add(Paths.get(path).getFileName().toString()); } assertTrue(simpleNames.contains("anotherfile.dummy")); assertTrue(simpleNames.contains("somefile.dummy")); @@ -46,7 +46,7 @@ public class CPDFilelistTest { assertEquals(2, paths.size()); Set simpleNames = new HashSet<>(); for (String path : paths) { - simpleNames.add(FilenameUtils.getName(path)); + simpleNames.add(Paths.get(path).getFileName().toString()); } assertTrue(simpleNames.contains("anotherfile.dummy")); assertTrue(simpleNames.contains("somefile.dummy")); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdXsltTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdXsltTest.java index 085475f8d0..af8d5ada20 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdXsltTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdXsltTest.java @@ -17,10 +17,11 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; +import net.sourceforge.pmd.util.IOUtil; + public class CpdXsltTest { /* Sample ant build.xml file. Run with "ant cpdxsl". @@ -49,7 +50,7 @@ public class CpdXsltTest { transformer.setErrorListener(errorListener); transformer.transform(cpdReport, result); - String expected = IOUtils.toString(CpdXsltTest.class.getResourceAsStream("ExpectedCpdHtmlReport.html"), StandardCharsets.UTF_8); + String expected = IOUtil.readToString(CpdXsltTest.class.getResourceAsStream("ExpectedCpdHtmlReport.html"), StandardCharsets.UTF_8); Assert.assertEquals(expected, result.getWriter().toString()); Assert.assertTrue("XSLT errors occured: " + errorListener, errorListener.hasNoErrors()); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/document/DocumentFileTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/document/DocumentFileTest.java index ece529938d..d578dec542 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/document/DocumentFileTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/document/DocumentFileTest.java @@ -16,12 +16,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import net.sourceforge.pmd.util.IOUtil; + public class DocumentFileTest { private static final String FILE_PATH = "psvm.java"; @@ -51,8 +52,8 @@ public class DocumentFileTest { @Test public void shouldPreserveNewlines() throws IOException { - final String testFileContent = IOUtils.toString( - DocumentFileTest.class.getResource("ShouldPreserveNewlines.java"), StandardCharsets.UTF_8); + final String testFileContent = IOUtil.readToString( + DocumentFileTest.class.getResourceAsStream("ShouldPreserveNewlines.java"), StandardCharsets.UTF_8); writeContentToTemporaryFile(testFileContent); try (DocumentFile documentFile = new DocumentFile(temporaryFile, StandardCharsets.UTF_8)) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/junit/JavaUtilLoggingRule.java b/pmd-core/src/test/java/net/sourceforge/pmd/junit/JavaUtilLoggingRule.java index 572ed0388f..da674a405a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/junit/JavaUtilLoggingRule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/junit/JavaUtilLoggingRule.java @@ -4,11 +4,12 @@ package net.sourceforge.pmd.junit; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.logging.Logger; import java.util.logging.StreamHandler; -import org.apache.commons.io.output.ByteArrayOutputStream; import org.junit.rules.ExternalResource; /** @@ -63,7 +64,11 @@ public class JavaUtilLoggingRule extends ExternalResource { */ public String getLog() { customLogHandler.flush(); - return stream.toString(StandardCharsets.UTF_8); + try { + return stream.toString(StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } } /** diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java index a439fa10db..901ef70534 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java @@ -12,7 +12,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.jaxen.Navigator; import net.sourceforge.pmd.Rule; @@ -29,6 +28,7 @@ import net.sourceforge.pmd.lang.rule.AbstractRuleChainVisitor; import net.sourceforge.pmd.lang.rule.AbstractRuleViolationFactory; import net.sourceforge.pmd.lang.rule.ParametricRuleViolation; import net.sourceforge.pmd.lang.rule.RuleChainVisitor; +import net.sourceforge.pmd.util.IOUtil; import net.sf.saxon.expr.XPathContext; import net.sf.saxon.sxpath.IndependentContext; @@ -130,7 +130,7 @@ public class DummyLanguageModule extends BaseLanguageModule { @Override public Node parse(String fileName, Reader source) throws ParseException { try { - String text = IOUtils.toString(source); + String text = IOUtil.readToString(source); DummyRootNode rootNode = readLispNode(text); AbstractParser.setFileName(fileName, rootNode); return rootNode; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java index faa66b88e4..52a5a2e293 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java @@ -10,7 +10,6 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; -import org.apache.commons.io.FileUtils; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -26,6 +25,7 @@ import net.sourceforge.pmd.RuleWithProperties; import net.sourceforge.pmd.lang.ast.DummyNode; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.ParametricRuleViolation; +import net.sourceforge.pmd.util.IOUtil; public abstract class AbstractRendererTest { @@ -204,6 +204,6 @@ public abstract class AbstractRendererTest { renderer.renderFileReport(report); renderer.end(); renderer.flush(); - return FileUtils.readFileToString(file, expectedEncoding); + return IOUtil.readFileToString(file, expectedEncoding); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/JsonRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/JsonRendererTest.java index 38f3a1ad9a..2ef04e695a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/JsonRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/JsonRendererTest.java @@ -11,7 +11,6 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -19,6 +18,7 @@ import net.sourceforge.pmd.FooRule; import net.sourceforge.pmd.Report; import net.sourceforge.pmd.Report.ConfigurationError; import net.sourceforge.pmd.Report.ProcessingError; +import net.sourceforge.pmd.util.IOUtil; public class JsonRendererTest extends AbstractRendererTest { @@ -69,7 +69,7 @@ public class JsonRendererTest extends AbstractRendererTest { private String readFile(String name) { try (InputStream in = JsonRendererTest.class.getResourceAsStream("json/" + name)) { - return IOUtils.toString(in, StandardCharsets.UTF_8); + return IOUtil.readToString(in, StandardCharsets.UTF_8); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SarifRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SarifRendererTest.java index ae6f605dd4..b13f03ca09 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SarifRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SarifRendererTest.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONObject; import org.junit.Test; @@ -18,7 +17,7 @@ import org.junit.contrib.java.lang.system.RestoreSystemProperties; import net.sourceforge.pmd.Report; import net.sourceforge.pmd.Rule; - +import net.sourceforge.pmd.util.IOUtil; public class SarifRendererTest extends AbstractRendererTest { @@ -112,7 +111,7 @@ public class SarifRendererTest extends AbstractRendererTest { private String readFile(String name) { try (InputStream in = SarifRendererTest.class.getResourceAsStream("sarif/" + name)) { - String asd = IOUtils.toString(in, StandardCharsets.UTF_8); + String asd = IOUtil.readToString(in, StandardCharsets.UTF_8); return asd; } catch (IOException e) { throw new RuntimeException(e); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java index e5ef41c5ed..9ead15cf85 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java @@ -12,7 +12,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import javax.xml.parsers.DocumentBuilderFactory; -import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -33,6 +32,7 @@ import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.lang.ast.DummyNode; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.ParametricRuleViolation; +import net.sourceforge.pmd.util.IOUtil; public class XMLRendererTest extends AbstractRendererTest { @Rule // Restores system properties after test @@ -177,7 +177,7 @@ public class XMLRendererTest extends AbstractRendererTest { renderer.flush(); try (FileInputStream input = new FileInputStream(reportFile)) { - return IOUtils.toString(input, expectedCharset); + return IOUtil.readToString(input, expectedCharset); } } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java index f52cc72a23..0b9ff1dd1f 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java @@ -14,7 +14,6 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.regex.Pattern; -import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -30,6 +29,7 @@ import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.lang.ast.DummyNode; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.ParametricRuleViolation; +import net.sourceforge.pmd.util.IOUtil; public class YAHTMLRendererTest extends AbstractRendererTest { @@ -79,8 +79,8 @@ public class YAHTMLRendererTest extends AbstractRendererTest { for (String file : htmlFiles) { try (FileInputStream in = new FileInputStream(new File(outputDir, file)); InputStream expectedIn = YAHTMLRendererTest.class.getResourceAsStream("yahtml/" + file)) { - String data = IOUtils.toString(in, StandardCharsets.UTF_8); - String expected = normalizeLineSeparators(IOUtils.toString(expectedIn, StandardCharsets.UTF_8)); + String data = IOUtil.readToString(in, StandardCharsets.UTF_8); + String expected = normalizeLineSeparators(IOUtil.readToString(expectedIn, StandardCharsets.UTF_8)); assertEquals("File " + file + " is different", expected, data); } @@ -88,8 +88,8 @@ public class YAHTMLRendererTest extends AbstractRendererTest { } private static String normalizeLineSeparators(String s) { - return s.replaceAll(Pattern.quote(IOUtils.LINE_SEPARATOR_WINDOWS), IOUtils.LINE_SEPARATOR_UNIX) - .replaceAll(Pattern.quote(IOUtils.LINE_SEPARATOR_UNIX), PMD.EOL); + return s.replaceAll(Pattern.quote("\r\n"), "\n") + .replaceAll(Pattern.quote("\n"), PMD.EOL); } @Override diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeExportCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeExportCliTest.java index edcf3e660b..ccd5403350 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeExportCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/TreeExportCliTest.java @@ -7,6 +7,7 @@ package net.sourceforge.pmd.util.treeexport; import static org.hamcrest.Matchers.containsString; import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -15,7 +16,6 @@ import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import org.apache.commons.io.IOUtils; import org.hamcrest.Matcher; import org.hamcrest.MatcherAssert; import org.junit.Assert; @@ -67,7 +67,7 @@ public class TreeExportCliTest { } private static InputStream stdinContaining(String input) { - return IOUtils.toInputStream(input, StandardCharsets.UTF_8); + return new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); } static class IoSpy { diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt index 560512b189..2538932a14 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt @@ -7,7 +7,7 @@ import net.sourceforge.pmd.* import net.sourceforge.pmd.lang.* import net.sourceforge.pmd.lang.ast.Node import net.sourceforge.pmd.lang.ast.RootNode -import org.apache.commons.io.IOUtils +import net.sourceforge.pmd.util.IOUtil import java.io.File import java.io.InputStream import java.io.StringReader @@ -160,7 +160,7 @@ abstract class BaseParsingHelper, T : RootNode } private fun consume(input: InputStream) = - IOUtils.toString(input, StandardCharsets.UTF_8) + IOUtil.readToString(input, StandardCharsets.UTF_8) .replace("\r\n", "\n") // normalize line-endings /** diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java index a1aa1327d5..3fca13161b 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java @@ -31,7 +31,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.apache.commons.io.FilenameUtils; import org.junit.BeforeClass; import org.junit.Test; import org.junit.contrib.java.lang.system.SystemErrRule; @@ -45,6 +44,7 @@ import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.rule.RuleReference; import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.ResourceLoader; /** @@ -155,7 +155,7 @@ public abstract class AbstractRuleSetFactoryTest { } else { String expectedExternalInfoURL = "https?://pmd.(sourceforge.net|github.io)/.+/pmd_rules_" + language.getTerseName() + "_" - + FilenameUtils.getBaseName(fileName) + + IOUtil.getFilenameBase(fileName) + ".html#" + rule.getName().toLowerCase(Locale.ROOT); if (rule.getExternalInfoUrl() == null From abfc463ef9003f2f3d85377b8b21882954550567 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 09:46:46 +0200 Subject: [PATCH 04/12] Update build-tools to 18-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 995f203476..459fe190c1 100644 --- a/pom.xml +++ b/pom.xml @@ -105,7 +105,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} - 17 + 18-SNAPSHOT 6.37.0 From a4ebb66769e780cc9b2bbe85fa9eb24b6418821f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 10:46:11 +0200 Subject: [PATCH 05/12] Replace IOUtils with IOUtil plsql, xml, apex, html, javascript, scala --- .../java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java | 5 ++--- .../java/net/sourceforge/pmd/lang/html/ast/HtmlParser.java | 4 ++-- .../pmd/lang/ecmascript/ast/EcmascriptParser.java | 4 ++-- .../java/net/sourceforge/pmd/lang/plsql/PLSQLParser.java | 4 +--- .../java/net/sourceforge/pmd/lang/scala/ScalaParser.java | 5 ++--- .../java/net/sourceforge/pmd/lang/xml/ast/XmlParser.java | 4 ++-- 6 files changed, 11 insertions(+), 15 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java index a6ff552503..fea54903e7 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java @@ -8,12 +8,11 @@ import java.io.IOException; import java.io.Reader; import java.util.Map; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.apex.ApexJorjeLogging; import net.sourceforge.pmd.lang.apex.ApexParserOptions; import net.sourceforge.pmd.lang.ast.ParseException; +import net.sourceforge.pmd.util.IOUtil; import apex.jorje.data.Locations; import apex.jorje.semantic.ast.compilation.Compilation; @@ -50,7 +49,7 @@ public class ApexParser { public ApexNode parse(final Reader reader) { try { - final String sourceCode = IOUtils.toString(reader); + final String sourceCode = IOUtil.readToString(reader); final Compilation astRoot = parseApex(sourceCode); final ApexTreeBuilder treeBuilder = new ApexTreeBuilder(sourceCode, parserOptions); suppressMap = treeBuilder.getSuppressMap(); diff --git a/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/HtmlParser.java b/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/HtmlParser.java index c61cb4f5a4..1c0b57f65c 100644 --- a/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/HtmlParser.java +++ b/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/HtmlParser.java @@ -10,7 +10,6 @@ import java.io.Reader; import java.util.HashMap; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.jsoup.nodes.Document; import org.jsoup.parser.Parser; @@ -18,6 +17,7 @@ import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.ParseException; +import net.sourceforge.pmd.util.IOUtil; public final class HtmlParser implements net.sourceforge.pmd.lang.Parser { @@ -29,7 +29,7 @@ public final class HtmlParser implements net.sourceforge.pmd.lang.Parser { @Override public Node parse(String fileName, Reader source) throws ParseException { try { - String data = IOUtils.toString(source); + String data = IOUtil.readToString(source); Document doc = Parser.xmlParser().parseInput(data, ""); HtmlTreeBuilder builder = new HtmlTreeBuilder(); return builder.build(doc, data); diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java index 359d96b0b4..156728171c 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.java @@ -11,7 +11,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.mozilla.javascript.CompilerEnvirons; import org.mozilla.javascript.Parser; import org.mozilla.javascript.ast.AstRoot; @@ -22,6 +21,7 @@ import org.mozilla.javascript.ast.ParseProblem; import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ecmascript.EcmascriptParserOptions; +import net.sourceforge.pmd.util.IOUtil; public class EcmascriptParser { @Deprecated @@ -64,7 +64,7 @@ public class EcmascriptParser { public EcmascriptNode parse(final Reader reader) { try { final List parseProblems = new ArrayList<>(); - final String sourceCode = IOUtils.toString(reader); + final String sourceCode = IOUtil.readToString(reader); final AstRoot astRoot = parseEcmascript(sourceCode, parseProblems); final EcmascriptTreeBuilder treeBuilder = new EcmascriptTreeBuilder(sourceCode, parseProblems); EcmascriptNode tree = treeBuilder.build(astRoot); diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLParser.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLParser.java index 4466d61480..442a6c8be0 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLParser.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLParser.java @@ -10,8 +10,6 @@ import java.io.StringReader; import java.util.HashMap; import java.util.Map; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.AbstractParser; import net.sourceforge.pmd.lang.LanguageVersionHandler; @@ -56,7 +54,7 @@ public class PLSQLParser extends AbstractParser { @Override public Node parse(String fileName, Reader source) throws ParseException { try { - String sourcecode = IOUtils.toString(source); + String sourcecode = IOUtil.readToString(source); AbstractTokenManager.setFileName(fileName); return createPLSQLParser(new StringReader(sourcecode)).Input(sourcecode); } catch (IOException e) { diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ScalaParser.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ScalaParser.java index 8edb8d5ab9..ded0c0c04a 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ScalaParser.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ScalaParser.java @@ -9,13 +9,12 @@ import java.io.Reader; import java.util.HashMap; import java.util.Map; -import org.apache.commons.io.IOUtils; - import net.sourceforge.pmd.lang.AbstractParser; import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.scala.ast.ASTSource; +import net.sourceforge.pmd.util.IOUtil; import scala.meta.Dialect; import scala.meta.Source; @@ -52,7 +51,7 @@ public class ScalaParser extends AbstractParser { public ASTSource parse(String fileName, Reader source) throws ParseException { Input.VirtualFile virtualFile; try { - String sourceString = IOUtils.toString(source); + String sourceString = IOUtil.readToString(source); virtualFile = new Input.VirtualFile(fileName, sourceString); } catch (IOException e) { throw new ParseException(e); diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlParser.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlParser.java index 2bf8d097f9..9ac2376389 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlParser.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlParser.java @@ -13,7 +13,6 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import org.apache.commons.io.IOUtils; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; @@ -22,6 +21,7 @@ import org.xml.sax.SAXException; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.xml.XmlParserOptions; +import net.sourceforge.pmd.util.IOUtil; public class XmlParser { @@ -37,7 +37,7 @@ public class XmlParser { protected Document parseDocument(Reader reader) throws ParseException { nodeCache.clear(); try { - String xmlData = IOUtils.toString(reader); + String xmlData = IOUtil.readToString(reader); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(parserOptions.isNamespaceAware()); From a1922c59565283c701dbb8aa8746badc11ca095f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 11:18:55 +0200 Subject: [PATCH 06/12] [dist] Replace IOUtils with IOUtil --- .../java/net/sourceforge/pmd/it/AntIT.java | 36 +++++++++++++++---- .../net/sourceforge/pmd/it/PMDExecutor.java | 12 ++++--- .../sourceforge/pmd/it/ZipFileExtractor.java | 5 +-- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/AntIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/AntIT.java index 6d11b7d9d7..2c840d2487 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/AntIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/AntIT.java @@ -8,15 +8,19 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.TimeUnit; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.SystemUtils; import org.junit.Assume; import org.junit.Test; import net.sourceforge.pmd.PMDVersion; +import net.sourceforge.pmd.util.IOUtil; /** * This test calls ant in a fake terminal to make sure we have a {@link java.io.Console} connected. @@ -41,10 +45,28 @@ public class AntIT extends AbstractBinaryDistributionTest { private File prepareAntTestProjectFolder() throws IOException { - File sourceProjectFolder = new File("src/test/resources/ant-it"); - File projectFolder = folder.newFolder(); - FileUtils.copyDirectory(sourceProjectFolder, projectFolder); - return projectFolder; + final Path sourceProjectFolder = new File("src/test/resources/ant-it").toPath(); + final Path projectFolder = folder.newFolder().toPath(); + Files.walkFileTree(sourceProjectFolder, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + assert !dir.isAbsolute(); + Path target = projectFolder.resolve(sourceProjectFolder.relativize(dir)); + if (!target.toFile().exists()) { + target.toFile().mkdir(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + assert !file.isAbsolute(); + Path target = projectFolder.resolve(sourceProjectFolder.relativize(file)); + Files.copy(file, target); + return FileVisitResult.CONTINUE; + } + }); + return projectFolder.toFile(); } @@ -64,7 +86,7 @@ public class AntIT extends AbstractBinaryDistributionTest { @Override public void run() { try (InputStream in = process.getInputStream()) { - String output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8); + String output = IOUtil.readToString(process.getInputStream(), StandardCharsets.UTF_8); result.withOutput(output); } catch (IOException e) { result.withOutput("Exception occurred: " + e.toString()); diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java index fdfaf79acb..69bd4bb3ce 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java @@ -5,18 +5,20 @@ package net.sourceforge.pmd.it; import java.io.IOException; +import java.io.Reader; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; import net.sourceforge.pmd.PMDVersion; +import net.sourceforge.pmd.util.IOUtil; /** * Executes PMD from command line. Deals with the differences, when PMD is run on Windows or on Linux. @@ -59,7 +61,7 @@ public class PMDExecutor { public void run() { String output; try { - output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8); + output = IOUtil.readToString(process.getInputStream(), StandardCharsets.UTF_8); result.withOutput(output); } catch (IOException e) { result.withOutput("Exception occurred: " + e.toString()); @@ -72,7 +74,7 @@ public class PMDExecutor { public void run() { String error; try { - error = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8); + error = IOUtil.readToString(process.getErrorStream(), StandardCharsets.UTF_8); result.withErrorOutput(error); } catch (IOException e) { result.withErrorOutput("Exception occurred: " + e.toString()); @@ -87,7 +89,9 @@ public class PMDExecutor { String report = null; if (reportFile != null) { - report = IOUtils.toString(reportFile.toUri(), StandardCharsets.UTF_8); + try (Reader reader = Files.newBufferedReader(reportFile, StandardCharsets.UTF_8)) { + report = IOUtil.readToString(reader); + } } return result.withExitCode(exitCode).withReport(report).build(); } diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/ZipFileExtractor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/ZipFileExtractor.java index 27a8b325d6..dbfe2d13a5 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/ZipFileExtractor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/ZipFileExtractor.java @@ -17,7 +17,8 @@ import java.util.List; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; -import org.apache.commons.io.IOUtils; + +import net.sourceforge.pmd.util.IOUtil; /** * Extracts a zip file with preserving the unix file permissions. @@ -49,7 +50,7 @@ public class ZipFileExtractor { } else { try (InputStream data = zip.getInputStream(entry); OutputStream fileOut = new FileOutputStream(file);) { - IOUtils.copy(data, fileOut); + IOUtil.copy(data, fileOut); } if ((entry.getUnixMode() & OWNER_EXECUTABLE) == OWNER_EXECUTABLE) { file.setExecutable(true); From bef7eed0ec1778427e54c03f0d2ec27ba90b3ad4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 11:39:22 +0200 Subject: [PATCH 07/12] [doc] Replace IOUtils with IOUtil --- .../pmd/docs/DeadLinksChecker.java | 5 ++- .../pmd/docs/GenerateRuleDocsCmd.java | 6 ++-- .../pmd/docs/RuleDocGenerator.java | 31 ++++++++++--------- .../sourceforge/pmd/docs/RuleSetUtils.java | 10 +++--- .../pmd/docs/MockedFileWriter.java | 5 ++- .../pmd/docs/RuleDocGeneratorTest.java | 12 +++---- .../pmd/docs/RuleSetResolverTest.java | 4 +-- .../pmd/docs/SidebarGeneratorTest.java | 4 +-- 8 files changed, 40 insertions(+), 37 deletions(-) diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java index 750e7c934c..9f651c3610 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java @@ -37,8 +37,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.commons.io.IOUtils; - +import net.sourceforge.pmd.util.IOUtil; /** * Checks links to local pages for non-existing link-targets. @@ -298,7 +297,7 @@ public class DeadLinksChecker { private String fileToString(Path mdFile) { try (InputStream inputStream = Files.newInputStream(mdFile)) { - return IOUtils.toString(inputStream, StandardCharsets.UTF_8); + return IOUtil.readToString(inputStream, StandardCharsets.UTF_8); } catch (IOException ex) { throw new RuntimeException("error reading " + mdFile, ex); } diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java index caf1cb67a5..d5b3002a6b 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java @@ -10,16 +10,16 @@ import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import org.apache.commons.io.FilenameUtils; - import net.sourceforge.pmd.RuleSet; import net.sourceforge.pmd.RuleSetLoader; +import net.sourceforge.pmd.util.IOUtil; public final class GenerateRuleDocsCmd { private GenerateRuleDocsCmd() { @@ -51,7 +51,7 @@ public final class GenerateRuleDocsCmd { try { List additionalRulesets = new ArrayList<>(); Pattern rulesetPattern = Pattern.compile("^.+" + Pattern.quote(File.separator) + "pmd-\\w+" - + Pattern.quote(FilenameUtils.normalize("/src/main/resources/rulesets/")) + + Pattern.quote(IOUtil.normalizePath(File.separator + Paths.get("src", "main", "resources", "rulesets").toString() + File.separator)) + "\\w+" + Pattern.quote(File.separator) + "\\w+.xml$"); Files.walkFileTree(basePath, new SimpleFileVisitor() { @Override diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java index 891580ad84..a1e23965cd 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java @@ -30,8 +30,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.SystemUtils; import org.apache.commons.text.StringEscapeUtils; import net.sourceforge.pmd.Rule; @@ -43,6 +43,7 @@ import net.sourceforge.pmd.lang.rule.RuleReference; import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.properties.MultiValuePropertyDescriptor; import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.util.IOUtil; public class RuleDocGenerator { private static final Logger LOG = Logger.getLogger(RuleDocGenerator.class.getName()); @@ -131,7 +132,7 @@ public class RuleDocGenerator { } private Path getAbsoluteOutputPath(String filename) { - return root.resolve(FilenameUtils.normalize(filename)); + return root.resolve(IOUtil.normalizePath(filename)); } private Map> sortRulesets(List rulesets) { @@ -608,17 +609,13 @@ public class RuleDocGenerator { // is replaced by a correct path. for (List rulesets : sortedRulesets.values()) { for (RuleSet ruleset : rulesets) { - // Note: the path is normalized to unix path separators, so that the editme link - // uses forward slashes - String rulesetFilename = FilenameUtils.normalize(StringUtils.chomp(ruleset.getFileName()), true); + String rulesetFilename = normalizeForwardSlashes(StringUtils.chomp(ruleset.getFileName())); allRulesets.put(ruleset.getFileName(), rulesetFilename); for (Rule rule : ruleset.getRules()) { String ruleClass = rule.getRuleClass(); String relativeSourceFilename = ruleClass.replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + ".java"; - // Note: the path is normalized to unix path separators, so that the editme link - // uses forward slashes - allRules.put(ruleClass, FilenameUtils.normalize(relativeSourceFilename, true)); + allRules.put(ruleClass, normalizeForwardSlashes(relativeSourceFilename)); } } } @@ -640,9 +637,7 @@ public class RuleDocGenerator { } if (foundRuleClass != null) { Path foundPath = root.relativize(file); - // Note: the path is normalized to unix path separators, so that the editme link - // uses forward slashes - allRules.put(foundRuleClass, FilenameUtils.normalize(foundPath.toString(), true)); + allRules.put(foundRuleClass, normalizeForwardSlashes(foundPath.toString())); } String foundRuleset = null; @@ -654,9 +649,7 @@ public class RuleDocGenerator { } if (foundRuleset != null) { Path foundPath = root.relativize(file); - // Note: the path is normalized to unix path separators, so that the editme link - // uses forward slashes - allRulesets.put(foundRuleset, FilenameUtils.normalize(foundPath.toString(), true)); + allRulesets.put(foundRuleset, normalizeForwardSlashes(foundPath.toString())); } } return FileVisitResult.CONTINUE; @@ -666,4 +659,14 @@ public class RuleDocGenerator { throw new RuntimeException(e); } } + + private static String normalizeForwardSlashes(String path) { + String normalized = IOUtil.normalizePath(path); + if (SystemUtils.IS_OS_WINDOWS) { + // Note: windows path separators are changed to forward slashes, + // so that the editme link works + normalized = normalized.replaceAll(Pattern.quote(File.separator), "/"); + } + return normalized; + } } diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java index f928fe1de6..a7afef7b5b 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java @@ -4,12 +4,14 @@ package net.sourceforge.pmd.docs; -import org.apache.commons.io.FilenameUtils; +import java.io.File; + import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleSet; import net.sourceforge.pmd.lang.rule.RuleReference; +import net.sourceforge.pmd.util.IOUtil; public final class RuleSetUtils { @@ -28,7 +30,7 @@ public final class RuleSetUtils { } public static String getRuleSetFilename(String rulesetFileName) { - return FilenameUtils.getBaseName(StringUtils.chomp(rulesetFileName)); + return IOUtil.getFilenameBase(StringUtils.chomp(rulesetFileName)); } /** @@ -50,8 +52,8 @@ public final class RuleSetUtils { } public static String getRuleSetClasspath(RuleSet ruleset) { - final String RESOURCES_PATH = "/resources/"; - String filename = FilenameUtils.normalize(StringUtils.chomp(ruleset.getFileName()), true); + final String RESOURCES_PATH = File.separator + "resources" + File.separator; + String filename = IOUtil.normalizePath(StringUtils.chomp(ruleset.getFileName())); int startIndex = filename.lastIndexOf(RESOURCES_PATH); if (startIndex > -1) { return filename.substring(startIndex + RESOURCES_PATH.length()); diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/MockedFileWriter.java b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/MockedFileWriter.java index dc5ee7e626..3f90cbe4cb 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/MockedFileWriter.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/MockedFileWriter.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.PMD; @@ -49,7 +48,7 @@ public class MockedFileWriter implements FileWriter { } public static String normalizeLineSeparators(String s) { - return s.replaceAll(Pattern.quote(IOUtils.LINE_SEPARATOR_WINDOWS), IOUtils.LINE_SEPARATOR_UNIX) - .replaceAll(Pattern.quote(IOUtils.LINE_SEPARATOR_UNIX), PMD.EOL); + return s.replaceAll(Pattern.quote("\r\n"), "\n") + .replaceAll(Pattern.quote("\n"), PMD.EOL); } } diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleDocGeneratorTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleDocGeneratorTest.java index dc96ec33a5..f994834900 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleDocGeneratorTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleDocGeneratorTest.java @@ -11,11 +11,10 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -24,6 +23,7 @@ import org.junit.rules.TemporaryFolder; import net.sourceforge.pmd.RuleSet; import net.sourceforge.pmd.RuleSetLoader; import net.sourceforge.pmd.docs.MockedFileWriter.FileEntry; +import net.sourceforge.pmd.util.IOUtil; public class RuleDocGeneratorTest { @@ -52,7 +52,7 @@ public class RuleDocGeneratorTest { private static String loadResource(String name) throws IOException { return MockedFileWriter.normalizeLineSeparators( - IOUtils.toString(RuleDocGeneratorTest.class.getResourceAsStream(name), StandardCharsets.UTF_8)); + IOUtil.readToString(RuleDocGeneratorTest.class.getResourceAsStream(name), StandardCharsets.UTF_8)); } @Test @@ -69,15 +69,15 @@ public class RuleDocGeneratorTest { assertEquals(3, writer.getData().size()); FileEntry languageIndex = writer.getData().get(0); - assertTrue(FilenameUtils.normalize(languageIndex.getFilename(), true).endsWith("docs/pages/pmd/rules/java.md")); + assertTrue(IOUtil.normalizePath(languageIndex.getFilename()).endsWith(Paths.get("docs", "pages", "pmd", "rules", "java.md").toString())); assertEquals(loadResource("/expected/java.md"), languageIndex.getContent()); FileEntry ruleSetIndex = writer.getData().get(1); - assertTrue(FilenameUtils.normalize(ruleSetIndex.getFilename(), true).endsWith("docs/pages/pmd/rules/java/sample.md")); + assertTrue(IOUtil.normalizePath(ruleSetIndex.getFilename()).endsWith(Paths.get("docs", "pages", "pmd", "rules", "java", "sample.md").toString())); assertEquals(loadResource("/expected/sample.md"), ruleSetIndex.getContent()); FileEntry sidebar = writer.getData().get(2); - assertTrue(FilenameUtils.normalize(sidebar.getFilename(), true).endsWith("docs/_data/sidebars/pmd_sidebar.yml")); + assertTrue(IOUtil.normalizePath(sidebar.getFilename()).endsWith(Paths.get("docs", "_data", "sidebars", "pmd_sidebar.yml").toString())); assertEquals(loadResource("/expected/pmd_sidebar.yml"), sidebar.getContent()); } } diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java index c2c082c44f..3d85da8daa 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java @@ -12,19 +12,19 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.apache.commons.io.FilenameUtils; import org.junit.Test; import net.sourceforge.pmd.RuleSetFactory; import net.sourceforge.pmd.RuleSetNotFoundException; import net.sourceforge.pmd.RulesetsFactoryUtils; +import net.sourceforge.pmd.util.IOUtil; public class RuleSetResolverTest { private static List excludedRulesets = new ArrayList<>(); static { - excludedRulesets.add(FilenameUtils.normalize("pmd-test/src/main/resources/rulesets/dummy/basic.xml")); + excludedRulesets.add(IOUtil.normalizePath("pmd-test/src/main/resources/rulesets/dummy/basic.xml")); } @Test diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/SidebarGeneratorTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/SidebarGeneratorTest.java index ea01604b3c..190a607bb1 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/SidebarGeneratorTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/SidebarGeneratorTest.java @@ -15,7 +15,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.SystemUtils; import org.junit.Before; import org.junit.Test; @@ -28,6 +27,7 @@ import net.sourceforge.pmd.RuleSet; import net.sourceforge.pmd.RulesetsFactoryUtils; import net.sourceforge.pmd.lang.Language; import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.util.IOUtil; public class SidebarGeneratorTest { private MockedFileWriter writer = new MockedFileWriter(); @@ -56,7 +56,7 @@ public class SidebarGeneratorTest { String yaml = new Yaml(options).dump(result); String expected = MockedFileWriter.normalizeLineSeparators( - IOUtils.toString(SidebarGeneratorTest.class.getResourceAsStream("sidebar.yml"), StandardCharsets.UTF_8)); + IOUtil.readToString(SidebarGeneratorTest.class.getResourceAsStream("sidebar.yml"), StandardCharsets.UTF_8)); assertEquals(expected, yaml); } } From cfacfbbff2e56041275fcf9b742e09bfc4b7b411 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 15:18:03 +0200 Subject: [PATCH 08/12] Fix tests under Windows --- .../java/net/sourceforge/pmd/RuleSetTest.java | 3 +- .../net/sourceforge/pmd/util/IOUtilTest.java | 66 +++++++++++++------ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java index 14f4db1072..3ff5ba5fb7 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -581,7 +582,7 @@ public class RuleSetTest { assertEquals("Wrong error message", "RuntimeException: Test exception while applying rule", processingError.getMsg()); assertTrue("Should be a RuntimeException", processingError.getError() instanceof RuntimeException); assertEquals("Wrong filename in processing error", - "net.sourceforge.pmd.RuleSetTest/ruleExceptionShouldBeReported.java", + Paths.get("net.sourceforge.pmd.RuleSetTest", "ruleExceptionShouldBeReported.java").toString(), IOUtil.normalizePath(processingError.getFile())); assertEquals("There should be a violation", 1, context.getReport().size()); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java index 35e772cfc9..7b21230fb6 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java @@ -80,30 +80,56 @@ public class IOUtilTest { @Test public void testNormalizePath() { - Assert.assertEquals("ab/cd.txt", IOUtil.normalizePath("ab/ef/../cd.txt")); - Assert.assertEquals("/a.txt", IOUtil.normalizePath("/x/../../a.txt")); - Assert.assertEquals("/foo", IOUtil.normalizePath("//../foo")); - Assert.assertEquals("/foo", IOUtil.normalizePath("/foo//")); - Assert.assertEquals("/foo", IOUtil.normalizePath("/foo/./")); - Assert.assertEquals("/bar", IOUtil.normalizePath("/foo/../bar")); - Assert.assertEquals("/bar", IOUtil.normalizePath("/foo/../bar/")); - Assert.assertEquals("/baz", IOUtil.normalizePath("/foo/../bar/../baz")); - Assert.assertEquals("/foo/bar", IOUtil.normalizePath("//foo//./bar")); - Assert.assertEquals("foo", IOUtil.normalizePath("foo/bar/..")); - Assert.assertEquals("bar", IOUtil.normalizePath("foo/../bar")); - Assert.assertEquals("/foo/baz", IOUtil.normalizePath("//foo/bar/../baz")); - Assert.assertEquals("~/bar", IOUtil.normalizePath("~/foo/../bar/")); - Assert.assertEquals("/", IOUtil.normalizePath("/../")); - Assert.assertEquals("bar", IOUtil.normalizePath("~/../bar")); - Assert.assertEquals("bar", IOUtil.normalizePath("./bar")); + if (SystemUtils.IS_OS_UNIX) { + Assert.assertEquals("ab/cd.txt", IOUtil.normalizePath("ab/ef/../cd.txt")); + Assert.assertEquals("/a.txt", IOUtil.normalizePath("/x/../../a.txt")); + Assert.assertEquals("/foo", IOUtil.normalizePath("//../foo")); + Assert.assertEquals("/foo", IOUtil.normalizePath("/foo//")); + Assert.assertEquals("/foo", IOUtil.normalizePath("/foo/./")); + Assert.assertEquals("/bar", IOUtil.normalizePath("/foo/../bar")); + Assert.assertEquals("/bar", IOUtil.normalizePath("/foo/../bar/")); + Assert.assertEquals("/baz", IOUtil.normalizePath("/foo/../bar/../baz")); + Assert.assertEquals("/foo/bar", IOUtil.normalizePath("//foo//./bar")); + Assert.assertEquals("foo", IOUtil.normalizePath("foo/bar/..")); + Assert.assertEquals("bar", IOUtil.normalizePath("foo/../bar")); + Assert.assertEquals("/foo/baz", IOUtil.normalizePath("//foo/bar/../baz")); + Assert.assertEquals("~/bar", IOUtil.normalizePath("~/foo/../bar/")); + Assert.assertEquals("/", IOUtil.normalizePath("/../")); + Assert.assertEquals("bar", IOUtil.normalizePath("~/../bar")); + Assert.assertEquals("bar", IOUtil.normalizePath("./bar")); - Assert.assertNull(IOUtil.normalizePath("../foo")); - Assert.assertNull(IOUtil.normalizePath("foo/../../bar")); - Assert.assertNull(IOUtil.normalizePath(".")); + Assert.assertNull(IOUtil.normalizePath("../foo")); + Assert.assertNull(IOUtil.normalizePath("foo/../../bar")); + Assert.assertNull(IOUtil.normalizePath(".")); - Assert.assertTrue(IOUtil.equalsNormalizedPaths("foo/../bar", "bar/./")); + Assert.assertTrue(IOUtil.equalsNormalizedPaths("foo/../bar", "bar/./")); + } if (SystemUtils.IS_OS_WINDOWS) { + Assert.assertEquals("ab\\cd.txt", IOUtil.normalizePath("ab\\ef\\..\\cd.txt")); + Assert.assertEquals("\\a.txt", IOUtil.normalizePath("\\x\\..\\..\\a.txt")); + Assert.assertEquals("\\foo", IOUtil.normalizePath("\\foo\\\\")); + Assert.assertEquals("\\foo", IOUtil.normalizePath("\\foo\\.\\")); + Assert.assertEquals("\\bar", IOUtil.normalizePath("\\foo\\..\\bar")); + Assert.assertEquals("\\bar", IOUtil.normalizePath("\\foo\\..\\bar\\")); + Assert.assertEquals("\\baz", IOUtil.normalizePath("\\foo\\..\\bar\\..\\baz")); + Assert.assertEquals("\\\\foo\\bar\\", IOUtil.normalizePath("\\\\foo\\bar")); + Assert.assertEquals("\\\\foo\\bar\\baz", IOUtil.normalizePath("\\\\foo\\bar\\..\\baz")); + Assert.assertEquals("foo", IOUtil.normalizePath("foo\\bar\\..")); + Assert.assertEquals("bar", IOUtil.normalizePath("foo\\..\\bar")); + Assert.assertEquals("\\foo\\baz", IOUtil.normalizePath("\\foo\\bar\\..\\baz")); + Assert.assertEquals("\\", IOUtil.normalizePath("\\..\\")); + Assert.assertEquals("bar", IOUtil.normalizePath(".\\bar")); + + Assert.assertNull(IOUtil.normalizePath("\\\\..\\foo")); + Assert.assertNull(IOUtil.normalizePath("..\\foo")); + Assert.assertNull(IOUtil.normalizePath("foo\\..\\..\\bar")); + Assert.assertNull(IOUtil.normalizePath(".")); + Assert.assertNull(IOUtil.normalizePath("\\\\foo\\\\.\\bar")); + Assert.assertNull(IOUtil.normalizePath("\\\\foo\\.\\bar")); + + Assert.assertTrue(IOUtil.equalsNormalizedPaths("foo\\..\\bar", "bar\\.\\")); + Assert.assertEquals("C:\\bar", IOUtil.normalizePath("C:\\..\\bar")); Assert.assertEquals("ab\\cd.txt", IOUtil.normalizePath("ab\\ef\\..\\cd.txt")); Assert.assertEquals("C:\\ab\\cd.txt", IOUtil.normalizePath("C:\\ab\\ef\\..\\.\\cd.txt")); From 1c9096809dd2cda3922c7cd0c98d0bed92c09202 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 15:25:24 +0200 Subject: [PATCH 09/12] [doc] Update release notes (#3942) --- docs/pages/release_notes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c31a705241..7ac4b956c8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,7 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### New and noteworthy ### Fixed Issues - +* core + * [#3942](https://github.com/pmd/pmd/issues/3942): \[core] common-io path traversal vulnerability (CVE-2021-29425) * javascript * [#3948](https://github.com/pmd/pmd/issues/3948): \[js] Invalid operator error for method property in object literal From 8addd05369b60e5169a7db304fc92fff6c08c018 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 16:43:17 +0200 Subject: [PATCH 10/12] Fix tests under Windows --- .../pmd/docs/RuleDocGenerator.java | 19 ++++--------------- .../sourceforge/pmd/docs/RuleSetUtils.java | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java index a1e23965cd..0cc2923649 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleDocGenerator.java @@ -31,7 +31,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.SystemUtils; import org.apache.commons.text.StringEscapeUtils; import net.sourceforge.pmd.Rule; @@ -609,13 +608,13 @@ public class RuleDocGenerator { // is replaced by a correct path. for (List rulesets : sortedRulesets.values()) { for (RuleSet ruleset : rulesets) { - String rulesetFilename = normalizeForwardSlashes(StringUtils.chomp(ruleset.getFileName())); + String rulesetFilename = RuleSetUtils.normalizeForwardSlashes(StringUtils.chomp(ruleset.getFileName())); allRulesets.put(ruleset.getFileName(), rulesetFilename); for (Rule rule : ruleset.getRules()) { String ruleClass = rule.getRuleClass(); String relativeSourceFilename = ruleClass.replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + ".java"; - allRules.put(ruleClass, normalizeForwardSlashes(relativeSourceFilename)); + allRules.put(ruleClass, RuleSetUtils.normalizeForwardSlashes(relativeSourceFilename)); } } } @@ -637,7 +636,7 @@ public class RuleDocGenerator { } if (foundRuleClass != null) { Path foundPath = root.relativize(file); - allRules.put(foundRuleClass, normalizeForwardSlashes(foundPath.toString())); + allRules.put(foundRuleClass, RuleSetUtils.normalizeForwardSlashes(foundPath.toString())); } String foundRuleset = null; @@ -649,7 +648,7 @@ public class RuleDocGenerator { } if (foundRuleset != null) { Path foundPath = root.relativize(file); - allRulesets.put(foundRuleset, normalizeForwardSlashes(foundPath.toString())); + allRulesets.put(foundRuleset, RuleSetUtils.normalizeForwardSlashes(foundPath.toString())); } } return FileVisitResult.CONTINUE; @@ -659,14 +658,4 @@ public class RuleDocGenerator { throw new RuntimeException(e); } } - - private static String normalizeForwardSlashes(String path) { - String normalized = IOUtil.normalizePath(path); - if (SystemUtils.IS_OS_WINDOWS) { - // Note: windows path separators are changed to forward slashes, - // so that the editme link works - normalized = normalized.replaceAll(Pattern.quote(File.separator), "/"); - } - return normalized; - } } diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java index a7afef7b5b..0ab05a68bc 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/RuleSetUtils.java @@ -5,8 +5,10 @@ package net.sourceforge.pmd.docs; import java.io.File; +import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.SystemUtils; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleSet; @@ -52,8 +54,8 @@ public final class RuleSetUtils { } public static String getRuleSetClasspath(RuleSet ruleset) { - final String RESOURCES_PATH = File.separator + "resources" + File.separator; - String filename = IOUtil.normalizePath(StringUtils.chomp(ruleset.getFileName())); + final String RESOURCES_PATH = "/resources/"; + String filename = normalizeForwardSlashes(StringUtils.chomp(ruleset.getFileName())); int startIndex = filename.lastIndexOf(RESOURCES_PATH); if (startIndex > -1) { return filename.substring(startIndex + RESOURCES_PATH.length()); @@ -62,6 +64,16 @@ public final class RuleSetUtils { } } + public static String normalizeForwardSlashes(String path) { + String normalized = IOUtil.normalizePath(path); + if (SystemUtils.IS_OS_WINDOWS) { + // Note: windows path separators are changed to forward slashes, + // so that the editme link works + normalized = normalized.replaceAll(Pattern.quote(File.separator), "/"); + } + return normalized; + } + /** * Recursively resolves rule references until the last reference. * The last reference is returned. From a9219b7967ed1fbbc3029625c40823fd49e84a5f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 May 2022 17:13:16 +0200 Subject: [PATCH 11/12] [core] Fix bug in IOUtil.fromReader --- .../java/net/sourceforge/pmd/util/IOUtil.java | 2 +- .../java/net/sourceforge/pmd/util/IOUtilTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java index 791561bc7a..881bc7efa2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java @@ -325,7 +325,7 @@ public final class IOUtil { charBuffer.flip(); encoder.encode(charBuffer, byteBuffer, eof); byteBuffer.flip(); - charBuffer.flip(); + charBuffer.compact(); } if (byteBuffer.hasRemaining()) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java index 7b21230fb6..b577de8f11 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/IOUtilTest.java @@ -193,6 +193,21 @@ public class IOUtilTest { } } + @Test + public void testInputStreamFromReader2() throws IOException { + int size = 8192 + 8192 + 10; + char[] data = new char[size]; + for (int i = 0; i < size; i++) { + data[i] = 'A'; + } + data[8192] = 'ä'; // block size border - in UTF-8 these are two bytes. Decoding needs to take the bytes + // from previous block and new block + try (InputStream inputStream = IOUtil.fromReader(new StringReader(new String(data)))) { + byte[] bytes = IOUtil.toByteArray(inputStream); + Assert.assertEquals(new String(data), new String(bytes, StandardCharsets.UTF_8)); + } + } + @Test public void testCopyStream() throws IOException { int size = 8192 + 8192 + 10; From c53a64c688d0d6d9811df886ea0bb24ece64f6e0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 08:51:52 +0200 Subject: [PATCH 12/12] Update pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Fournier --- .../src/main/java/net/sourceforge/pmd/util/IOUtil.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java index 881bc7efa2..ebe98f9dbe 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/IOUtil.java @@ -180,6 +180,13 @@ public final class IOUtil { } } + + // The following methods are taken from Apache Commons IO. + // The dependency was removed from PMD 6 because it had a security issue, + // and upgrading was not possible without upgrading to Java 8. + // See https://github.com/pmd/pmd/pull/3968 + // TODO PMD 7: consider bringing back commons-io and cleaning this class up. + public static void closeQuietly(Closeable closeable) { try { closeable.close();