You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by "Howard M. Lewis Ship (JIRA)" <de...@tapestry.apache.org> on 2009/12/29 19:15:20 UTC

[jira] Created: (TAPESTRY-2758) For very complex forms, encoding the allocated ID string results in a java.io.UTFDataFormatException

For very complex forms, encoding the allocated ID string results in a java.io.UTFDataFormatException
----------------------------------------------------------------------------------------------------

                 Key: TAPESTRY-2758
                 URL: https://issues.apache.org/jira/browse/TAPESTRY-2758
             Project: Tapestry
          Issue Type: Bug
          Components: Framework
    Affects Versions: 4.1.6
            Reporter: Howard M. Lewis Ship


    *   java.io.UTFDataFormatException
      java.io.ObjectOutputStream$BlockDataOutputStream#writeUTF (ObjectOutputStream.java:2125)
      java.io.ObjectOutputStream$BlockDataOutputStream#writeUTF (ObjectOutputStream.java:1968)
      java.io.ObjectOutputStream#writeUTF (ObjectOutputStream.java:841)
      org.apache.tapestry.util.io.CompressedDataEncoder#encodeString (CompressedDataEncoder.java:55)
      org.apache.tapestry.engine.RequestCycle#encodeIdState (RequestCycle.java:678)
      org.apache.tapestry.form.FormSupportImpl#render (FormSupportImpl.java:482)
      org.apache.tapestry.form.Form#renderComponent (Form.java:217) 

A little digging found out that this can only happen for exceptionally large forms.  The relevent code:

RequestCycle.java:

  public String encodeIdState()
    {
        return CompressedDataEncoder.encodeString(_idAllocator.toExternalString());
    }

CompressedDataEncoder.java:

    public static String encodeString(String input)
    {
        Defense.notNull(input, "input");

        if (HiveMind.isBlank(input))
            return "";

        try {
            ByteArrayOutputStream bosPlain = new ByteArrayOutputStream();
            ByteArrayOutputStream bosCompressed = new ByteArrayOutputStream();

            GZIPOutputStream gos = new GZIPOutputStream(bosCompressed);
            TeeOutputStream tos = new TeeOutputStream(bosPlain, gos);
            ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(tos));
            
            oos.writeUTF(input);
            
            oos.close();

            boolean useCompressed = bosCompressed.size() < bosPlain.size();

            byte[] data = useCompressed ? bosCompressed.toByteArray() : bosPlain.toByteArray();
            
            byte[] encoded = Base64.encodeBase64(data);

            String prefix = useCompressed ? GZIP_BYTESTREAM_PREFIX : BYTESTREAM_PREFIX;

            return prefix + new String(encoded);
        }
        catch (Exception ex) {
            throw new ApplicationRuntimeException(IoMessages.encodeFailure(input, ex), ex);
        }
    }

ObjectOutputStream.java:

	void writeUTF(String s, long utflen) throws IOException {
	    if (utflen > 0xFFFFL) {
		throw new UTFDataFormatException();
	    }
	    writeShort((int) utflen);
	    if (utflen == (long) s.length()) {
		writeBytes(s);
	    } else {
		writeUTFBody(s);
	    }
	}

So for strings larger than 65K, we get the exception.  Yes, that's an incredibly large form!


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.