[e-lang] JSONSerializer review, further study of reviewable coding techniques

Tyler Close tyler.close at gmail.com
Tue Aug 19 16:33:59 CDT 2008


On Tue, Aug 19, 2008 at 11:50 AM, Tyler Close <tyler.close at gmail.com> wrote:
> Given that the Exporter needs to be able to save the value argument
> for later use, it seems really hard to code the implementation such
> that we know the Exporter doesn't survive the call to
> JSONSerializer.write(). So far, the best I've got is:
>
> final Map<?> exported = ...
> final ConstArray<?> values = ...
> final Milestone done = new Milestone();
> final Exporter export = new Exporter() {
>   public String
>   run(final Object value) {
>        if (done.is()) { throw new AssertionError(); }
>
>        if (value == this) {
>            evil[0] = value;
>        } else if (value instanceof Victim) {
>             ((Victim)value).kill();
>        }
>        final String r = generateURL();
>        exported.add(r, value);
>        return r;
>   }
> };
> final String text = JSONSerializer.write(export, values);
> done.mark();
>
> That's pretty awkward to write and verify. Can anyone do any better?

Well, I suppose this problem can be solved without providing an
additional mechanism to peel off an @inert annotation. The API could
be:

class Serialization {
    public final String text;
    public final ConstArray<String> urls;
    public final ConstArray<Object> exported;

    public
    Serialization(final String text,
                       final ConstArray<String> urls,
                       @inert final ConstArray<Object> exported) {
        this.text = text;
        this.urls = urls;
        this.exported = exported;
    }
}

static public Serialization
write(Exporter export, @inert ConstArray<?> values);

So the calling code looks like:

final Map<?> exported = ..
final ConstArray<?> values = ..
final Serialization stuff = JSONSerializer.write(new Exporter() {
     public String
     run(@inert final Object value) {
         // calculate a URL and return it, but don't store anything yet.
         return generateURL(value);
     }
}, values);
for (int i = stuff.urls.length(); 0 != i--;) {
    exported.add(stuff.urls.get(i), stuff.exported.get(i));
}
return stuff.text;

In this implementation, the JSONSerializer remembers the exported
objects and URLs and gives them back to the caller in the return
value. Essentially, this pattern never reifies the authority to drop
an @inert tag, so no one can hold onto it and use it in unexpected
ways. No escape analysis needed for something that's not reified.

So I think the Joe-E verifier rules listed at the top of the previous
message are sufficient to implement the @inert annotation, and this
new auditor is sufficient to verify the security claims of both the
JSONSerializer and several spots in the ref_send library.

--Tyler


More information about the e-lang mailing list