]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fixes OOM for broken upload request
authorIlia Motornyi <elmot@vaadin.com>
Fri, 26 May 2017 06:42:18 +0000 (09:42 +0300)
committerGitHub <noreply@github.com>
Fri, 26 May 2017 06:42:18 +0000 (09:42 +0300)
Related to #9102

server/src/main/java/com/vaadin/server/communication/FileUploadHandler.java
server/src/test/java/com/vaadin/server/communication/HugeFileUploadTest.java [new file with mode: 0644]

index 3a0f8f7d795fdbbbb00bef4d1398717667a2af0e..08bcffa442229d504c1c8cc16168a5fb77ae7f04 100644 (file)
@@ -48,6 +48,8 @@ import com.vaadin.ui.Upload.FailedEvent;
  */
 public class FileUploadHandler implements RequestHandler {
 
+    public static final int MULTIPART_BOUNDARY_LINE_LIMIT = 20000;
+
     /**
      * Stream that extracts content from another stream until the boundary
      * string is encountered.
@@ -306,6 +308,10 @@ public class FileUploadHandler implements RequestHandler {
                         "The multipart stream ended unexpectedly");
             }
             bout.write(readByte);
+            if(bout.size() > MULTIPART_BOUNDARY_LINE_LIMIT) {
+                throw new IOException(
+                        "The multipart stream does not contain boundary");
+            }
             readByte = stream.read();
         }
         byte[] bytes = bout.toByteArray();
diff --git a/server/src/test/java/com/vaadin/server/communication/HugeFileUploadTest.java b/server/src/test/java/com/vaadin/server/communication/HugeFileUploadTest.java
new file mode 100644 (file)
index 0000000..50e779c
--- /dev/null
@@ -0,0 +1,64 @@
+package com.vaadin.server.communication;
+
+import com.vaadin.server.StreamVariable;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinResponse;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.ConnectorTracker;
+import com.vaadin.ui.UI;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static com.vaadin.server.ServletPortletHelper.UPLOAD_URL_PREFIX;
+import static org.mockito.Mockito.when;
+
+public class HugeFileUploadTest {
+    private static final String SEC_KEY = "4";
+    private static final String CONN_ID = "2";
+    private static final int UI_ID = 1;
+    @Mock
+    private VaadinSession session;
+
+    @Mock
+    private VaadinResponse response;
+
+    @Mock
+    private VaadinRequest request;
+    @Mock
+    private UI ui;
+    @Mock
+    private StreamVariable streamVariable;
+    @Mock
+    private ConnectorTracker connectorTracker;
+
+    @Before
+    public void setup() throws IOException {
+        MockitoAnnotations.initMocks(this);
+        // 0= UIid, 1 = cid, 2= name, 3 = sec key
+        when(request.getPathInfo()).thenReturn("/" + UPLOAD_URL_PREFIX + UI_ID + "/" + CONN_ID + "/var/" + SEC_KEY);
+        when(request.getContentType()).thenReturn("application/multipart-attached;boundary=bbbbb");
+        when(session.hasLock()).thenReturn(true);
+        when(session.getUIById(UI_ID)).thenReturn(ui);
+        when(ui.getConnectorTracker()).thenReturn(connectorTracker);
+        when(connectorTracker.getStreamVariable(CONN_ID,"var")).thenReturn(streamVariable);
+        when(connectorTracker.getSeckey(streamVariable)).thenReturn(SEC_KEY);
+        when(request.getInputStream()).thenReturn(new InputStream() {
+            @Override
+            public int read() throws IOException {
+                return 'a';
+            }
+        });
+    }
+
+    @Test(expected = IOException.class, timeout = 60000)
+    public void testHugeFileWithoutNewLine() throws IOException {
+        FileUploadHandler fileUploadHandler = new FileUploadHandler();
+        fileUploadHandler.handleRequest(session, request, response);
+    }
+
+}