Hi,

The Bug Reporting System dosn't seem to be working so hope you don't mind me
logging it this way.

There appears to be a bug in the File Upload fucntionality of Struts 1.0
Final Release.

After uploading a file and doing a binary compare of the original file and
the one uploaded, the files are different. Some characters in the uploaded
file have been replaced with a newline ('\n') character.

>From the code, I deduced that the problem was due to the fact that
MultipartIterator::createLocalFile was calling
inputStream.readLine(lineBuffer, 0, MAX_LINE_SIZE) and assuming that a
newline character was always found. This is not the case if you have filled
your buffer to MAX_LINE_SIZE without finding a newline.  Because of this
assumption, a newline character was always being added. However, this didn't
explain why the original character was being replaced by a newline. That
problem lies in BufferedMultipartInputStream::readLine, because if no
newline character is found it reads one extra character from the stream and
does nothing with it.

I've made the changes which fix this problem and tested it briefly. I have
included the original function followed by the modified one below for your
approval.

Original:

    public int readLine(byte[] b, int offset, int length) throws IOException
{

        int count = 0;
        int read = read();
        if (read == -1) {
            return -1;
        }

        while ((read != -1) && (count < length)) {
            if (read == '\n')
                break;
            b[offset] = (byte) read;
            count++;
            offset++;
            read = read();
        }

        return count;
    }

Modified:

    public int readLine(byte[] b, int offset, int length) throws IOException
{

        int count = 0;
        int read = read();
        if (read == -1) {
            return -1;
        }

        while ((read != -1) && (count < length)) {
            if (read == '\n')
                break;
            b[offset] = (byte) read;
            count++;
            offset++;

            if (count < length)
                read = read();
        }

        return count;
    }

Original:

    protected File createLocalFile() throws IOException {

        File tempFile = File.createTempFile("strts", null, new
File(tempDir));
        BufferedOutputStream fos = new BufferedOutputStream(new
FileOutputStream(tempFile), diskBufferSize);

        byte[] lineBuffer = new byte[MAX_LINE_SIZE];

        int bytesRead = inputStream.readLine(lineBuffer, 0, MAX_LINE_SIZE);

        boolean cutCarriage = false;
        boolean cutNewline = false;

        try {
            while ((bytesRead != -1) && (!equals(lineBuffer, 0,
boundaryBytes.length,
                    boundaryBytes))) {

                        if (cutCarriage) {
                            fos.write('\r');
                        }
                        if (cutNewline) {
                            fos.write('\n');
                        }
                        cutCarriage = false;
                        if (bytesRead > 0) {
                            if (lineBuffer[bytesRead-1] == '\r') {
                                bytesRead--;
                                cutCarriage = true;
                            }
                        }
                        cutNewline = true;
                        fos.write(lineBuffer, 0, bytesRead);
                        bytesRead = inputStream.readLine(lineBuffer, 0,
MAX_LINE_SIZE);
            }
        }
        catch (IOException ioe) {
            fos.close();
            tempFile.delete();
            throw ioe;
        }

        fos.flush();
        fos.close();
        return tempFile;
    }

Modifed:

    protected File createLocalFile() throws IOException {

        File tempFile = File.createTempFile("strts", null, new
File(tempDir));
        BufferedOutputStream fos = new BufferedOutputStream(new
FileOutputStream(tempFile), diskBufferSize);

        byte[] lineBuffer = new byte[MAX_LINE_SIZE];

        int bytesRead = inputStream.readLine(lineBuffer, 0, MAX_LINE_SIZE);

        boolean cutCarriage = false;
        boolean cutNewline = false;

        try {
            while ((bytesRead != -1) && (!equals(lineBuffer, 0,
boundaryBytes.length, boundaryBytes))) {

                if (cutCarriage) {
                    fos.write('\r');
                    cutCarriage = false;
                }

                if (cutNewline) {
                    fos.write('\n');
                    cutNewline = false;
                }

                if (bytesRead > 0) {
                    if (lineBuffer[bytesRead - 1] == '\r') {
                        cutCarriage = true;
                        fos.write(lineBuffer, 0, bytesRead - 1);
                    } else
                        fos.write(lineBuffer, 0, bytesRead);
                }

                if (bytesRead < MAX_LINE_SIZE)
                    cutNewline = true;

                bytesRead = inputStream.readLine(lineBuffer, 0,
MAX_LINE_SIZE);

            }
        }
        catch (IOException ioe) {
            fos.close();
            tempFile.delete();
            throw ioe;
        }

        fos.flush();
        fos.close();
        return tempFile;
    }

Rgds
Mason Blackwood

Reply via email to