Sorry to harp on this :-) But the more I work with the XML-RPC interface from non-python code the more I think we've got a problem.

The first problem is what was discussed in the team meeting. You don't know what a function is going to return and nothing enforces the consistency of return values. Jason has done an awesome job of enforcing the consistency of input arguments, but that's only half the battle. What gets returned is purely a function of what the plugin author happens to stuff into the plugin's return statement. There is no enforcement of how many values get returned, what their types are, what is optional, what is mandatory, etc. In other words everything which is enforced on the input side of the call is absent on the output side, it should be obvious why this is a problem, especially for any callers of XML-RPC which are *not* in the python plugin framework.

The second problem I've run into with return values is especially pernicious because the plugin framework is hiding a very fundamental and apparently common error. Here is the issue:

* We've adopted the convention that *all* strings will be unicode objects.

* str objects will be treated as binary data

* Python will in many instances freely convert between str objects and unicode objects.

* If a plugin wants to return a string it *must* return a unicode object. If the plugin mistakenly returns a str object (a very very easy mistake to make) then what gets returned through XML-RPC is a *binary* base64 encoded blob, not an XML-RPC *string* value!

The above is so critical let me repeat it: FAILING TO ASSURE A RETURNED STRING IS UNICODE AND NOT STR RESULTS IN BINARY BLOBS ON THE RECEIVING END INSTEAD OF A STRING.

* However, the python framework *hides* the error on the return side because it decodes the base64 binary value back into a str object. Because str objects and unicode objects are often interchangeable the python code receiving the return value thinks it sees the right result even though it's not.

If we're going to have other clients of the XML-RPC interface then that client *must* know what the return values are and what their type is. It can't (or shouldn't) do things like:

* I was expecting a string but I got a binary blob so that must have been a mistake so I'll treat the binary blob as a string and hope it's correct.

-or-

* I was expecting an integer but I actually got a string (yes there are plugins which do this), so I'll try to read an integer value out of the string. But wait, suppose the plugin author who returned the integer as a string forget to assure that the string representing the integer was a unicode object and not a str object, then the receiver really has to start guessing because he's gotten back a binary blob. Is that binary blob a 2's compliment representation of a signed integer, is it unsigned integer, or is the binary blob a string representation of the integer? Clearly this doesn't work.

Now let's suppose another common scenario. The plugin author discovers he has mistakenly returned a str object when it should have been a unicode object and corrects his mistake, seemingly innocent because everything continues to work (but only in python). We have a non-python client of the XML-RPC interface who has corrected for the mistake by expecting binary data for the string, now that client fails! Or let's say the plugin was correctly returning a unicode object but some seemingly innocent change is made and the value ends up being a str object instead. Once again the python code continues to work correctly but the non-python code fails.

So how easy it for Python programmers to make the mistake between str and unicode? *VERY VERY EASY!* In fact it's so easy even Jason's documentation and examples sometimes make the mistake. It's especially easy mistake to make when calling another function because the vast majority of existing Python libraries return str objects for strings.

If we don't validate the return values from the plugin's I don't see how we'll ever have non-python XML-RPC clients which are robust.

I'm happy to work with Jason to get the return validation implemented. I now know the insides of the plugin rpc mechanism in gory detail :-)

I don't think we should postpone this, I think there are all sorts of errors lurking in the code, or will get introduced in the code in the future. For robustness sake it's better to fix this sooner rather than later IMHO.

Of course the other option is to do away with the rule that str objects will get converted into binary blobs in XML-RPC. I think there is a good argument for treating both str objects and unicode objects as strings in XML-RPC. How often do we really need to pass binary data back in XLM-RPC? I'm thinking it's not very often. For those limited cases wouldn't it be better to require the plugin to return a Binary object instead of a str?. This has the advantage that's it's explicit and removes the dangerous practice of automatic conversion of conventional python strings into binary blobs when 99% of the time that's not the intention of the programmer.

BTW, removing the automatic conversion of str to binary is a simple one line change which would have a huge impact on robustness without any loss of functionality. However that still does not address the issue of return value validation, but it does remove the single most common error we have with return values at the moment.

--
John Dennis <jden...@redhat.com>

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to