LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/xmlsec/src - xpath.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 404 0.0 %
Date: 2012-12-17 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /** 
       2             :  * XML Security Library (http://www.aleksey.com/xmlsec).
       3             :  *
       4             :  * XPath transform
       5             :  *
       6             :  * This is free software; see Copyright file in the source
       7             :  * distribution for preciese wording.
       8             :  * 
       9             :  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
      10             :  */
      11             : #include "globals.h"
      12             : 
      13             : #include <stdlib.h>
      14             : #include <string.h>
      15             : 
      16             : #include <libxml/tree.h>
      17             : #include <libxml/xpath.h>
      18             : #include <libxml/xpathInternals.h>
      19             : #include <libxml/xpointer.h>
      20             : 
      21             : #include <xmlsec/xmlsec.h>
      22             : #include <xmlsec/xmltree.h>
      23             : #include <xmlsec/keys.h>
      24             : #include <xmlsec/list.h>
      25             : #include <xmlsec/transforms.h>
      26             : #include <xmlsec/errors.h>
      27             : 
      28             : 
      29             : /**************************************************************************
      30             :  *
      31             :  * xmlSecXPathHereFunction:
      32             :  * @ctxt:               the ponter to XPath context.
      33             :  * @nargs:              the arguments nubmer.
      34             :  *
      35             :  * The implementation of XPath "here()" function.
      36             :  * See xmlXPtrHereFunction() in xpointer.c. the only change is that 
      37             :  * we return NodeSet instead of NodeInterval.
      38             :  *
      39             :  *****************************************************************************/
      40             : static void 
      41           0 : xmlSecXPathHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
      42           0 :     CHECK_ARITY(0);
      43             : 
      44           0 :     if((ctxt == NULL) || (ctxt->context == NULL) || (ctxt->context->here == NULL)) {
      45           0 :         XP_ERROR(XPTR_SYNTAX_ERROR);
      46             :     }
      47           0 :     valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->here));
      48             : }
      49             : 
      50             : /**************************************************************************
      51             :  *
      52             :  * XPath/XPointer data
      53             :  *
      54             :  *****************************************************************************/
      55             : typedef struct _xmlSecXPathData                 xmlSecXPathData,
      56             :                                                 *xmlSecXPathDataPtr;
      57             : typedef enum {
      58             :     xmlSecXPathDataTypeXPath,
      59             :     xmlSecXPathDataTypeXPath2,
      60             :     xmlSecXPathDataTypeXPointer
      61             : } xmlSecXPathDataType;
      62             : 
      63             : struct _xmlSecXPathData {
      64             :     xmlSecXPathDataType                 type;
      65             :     xmlXPathContextPtr                  ctx;
      66             :     xmlChar*                            expr;
      67             :     xmlSecNodeSetOp                     nodeSetOp;
      68             :     xmlSecNodeSetType                   nodeSetType;    
      69             : };
      70             : 
      71             : static xmlSecXPathDataPtr       xmlSecXPathDataCreate           (xmlSecXPathDataType type);
      72             : static void                     xmlSecXPathDataDestroy          (xmlSecXPathDataPtr data);
      73             : static int                      xmlSecXPathDataSetExpr          (xmlSecXPathDataPtr data,
      74             :                                                                  const xmlChar* expr);
      75             : static int                      xmlSecXPathDataRegisterNamespaces(xmlSecXPathDataPtr data, 
      76             :                                                                  xmlNodePtr node);
      77             : static int                      xmlSecXPathDataNodeRead         (xmlSecXPathDataPtr data,
      78             :                                                                  xmlNodePtr node);
      79             : static xmlSecNodeSetPtr         xmlSecXPathDataExecute          (xmlSecXPathDataPtr data,
      80             :                                                                  xmlDocPtr doc,
      81             :                                                                  xmlNodePtr hereNode);
      82             : 
      83             : static xmlSecXPathDataPtr  
      84           0 : xmlSecXPathDataCreate(xmlSecXPathDataType type) {
      85             :     xmlSecXPathDataPtr data;
      86             : 
      87           0 :     data = (xmlSecXPathDataPtr) xmlMalloc(sizeof(xmlSecXPathData));
      88           0 :     if(data == NULL) {
      89           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
      90             :                     NULL,
      91             :                     NULL,
      92             :                     XMLSEC_ERRORS_R_MALLOC_FAILED,
      93             :                     "sizeof(xmlSecXPathData)=%d",
      94             :                     sizeof(xmlSecXPathData));
      95           0 :         return(NULL);
      96             :     }
      97           0 :     memset(data, 0, sizeof(xmlSecXPathData)); 
      98             : 
      99           0 :     data->type = type;
     100           0 :     data->nodeSetType = xmlSecNodeSetTree;
     101             : 
     102             :     /* create xpath or xpointer context */
     103           0 :     switch(data->type) {
     104             :     case xmlSecXPathDataTypeXPath:    
     105             :     case xmlSecXPathDataTypeXPath2:    
     106           0 :         data->ctx = xmlXPathNewContext(NULL); /* we'll set doc in the context later */
     107           0 :         if(data->ctx == NULL) {
     108           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     109             :                         NULL,
     110             :                         "xmlXPathNewContext",
     111             :                         XMLSEC_ERRORS_R_XML_FAILED,
     112             :                         XMLSEC_ERRORS_NO_MESSAGE);
     113           0 :             xmlSecXPathDataDestroy(data);
     114           0 :             return(NULL);
     115             :         }
     116           0 :         break;
     117             :     case xmlSecXPathDataTypeXPointer:    
     118           0 :         data->ctx = xmlXPtrNewContext(NULL, NULL, NULL); /* we'll set doc in the context later */
     119           0 :         if(data->ctx == NULL) {
     120           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     121             :                         NULL,
     122             :                         "xmlXPtrNewContext",
     123             :                         XMLSEC_ERRORS_R_XML_FAILED,
     124             :                         XMLSEC_ERRORS_NO_MESSAGE);
     125           0 :             xmlSecXPathDataDestroy(data);
     126           0 :             return(NULL);
     127             :         }
     128           0 :         break;
     129             :     }
     130             : 
     131           0 :     return(data);
     132             : }
     133             : 
     134             : static void                             
     135           0 : xmlSecXPathDataDestroy(xmlSecXPathDataPtr data) {
     136           0 :     xmlSecAssert(data != NULL);    
     137             : 
     138           0 :     if(data->expr != NULL) {
     139           0 :         xmlFree(data->expr);
     140             :     }
     141           0 :     if(data->ctx != NULL) {
     142           0 :         xmlXPathFreeContext(data->ctx);
     143             :     }
     144           0 :     memset(data, 0, sizeof(xmlSecXPathData));  
     145           0 :     xmlFree(data);
     146             : }
     147             : 
     148             : static int 
     149           0 : xmlSecXPathDataSetExpr(xmlSecXPathDataPtr data, const xmlChar* expr) {
     150           0 :     xmlSecAssert2(data != NULL, -1);    
     151           0 :     xmlSecAssert2(data->expr == NULL, -1);
     152           0 :     xmlSecAssert2(data->ctx != NULL, -1);
     153           0 :     xmlSecAssert2(expr != NULL, -1);    
     154             :             
     155           0 :     data->expr = xmlStrdup(expr);
     156           0 :     if(data->expr == NULL) {
     157           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     158             :                     NULL,
     159             :                     NULL,
     160             :                     XMLSEC_ERRORS_R_STRDUP_FAILED,
     161             :                     XMLSEC_ERRORS_NO_MESSAGE);
     162           0 :         return(-1);
     163             :     }
     164           0 :     return(0);
     165             : }
     166             : 
     167             : 
     168             : static int 
     169           0 : xmlSecXPathDataRegisterNamespaces(xmlSecXPathDataPtr data, xmlNodePtr node) {
     170             :     xmlNodePtr cur;
     171             :     xmlNsPtr ns;
     172             :     int ret;
     173             :     
     174           0 :     xmlSecAssert2(data != NULL, -1);    
     175           0 :     xmlSecAssert2(data->ctx != NULL, -1);
     176           0 :     xmlSecAssert2(node != NULL, -1);
     177             : 
     178             :     /* register namespaces */
     179           0 :     for(cur = node; cur != NULL; cur = cur->parent) {
     180           0 :         for(ns = cur->nsDef; ns != NULL; ns = ns->next) {
     181             :             /* check that we have no other namespace with same prefix already */
     182           0 :             if((ns->prefix != NULL) && (xmlXPathNsLookup(data->ctx, ns->prefix) == NULL)){
     183           0 :                 ret = xmlXPathRegisterNs(data->ctx, ns->prefix, ns->href);
     184           0 :                 if(ret != 0) {
     185           0 :                     xmlSecError(XMLSEC_ERRORS_HERE,
     186             :                                 NULL,
     187             :                                 "xmlXPathRegisterNs",
     188             :                                 XMLSEC_ERRORS_R_XML_FAILED,
     189             :                                 "href=%s;prefix=%s",
     190           0 :                                 xmlSecErrorsSafeString(ns->href),
     191           0 :                                 xmlSecErrorsSafeString(ns->prefix)); 
     192           0 :                     return(-1);
     193             :                 }
     194             :             }
     195             :         }
     196             :     }
     197             :     
     198           0 :     return(0);
     199             : }
     200             : 
     201             : static int 
     202           0 : xmlSecXPathDataNodeRead(xmlSecXPathDataPtr data, xmlNodePtr node) {
     203             :     int ret;
     204             :     
     205           0 :     xmlSecAssert2(data != NULL, -1);    
     206           0 :     xmlSecAssert2(data->expr == NULL, -1);
     207           0 :     xmlSecAssert2(data->ctx != NULL, -1);
     208           0 :     xmlSecAssert2(node != NULL, -1);
     209             : 
     210           0 :     ret = xmlSecXPathDataRegisterNamespaces (data, node);
     211           0 :     if(ret < 0) {
     212           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     213             :                     NULL,
     214             :                     "xmlSecXPathDataRegisterNamespaces",
     215             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     216             :                     XMLSEC_ERRORS_NO_MESSAGE);
     217           0 :         return(-1);
     218             :     }
     219             :     
     220             :     /* read node content and set expr */
     221           0 :     data->expr = xmlNodeGetContent(node);
     222           0 :     if(data->expr == NULL) {
     223           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     224             :                     NULL,
     225           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
     226             :                     XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
     227             :                     XMLSEC_ERRORS_NO_MESSAGE);
     228           0 :         return(-1);
     229             :     }
     230             :     
     231           0 :     return(0);
     232             : }
     233             : 
     234             : static xmlSecNodeSetPtr
     235           0 : xmlSecXPathDataExecute(xmlSecXPathDataPtr data, xmlDocPtr doc, xmlNodePtr hereNode) {
     236           0 :     xmlXPathObjectPtr xpathObj = NULL; 
     237             :     xmlSecNodeSetPtr nodes;
     238             : 
     239           0 :     xmlSecAssert2(data != NULL, NULL);    
     240           0 :     xmlSecAssert2(data->expr != NULL, NULL);
     241           0 :     xmlSecAssert2(data->ctx != NULL, NULL);
     242           0 :     xmlSecAssert2(doc != NULL, NULL);
     243           0 :     xmlSecAssert2(hereNode != NULL, NULL);
     244             : 
     245             :     /* do not forget to set the doc */
     246           0 :     data->ctx->doc = doc;
     247             :     
     248             :     /* here function works only on the same document */
     249           0 :     if(hereNode->doc == doc) {
     250           0 :         xmlXPathRegisterFunc(data->ctx, (xmlChar *)"here", xmlSecXPathHereFunction);
     251           0 :         data->ctx->here = hereNode;
     252           0 :         data->ctx->xptr = 1;
     253             :     }
     254             : 
     255             :     /* execute xpath or xpointer expression */
     256           0 :     switch(data->type) {
     257             :     case xmlSecXPathDataTypeXPath:    
     258             :     case xmlSecXPathDataTypeXPath2:    
     259           0 :         xpathObj = xmlXPathEvalExpression(data->expr, data->ctx);
     260           0 :         if(xpathObj == NULL) {
     261           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     262             :                         NULL,
     263             :                         "xmlXPathEvalExpression",
     264             :                         XMLSEC_ERRORS_R_XML_FAILED,
     265             :                         "expr=%s", 
     266           0 :                         xmlSecErrorsSafeString(data->expr));
     267           0 :             return(NULL);
     268             :         }
     269           0 :         break;
     270             :     case xmlSecXPathDataTypeXPointer:    
     271           0 :         xpathObj = xmlXPtrEval(data->expr, data->ctx);
     272           0 :         if(xpathObj == NULL) {
     273           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     274             :                         NULL,
     275             :                         "xmlXPtrEval",
     276             :                         XMLSEC_ERRORS_R_XML_FAILED,
     277             :                         "expr=%s", 
     278           0 :                         xmlSecErrorsSafeString(data->expr));
     279           0 :             return(NULL);
     280             :         }
     281           0 :         break;
     282             :     }
     283             :     
     284           0 :     nodes = xmlSecNodeSetCreate(doc, xpathObj->nodesetval, data->nodeSetType);
     285           0 :     if(nodes == NULL) {
     286           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     287             :                     NULL,
     288             :                     "xmlSecNodeSetCreate",
     289             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     290           0 :                     "type=%d", data->nodeSetType);
     291           0 :         xmlXPathFreeObject(xpathObj);     
     292           0 :         return(NULL);
     293             :     }
     294           0 :     xpathObj->nodesetval = NULL;
     295           0 :     xmlXPathFreeObject(xpathObj); 
     296             :     
     297           0 :     return(nodes);
     298             : }
     299             : 
     300             : 
     301             : /**************************************************************************
     302             :  *
     303             :  * XPath data list
     304             :  *
     305             :  *****************************************************************************/
     306             : #define xmlSecXPathDataListId   \
     307             :         xmlSecXPathDataListGetKlass()
     308             : static xmlSecPtrListId  xmlSecXPathDataListGetKlass             (void);
     309             : static xmlSecNodeSetPtr xmlSecXPathDataListExecute              (xmlSecPtrListPtr dataList,
     310             :                                                                  xmlDocPtr doc,
     311             :                                                                  xmlNodePtr hereNode,
     312             :                                                                  xmlSecNodeSetPtr nodes);
     313             : 
     314             : static xmlSecPtrListKlass xmlSecXPathDataListKlass = {
     315             :     BAD_CAST "xpath-data-list",
     316             :     NULL,                                               /* xmlSecPtrDuplicateItemMethod duplicateItem; */
     317             :     (xmlSecPtrDestroyItemMethod)xmlSecXPathDataDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
     318             :     NULL,                                               /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
     319             :     NULL,                                               /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
     320             : };
     321             : 
     322             : static xmlSecPtrListId 
     323           0 : xmlSecXPathDataListGetKlass(void) {
     324           0 :     return(&xmlSecXPathDataListKlass);
     325             : }
     326             : 
     327             : static xmlSecNodeSetPtr 
     328           0 : xmlSecXPathDataListExecute(xmlSecPtrListPtr dataList, xmlDocPtr doc, 
     329             :                            xmlNodePtr hereNode, xmlSecNodeSetPtr nodes) {
     330             :     xmlSecXPathDataPtr data;
     331             :     xmlSecNodeSetPtr res, tmp, tmp2;
     332             :     xmlSecSize pos;
     333             :     
     334           0 :     xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), NULL);
     335           0 :     xmlSecAssert2(xmlSecPtrListGetSize(dataList) > 0, NULL);
     336           0 :     xmlSecAssert2(doc != NULL, NULL);
     337           0 :     xmlSecAssert2(hereNode != NULL, NULL);
     338             : 
     339           0 :     res = nodes;
     340           0 :     for(pos = 0; pos < xmlSecPtrListGetSize(dataList); ++pos) {
     341           0 :         data = (xmlSecXPathDataPtr)xmlSecPtrListGetItem(dataList, pos);
     342           0 :         if(data == NULL) {
     343           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     344             :                         NULL,
     345             :                         "xmlSecPtrListGetItem",
     346             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     347             :                         "pos=%d", pos);
     348           0 :             if((res != NULL) && (res != nodes)) {
     349           0 :                 xmlSecNodeSetDestroy(res);
     350             :             }
     351           0 :             return(NULL);
     352             :         }
     353             : 
     354           0 :         tmp = xmlSecXPathDataExecute(data, doc, hereNode);
     355           0 :         if(tmp == NULL) {
     356           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     357             :                         NULL,
     358             :                         "xmlSecXPathDataExecute",
     359             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     360             :                         XMLSEC_ERRORS_NO_MESSAGE);
     361           0 :             if((res != NULL) && (res != nodes)) {
     362           0 :                 xmlSecNodeSetDestroy(res);
     363             :             }
     364           0 :             return(NULL);
     365             :         }    
     366             : 
     367           0 :         tmp2 = xmlSecNodeSetAdd(res, tmp, data->nodeSetOp);
     368           0 :         if(tmp2 == NULL) {
     369           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     370             :                         NULL,
     371             :                         "xmlSecNodeSetAdd",
     372             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     373             :                         "xmlSecNodeSetIntersection");
     374           0 :             if((res != NULL) && (res != nodes)) {
     375           0 :                 xmlSecNodeSetDestroy(res);
     376             :             }
     377           0 :             xmlSecNodeSetDestroy(tmp);
     378           0 :             return(NULL);
     379             :         }
     380           0 :         res = tmp2;
     381             :     }
     382             : 
     383           0 :     return(res);
     384             : }
     385             : 
     386             : /******************************************************************************
     387             :  *
     388             :  * XPath/XPointer transforms
     389             :  *
     390             :  * xmlSecXPathDataList is located after xmlSecTransform structure
     391             :  * 
     392             :  *****************************************************************************/
     393             : #define xmlSecXPathTransformSize        \
     394             :     (sizeof(xmlSecTransform) + sizeof(xmlSecPtrList))
     395             : #define xmlSecXPathTransformGetDataList(transform) \
     396             :     ((xmlSecTransformCheckSize((transform), xmlSecXPathTransformSize)) ? \
     397             :         (xmlSecPtrListPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)) : \
     398             :         (xmlSecPtrListPtr)NULL)
     399             : #define xmlSecTransformXPathCheckId(transform) \
     400             :     (xmlSecTransformCheckId((transform), xmlSecTransformXPathId) || \
     401             :      xmlSecTransformCheckId((transform), xmlSecTransformXPath2Id) || \
     402             :      xmlSecTransformCheckId((transform), xmlSecTransformXPointerId))
     403             : 
     404             : static int              xmlSecTransformXPathInitialize  (xmlSecTransformPtr transform);
     405             : static void             xmlSecTransformXPathFinalize    (xmlSecTransformPtr transform);
     406             : static int              xmlSecTransformXPathExecute     (xmlSecTransformPtr transform,
     407             :                                                          int last, 
     408             :                                                          xmlSecTransformCtxPtr transformCtx);
     409             : 
     410             : static int
     411           0 : xmlSecTransformXPathInitialize(xmlSecTransformPtr transform) {  
     412             :     xmlSecPtrListPtr dataList;
     413             :     int ret;
     414             :         
     415           0 :     xmlSecAssert2(xmlSecTransformXPathCheckId(transform), -1);
     416             : 
     417           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     418           0 :     xmlSecAssert2(dataList != NULL, -1);
     419             :     
     420           0 :     ret = xmlSecPtrListInitialize(dataList, xmlSecXPathDataListId);
     421           0 :     if(ret < 0) {
     422           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     423           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     424             :                     "xmlSecPtrListInitialize",
     425             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     426             :                     XMLSEC_ERRORS_NO_MESSAGE);
     427           0 :         return(-1);
     428             :     }
     429           0 :     return(0);
     430             : }
     431             : 
     432             : static void
     433           0 : xmlSecTransformXPathFinalize(xmlSecTransformPtr transform) {
     434             :     xmlSecPtrListPtr dataList;
     435             : 
     436           0 :     xmlSecAssert(xmlSecTransformXPathCheckId(transform));
     437             : 
     438           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     439           0 :     xmlSecAssert(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId));
     440             :     
     441           0 :     xmlSecPtrListFinalize(dataList);
     442             : }
     443             : 
     444             : static int
     445           0 : xmlSecTransformXPathExecute(xmlSecTransformPtr transform, int last,
     446             :                             xmlSecTransformCtxPtr transformCtx) {
     447             :     xmlSecPtrListPtr dataList;
     448             :     xmlDocPtr doc;
     449             :     
     450           0 :     xmlSecAssert2(xmlSecTransformXPathCheckId(transform), -1);
     451           0 :     xmlSecAssert2(transform->hereNode != NULL, -1);
     452           0 :     xmlSecAssert2(transform->outNodes == NULL, -1);
     453           0 :     xmlSecAssert2(last != 0, -1);
     454           0 :     xmlSecAssert2(transformCtx != NULL, -1);
     455             : 
     456           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     457           0 :     xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
     458           0 :     xmlSecAssert2(xmlSecPtrListGetSize(dataList) > 0, -1);
     459             : 
     460           0 :     doc = (transform->inNodes != NULL) ? transform->inNodes->doc : transform->hereNode->doc;
     461           0 :     xmlSecAssert2(doc != NULL, -1);
     462             : 
     463           0 :     transform->outNodes = xmlSecXPathDataListExecute(dataList, doc, 
     464             :                                 transform->hereNode, transform->inNodes);
     465           0 :     if(transform->outNodes == NULL) {
     466           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     467           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     468             :                     "xmlSecXPathDataExecute",
     469             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     470             :                     XMLSEC_ERRORS_NO_MESSAGE);
     471           0 :         return(-1);
     472             :     }    
     473           0 :     return(0);
     474             : }
     475             : 
     476             : /******************************************************************************
     477             :  *
     478             :  * XPath transform
     479             :  * 
     480             :  *****************************************************************************/
     481             : static int              xmlSecTransformXPathNodeRead    (xmlSecTransformPtr transform,
     482             :                                                          xmlNodePtr node,
     483             :                                                          xmlSecTransformCtxPtr transformCtx);
     484             : 
     485             : static xmlSecTransformKlass xmlSecTransformXPathKlass = {
     486             :     /* klass/object sizes */
     487             :     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
     488             :     xmlSecXPathTransformSize,                   /* xmlSecSize objSize */
     489             : 
     490             :     xmlSecNameXPath,                            /* const xmlChar* name; */
     491             :     xmlSecXPathNs,                              /* const xmlChar* href; */
     492             :     xmlSecTransformUsageDSigTransform,          /* xmlSecTransformUsage usage; */
     493             : 
     494             :     xmlSecTransformXPathInitialize,             /* xmlSecTransformInitializeMethod initialize; */
     495             :     xmlSecTransformXPathFinalize,               /* xmlSecTransformFinalizeMethod finalize; */
     496             :     xmlSecTransformXPathNodeRead,               /* xmlSecTransformNodeReadMethod readNode; */
     497             :     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
     498             :     NULL,                                       /* xmlSecTransformSetKeyReqMethod setKeyReq; */
     499             :     NULL,                                       /* xmlSecTransformSetKeyMethod setKey; */
     500             :     NULL,                                       /* xmlSecTransformValidateMethod validate; */
     501             :     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
     502             :     NULL,                                       /* xmlSecTransformPushBinMethod pushBin; */
     503             :     NULL,                                       /* xmlSecTransformPopBinMethod popBin; */
     504             :     xmlSecTransformDefaultPushXml,              /* xmlSecTransformPushXmlMethod pushXml; */
     505             :     xmlSecTransformDefaultPopXml,               /* xmlSecTransformPopXmlMethod popXml; */
     506             :     xmlSecTransformXPathExecute,                /* xmlSecTransformExecuteMethod execute; */
     507             :     
     508             :     NULL,                                       /* void* reserved0; */
     509             :     NULL,                                       /* void* reserved1; */
     510             : };
     511             : 
     512             : /**
     513             :  * xmlSecTransformXPathGetKlass:
     514             :  *
     515             :  * The XPath transform evaluates given XPath expression and 
     516             :  * intersects the result with the previous nodes set. See 
     517             :  * http://www.w3.org/TR/xmldsig-core/#sec-XPath for more details.
     518             :  *
     519             :  * Returns: XPath transform id.
     520             :  */
     521             : xmlSecTransformId 
     522           0 : xmlSecTransformXPathGetKlass(void) {
     523           0 :     return(&xmlSecTransformXPathKlass);
     524             : }
     525             : 
     526             : static const char xpathPattern[] = "(//. | //@* | //namespace::*)[boolean(%s)]";
     527             : static int 
     528           0 : xmlSecTransformXPathNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
     529             :     xmlSecPtrListPtr dataList;
     530             :     xmlSecXPathDataPtr data;
     531             :     xmlNodePtr cur;
     532             :     xmlChar* tmp;
     533             :     int ret;
     534             : 
     535           0 :     xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPathId), -1);
     536           0 :     xmlSecAssert2(node != NULL, -1);
     537           0 :     xmlSecAssert2(transformCtx != NULL, -1);
     538             : 
     539           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     540           0 :     xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
     541           0 :     xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
     542             : 
     543             :     /* there is only one required node */
     544           0 :     cur = xmlSecGetNextElementNode(node->children);  
     545           0 :     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeXPath, xmlSecDSigNs))) {
     546           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     547           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     548           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     549             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     550             :                     "expected=%s",
     551             :                     xmlSecErrorsSafeString(xmlSecNodeXPath));
     552           0 :         return(-1);
     553             :     }
     554             :     
     555             :     /* read information from the node */
     556           0 :     data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPath);
     557           0 :     if(data == NULL) {
     558           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     559           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     560             :                     "xmlSecXPathDataCreate",
     561             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     562             :                     XMLSEC_ERRORS_NO_MESSAGE);
     563           0 :         return(-1);
     564             :     }
     565             :     
     566           0 :     ret = xmlSecXPathDataNodeRead(data, cur);
     567           0 :     if(ret < 0) {
     568           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     569           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     570             :                     "xmlSecXPathDataNodeRead",
     571             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     572             :                     XMLSEC_ERRORS_NO_MESSAGE);
     573           0 :         xmlSecXPathDataDestroy(data);
     574           0 :         return(-1);
     575             :     }
     576             :         
     577             :     /* append it to the list */
     578           0 :     ret = xmlSecPtrListAdd(dataList, data);
     579           0 :     if(ret < 0) {
     580           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     581           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     582             :                     "xmlSecPtrListAdd",
     583             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     584             :                     XMLSEC_ERRORS_NO_MESSAGE);
     585           0 :         xmlSecXPathDataDestroy(data);
     586           0 :         return(-1);
     587             :     }
     588             :     
     589             :     /* create full XPath expression */
     590           0 :     xmlSecAssert2(data->expr != NULL, -1);
     591           0 :     tmp = (xmlChar*) xmlMalloc(sizeof(xmlChar) * (xmlStrlen(data->expr) + 
     592           0 :                                                   strlen(xpathPattern) + 1));
     593           0 :     if(tmp == NULL) {
     594           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     595           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     596             :                     NULL,
     597             :                     XMLSEC_ERRORS_R_MALLOC_FAILED,
     598             :                     "size=%d",
     599           0 :                     xmlStrlen(data->expr) + strlen(xpathPattern) + 1);
     600           0 :         return(-1);
     601             :     }
     602           0 :     sprintf((char*)tmp, xpathPattern, (char*)data->expr);    
     603           0 :     xmlFree(data->expr);
     604           0 :     data->expr = tmp;
     605             : 
     606             :     /* set correct node set type and operation */
     607           0 :     data->nodeSetOp  = xmlSecNodeSetIntersection;
     608           0 :     data->nodeSetType        = xmlSecNodeSetNormal;
     609             :     
     610             :     /* check that we have nothing else */
     611           0 :     cur = xmlSecGetNextElementNode(cur->next);        
     612           0 :     if(cur != NULL) {
     613           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     614           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     615           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     616             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
     617             :                     XMLSEC_ERRORS_NO_MESSAGE);
     618           0 :         return(-1);
     619             :     }
     620           0 :     return(0);
     621             : }
     622             : 
     623             : /******************************************************************************
     624             :  *
     625             :  * XPath2 transform
     626             :  * 
     627             :  *****************************************************************************/
     628             : static int              xmlSecTransformXPath2NodeRead   (xmlSecTransformPtr transform,
     629             :                                                          xmlNodePtr node,
     630             :                                                          xmlSecTransformCtxPtr transformCtx);
     631             : static xmlSecTransformKlass xmlSecTransformXPath2Klass = {
     632             :     /* klass/object sizes */
     633             :     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
     634             :     xmlSecXPathTransformSize,                   /* xmlSecSize objSize */
     635             : 
     636             :     xmlSecNameXPath2,                           /* const xmlChar* name; */
     637             :     xmlSecXPath2Ns,                             /* const xmlChar* href; */
     638             :     xmlSecTransformUsageDSigTransform,          /* xmlSecTransformUsage usage; */
     639             : 
     640             :     xmlSecTransformXPathInitialize,             /* xmlSecTransformInitializeMethod initialize; */
     641             :     xmlSecTransformXPathFinalize,               /* xmlSecTransformFinalizeMethod finalize; */
     642             :     xmlSecTransformXPath2NodeRead,              /* xmlSecTransformNodeReadMethod readNode; */
     643             :     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
     644             :     NULL,                                       /* xmlSecTransformSetKeyReqMethod setKeyReq; */
     645             :     NULL,                                       /* xmlSecTransformSetKeyMethod setKey; */
     646             :     NULL,                                       /* xmlSecTransformValidateMethod validate; */
     647             :     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
     648             :     NULL,                                       /* xmlSecTransformPushBinMethod pushBin; */
     649             :     NULL,                                       /* xmlSecTransformPopBinMethod popBin; */
     650             :     xmlSecTransformDefaultPushXml,              /* xmlSecTransformPushXmlMethod pushXml; */
     651             :     xmlSecTransformDefaultPopXml,               /* xmlSecTransformPopXmlMethod popXml; */
     652             :     xmlSecTransformXPathExecute,                /* xmlSecTransformExecuteMethod execute; */
     653             : 
     654             :     NULL,                                       /* void* reserved0; */
     655             :     NULL,                                       /* void* reserved1; */
     656             : };
     657             : 
     658             : /**
     659             :  * xmlSecTransformXPath2GetKlass:
     660             :  * 
     661             :  * The XPath2 transform (http://www.w3.org/TR/xmldsig-filter2/).
     662             :  *
     663             :  * Returns: XPath2 transform klass.
     664             :  */
     665             : xmlSecTransformId 
     666           0 : xmlSecTransformXPath2GetKlass(void) {
     667           0 :     return(&xmlSecTransformXPath2Klass);
     668             : }
     669             : 
     670             : static int 
     671           0 : xmlSecTransformXPath2NodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
     672             :     xmlSecPtrListPtr dataList;
     673             :     xmlSecXPathDataPtr data;
     674             :     xmlNodePtr cur;
     675             :     xmlChar* op;
     676             :     int ret;
     677             : 
     678           0 :     xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPath2Id), -1);
     679           0 :     xmlSecAssert2(node != NULL, -1);
     680           0 :     xmlSecAssert2(transformCtx != NULL, -1);
     681             : 
     682           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     683           0 :     xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
     684           0 :     xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
     685             :     
     686             :     /* There are only xpath nodes */
     687           0 :     cur = xmlSecGetNextElementNode(node->children);  
     688           0 :     while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeXPath2, xmlSecXPath2Ns)) {
     689             :         /* read information from the node */
     690           0 :         data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPath2);
     691           0 :         if(data == NULL) {
     692           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     693           0 :                         xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     694             :                         "xmlSecXPathDataCreate",
     695             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     696             :                         XMLSEC_ERRORS_NO_MESSAGE);
     697           0 :             return(-1);
     698             :         }
     699             : 
     700           0 :         ret = xmlSecXPathDataNodeRead(data, cur);
     701           0 :         if(ret < 0) {
     702           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     703           0 :                         xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     704             :                         "xmlSecXPathDataNodeRead",
     705             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     706             :                         XMLSEC_ERRORS_NO_MESSAGE);
     707           0 :             xmlSecXPathDataDestroy(data);
     708           0 :             return(-1);
     709             :         }
     710             :     
     711             :         /* append it to the list */
     712           0 :         ret = xmlSecPtrListAdd(dataList, data);
     713           0 :         if(ret < 0) {
     714           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     715           0 :                         xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     716             :                         "xmlSecPtrListAdd",
     717             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     718             :                         XMLSEC_ERRORS_NO_MESSAGE);
     719           0 :             xmlSecXPathDataDestroy(data);
     720           0 :             return(-1);
     721             :         }
     722             : 
     723             :         /* set correct node set type and operation */
     724           0 :         data->nodeSetType = xmlSecNodeSetTree;
     725           0 :         op = xmlGetProp(cur, xmlSecAttrFilter);
     726           0 :         if(op == NULL) {
     727           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     728           0 :                         xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     729             :                         xmlSecErrorsSafeString(xmlSecAttrFilter),
     730             :                         XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
     731             :                         "node=%s",
     732           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     733           0 :             return(-1);
     734             :         }
     735           0 :         if(xmlStrEqual(op, xmlSecXPath2FilterIntersect)) {
     736           0 :             data->nodeSetOp = xmlSecNodeSetIntersection;
     737           0 :         } else if(xmlStrEqual(op, xmlSecXPath2FilterSubtract)) {
     738           0 :             data->nodeSetOp = xmlSecNodeSetSubtraction;
     739           0 :         } else if(xmlStrEqual(op, xmlSecXPath2FilterUnion)) {
     740           0 :             data->nodeSetOp = xmlSecNodeSetUnion;
     741             :         } else {
     742           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     743           0 :                         xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     744             :                         xmlSecErrorsSafeString(xmlSecAttrFilter),
     745             :                         XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
     746             :                         "filter=%s", 
     747             :                         xmlSecErrorsSafeString(op));
     748           0 :             xmlFree(op);
     749           0 :             return(-1);
     750             :         }
     751           0 :         xmlFree(op);
     752             : 
     753           0 :         cur = xmlSecGetNextElementNode(cur->next);  
     754             :     }
     755             : 
     756             :     /* check that we have nothing else */
     757           0 :     if(cur != NULL) {
     758           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     759           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     760           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     761             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
     762             :                     XMLSEC_ERRORS_NO_MESSAGE);
     763           0 :         return(-1);
     764             :     }
     765           0 :     return(0);
     766             : }
     767             : 
     768             : /******************************************************************************
     769             :  *
     770             :  * XPointer transform
     771             :  * 
     772             :  *****************************************************************************/
     773             : static int              xmlSecTransformXPointerNodeRead (xmlSecTransformPtr transform,
     774             :                                                          xmlNodePtr node,
     775             :                                                          xmlSecTransformCtxPtr transformCtx);
     776             : static xmlSecTransformKlass xmlSecTransformXPointerKlass = {
     777             :     /* klass/object sizes */
     778             :     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
     779             :     xmlSecXPathTransformSize,                   /* xmlSecSize objSize */
     780             : 
     781             :     xmlSecNameXPointer,                         /* const xmlChar* name; */
     782             :     xmlSecXPointerNs,                           /* const xmlChar* href; */
     783             :     xmlSecTransformUsageDSigTransform,          /* xmlSecTransformUsage usage; */
     784             : 
     785             :     xmlSecTransformXPathInitialize,             /* xmlSecTransformInitializeMethod initialize; */
     786             :     xmlSecTransformXPathFinalize,               /* xmlSecTransformFinalizeMethod finalize; */
     787             :     xmlSecTransformXPointerNodeRead,            /* xmlSecTransformNodeReadMethod readNode; */
     788             :     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
     789             :     NULL,                                       /* xmlSecTransformSetKeyReqMethod setKeyReq; */
     790             :     NULL,                                       /* xmlSecTransformSetKeyMethod setKey; */
     791             :     NULL,                                       /* xmlSecTransformValidateMethod validate; */
     792             :     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
     793             :     NULL,                                       /* xmlSecTransformPushBinMethod pushBin; */
     794             :     NULL,                                       /* xmlSecTransformPopBinMethod popBin; */
     795             :     xmlSecTransformDefaultPushXml,              /* xmlSecTransformPushXmlMethod pushXml; */
     796             :     xmlSecTransformDefaultPopXml,               /* xmlSecTransformPopXmlMethod popXml; */
     797             :     xmlSecTransformXPathExecute,                /* xmlSecTransformExecuteMethod execute; */
     798             : 
     799             :     NULL,                                       /* void* reserved0; */
     800             :     NULL,                                       /* void* reserved1; */
     801             : };
     802             : 
     803             : /**
     804             :  * xmlSecTransformXPointerGetKlass:
     805             :  * 
     806             :  * The XPointer transform klass 
     807             :  * (http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt).
     808             :  *
     809             :  * Returns: XPointer transform klass.
     810             :  */
     811             : xmlSecTransformId 
     812           0 : xmlSecTransformXPointerGetKlass(void) {
     813           0 :     return(&xmlSecTransformXPointerKlass);
     814             : }
     815             : 
     816             : /**
     817             :  * xmlSecTransformXPointerSetExpr: 
     818             :  * @transform:          the pointer to XPointer transform.
     819             :  * @expr:               the XPointer expression.
     820             :  * @nodeSetType:        the type of evaluated XPointer expression.
     821             :  * @hereNode:           the pointer to "here" node.
     822             :  *
     823             :  * Sets the XPointer expression for an XPointer @transform.
     824             :  *
     825             :  * Returns: 0 on success or a negative value if an error occurs.
     826             :  */
     827             : int 
     828           0 : xmlSecTransformXPointerSetExpr(xmlSecTransformPtr transform, const xmlChar* expr, 
     829             :                             xmlSecNodeSetType  nodeSetType, xmlNodePtr hereNode) {
     830             :     xmlSecPtrListPtr dataList;
     831             :     xmlSecXPathDataPtr data;
     832             :     int ret;
     833             : 
     834           0 :     xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPointerId), -1);
     835           0 :     xmlSecAssert2(transform->hereNode == NULL, -1);
     836           0 :     xmlSecAssert2(expr != NULL, -1);
     837           0 :     xmlSecAssert2(hereNode != NULL, -1);    
     838             : 
     839           0 :     transform->hereNode = hereNode;
     840             :     
     841           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     842           0 :     xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
     843           0 :     xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
     844             : 
     845           0 :     data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPointer);
     846           0 :     if(data == NULL) {
     847           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     848           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     849             :                     "xmlSecXPathDataCreate",
     850             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     851             :                     XMLSEC_ERRORS_NO_MESSAGE);
     852           0 :         return(-1);
     853             :     }
     854             : 
     855           0 :     ret = xmlSecXPathDataRegisterNamespaces(data, hereNode);
     856           0 :     if(ret < 0) {
     857           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     858           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     859             :                     "xmlSecXPathDataRegisterNamespaces",
     860             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     861             :                     XMLSEC_ERRORS_NO_MESSAGE);
     862           0 :         xmlSecXPathDataDestroy(data);
     863           0 :         return(-1);
     864             :     }    
     865             : 
     866           0 :     ret = xmlSecXPathDataSetExpr(data, expr);
     867           0 :     if(ret < 0) {
     868           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     869           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     870             :                     "xmlSecXPathDataSetExpr",
     871             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     872             :                     XMLSEC_ERRORS_NO_MESSAGE);
     873           0 :         xmlSecXPathDataDestroy(data);
     874           0 :         return(-1);
     875             :     }
     876             :     
     877             :     /* append it to the list */
     878           0 :     ret = xmlSecPtrListAdd(dataList, data);
     879           0 :     if(ret < 0) {
     880           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     881           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     882             :                     "xmlSecPtrListAdd",
     883             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     884             :                     XMLSEC_ERRORS_NO_MESSAGE);
     885           0 :         xmlSecXPathDataDestroy(data);
     886           0 :         return(-1);
     887             :     }
     888             : 
     889             :     /* set correct node set type and operation */
     890           0 :     data->nodeSetOp  = xmlSecNodeSetIntersection;
     891           0 :     data->nodeSetType        = nodeSetType;
     892             :     
     893           0 :     return(0);
     894             : }
     895             : 
     896             : static int 
     897           0 : xmlSecTransformXPointerNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
     898             :     xmlSecPtrListPtr dataList;
     899             :     xmlSecXPathDataPtr data;
     900             :     xmlNodePtr cur;
     901             :     int ret;
     902             : 
     903           0 :     xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPointerId), -1);
     904           0 :     xmlSecAssert2(node != NULL, -1);
     905           0 :     xmlSecAssert2(transformCtx != NULL, -1);
     906             : 
     907           0 :     dataList = xmlSecXPathTransformGetDataList(transform);
     908           0 :     xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
     909           0 :     xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
     910             : 
     911             :     /* there is only one required node */
     912           0 :     cur = xmlSecGetNextElementNode(node->children);  
     913           0 :     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeXPointer, xmlSecXPointerNs))) {
     914           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     915           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     916           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     917             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     918             :                     "expected=%s",
     919             :                     xmlSecErrorsSafeString(xmlSecNodeXPath));
     920           0 :         return(-1);
     921             :     }
     922             :     
     923             :     /* read information from the node */
     924           0 :     data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPointer);
     925           0 :     if(data == NULL) {
     926           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     927           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     928             :                     "xmlSecXPathDataCreate",
     929             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     930             :                     XMLSEC_ERRORS_NO_MESSAGE);
     931           0 :         return(-1);
     932             :     }
     933             : 
     934           0 :     ret = xmlSecXPathDataNodeRead(data, cur);
     935           0 :     if(ret < 0) {
     936           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     937           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     938             :                     "xmlSecXPathDataNodeRead",
     939             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     940             :                     XMLSEC_ERRORS_NO_MESSAGE);
     941           0 :         xmlSecXPathDataDestroy(data);
     942           0 :         return(-1);
     943             :     }
     944             :     
     945             :     /* append it to the list */
     946           0 :     ret = xmlSecPtrListAdd(dataList, data);
     947           0 :     if(ret < 0) {
     948           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     949           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     950             :                     "xmlSecPtrListAdd",
     951             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     952             :                     XMLSEC_ERRORS_NO_MESSAGE);
     953           0 :         xmlSecXPathDataDestroy(data);
     954           0 :         return(-1);
     955             :     }
     956             : 
     957             :     /* set correct node set type and operation */
     958           0 :     data->nodeSetOp  = xmlSecNodeSetIntersection;
     959           0 :     data->nodeSetType        = xmlSecNodeSetTree;
     960             :     
     961             :     /* check that we have nothing else */
     962           0 :     cur = xmlSecGetNextElementNode(cur->next);        
     963           0 :     if(cur != NULL) {
     964           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     965           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
     966           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     967             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
     968             :                     XMLSEC_ERRORS_NO_MESSAGE);
     969           0 :         return(-1);
     970             :     }
     971           0 :     return(0);
     972             : }
     973             : 
     974             : 
     975             : /******************************************************************************
     976             :  *
     977             :  * Visa3DHack transform
     978             :  * 
     979             :  *****************************************************************************/
     980             : #define xmlSecVisa3DHackTransformSize   \
     981             :     (sizeof(xmlSecTransform) + sizeof(xmlChar*))
     982             : #define xmlSecVisa3DHackTransformGetIDPtr(transform) \
     983             :     ((xmlSecTransformCheckSize((transform), xmlSecVisa3DHackTransformSize)) ? \
     984             :         (xmlChar**)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)) : \
     985             :         (xmlChar**)NULL)
     986             : #define xmlSecTransformVisa3DHackCheckId(transform) \
     987             :     (xmlSecTransformCheckId((transform), xmlSecTransformVisa3DHackId))
     988             : 
     989             : static int              xmlSecTransformVisa3DHackInitialize     (xmlSecTransformPtr transform);
     990             : static void             xmlSecTransformVisa3DHackFinalize       (xmlSecTransformPtr transform);
     991             : static int              xmlSecTransformVisa3DHackExecute        (xmlSecTransformPtr transform,
     992             :                                                                  int last, 
     993             :                                                                  xmlSecTransformCtxPtr transformCtx);
     994             : 
     995             : static xmlSecTransformKlass xmlSecTransformVisa3DHackKlass = {
     996             :     /* klass/object sizes */
     997             :     sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
     998             :     xmlSecVisa3DHackTransformSize,              /* xmlSecSize objSize */
     999             : 
    1000             :     BAD_CAST "Visa3DHackTransform",           /* const xmlChar* name; */
    1001             :     NULL,                                       /* const xmlChar* href; */
    1002             :     xmlSecTransformUsageDSigTransform,          /* xmlSecTransformUsage usage; */
    1003             : 
    1004             :     xmlSecTransformVisa3DHackInitialize,        /* xmlSecTransformInitializeMethod initialize; */
    1005             :     xmlSecTransformVisa3DHackFinalize,          /* xmlSecTransformFinalizeMethod finalize; */
    1006             :     NULL,                                       /* xmlSecTransformNodeReadMethod readNode; */
    1007             :     NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
    1008             :     NULL,                                       /* xmlSecTransformSetKeyReqMethod setKeyReq; */
    1009             :     NULL,                                       /* xmlSecTransformSetKeyMethod setKey; */
    1010             :     NULL,                                       /* xmlSecTransformValidateMethod validate; */
    1011             :     xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
    1012             :     NULL,                                       /* xmlSecTransformPushBinMethod pushBin; */
    1013             :     NULL,                                       /* xmlSecTransformPopBinMethod popBin; */
    1014             :     xmlSecTransformDefaultPushXml,              /* xmlSecTransformPushXmlMethod pushXml; */
    1015             :     xmlSecTransformDefaultPopXml,               /* xmlSecTransformPopXmlMethod popXml; */
    1016             :     xmlSecTransformVisa3DHackExecute,           /* xmlSecTransformExecuteMethod execute; */
    1017             : 
    1018             :     NULL,                                       /* void* reserved0; */
    1019             :     NULL,                                       /* void* reserved1; */
    1020             : };
    1021             : 
    1022             : /**
    1023             :  * xmlSecTransformVisa3DHackGetKlass:
    1024             :  * 
    1025             :  * The Visa3DHack transform klass. The only reason why we need this 
    1026             :  * is Visa3D protocol. It doesn't follow XML/XPointer/XMLDSig specs and allows 
    1027             :  * invalid XPointer expressions in the URI attribute. Since we couldn't evaluate 
    1028             :  * such expressions thru XPath/XPointer engine, we need to have this hack here. 
    1029             :  *
    1030             :  * Returns: Visa3DHack transform klass.
    1031             :  */
    1032             : xmlSecTransformId 
    1033           0 : xmlSecTransformVisa3DHackGetKlass(void) {
    1034           0 :     return(&xmlSecTransformVisa3DHackKlass);
    1035             : }
    1036             : 
    1037             : /**
    1038             :  * xmlSecTransformVisa3DHackSetID:
    1039             :  * @transform:          the pointer to Visa3DHack transform.
    1040             :  * @id:                 the ID value.
    1041             :  *
    1042             :  * Sets the ID value for an Visa3DHack @transform.
    1043             :  *
    1044             :  * Returns: 0 on success or a negative value if an error occurs.
    1045             :  */
    1046             : int 
    1047           0 : xmlSecTransformVisa3DHackSetID(xmlSecTransformPtr transform, const xmlChar* id) {
    1048             :     xmlChar** idPtr;
    1049             :     
    1050           0 :     xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformVisa3DHackId), -1);
    1051           0 :     xmlSecAssert2(id != NULL, -1);
    1052             : 
    1053           0 :     idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
    1054           0 :     xmlSecAssert2(idPtr != NULL, -1);
    1055           0 :     xmlSecAssert2((*idPtr) == NULL, -1);
    1056             : 
    1057           0 :     (*idPtr) = xmlStrdup(id);
    1058           0 :     if((*idPtr) == NULL) {
    1059           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1060           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
    1061             :                     "xmlStrdup",
    1062             :                     XMLSEC_ERRORS_R_MALLOC_FAILED,
    1063             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1064           0 :         return(-1);
    1065             :     }
    1066             : 
    1067           0 :     return(0);
    1068             : }
    1069             : 
    1070             : static int
    1071           0 : xmlSecTransformVisa3DHackInitialize(xmlSecTransformPtr transform) {     
    1072           0 :     xmlSecAssert2(xmlSecTransformVisa3DHackCheckId(transform), -1);
    1073             : 
    1074           0 :     return(0);
    1075             : }
    1076             : 
    1077             : static void
    1078           0 : xmlSecTransformVisa3DHackFinalize(xmlSecTransformPtr transform) {
    1079             :     xmlChar** idPtr;
    1080             : 
    1081           0 :     xmlSecAssert(xmlSecTransformVisa3DHackCheckId(transform));
    1082             : 
    1083           0 :     idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
    1084           0 :     xmlSecAssert(idPtr != NULL);
    1085             :     
    1086           0 :     if((*idPtr) != NULL) {
    1087           0 :         xmlFree((*idPtr));
    1088             :     }
    1089           0 :     (*idPtr) = NULL;
    1090             : }
    1091             : 
    1092             : static int
    1093           0 : xmlSecTransformVisa3DHackExecute(xmlSecTransformPtr transform, int last,
    1094             :                             xmlSecTransformCtxPtr transformCtx) {
    1095             :     xmlChar** idPtr;
    1096             :     xmlDocPtr doc;
    1097             :     xmlAttrPtr attr;
    1098             :     xmlNodeSetPtr nodeSet;
    1099             :     
    1100           0 :     xmlSecAssert2(xmlSecTransformVisa3DHackCheckId(transform), -1);
    1101           0 :     xmlSecAssert2(transform->outNodes == NULL, -1);
    1102           0 :     xmlSecAssert2(last != 0, -1);
    1103           0 :     xmlSecAssert2(transformCtx != NULL, -1);
    1104             : 
    1105           0 :     idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
    1106           0 :     xmlSecAssert2(idPtr != NULL, -1);
    1107           0 :     xmlSecAssert2((*idPtr) != NULL, -1);
    1108             : 
    1109           0 :     doc = (transform->inNodes != NULL) ? transform->inNodes->doc : transform->hereNode->doc;
    1110           0 :     xmlSecAssert2(doc != NULL, -1);
    1111             : 
    1112           0 :     attr = xmlGetID(doc, (*idPtr));
    1113           0 :     if((attr == NULL) || (attr->parent == NULL)) {
    1114           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1115           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
    1116             :                     "xmlGetID",
    1117             :                     XMLSEC_ERRORS_R_XML_FAILED,
    1118             :                     "id=\"%s\"",
    1119           0 :                     xmlSecErrorsSafeString((*idPtr)));
    1120           0 :         return(-1);
    1121             :     }    
    1122             : 
    1123           0 :     nodeSet = xmlXPathNodeSetCreate(attr->parent);
    1124           0 :     if(nodeSet == NULL) {
    1125           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1126           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
    1127             :                     "xmlXPathNodeSetCreate",
    1128             :                     XMLSEC_ERRORS_R_XML_FAILED,
    1129             :                     "id=\"%s\"",
    1130           0 :                     xmlSecErrorsSafeString((*idPtr)));
    1131           0 :         return(-1);
    1132             :     }    
    1133             : 
    1134           0 :     transform->outNodes = xmlSecNodeSetCreate(doc, nodeSet, xmlSecNodeSetTreeWithoutComments);
    1135           0 :     if(transform->outNodes == NULL) {
    1136           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1137           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
    1138             :                     "xmlSecNodeSetCreate",
    1139             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1140             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1141           0 :         xmlXPathFreeNodeSet(nodeSet);
    1142           0 :         return(-1);
    1143             :     }    
    1144           0 :     return(0);
    1145             : }
    1146             : 
    1147             : 
    1148             : 

Generated by: LCOV version 1.10