[e-lang] TextWriter/__printOn expectations/contract questions
Mark Miller
markm at cs.jhu.edu
Fri Mar 4 19:25:10 EST 2005
Kevin Reid wrote:
> I'm thinking about various extensions to the TextWriter protocol. I'd
> like to hear your opinions on them, and the general issues I mention,
> particularly as to whether they break reasonable security expectations
> of the programmer writing __printOn methods.
Not only are these good questions, they are good examples of the kinds of
issues that differentiate capability discipline from conventional POLA-unaware
software engineering discipline.
I'll offer some quick reactions; but all these issues bear further discussion.
> 1. Outward privacy
>
> What can an object participating in printing expect to not be revealed
> about its components?
>
> When an object provides a __printOn/1 method
>
> def original := [1 => 2].diverge()
>
> def readOnlyMap {
> to __printOn(tw :TextWriter) {
> tw.print(original, ".readOnly()")
> }
> }
>
> it expects the TextWriter guard to guarantee that 'tw' will not reveal
> 'original' to its invoker, nor do anything other than printing it.
>
> But what qualifies as printing? What if, for example, 'tw' produced
> output like this, creating element separators and showing alleged FQNs?
>
> __main$readOnlyMap<org.erights.e.elib.tables.FlexMap<"[",
> org.erights.e.meta.java.math.EInt<"1">, " => ",
> org.erights.e.meta.java.math.EInt<"2">, "]">, ".readOnly()">
I think showing the element separation should not be considered a violation. I
think showing the FQNs, perhaps, should. But I don't feel strongly about the
latter.
> Or, less excessively, what if 'tw' arranged to print cycles more
> informatively, as Common Lisp's printer does? This would reveal some
> information about sameness.
>
> ? def thingy := [def a := [[].diverge(), a], def b := [[].diverge(), b]]
> # value: [[[].diverge(), ***CYCLE***], [[].diverge(), ***CYCLE***]]
>
> ? toQuoteWithCycleTagging(thingy)
> # value: "[def cycle_1 := [[].diverge(), cycle_1], def cycle_2 :=
> [[].diverge(), cycle_2]]"
I think this would not only be fine, but would be a welcome improvement on the
current system.
> 2. Inward privacy
>
> What can an object participating in printing expect to not be revealed
> *to* its components?
>
> For example, suppose there was code in multiple (programming) languages
> operating in the same Vat, and using the same ELib primitive objects.
> TextWriter could be extended to provide access to an object describing
> the syntax of the language.
>
> def readOnlyMap {
> to __printOn(tw :TextWriter) {
> tw.getCodeSyntax().printCall(original, "readOnly", [])
> }
> }
>
> ? NotE:toQuote readOnlyMap
> ; value: "{1 = 2}:readOnly"
>
> This could even replace the specialized subPrintOn interface for ENodes
> - the 'code syntax' object containing the 'priority' information.
If I understand correctly, this is not revealing information about the
container to the contained that the container does not choose to reveal.
Rather, it is allowing information in the TextWriter to be passed through to
the contained. There is a danger here. But so long as the extra information is
limited to data and DeepPassByCopy objects, it would seem we already have this
danger with the TextWriter indent level. We should examine how one might abuse
such a channel.
These issues remind be of the Throwable issue: Prior to the DarpaBrowser
review, I thought that the restriction that one could only throw
DeepPassByCopy data was adequate protection. Perhaps there's the same rude
surprise lurking here?
> Or human languages (though a low-level object like this is not a
> particularly good example):
>
> ? makeSturdyRef
> # value: <makeSturdyRef Off The Air>
>
> ? interp.setLanguage("jbo")
>
> ? makeSturdyRef
> # value <makeSturdyRef noi ca nai tcana>
>
> Both of these would involve passing information (tw.getCodeSyntax(),
> language code, etc) to the objects being printed. However, this allows
> information to be communicated to objects not otherwise accessible, via
> printing other objects that wrap them. (I assume the object called
> tw.getCodeSyntax() would be required to be DeepFrozen, so no authority
> is involved.)
Yes, we should at least insist on that restriction.
> Would allowing such parameterization break any intended properties of
> the __printOn/TextWriter interface?
>
> (The current interface, of course, already reveals some information: the
> time-ordering of __printOn messages vs. other messages.)
The question is hard to answer, since it depends on programmer psychology. The
main "intended property" is that the programmer can write useful __printOn
methods using the standard pattern and the TextWriter guard, and be fairly
confident, without needing to think about it hard, that they haven't thereby
blown the normal object-cap security properties that the rest of their program
may be depending on.
> 3. Extension of output types
>
> What if the kinds of 'primitive' output (currently String, or rather,
> stream-of-Characters) were extended? For example, styled text (or
> markup), or 'printing' an image?
>
> At some point, it becomes more appropriate to provide a custom visitor
> interface, but __printOn has the advantage of being universal, so such
> special 'printing' could pass through preexisting
> collection/container/proxy/slot/... objects.
I don't see a problem with that, but I haven't really thought about it.
Other opinions?
--
Text by me above is hereby placed in the public domain
Cheers,
--MarkM
More information about the e-lang
mailing list