JSON decoding

Bob Ippolito bob at redivi.com
Tue Oct 24 20:56:13 PDT 2006


On 10/24/06, Brendan Eich <brendan at mozilla.com> wrote:
> On Oct 24, 2006, at 10:57 PM, Bob Ippolito wrote:
>
> > toJSONString is the wrong level of abstraction. The return value
> > should NOT be a string that inserts arbitrary text into the encoding
> > stream. Injecting arbitrary text into the stream is an absolute
> > guarantee that (most) people will do it incorrectly and produce
> > invalid documents. Worst case they will use it to intermittently
> > produce invalid documents. Maybe there's even something
>
> Last sentence was cut off.

Maybe there's even something like SQL injection attacks that will
happen with toJSONString.

> I thought you might mean that, but I don't see how to do it.  We
> can't declare a type for "the set of all valid JSON values".  If we
> take an object of some type, we want to rule out cycles, Date objects
> that don't have toJSON or whatever methods, etc.  How does simplejson
> do this?

How would you rule out cycles with toJSONString? Do it exactly the same way.

simplejson (by default) does cycle detection by maintaining a set of
objects it has seen. If it sees the same one twice, then it bails (of
course the built-in immutable types are not included here). It's not a
perfect strategy, because it really should be done with respect to the
stack, but for all practical purposes it's fine. If people need to
encode a weird object graph they can turn cycle detection off.

toJSONString will actually ensure undetectable cycles if people call
it recursively, which they will... because if they don't call it
recursively, then they can't be sure they're generating a valid
document.

> > The return value should be any JSON-encodable object that gets
> > properly encoded into the string (called "toJSON" perhaps). If this
> > approach is taken then it will be *impossible* to produce invalid
> > documents, much like it's impossible to produce an invalid XML
> > document by serializing a DOM tree.
>
> That's circular in that a DOM implementation will build only well-
> formed DOM trees.  To express the type "valid JSON value" we would
> need recursive structural types, and that still wouldn't catch
> cycles.  We can't force this type into the nominal part of the type
> system.

Once you find a valid that isn't valid in JSON, you throw an error and
that's that. I don't see how it's circular. If you pass the wrong kind
of object to the XML serializer you'll get an error too.

> Anyway, if we are missing something in simplejson, please show us the
> way.  Thanks,

The equivalent encoder with simplejson would be this:

class JSONMethodEncoder(simplejson.JSONEncoder):
    def default(self, obj):
        if callable(getattr(obj, 'toJSON', None)):
            return obj.toJSON()
        return simplejson.JSONEncoder.default(self)

-bob



More information about the Es4-discuss mailing list