Subject: [vwrap] Parsing of invalid LLSD elements in XML

From: Joshua Bell <[email-masked]>
Date: Wed, 31 Mar 2010 14:53:25 -0700

Mark Lentczner and I were discussing this issue earlier today offline, and I
wanted to recap it to the list.

draft-hamrick-vwrap-type-system-00 does not define what should happen when
trying to parse this LLSD XML fragment (pretend it has the right prologue
and hence is well-formed XML):

<llsd>
    <map>
        <key>test</key>
        <uuid>this is not a uuid</uuid>
    </map>
</llsd>

There are at least three reasonable outcomes:
(1) Reject the payload entirely - the entire message should be rejected
(2) Produces a map; value associated with key "test" is a UUID of
00000000-0000-0000-0000-000000000000 - which would be the result of
converting the string "this is not a uuid" to a UUID
(3) Produces a map; value associated with key "test" is the Undefined value

(The map is, strictly speaking unnecessary, to the example, but it clarifies
the context in which #3 occurs)

This is not confined to UUIDs; similar issues occur with Date and Binary
types in the XML serialization. The JSON serialization appears  "immune" to
this spec ambiguity because primitive types always end up as
Boolean/String/Real/Undefined (in LLSD parlance); conversion to
Integer/UUID/Date/URI/Binary can only occur at the application level. The
Binary serialization appears "immune" to the spec ambiguity as well
(possibly edge cases if a NaN or Infinity was used for a Date?)

Thoughts?

---

From: David W Levine <[email-masked]>
Date: Wed, 31 Mar 2010 18:14:56 -0400

[email-masked] wrote on 03/31/2010 05:53:25 PM:

> [image removed] 
> 
> [vwrap] Parsing of invalid LLSD elements in XML
> 
> Joshua Bell 
> 
> to:
> 
> vwrap
> 
> 03/31/2010 05:53 PM
> 
> Sent by:
> 
> [email-masked]
> 
> Mark Lentczner and I were discussing this issue earlier today 
> offline, and I wanted to recap it to the list.
> 
> draft-hamrick-vwrap-type-system-00 does not define what should 
> happen when trying to parse this LLSD XML fragment (pretend it has 
> the right prologue and hence is well-formed XML):
> 
> <llsd>
>     <map>
>         <key>test</key>
> (The map is, strictly speaking unnecessary, to the example, but it 
> clarifies the context in which #3 occurs)
> 
> This is not confined to UUIDs; similar issues occur with Date and 
> Binary types in the XML serialization. The JSON serialization 
> appears  "immune" to this spec ambiguity because primitive types 
> always end up as Boolean/String/Real/Undefined (in LLSD parlance); 
> conversion to Integer/UUID/Date/URI/Binary can only occur at the 
> application level. The Binary serialization appears "immune" to the 
> spec ambiguity as well (possibly edge cases if a NaN or Infinity was
> used for a Date?)
> 
> Thoughts?
> 

My fairly strong preference is for choice (3). Choice (2) allows an error 
to propagate
in ways which strikes me as highly undesirable. Choice (1) stops the error 
from propagating
but likely at the expense of generating the error detection some distance 
from a good place 
to actually handle the error. The element is invalid, the elements framing 
it (in this example,
the map) is valid, and allows the error to be stated quite explicitly. 

- David
~ Zha

---

From: Meadhbh Hamrick <[email-masked]>
Date: Wed, 31 Mar 2010 15:32:06 -0700

i have a vague memory of us agreeing in the OGP era that if a value
was invalid, you got the default. i believe the justification was the
same as why you get the default if you ask for a map entry that
doesn't exist, to cope with version skew.

it may sound weird that we would want something like that, but consider this...

in rev one of a service, you may have a map with a map entry whose
name is 'foo' and who's string value is "bar". like this:

<llsd>
  <map>
    <key>foo</key>
    <string>bar</string>
  </map>
</llsd>

the "correct" way to access this in JavaScript would be something like:

var interestingMap = LLSD.deserialize( msg )[0];
alert( interestingMap["foo"].asString() );

(other implementations like C++ and python have similar facilities to
render a value in a particular type.) now let's imagine that the next
rev of the interface changes foo to be a UUID:

<llsd>
  <map>
    <key>foo</key>
    <uuid>b42bd48f-7452-40ff-8d70-9d1b31a96cad</uuid>
  </map>
</llsd>

what should the code above do with the new LLSD above? the consensus
in the OGP era was that it SHOULD create an alert box with the string
("b42bd48f-7452-40ff-8d70-9d1b31a96cad") because the default
conversion from a UUID to a string is simply to return the textual
representation of the hex digits representing the 128 bits of the
UUID.

however, the new code:

var interestingMap = LLSD.deserialize( msg )[0];
alert( interestingMap["foo"].asUUID() );

should create an alert box with the default UUID (00000000- ... -0000)
when fed the first LLSD message above because this is the conversion
described in the document when converting non 8-4-4-4-12 strings to
uuids.

again, the justification for this was to reduce the impact of version
skew between loosely coupled services. the thinking is that since a
service that is looking at strings or UUIDs is going to have to figure
out what to do with invalid, parameters (like empty strings or default
UUIDs,) so you might as well let the application layer do it's job.

so, my vote is option 2.
--
meadhbh hamrick * it's pronounced "maeve"
@OhMeadhbh * http://meadhbh.org/ * [email-masked]

On Wed, Mar 31, 2010 at 2:53 PM, Joshua Bell <[email-masked]> wrote:
> _______________________________________________
> vwrap mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/vwrap
>
>

---

From: Meadhbh Hamrick <[email-masked]>
Date: Wed, 31 Mar 2010 15:32:59 -0700

hmm. this case is actually covered in the draft. i'll have to recode
some things if we change it.
--
meadhbh hamrick * it's pronounced "maeve"
@OhMeadhbh * http://meadhbh.org/ * [email-masked]

On Wed, Mar 31, 2010 at 3:14 PM, David W Levine <[email-masked]> wrote:
> My fairly strong preference is for choice (3). Choice (2) allows an error to
> propagate

---

From: Meadhbh Hamrick <[email-masked]>
Date: Wed, 31 Mar 2010 15:54:49 -0700

heck. discord already? that's got to be a record, david. normally we
have to wait at least a couple hours to work up a really good
technical disagreement. ;-)

before i go off about how good it is to reduce the impact of version
skew, let me say i totally get your answer. it reminds me a bit of the
gulf between lovers of dynamic and statically typed languages. one of
the criticisms i hear over and over again about javascript and python
is that it's very easy for programmers to mistakenly mistype a member
name and for it to be vaguely difficult to find the error. static
typing fans frequently say dynamic languages allow errors in code to
propagate and make it hard to pin down the cause of the error. dynamic
language fans reply with long and drawn out descriptions for why the
fragile base class problem is evil. and so it goes back and forth
until functional language fans go off and make type inferring
languages with the intent of making the C++ and python fans heads'
explode.

this is the point in a typical rant where the author predicts dire
consequences if the group chooses incorrectly. so include your
favorite prediction of dire consequences here.

seriously though. i think this is the type of thing we need to think
about a little bit more. david, you want to find some time to work
through some examples next week?

---

From: John Hurliman <[email-masked]>
Date: Wed, 31 Mar 2010 23:23:33 -0700

How are (2) and (3) different in practice? My understanding is that
the undefined value has conversions to string, uuid, date, etc and
will convert as the default value for each type.

I think (2) is the current behavior of OpenMetaverse.StructuredData
but it can be changed in the future.

John