diff --git a/api/src/org/labkey/api/premium/DefaultAVMultipartResolver.java b/api/src/org/labkey/api/premium/DefaultAVMultipartResolver.java index cd3b963cbf4..0899c3b8f77 100644 --- a/api/src/org/labkey/api/premium/DefaultAVMultipartResolver.java +++ b/api/src/org/labkey/api/premium/DefaultAVMultipartResolver.java @@ -3,8 +3,11 @@ import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.Part; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import org.labkey.api.action.ApiUsageException; import org.labkey.api.util.FileUtil; +import org.labkey.api.view.UnauthorizedException; import org.springframework.web.multipart.MultipartException; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; @@ -22,10 +25,17 @@ public class DefaultAVMultipartResolver extends StandardServletMultipartResolver for (Part part : request.getParts()) { // Filter to just file uploads - if (part.getSubmittedFileName() != null) + if (!StringUtils.isEmpty(part.getSubmittedFileName())) { - FileUtil.checkAllowedFileName(part.getSubmittedFileName(), true); - validate(part); + try + { + FileUtil.checkAllowedFileName(part.getSubmittedFileName(), true); + validate(part); + } + catch (IOException e) + { + throw new InvalidFileExtensionException(e.getMessage()); + } } } } @@ -40,4 +50,12 @@ protected void validate(Part part) { //do nothing by default, but give subclasses a chance to override } + + public static class InvalidFileExtensionException extends ApiUsageException + { + public InvalidFileExtensionException(String msg) + { + super(msg); + } + } } diff --git a/api/src/org/labkey/api/util/FileUtil.java b/api/src/org/labkey/api/util/FileUtil.java index 8446e0c3535..ff7dece5515 100644 --- a/api/src/org/labkey/api/util/FileUtil.java +++ b/api/src/org/labkey/api/util/FileUtil.java @@ -326,7 +326,7 @@ static String isAllowedFileName(String s, boolean checkFileExtension, AppProps a { String badExtension = checkExtension(s, AppProps.getInstance()); if (badExtension != null) - return "This file type [" + badExtension + "] is not allowed."; + return "This file type [" + badExtension + "] is not allowed. Accepted file extensions: " + AppProps.getInstance().getAllowedExtensions(); } return null; } @@ -1533,11 +1533,6 @@ else if (ch == '-' && if (ch == ' ' || ch == '.') ret[lastIndex] = '_'; - String result = new String(ret); - - assert !AppProps.getWriteableInstance().isInvalidFilenameBlocked() || isAllowedFileName(result, true) == null : - "Failed to make filename safe. Original: " + name + ", transformed: " + result + ", error: " + isAllowedFileName(result, true); - return new String(ret); } diff --git a/api/src/org/labkey/api/view/MockHttpResponseWithRealPassthrough.java b/api/src/org/labkey/api/view/MockHttpResponseWithRealPassthrough.java index ef97b11cf24..41f136bbeb8 100644 --- a/api/src/org/labkey/api/view/MockHttpResponseWithRealPassthrough.java +++ b/api/src/org/labkey/api/view/MockHttpResponseWithRealPassthrough.java @@ -15,6 +15,7 @@ */ package org.labkey.api.view; +import org.jetbrains.annotations.NotNull; import org.labkey.api.action.ApiUsageException; import org.springframework.mock.web.MockHttpServletResponse; @@ -50,7 +51,7 @@ public HttpServletResponse getResponse() } @Override - public PrintWriter getWriter() throws UnsupportedEncodingException + public @NotNull PrintWriter getWriter() throws UnsupportedEncodingException { if (_writer == null) { @@ -76,7 +77,7 @@ public SizeLimitExceededException() /** Checks the size of the current output to make sure it hasn't exceeded the limit before appending the new content */ private class SizeLimitingPrintWriter extends PrintWriter { - private PrintWriter _out; + private final PrintWriter _out; public SizeLimitingPrintWriter(PrintWriter out) { @@ -100,28 +101,28 @@ private void checkSize() } @Override - public void write(char[] buf, int off, int len) + public void write(char @NotNull [] buf, int off, int len) { checkSize(); _out.write(buf, off, len); } @Override - public void write(char[] buf) + public void write(char @NotNull [] buf) { checkSize(); _out.write(buf); } @Override - public void write(String s, int off, int len) + public void write(@NotNull String s, int off, int len) { checkSize(); _out.write(s, off, len); } @Override - public void write(String s) + public void write(@NotNull String s) { checkSize(); _out.write(s); @@ -170,7 +171,7 @@ public void print(double d) } @Override - public void print(char[] s) + public void print(char @NotNull [] s) { checkSize(); _out.print(s); @@ -240,7 +241,7 @@ public void println(double x) } @Override - public void println(char[] x) + public void println(char @NotNull [] x) { checkSize(); _out.println(x); @@ -261,28 +262,28 @@ public void println(Object x) } @Override - public PrintWriter printf(String format, Object... args) + public PrintWriter printf(@NotNull String format, Object... args) { checkSize(); return _out.printf(format, args); } @Override - public PrintWriter printf(Locale l, String format, Object... args) + public PrintWriter printf(Locale l, @NotNull String format, Object... args) { checkSize(); return _out.printf(l, format, args); } @Override - public PrintWriter format(String format, Object... args) + public PrintWriter format(@NotNull String format, Object... args) { checkSize(); return _out.format(format, args); } @Override - public PrintWriter format(Locale l, String format, Object... args) + public PrintWriter format(Locale l, @NotNull String format, Object... args) { checkSize(); return _out.format(l, format, args);