Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,13 @@ Licensed to the Apache Software Foundation (ASF) under one
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload2.core.FileUploadByteCountLimitException;
import java.util.ResourceBundle;
import org.apache.wiki.tags.MaxUploadTag;


/**
Expand Down Expand Up @@ -103,6 +106,8 @@ public class AttachmentServlet extends HttpServlet {

/**
* Initializes the servlet from Engine properties.
* @param config
* @throws jakarta.servlet.ServletException
*/
@Override
public void init( final ServletConfig config ) throws ServletException {
Expand Down Expand Up @@ -352,7 +357,17 @@ public void doPost( final HttpServletRequest req, final HttpServletResponse res
} catch( final RedirectException e ) {
final Session session = Wiki.session().find( m_engine, req );
session.addMessage( e.getMessage() );

//drain the request body
try (ServletInputStream inputStream = req.getInputStream();) {
int data;
while ((data = inputStream.read()) != -1) {
//we are just reading the stream to the end
}
} catch (Exception err) {
//ignore it
}


req.getSession().setAttribute("msg", e.getMessage());
res.sendRedirect( e.getRedirect() );
}
Expand All @@ -376,6 +391,8 @@ private String validateNextPage( String nextPage, final String errorPage ) {

/**
* Uploads a specific mime multipart input set, intercepts exceptions.
*
* If the total request size is too big, the user will be redirected to the Error.jsp page
*
* @param req The servlet request
* @return The page to which we should go next.
Expand All @@ -391,7 +408,7 @@ protected String upload( final HttpServletRequest req ) throws RedirectException

// Check that we have a file upload request
if( !JakartaServletFileUpload.isMultipartContent(req) ) {
throw new RedirectException( "Not a file upload", errorPage );
throw new RedirectException( "Not a file upload", nextPage );
}

try {
Expand All @@ -402,15 +419,24 @@ protected String upload( final HttpServletRequest req ) throws RedirectException
final UploadListener pl = new UploadListener();

m_engine.getManager( ProgressManager.class ).startProgress( pl, progressId );


if (req.getContentLengthLong() > m_maxSize) {
//we don't want total upload size to be larger than the max
//this is to prevent resource exhaustion
//TODO i18n this error message
throw new RedirectException("Request too big " +
MaxUploadTag.humanReadableByteCountBin(req.getContentLengthLong()) + " vs " +
MaxUploadTag.humanReadableByteCountBin(m_maxSize), errorPage +"?Error=true");
}
final JakartaServletFileUpload upload = new JakartaServletFileUpload( factory );
upload.setHeaderCharset(StandardCharsets.UTF_8);
if( !context.hasAdminPermissions() ) {
upload.setFileSizeMax( m_maxSize );
}
upload.setProgressListener( pl );
final List<FileItem> items = upload.parseRequest( req );

final List<FileItem> items;
try {
items = upload.parseRequest(req);
} catch (FileUploadByteCountLimitException ex) {
throw new RedirectException( "Request too big " + ex.getMessage(), nextPage );
}
String wikipage = null;
String changeNote = null;
//FileItem actualFile = null;
Expand Down Expand Up @@ -443,10 +469,19 @@ protected String upload( final HttpServletRequest req ) throws RedirectException
}

if(fileItems.isEmpty()) {
throw new RedirectException( "Broken file upload", errorPage );
throw new RedirectException( "Broken file upload", nextPage );

} else {
for( final FileItem actualFile : fileItems ) {
if( !context.hasAdminPermissions() ) {
if (actualFile.getSize()> m_maxSize) {
//TODO i18n this error message
throw new RedirectException("Attachment too big " + actualFile.getName() + " " +
MaxUploadTag.humanReadableByteCountBin(actualFile.getSize()) + " vs " +
MaxUploadTag.humanReadableByteCountBin(m_maxSize), nextPage);
}
}

final String filename = actualFile.getName();
final long fileSize = actualFile.getSize();
try( final InputStream in = actualFile.getInputStream() ) {
Expand Down
66 changes: 66 additions & 0 deletions jspwiki-main/src/main/java/org/apache/wiki/tags/MaxUploadTag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2025 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.wiki.tags;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.wiki.util.TextUtil;

/**
* Outputs the server's configured maximum file upload size.
*
* @since 3.0.0
*/
public class MaxUploadTag extends WikiTagBase {

private static final Logger LOG = LogManager.getLogger(MaxUploadTag.class);

@Override
public int doWikiStartTag() throws Exception {
String maxUploadSize = m_wikiContext.getEngine().getWikiProperties().getProperty("jspwiki.attachment.maxsize");
if (maxUploadSize != null) {
try {
long bytes = Long.parseLong(maxUploadSize);
String humanFormat = humanReadableByteCountBin(bytes);
pageContext.getOut().print(TextUtil.replaceEntities(humanFormat));
} catch (NumberFormatException ex) {
LOG.warn("Parse error from configuration setting jspwiki.attachment.maxsize " + ex.getMessage());
}
}
return SKIP_BODY;
}

/*
Binary (1 Ki = 1,024)
from https://stackoverflow.com/a/3758880/1203182
*/
public static String humanReadableByteCountBin(long bytes) {
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
if (absB < 1024) {
return bytes + " B";
}
long value = absB;
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
value >>= 10;
ci.next();
}
value *= Long.signum(bytes);
return String.format("%.1f %ciB", value / 1024.0, ci.current());
}
}
6 changes: 6 additions & 0 deletions jspwiki-main/src/main/resources/META-INF/jspwiki.tld
Original file line number Diff line number Diff line change
Expand Up @@ -872,4 +872,10 @@
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

<tag>
<name>MaxUpload</name>
<tag-class>org.apache.wiki.tags.MaxUploadTag</tag-class>
<body-content>JSP</body-content>
</tag>
</taglib>
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ attach.add.info=In order to upload a new attachment to this page, please use the
attach.add.permission=Only authorized users are allowed to upload new attachments.
attach.bytes=bytes
attach.add.selectfile=Select file:
attach.add.maxUpload=Max upload size:
attach.add.changenote=Change Note:
attach.add.submit=Upload
attach.add.select=Select files or drop them here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,3 +742,4 @@ javascript.tip.default.title=Weitere...

javascript.prefs.areyousure=Wenn du nicht auf 'Benutzereinstellungen speichern' klickst, \
werden deine Einstellungen verworfen. Bist du sicher, dass diese Seite verlassen werden soll?
attach.add.maxUpload=Maximale Uploadgr\u00f6\u00dfe:
Original file line number Diff line number Diff line change
Expand Up @@ -698,4 +698,5 @@ javascript.dialog.plugin = Plugin
javascript.dialog.principal = Roles, Grupos o Usuarios
javascript.dialog.styles = Estilos adicionales
javascript.dialog.toc.options = opciones de la Tabla de Contenidos
javascript.preview.zone = Zona de previsualizaci\u00f3n
javascript.preview.zone = Zona de previsualizaci\u00f3n
attach.add.maxUpload=Tama\u00f1o m\u00e1ximo de carga:
Original file line number Diff line number Diff line change
Expand Up @@ -707,3 +707,4 @@ notification.createUserProfile.accept.subject=Tervetuloa {0}:aan
info.keywords=Avainsanat: {0}
notification.createUserProfile.accept.content=Onnittelut! Uusi profiilisi {0}:ssa on luotu. Profiilisi tiedot ovat seuraavat: \n\nKirjautumisnimi: \
{1} \nNimesi: {2} \nS\u00e4hk\u00f6posti: {3} \n\nJos unohdat salasanasi, voit palauttaa sen osoitteessa {4}
attach.add.maxUpload=Suurin l\u00e4hetyskoko:
Original file line number Diff line number Diff line change
Expand Up @@ -748,3 +748,4 @@ javascript.tip.default.title=Plus...

javascript.prefs.areyousure=Si vous ne cliquez pas sur le bouton 'Enregistrer les pr\u00e9f\u00e9rences utilisateur', \
vos changements seront perdus. Etes-vous s\u00fbr de vouloir quitter cette page\u00a0?
attach.add.maxUpload=Taille maximale de t\u00e9l\u00e9chargement\u00a0:
Original file line number Diff line number Diff line change
Expand Up @@ -736,3 +736,4 @@ prefs.user.pagecookies.actions = Azioni
javascript.dialog.character.entities = Entit\u00e0 dei caratteri
prefs.password0 = Password attuale *
userbox.button = Menu utente
attach.add.maxUpload=Dimensione massima di caricamento:
Original file line number Diff line number Diff line change
Expand Up @@ -737,3 +737,4 @@ javascript.dialog.styles = Extra Stijlen
javascript.dialog.toc.options = TOC-opties
prefs.password0 = Huidig Wachtwoord *
javascript.dialog.plugin = Plug-in
attach.add.maxUpload=Maximale uploadgrootte:
Original file line number Diff line number Diff line change
Expand Up @@ -682,3 +682,4 @@ javascript.slimbox.previous=&laquo;Anterior
javascript.slimbox.btn=Clique para visualizar {0}
javascript.slimbox.size=Tamanho: {0}px x {1}px
javascript.tip.default.title=Mais...
attach.add.maxUpload=Tamanho m\u00e1ximo de upload:
Original file line number Diff line number Diff line change
Expand Up @@ -722,3 +722,4 @@ javascript.filter.hint=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0448\u0430\u
javascript.tablefilter=\u0424\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b
javascript.slimbox.caption=\u041f\u0440\u044f\u043c\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 {0}
javascript.slimbox.btn=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c {0}
attach.add.maxUpload=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:
Original file line number Diff line number Diff line change
Expand Up @@ -723,3 +723,4 @@ attach.add.drop = \u6216\u62d6\u653e\u5230\u6b64\u5904!
sbox.search.button = \u5feb\u9012\u641c\u7d22\u83dc\u5355
javascript.dialog.principal = \u89d2\u8272\u3001\u7fa4\u7ec4\u6216\u7528\u6237
prefs.user.pagecookies.actions = \u64cd\u4f5c
attach.add.maxUpload=\u6700\u5927\u4e0a\u4f20\u5927\u5c0f:
17 changes: 11 additions & 6 deletions jspwiki-war/src/main/webapp/Error.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@
<%
Engine wiki = Wiki.engine().find( getServletConfig() );
Context wikiContext = Wiki.context().create( wiki, request, ContextEnum.WIKI_ERROR.getRequestContext() );
//the following line is critical to get the jspwiki jsp tags to work
pageContext.setAttribute( Context.ATTR_CONTEXT, wikiContext, PageContext.REQUEST_SCOPE);
String pagereq = wikiContext.getName();

response.setContentType("text/html; charset="+wiki.getContentEncoding() );

String msg = "An unknown error was caught by Error.jsp";

if ("true".equalsIgnoreCase(request.getParameter("Error"))) {
//this is coming from the attaching upload servlet
msg = (String) request.getSession().getAttribute("msg");
}
Throwable realcause = null;

msg = exception.getMessage();
if (exception!=null)
msg = exception.getMessage();
if( msg == null || msg.isEmpty())
{
msg = "An unknown exception "+exception.getClass().getName()+" was caught by Error.jsp.";
Expand All @@ -52,7 +57,7 @@
// imported in JSP pages.
//

if( exception instanceof jakarta.servlet.jsp.JspException )
if( exception!=null && exception instanceof jakarta.servlet.jsp.JspException )
{
log.debug("IS JSPEXCEPTION");
realcause = ((jakarta.servlet.jsp.JspException)exception).getCause();
Expand Down Expand Up @@ -83,9 +88,9 @@
</dd>
<% if (wikiContext.hasAdminPermissions()) { %>
<dt>Exception</dt>
<dd><%=realcause.getClass().getName()%></dd>
<dd><%=realcause!=null ? realcause.getClass().getName() : ""%></dd>
<dt>Place where detected</dt>
<dd><%=FileUtil.getThrowingMethod(realcause)%></dd>
<dd><%=realcause!=null ? FileUtil.getThrowingMethod(realcause) : ""%></dd>
<% } %>
</dl>
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@

<%-- <p><fmt:message key="attach.add.info" /></p> --%>
<div class="form-group">
<label class="control-label form-col-20" for="files"><fmt:message key="attach.add.selectfile"/></label>
<label class="control-label form-col-20" for="files">
<fmt:message key="attach.add.selectfile"/><br>
<fmt:message key="attach.add.maxUpload" />
<wiki:MaxUpload />
</label>

<ul class="list-group form-col-50">
<li class="list-group-item droppable">
Expand Down
Loading