Are 3702 and 3828 resolved now? Or are they being held open pending the unit test?
[EMAIL PROTECTED] wrote: > > mschachter 01/10/11 09:28:17 > > Modified: src/share/org/apache/struts/upload > BufferedMultipartInputStream.java > MultipartIterator.java > Log: > - port from 1.0 branch to address bugs #3702, #3828, and #2683 > > Revision Changes Path > 1.6 +7 -4 >jakarta-struts/src/share/org/apache/struts/upload/BufferedMultipartInputStream.java > > Index: BufferedMultipartInputStream.java > =================================================================== > RCS file: >/home/cvs/jakarta-struts/src/share/org/apache/struts/upload/BufferedMultipartInputStream.java,v > retrieving revision 1.5 > retrieving revision 1.6 > diff -u -r1.5 -r1.6 > --- BufferedMultipartInputStream.java 2001/09/24 16:41:37 1.5 > +++ BufferedMultipartInputStream.java 2001/10/11 16:28:17 1.6 > @@ -218,13 +218,16 @@ > > int read = read(); > ByteArrayOutputStream baos = new ByteArrayOutputStream(); > - while (read != -1) { > - if (read == '\n') { > - return baos.toByteArray(); > - } > + > + // return null if there are no more bytes to read > + if( -1 == read ) > + return null; > + > + while ((read != -1) && (read != '\n')) { > baos.write(read); > read = read(); > } > + > return baos.toByteArray(); > } > > > > > 1.18 +95 -90 >jakarta-struts/src/share/org/apache/struts/upload/MultipartIterator.java > > Index: MultipartIterator.java > =================================================================== > RCS file: >/home/cvs/jakarta-struts/src/share/org/apache/struts/upload/MultipartIterator.java,v > retrieving revision 1.17 > retrieving revision 1.18 > diff -u -r1.17 -r1.18 > --- MultipartIterator.java 2001/09/24 16:41:37 1.17 > +++ MultipartIterator.java 2001/10/11 16:28:17 1.18 > @@ -21,7 +21,7 @@ > * <pre> > * MultipartIterator iterator = new MultipartIterator(request); > * MultipartElement element; > - * > + * > * while ((element = iterator.getNextElement()) != null) { > * //do something with element > * } > @@ -31,64 +31,64 @@ > * @author Mike Schachter > */ > public class MultipartIterator { > - > + > /** > * The maximum size in bytes of the buffer used to read lines [4K] > */ > public static int MAX_LINE_SIZE = 4096; > - > + > /** > * The request instance for this class > */ > protected HttpServletRequest request; > - > + > /** > * The input stream instance for this class > */ > protected BufferedMultipartInputStream inputStream; > - > + > /** > * The boundary for this multipart request > */ > protected String boundary; > - > + > /** > * The byte array representing the boundary for this multipart request > */ > protected byte[] boundaryBytes; > - > + > /** > * Whether or not the input stream is finished > */ > protected boolean contentRead = false; > - > + > /** > * The maximum file size in bytes allowed. Ignored if -1 > */ > protected long maxSize = -1; > - > + > /** > * The total bytes read from this request > */ > protected long totalLength = 0; > - > + > /** > * The content length of this request > */ > protected int contentLength; > - > + > /** > * The size in bytes written to the filesystem at a time [20K] > */ > protected int diskBufferSize = 2 * 10240; > - > + > /** > * The amount of data read from a request at a time. > * This also represents the maximum size in bytes of > * a line read from the request [4KB] > */ > protected int bufferSize = 4096; > - > + > /** > * The temporary directory to store files > */ > @@ -97,13 +97,13 @@ > /** > * Constructs a MultipartIterator with a default buffer size and no file size > * limit > - * > + * > * @param request The multipart request to iterate > */ > public MultipartIterator(HttpServletRequest request) throws ServletException{ > this(request, -1); > } > - > + > /** > * Constructs a MultipartIterator with the specified buffer size and > * no file size limit > @@ -112,10 +112,10 @@ > * @param bufferSize The size in bytes that should be read from the input > * stream at a times > */ > - public MultipartIterator(HttpServletRequest request, int bufferSize) throws >ServletException { > + public MultipartIterator(HttpServletRequest request, int bufferSize) throws >ServletException { > this (request, bufferSize, -1); > } > - > + > /** > * Constructs a MultipartIterator with the specified buffer size and > * the specified file size limit in bytes > @@ -125,18 +125,18 @@ > * stream at a times > * @param maxSize The maximum size in bytes allowed for a multipart element's >data > */ > - public MultipartIterator(HttpServletRequest request, int bufferSize, long >maxSize) > + public MultipartIterator(HttpServletRequest request, int bufferSize, long >maxSize) > throws >ServletException { > - > - this(request, bufferSize, maxSize, null); > - > + > + this(request, bufferSize, maxSize, null); > + > } > - > + > public MultipartIterator(HttpServletRequest request, > int bufferSize, > long maxSize, > String tempDir) throws ServletException { > - > + > this.request = request; > this.maxSize = maxSize; > if (bufferSize > -1) { > @@ -151,7 +151,7 @@ > } > parseRequest(); > } > - > + > /** > * Retrieves the next element in the iterator if one exists. > * > @@ -166,18 +166,18 @@ > //retrieve the "Content-Disposition" header > //and parse > String disposition = readLine(); > - > - > + > + > if ((disposition != null) && >(disposition.startsWith("Content-Disposition"))) { > String name = parseDispositionName(disposition); > String filename = parseDispositionFilename(disposition); > - > + > String contentType = null; > boolean isFile = (filename != null); > - > + > if (isFile) { > filename = new File(filename).getName(); > - > + > //check for windows filenames, > //from linux jdk's the entire filepath > //isn't parsed correctly from File.getName() > @@ -187,29 +187,29 @@ > colonIndex = filename.indexOf("\\\\"); > } > int slashIndex = filename.lastIndexOf("\\"); > - > + > if ((colonIndex > -1) && (slashIndex > -1)) { > //then consider this filename to be a full > //windows filepath, and parse it accordingly > //to retrieve just the file name > filename = filename.substring(slashIndex+1, >filename.length()); > } > - > + > //get the content type > contentType = readLine(); > contentType = parseContentType(contentType); > } > - > - > - > + > + > + > //ignore next line (whitespace) (unless it's a file > //without content-type) > if (! ((isFile) && contentType == null)) { > readLine(); > } > - > + > MultipartElement element = null; > - > + > //process a file element > if (isFile) { > try { > @@ -218,6 +218,7 @@ > > element = new MultipartElement(name, filename, contentType, >elementFile); > } catch (IOException ioe) { > + ioe.printStackTrace(System.err); > throw new ServletException("IOException while reading file >element: " + ioe.getMessage(), ioe); > } > } > @@ -240,13 +241,13 @@ > textData.setLength(textData.length()-1); > } > } > - > + > //create the element > element = new MultipartElement(name, textData.toString()); > } > return element; > - } > - > + } > + > //reset stream > if (inputStream.markSupported()) { > try { > @@ -257,9 +258,9 @@ > ioe.getMessage()); > } > } > - return null; > + return null; > } > - > + > /** > * Set the maximum amount of bytes read from a line at one time > * > @@ -268,7 +269,7 @@ > public void setBufferSize(int bufferSize) { > this.bufferSize = bufferSize; > } > - > + > /** > * Get the maximum amount of bytes read from a line at one time > * > @@ -277,7 +278,7 @@ > public int getBufferSize() { > return bufferSize; > } > - > + > /** > * Set the maximum post data size allowed for a multipart request > * @param maxSize The maximum post data size in bytes, set to <code>-1</code> > @@ -286,26 +287,26 @@ > public void setMaxSize(long maxSize) { > this.maxSize = maxSize; > } > - > - /** > + > + /** > * Get the maximum post data size allowed for a multipart request > * @return The maximum post data size in bytes > */ > public long getMaxSize() { > return maxSize; > } > - > + > /** > * Handles retrieving the boundary and setting the input stream > */ > protected void parseRequest() throws ServletException { > - > + > contentLength = request.getContentLength(); > - > + > //set boundary > boundary = parseBoundary(request.getContentType()); > boundaryBytes = boundary.getBytes(); > - > + > try { > //set the input stream > inputStream = new >BufferedMultipartInputStream(request.getInputStream(), > @@ -316,23 +317,23 @@ > if (inputStream.markSupported()) { > inputStream.mark(contentLength+1); > } > - > + > } > catch (IOException ioe) { > - throw new ServletException("Problem while reading request: " + > + throw new ServletException("Problem while reading request: " + > ioe.getMessage(), ioe); > } > - > + > if ((boundary == null) || (boundary.length() < 1)) { > //try retrieving the header through more "normal" means > boundary = parseBoundary(request.getHeader("Content-type")); > } > - > + > if ((boundary == null) || (boundary.length() < 1)) { > throw new ServletException("MultipartIterator: cannot retrieve >boundary " + > "for multipart request"); > } > - > + > //read first line > try { > String firstLine = readLine(); > @@ -350,37 +351,39 @@ > throw new ServletException("MultipartIterator: encoding >\"ISO-8859-1\" not supported"); > } > } > - > + > /** > - * Parses a content-type String for the boundary. Appends a > + * Parses a content-type String for the boundary. Appends a > * "--" to the beginning of the boundary, because thats the > * real boundary as opposed to the shortened one in the > * content type. > */ > public static String parseBoundary(String contentType) { > if (contentType.lastIndexOf("boundary=") != -1) { > - String _boundary = "--" + > + String _boundary = "--" + > >contentType.substring(contentType.lastIndexOf("boundary=")+9); > if (_boundary.endsWith("\n")) { > //strip it off > return _boundary.substring(0, _boundary.length()-1); > } > - return _boundary; > + return _boundary; > } > - return null; > + return null; > } > - > + > /** > * Parses the "Content-Type" line of a multipart form for a content type > * > - * @param contentTypeString A String reprsenting the Content-Type line, > + * @param contentTypeString A String reprsenting the Content-Type line, > * with a trailing "\n" > * @return The content type specified, or <code>null</code> if one can't be > * found. > */ > public static String parseContentType(String contentTypeString) { > int nameIndex = contentTypeString.indexOf("Content-Type: "); > - > + if (nameIndex == -1) > + nameIndex = contentTypeString.indexOf("\n"); > + > if (nameIndex != -1) { > int endLineIndex = contentTypeString.indexOf("\n"); > if (endLineIndex == -1) { > @@ -390,10 +393,10 @@ > } > return null; > } > - > + > /** > * Retrieves the "name" attribute from a content disposition line > - * > + * > * @param dispositionString The entire "Content-disposition" string > * @return <code>null</code> if no name could be found, otherwise, > * returns the name > @@ -402,8 +405,8 @@ > public static String parseDispositionName(String dispositionString) { > return parseForAttribute("name", dispositionString); > } > - > - /** > + > + /** > * Retrieves the "filename" attribute from a content disposition line > * > * @param dispositionString The entire "Content-disposition" string > @@ -414,8 +417,8 @@ > public static String parseDispositionFilename(String dispositionString) { > return parseForAttribute("filename", dispositionString); > } > - > - > + > + > /** > * Parses a string looking for a attribute-value pair, and returns the value. > * For example: > @@ -424,7 +427,7 @@ > * MultipartIterator.parseForAttribute(parseString, "name"); > * </pre> > * That will return "bob". > - * > + * > * @param attribute The name of the attribute you're trying to get > * @param parseString The string to retrieve the value from > * @return The value of the attribute, or <code>null</code> if none could be >found > @@ -432,17 +435,17 @@ > public static String parseForAttribute(String attribute, String parseString) { > int nameIndex = parseString.indexOf(attribute + "=\""); > if (nameIndex != -1) { > - > + > int endQuoteIndex = parseString.indexOf("\"", >nameIndex+attribute.length()+3); > - > + > if (endQuoteIndex != -1) { > return parseString.substring(nameIndex+attribute.length()+2, >endQuoteIndex); > } > return ""; > - } > + } > return null; > } > - > + > /** > * Reads the input stream until it reaches a new line > */ > @@ -450,42 +453,44 @@ > > byte[] bufferByte; > int bytesRead; > - > + > if (totalLength >= contentLength) { > return null; > } > - > + > try { > bufferByte = inputStream.readLine(); > + if (bufferByte == null) > + return null; > bytesRead = bufferByte.length; > } > catch (IOException ioe) { > - throw new ServletException("IOException while reading multipart >request: " + > + throw new ServletException("IOException while reading multipart >request: " + > ioe.getMessage()); > } > if (bytesRead == -1) { > return null; > } > - > + > totalLength += bytesRead; > return new String(bufferByte, 0, bytesRead, "ISO-8859-1"); > } > - > + > /** > * Creates a file on disk from the current mulitpart element > * @param fileName the name of the multipart file > */ > protected File createLocalFile() throws IOException { > - > + > File tempFile = File.createTempFile("strts", null, new File(tempDir)); > BufferedOutputStream fos = new BufferedOutputStream(new >FileOutputStream(tempFile), > diskBufferSize); > byte[] lineBuffer = inputStream.readLine(); > int bytesRead = lineBuffer.length; > - > + > boolean cutCarriage = false; > boolean cutNewline = false; > - > + > try { > while ((bytesRead != -1) && (!equals(lineBuffer, 0, >boundaryBytes.length, > boundaryBytes))) { > @@ -514,12 +519,12 @@ > tempFile.delete(); > throw ioe; > } > - > - fos.flush(); > + > + fos.flush(); > fos.close(); > return tempFile; > } > - > + > /** > * Checks bytes for equality. Two byte arrays are equal if > * each of their elements are the same. This method checks > @@ -528,21 +533,21 @@ > * @param comp The byte to compare to <code>source</code> > * @param offset The offset to start at in <code>comp</code> > * @param length The length of <code>comp</code> to compare to > - * @param source The reference byte to test for equality > + * @param source The reference byte array to test for equality > */ > public static boolean equals(byte[] comp, int offset, int length, > byte[] source) { > - > - if (length != source.length) { > - return false; > + > + if ((length != source.length) || (comp.length - offset < length)) { > + return false; > } > - > + > for (int i = 0; i < length; i++) { > if (comp[offset+i] != source[i]) { > return false; > } > } > - return true; > + return true; > } > > } > > > -- Ted Husted, Husted dot Com, Fairport NY USA. -- Custom Software ~ Technical Services. -- Tel +1 716 737-3463 -- http://www.husted.com/struts/ -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>