From e28d7dec9754df3b5789827887d40d694d4c5091 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Tue, 30 Sep 2025 16:06:28 -0700 Subject: [PATCH] Test: Use copied implementation of FileUtil.makeLegalName() --- src/org/labkey/test/TestFileUtils.java | 69 ++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/src/org/labkey/test/TestFileUtils.java b/src/org/labkey/test/TestFileUtils.java index c983d5237b..f87b5c1601 100644 --- a/src/org/labkey/test/TestFileUtils.java +++ b/src/org/labkey/test/TestFileUtils.java @@ -15,11 +15,9 @@ */ package org.labkey.test; -import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; -import org.apache.commons.io.FileSystem; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -70,7 +68,6 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; -import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; @@ -628,7 +625,7 @@ public static List unzipToDirectory(File sourceZip, File unzipDir) throws * The output file is created in the output folder, having the same name * as the input file, minus the '.tar' extension. */ - private static List unTar(final File inputFile, final File outputDir) throws IOException, ArchiveException + private static List unTar(final File inputFile, final File outputDir) throws IOException { final List untaredFiles = new ArrayList<>(); try (InputStream is = new FileInputStream(inputFile); @@ -678,7 +675,7 @@ private static File unGzip(final File inputFile, final File outputDir) throws IO return outputFile; } - public static List extractTarGz(File archive, File destDir) throws IOException, ArchiveException + public static List extractTarGz(File archive, File destDir) throws IOException { destDir.mkdirs(); return unTar(unGzip(archive, destDir), destDir); @@ -717,15 +714,67 @@ public static byte[] decrypt(byte[] encrypted, char[] passPhrase) throws IOExcep return Streams.readAll(ld.getInputStream()); } - private static final Pattern badChars = Pattern.compile("[\\\\:/\\[\\]?*|]"); + // NOTE: These constants are copied from FileUtil.java and should be kept in sync. + private static final char[] ILLEGAL_CHARS = {'/','\\',':','?','<','>','*','|','"','^', '\n', '\r', '\''}; + public static final String ILLEGAL_CHARS_STRING = new String(ILLEGAL_CHARS); /** * Determining expected file names for downloaded files that are named according to some - * value that might include characters that are not legal for files - * @see FileSystem#toLegalFileName(String, char) + * value that might include characters that are not legal for files. + * NOTE: This implementation is expected to exactly match FileUtil.makeLegalName(String name) defined on the server. */ - public static String makeLegalFileName(String candidate) + public static String makeLegalFileName(String name) { - return badChars.matcher(candidate).replaceAll("_"); + if (name == null) + { + return "__null__"; + } + + if (name.isEmpty()) + { + return "__empty__"; + } + + //limit to 255 chars (FAT and OS X) + //replace illegal chars + char[] ret = new char[Math.min(255, name.length())]; + for(int idx = 0; idx < ret.length; ++idx) + { + char ch = name.charAt(idx); + // Reject characters that are illegal anywhere + if (StringUtils.contains(ILLEGAL_CHARS_STRING, ch) || + // Or characters that are illegal starts to a file name + (idx == 0 && (ch == '-' || ch == '$'))) + { + ch = '_'; + } + else if (ch == '-' && + idx > 0 && + name.charAt(idx - 1) == ' ') + { + int i = idx + 1; + // Skip through as many consecutive '-' as there might be + while (i < name.length() && name.charAt(i) == '-') + { + i++; + } + // If the next character after the '-' isn't a space, transform the leading '-' in the sequence + if (i < name.length() && name.charAt(i) != ' ') + { + ch = '_'; + } + } + + ret[idx] = ch; + } + + //can't end with space (windows) + //can't end with period (windows) + int lastIndex = ret.length - 1; + char ch = ret[lastIndex]; + if (ch == ' ' || ch == '.') + ret[lastIndex] = '_'; + + return new String(ret); } }