1

I'm getting IndexOutOfBoundsException while uploading a zip file. What could be the reason? How can I solve it?

Code:-

    String sf="";
    String contentType = req.getContentType();
    DataInputStream in = new DataInputStream(req.getInputStream());
    int formDataLength = req.getContentLength();
    byte dataBytes[] = new byte[formDataLength];
    int byteRead = 0;
    int totalBytesRead = 0;
    while (totalBytesRead < formDataLength) {
        byteRead = in.read(dataBytes, totalBytesRead, formDataLength);
        totalBytesRead += byteRead;
    }
    String file = new String(dataBytes);
    String saveFile = file.substring(file.indexOf("filename=\"") + 10);
    saveFile = saveFile.substring(0, saveFile.indexOf("\n"));
    saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1,saveFile.indexOf("\""));
    int lastIndex = contentType.lastIndexOf("=");
    String boundary = contentType.substring(lastIndex + 1,contentType.length());
    int pos;
    pos = file.indexOf("filename=\"");
    pos = file.indexOf("\n", pos) + 1;
    pos = file.indexOf("\n", pos) + 1;
    pos = file.indexOf("\n", pos) + 1;
    int boundaryLocation = file.indexOf(boundary, pos) - 4;
    int startPos = ((file.substring(0, pos)).getBytes()).length;
    int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length;
    sf = "../" + File.separator + saveFile;
    FileOutputStream fileOut = new FileOutputStream(sf);
    fileOut.write(dataBytes, startPos, (endPos - startPos));  //----- Exception occurs on this line.
    fileOut.flush();
    fileOut.close();

Stacktrace:-

java.lang.IndexOutOfBoundsException
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:297)
at com.apprika.servlets.UpgradePatchServlet.uploadFile(UpgradePatchServlet.java:77)
at com.apprika.servlets.UpgradePatchServlet.upgradeServer(UpgradePatchServlet.java:40)
at com.apprika.servlets.UpgradePatchServlet.doPost(UpgradePatchServlet.java:30)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:636)

Server is running on Linux and uploading file from Windows.


I've tried apache commons file upload but still not getting any success.

    try {
                 DiskFileItemFactory factory = new DiskFileItemFactory();
                 ServletFileUpload upload = new ServletFileUpload(factory);
                 List<FileItem> items = upload.parseRequest(req);
                 for (FileItem item : items) {
                    if (!item.isFormField()) {
                        InputStream is = item.getInputStream();
                        FileOutputStream os = new FileOutputStream("/up/" + item.getName());
                        byte[] b = new byte[4096];
                        int bytesRead = 0;
                        while ((bytesRead = is.read(b)) != -1) {
                            os.write(b, 0, bytesRead);
                        }
                        os.flush();
                        os.close();
                        is.close();
                    }
                 }
            }catch (Exception e) {
                e.printStackTrace();
            }

Now it gives error java.io.FileNotFoundException: /up (Is a directory) `

Harry Joy
  • 58,650
  • 30
  • 162
  • 207
  • Have you checked whether the values of `startPos` and `(endPos - startPos)` are within the boundaries of the `dataBytes` array? There's probably something wrong with those values. – wjans May 11 '11 at 04:59

3 Answers3

1

You are converting the uploaded bytes into a string without specifying the encoding. The default encoding on the server is not necessary the same as the one used for the upload.
Therefore the strings length is not guaranteed to be the same as the byte arrays length, so computing the offsets into this array based on the string could lead to all sorts of problems.

I would recommend using something like Apache Commons Fileupload instead of trying to do all the parsing yourself as getting all the details right is not easy.
A good starting point would be this answer: How to upload files to server using JSP/Servlet?

Community
  • 1
  • 1
Turismo
  • 2,064
  • 2
  • 16
  • 23
0

change the following lines and try ..

String file = new String(dataBytes); 

to

String file = new String(dataBytes,"CP1256");

and

int startPos = ((file.substring(0, pos)).getBytes()).length; 

to

int startPos = ((file.substring(0, pos)).getBytes("CP1256")).length;

and

int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length; 

to

int endPos = ((file.substring(0, boundaryLocation)).getBytes("CP1256")).length;
Harry Joy
  • 58,650
  • 30
  • 162
  • 207
0

The problem is in how you extract the startPos and endPos values, resulting in invalid offsets. I suggest you carefully examine the values being extracted, in a debugger, and you'll find that something's wrong with the code that parses the form data.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • yes. You are right it's getting values as : databytes.length-->4657718 start-->1881 end-->8295738. How can I resolve this? – Harry Joy May 11 '11 at 05:07
  • a) make sure you're looking in the right place in the input; b) make sure you're using the right encoding to interpret the input values for conversion to numeric. – Jim Garrison May 11 '11 at 05:10