/*
 * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
 * @bug 4806007
 * @summary Checks for vague exceptions from writeUTF/readUTF
 */

import java.io.*;
import java.util.*;

public class ReadUTF {

    private static Random generator = new Random();

    private static final int TEST_ITERATIONS = 1000;

    private static final int A_NUMBER_NEAR_65535 = 60000;

    private static final int MAX_CORRUPTIONS_PER_CYCLE = 3;

    public static final void main(String[] args) throws Exception {
        for (int i=0; i<TEST_ITERATIONS; i++) {
            try {
                writeAndReadAString();
            } catch (UTFDataFormatException utfdfe) {
                if (utfdfe.getMessage() == null)
                    throw new RuntimeException("vague exception thrown");
            } catch (EOFException eofe) {
                // These are rare and beyond the scope of the test
            }
        }
    }

    private static void writeAndReadAString() throws Exception {
        // Write out a string whose UTF-8 encoding is quite possibly
        // longer than 65535 bytes
        int length = generator.nextInt(A_NUMBER_NEAR_65535) + 1;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        StringBuffer testBuffer = new StringBuffer();
        for (int i=0; i<length; i++)
            testBuffer.append((char)generator.nextInt());
        String testString = testBuffer.toString();
        DataOutputStream dos = new DataOutputStream(baos);
        dos.writeUTF(testString);

        // Corrupt the data to produce malformed characters
        byte[] testBytes = baos.toByteArray();
        int dataLength = testBytes.length;
        int corruptions = generator.nextInt(MAX_CORRUPTIONS_PER_CYCLE);
        for (int i=0; i<corruptions; i++) {
            int index = generator.nextInt(dataLength);
            testBytes[index] = (byte)generator.nextInt();
        }

        // Pay special attention to mangling the end to produce
        // partial characters at end
        testBytes[dataLength-1] = (byte)generator.nextInt();
        testBytes[dataLength-2] = (byte)generator.nextInt();

        // Attempt to decode the bytes back into a String
        ByteArrayInputStream bais = new ByteArrayInputStream(testBytes);
        DataInputStream dis = new DataInputStream(bais);
        dis.readUTF();
    }
}
