Explicit Serialization API and Security
Peter Firmstone
peter.firmstone at zeus.net.au
Mon Jan 5 12:01:51 UTC 2015
My mistake, thank you.
Peter.
On 5/01/2015 9:57 PM, David Holmes wrote:
> Hi Peter,
>
> Did you send this to the list? I haven't seen it turn up yet.
>
> David
>
> On 5/01/2015 6:51 PM, Peter Firmstone wrote:
>> Thanks Dave,
>>
>> That's another way of checking invariants, you could expose A's check
>> method but you'd also need a couple of additional static methods to
>> obtain integers upper and lower from ReadSerial, so that B can ensure
>> its invariant.
>>
>> ReadSerial is caller sensitive so B can't obtain A's stream values via
>> ReadSerial and must do so via A's API. This prevents the publication of
>> A's implementation, you don't wan't B depending on A's serial form.
>> Instead A can reorder and rename it's fields and change their values,
>> have multiple serial forms and be able to remain compatible with all
>> forms relatively easily.
>>
>> There are some benefits to using a temporary object instance of A; it
>> reduces the amount of code required, eg it would be a beneficial for RMI
>> to minimise code downloads, the JVM is free to inline access to these
>> fields and the temporary instance of A never leaves the cpu cache, so
>> it's not likely to become a performance issue. Well it might on real
>> time java :)
>>
>> If circular relationships are mutable, or effectively mutable after
>> publication, then we could eventually deprecate the requirement to
>> support special treatment of final fields for Serializable.
>>
>> Cheers,
>>
>> Peter.
>>
>> On 5/01/2015 10:38 AM, David Holmes wrote:
>>>
>>>>> - I don't see how this invariant-checking mechanism can enforce
>>>>> invariants between superclass fields and subclass fields. For
>>>>> example:
>>>>>
>>>>> class A {
>>>>> int lower, upper; // invariant: lower <= upper
>>>>> }
>>>>>
>>>>> class B extends A {
>>>>> int cur; // invariant: lower <= cur <= upper
>>>>> }
>>>>>
>>>>
>>>> The serialization framework should only construct an objects fields
>>>> and make these available from ReadSerial, each class then calls a
>>>> static method before calling a superclass constructor that's
>>>> responsible for an objects creation, to prevent construction of the
>>>> object, if necessary.
>>>>
>>>> Eg, some complexity, but bullet proof:
>>>>
>>>> public class A (
>>>>
>>>> public final int lower, upper;
>>>>
>>>> private static boolean check(ReadSerial rs){
>>>> if (rs.getInt("lower") > rs.getInt("upper"))
>>>> throw new IllegalArgumentException(
>>>> "lower bound must be less than or equal to upper");
>>>> return true;
>>>> }
>>>>
>>>> public A(ReadSerial rs){
>>>> this(check(rs), rs);
>>>> }
>>>>
>>>> private A(boolean checked, ReadSerial rs){
>>>> super();
>>>> lower = rs.getInt("lower");
>>>> upper = rs.getInt("upper");
>>>> }
>>>>
>>>> // other constructors omitted must also check invarients
>>>> }
>>>>
>>>> class B extends A {
>>>>
>>>> public final int cur;
>>>>
>>>> private static ReadSerial check(ReadSerial rs) {
>>>> A a = new A(rs);
>>>
>>>
>>> It doesn't seem practical in general to have to create an instance of
>>> your supertype to validate the passed in serialized form. Why not
>>> expose the check method?
>>>
>>> David
>>> -----
>>>
>>>> int cur = rs.getInt("cur");
>>>> if ( a.lower > cur || cur > a.upper )
>>>> throw new IllegalArgumentException(
>>>> "cur outside lower and upper bounds");
>>>> return rs;
>>>> }
>>>>
>>>> public B(ReadSerial rs) {
>>>> super(check(rs));
>>>> cur = rs.getInt("cur");
>>>> }
>>>> }
>>>>
>>>>
>>
More information about the core-libs-dev
mailing list