From: Petr P. <pa...@us...> - 2003-03-18 08:44:17
|
Update of /cvsroot/perl-xml/XML-LibXML-XPathContext In directory sc8-pr-cvs1:/tmp/cvs-serv12274 Modified Files: XPathContext.xs Log Message: fixed all *v_fetch to avoid sigsegvs (esp. with undefined varLookupData) Index: XPathContext.xs =================================================================== RCS file: /cvsroot/perl-xml/XML-LibXML-XPathContext/XPathContext.xs,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- XPathContext.xs 17 Mar 2003 12:27:22 -0000 1.8 +++ XPathContext.xs 18 Mar 2003 08:44:12 -0000 1.9 @@ -70,8 +70,8 @@ const xmlChar *ns_uri) { xmlXPathObjectPtr ret; - SV * lookup_func; - SV * lookup_data; + SV ** lookup_func; + SV ** lookup_data; I32 count; STRLEN n_a; SV * perl_result; @@ -82,6 +82,7 @@ double tmp_double; int tmp_int; SV * data; + SV ** fetch; data = (SV *) varLookupData; if (varLookupData == NULL || !SvROK(data) || @@ -89,19 +90,22 @@ croak("XPathContext: lost variable lookup data structure!\n"); } - lookup_func = *(av_fetch((AV *) SvRV(data),0,0 )); - lookup_data = *(av_fetch((AV *) SvRV(data),1,0 )); + lookup_func = av_fetch((AV *) SvRV(data),0,0 ); + if ( lookup_func == NULL || !SvROK(*lookup_func) || SvTYPE(SvRV(*lookup_func)) != SVt_PVCV ) { + croak("XPathContext: lost variable lookup function!\n"); + } + lookup_data = av_fetch((AV *) SvRV(data),1,0 ); ENTER; SAVETMPS; PUSHMARK(SP); - XPUSHs(lookup_data); + XPUSHs( (lookup_data != NULL) ? *lookup_data : &PL_sv_undef ); XPUSHs(sv_2mortal(C2Sv(name,NULL))); XPUSHs(sv_2mortal(C2Sv(ns_uri,NULL))); PUTBACK ; - count = perl_call_sv(lookup_func, G_SCALAR|G_EVAL); + count = perl_call_sv(*lookup_func, G_SCALAR|G_EVAL); SPAGAIN; if (SvTRUE(ERRSV)) { @@ -120,19 +124,19 @@ SvTYPE(SvRV(perl_result)) == SVt_PVAV) { /* consider any array ref to be a nodelist */ int i = 0; - int len; - SV * pnode; + int length; + SV ** pnode; /* warn("result is a node list\n"); */ ret = (xmlXPathObjectPtr) xmlXPathNewNodeSet((xmlNodePtr) NULL); array_result = (AV*)SvRV(perl_result); - len = av_len(array_result); - for( i; i <= len ; i++ ) { - pnode = *(av_fetch(array_result,i,0)); - if (sv_isobject(pnode) && - sv_derived_from(pnode,"XML::LibXML::Node")) { + length = av_len(array_result); + for( i; i <= length ; i++ ) { + pnode = av_fetch(array_result,i,0); + if (pnode != NULL && sv_isobject(*pnode) && + sv_derived_from(*pnode,"XML::LibXML::Node")) { xmlXPathNodeSetAdd(ret->nodesetval, - (xmlNodePtr)PmmSvNode(pnode)); + (xmlNodePtr)PmmSvNode(*pnode)); } else { warn("XPathContext: ignoring non-node member of a nodelist"); } @@ -232,6 +236,10 @@ strkey = SvPV(key, len); perl_function = hv_fetch((HV*)SvRV(data), strkey, len, 0); + if ( perl_function == NULL || !SvROK(*perl_function) || + SvTYPE(SvRV(*perl_function)) != SVt_PVCV ) { + croak("XPathContext: lost perl extension function!\n"); + } SvREFCNT_dec(key); ENTER; @@ -338,19 +346,19 @@ if (SvROK(perl_result) && SvTYPE(SvRV(perl_result)) == SVt_PVAV) { /* consider any array ref to be a nodelist */ - SV * pnode; - i = 0; + int length = 0; + SV ** pnode; /* warn("result is a node list\n"); */ ret = (xmlXPathObjectPtr) xmlXPathNewNodeSet((xmlNodePtr) NULL); array_result = (AV*)SvRV(perl_result); - len = av_len(array_result); - for( i; i <= len ; i++ ) { - pnode = *(av_fetch(array_result,i,0)); - if (sv_isobject(pnode) && - sv_derived_from(pnode,"XML::LibXML::Node")) { + length = av_len(array_result); + for( i=0 ; i <= length ; i++ ) { + pnode = av_fetch(array_result,i,0); + if (pnode != NULL && sv_isobject(*pnode) && + sv_derived_from(*pnode,"XML::LibXML::Node")) { xmlXPathNodeSetAdd(ret->nodesetval, - (xmlNodePtr)PmmSvNode(pnode)); + (xmlNodePtr)PmmSvNode(*pnode)); } else { warn("XPathContext: ignoring non-node member of a nodelist"); } @@ -556,13 +564,19 @@ getVarLookupData( self ) SV * self INIT: + SV ** lookup_data; xmlXPathContextPtr ctxt = (xmlXPathContextPtr)SvIV(SvRV(self)); CODE: if (ctxt->varLookupData != NULL && SvROK((SV*)(ctxt->varLookupData)) && SvTYPE(SvRV((SV*)(ctxt->varLookupData))) == SVt_PVAV) { - RETVAL = *(av_fetch((AV *) SvRV((SV*)(ctxt->varLookupData)),1,0)); - SvREFCNT_inc(RETVAL); + lookup_data = av_fetch((AV *) SvRV((SV*)(ctxt->varLookupData)),1,0); + if (lookup_data != NULL) { + SvREFCNT_inc(*lookup_data); + RETVAL = *lookup_data; + } else { + RETVAL = &PL_sv_undef; + } } else { RETVAL = &PL_sv_undef; } |