[Pyxmlsec-devel] [Bug] addIDs(doc, cur, [...]): argument 3 must be an instance

Dieter Maurer dieter at handshake.de
Fri Nov 12 10:15:56 CET 2010


"addIDs" broken, probably from Python 2.3 on, maybe through all versions.

PyXMLSec version:   0.3.0
Python version:	    2.4.x
other versions irrelevant (as the bug depends only on Python and PyXMLSec).

Bug reproducing script:

doc = '''
<doc ID="id">
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <Reference URI="#id">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue />
      </Reference>
    </SignedInfo>
    <SignatureValue />
  </Signature>
</doc>
'''
import libxml2
import xmlsec

libxml2.initParser()
libxml2.substituteEntitiesDefault(1)

xmlsec.init() # 0
xmlsec.checkVersion() # 1
xmlsec.cryptoAppInit(None) # 0
xmlsec.cryptoInit() # 0

doc_tree = libxml2.parseMemory(doc, len(doc))
xmlsec.addIDs(doc_tree, doc_tree.getRootElement(), ['ID'])


Supposed problem:

  "xmlsecmod" uses its own argument parsing via the function
  "CheckArgs". "CheckArgs" checks "O" type arguments with
  "PyInstance_Check" and (understandably) at least Python 2.4
  does not see a list object as an instance.

Unfortunately, wrapping the list argument into a "UserList" instance
would not be a workaround as the argument is passed on
to "PythonStringList_get" which requires a true Python list.


Patch:
--- utils.c~	2005-12-13 16:53:29.000000000 +0100
+++ utils.c	2010-11-12 10:09:38.000000000 +0100
@@ -38,6 +38,7 @@
   /* S : String   */
   /* I : Integer  */
   /* F : File     */
+  /* L : List     */
   for (i = 0; i < nb_args; i++) {
     obj = PyTuple_GET_ITEM(args, i);
     /* O or o : instance */
@@ -90,6 +91,16 @@
 	return 0;
       }
     }
+    /* L or l : list */
+    else if (format[i] == 'L' || format[i] == 'l') {
+      if (!PyList_Check(obj)) {
+	if (format[i] == 'l' && obj == Py_None) continue;
+	PyErr_Format(xmlsec_error,
+		     "%s() argument %d must be a list.",
+		     format + nb_args, i+1);
+	return 0;
+      }
+    }
     /* type is variable */
     else if (format[i] == '?') {
       continue;
--- xmltree.c~	2005-12-13 16:53:29.000000000 +0100
+++ xmltree.c	2010-11-12 10:13:10.000000000 +0100
@@ -271,7 +271,7 @@
   xmlNodePtr cur;
   xmlChar **ids = NULL;

-  if (CheckArgs(args, "OOO:addIDs")) {
+  if (CheckArgs(args, "OOL:addIDs")) {
     if (!PyArg_ParseTuple(args, (char *) "OOO:addIDs",
 			  &doc_obj, &cur_obj, &ids_obj))
       return NULL;





--
Dieter


More information about the Pyxmlsec-devel mailing list