[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Property objects bug fix



Hi,
  So I thought about this some more, and while the previous fixes I gave
fix the problem, they might introduce a more subtle bug.  Here is the
explanation:

The original problem was that data was being DEcoded from bytes into chars,
using the platform's default encoding, and then stored as chars.  When it
was being read back in, it was ENcoded from chars to bytes by just trimming
the high-byte.  This mismatch in encoding styles was a problem.

My original fix was to just make the coding styles match up by using the
platforms default encoding in each case.

This may have introduced a new problem.  Bytes are generally considered the
lower level representation.  The java classes are there to encode char
strings as byte strings and then decode the byte strings back into char
strings.  The problem is that I DO NOT KNOW if all byte strings represent
legal character stings (it will probably vary by the encoding used anyway,
and the default encoding varies by platform).  My fix used the standard
encoding backwards.  If it tried to store a byte string that does not
correspond to the encoding of a char string it is unclear what will happen.

The fix is make sure that the coding chosen has a char string for every
byte string.  This is possible if we fix the original problem in the other
direction.  Instead of making both encode and decode use the default
character encoding, we should make neither use the default character
encoding.

Here are the relevant methods from Setup.java:

>     /**
>     @param _val
>     @param _key
>     */
>     public void setProperty (String _key, Object _val) {
>         try {
>             ByteArrayOutputStream buf = new ByteArrayOutputStream (1024);
>             ObjectOutputStream out = new ObjectOutputStream (buf);
>             out.writeObject (_val);
>             out.close();
>             // magic prefix to distinguish between primitive and object
properties
>             // XXX do we want the 0 or not?
>             setStringProperty (_key, buf.toString(0));
>             }
>         catch (Exception e) {
>             throw new RuntimeException (e.getMessage());
>             }
>         }
>     
> 
>     /** 
>     @param _key
>     @param _default The default value to use if no property is found.
>     */
>     public Object property (String _key, Object _default) {
>         try {
>             String result = stringProperty (_key, (String)_default);
>             if (result != null) {
>            	 // XXX do we want to use this or just
>            	 // byte[] bytes = result.getBytes();
>                 byte[] bytes = new byte[result.length()];
>                 result.getBytes(0, bytes.length, bytes, 0);
>                 ObjectInputStream in = new ObjectInputStream(new
ByteArrayInputStream (bytes));
>                 return in.readObject();
>                 }
>             else
>                 return null;
>             }
>         catch (Exception e) {
>             throw new RuntimeException (e.getMessage());
>             }
>         }

I should note that the methods I'm using to do the conversion here are
deprecated.  I think they do apply in this case because we are encoding
bytes as characters for storage.  The usual case is to encode characters as
bytes.

Another option would be to use a real encoding from bytes to characters -
store each byte as the ASCII representation of its hex value, or use Base64
or something else?

Thoughts, comments?

\x/ill          :-}