Commits

Anonymous committed ab441b8

Fixed validation mode, and added proper tests for it

  • Participants
  • Parent commits 3de52f3

Comments (0)

Files changed (6)

     xmlDocPtr doc;
     xmlParserCtxtPtr ctxt;
     int well_formed;
+    int valid;
     char buffer[1024];
     int read_length;
     int ret = -1;
         
         doc = ctxt->myDoc;
         well_formed = ctxt->wellFormed;
+        valid = ctxt->valid;
 
         xmlFreeParserCtxt(ctxt);
     }
     
-    if (!well_formed) {
+    if (!well_formed || (xmlDoValidityCheckingDefaultValue && !valid)) {
         xmlFreeDoc(doc);
         return NULL;
     }
         STRLEN len;
         char * ptr;
         int well_formed;
+        int valid;
         int ret;
         xmlDocPtr real_dom;
         ProxyObject * proxy;
         ret = xmlParseDocument(ctxt);
         
         well_formed = ctxt->wellFormed;
+        valid = ctxt->valid;
 
         real_dom = ctxt->myDoc;
         xmlFreeParserCtxt(ctxt);
         
         sv_2mortal(LibXML_error);
         
-        if (!well_formed) {
+        if (!well_formed || (xmlDoValidityCheckingDefaultValue && !valid)) {
             xmlFreeDoc(real_dom);
             RETVAL = &PL_sv_undef;    
             croak(SvPV(LibXML_error, len));
         xmlParserCtxtPtr ctxt;
         char * CLASS = "XML::LibXML::Document";
         int well_formed;
+        int valid;
         STRLEN len;
         xmlDocPtr real_dom;
         ProxyObject * proxy;
         
         xmlParseDocument(ctxt);
         well_formed = ctxt->wellFormed;
+        valid = ctxt->valid;
 
         real_dom = ctxt->myDoc;
         xmlFreeParserCtxt(ctxt);
         
         sv_2mortal(LibXML_error);
         
-        if (!well_formed) {
+        if (!well_formed || (xmlDoValidityCheckingDefaultValue && !valid)) {
             xmlFreeDoc(real_dom);
             RETVAL = &PL_sv_undef ;  
             croak(SvPV(LibXML_error, len));
 DESTROY(self)
         ProxyObject* self
     CODE:
+        /* warn("destroy DOC\n"); */
         if ( self->object != NULL ) {
             xmlFreeDoc((xmlDocPtr)self->object);
             #warn( "REAL DOCUMENT DROP SUCCEEDS" );
     PREINIT:
         xmlNodePtr real_node;
     CODE:
+        /* warn("destroy NODE\n"); */
         if (node == NULL) {
            XSRETURN_UNDEF;
         }
             if( real_node->type == XML_DOCUMENT_FRAG_NODE ) {
                 warn( "NODE DESTROY: NODE ISA DOCUMENT_FRAGMENT!" );
             }
-
+            
             if ( SvREFCNT( node->extra ) > 0 ){
+                /* warn("dec REFCNT extra : %d\n", SvREFCNT(node->extra)); */
                 SvREFCNT_dec(node->extra);
             }
             if ( real_node->type != XML_DOCUMENT_NODE ) {
                 cls = domNodeTypeName( tnode );
 
                 proxy = make_proxy_node(tnode);
-                if ( node->extra != NULL ) {
+                if ( node->extra != NULL && ((xmlNodePtr)node->object)->type != XML_DOCUMENT_NODE ) {
                     proxy->extra = node->extra;
                     SvREFCNT_inc(node->extra);
                 }
                         cls = domNodeTypeName( tnode );
         
                         proxy = make_proxy_node(tnode);
-                        if ( node->extra != NULL ) {
+                        if ( node->extra != NULL && ((xmlNodePtr)node->object)->type != XML_DOCUMENT_NODE ) {
                             proxy->extra = node->extra;
                             SvREFCNT_inc(node->extra);
                         }
 DESTROY(self)
         ProxyObject* self
     CODE:
+        /* warn("destroy FRAGMENT\n"); */
         if ( (xmlNodePtr)self->object != NULL ) {
             # domSetOwnerDocument( (xmlNodePtr)self->object, NULL ); 
             # if( ((xmlNodePtr)self->object)->children !=NULL){
 example/test.dtd
 example/article.xml
 example/article_bad.xml
+example/article_internal.xml
+example/article_internal_bad.xml
 t/01basic.t
 t/02parsestring.t
 t/03parsefile.t

example/article_internal.xml

+<!DOCTYPE article [
+<!ELEMENT article (pubData*, pubArticleID*, pubDate+, pubName+, section+, memo*, headline1*, headline2*, byline*, lead*, rest*, graphics*, keywords*, caption*)>
+<!ELEMENT pubData (#PCDATA)>
+<!ELEMENT pubArticleID (#PCDATA)>
+<!ELEMENT pubDate (#PCDATA)>
+<!ELEMENT pubName (#PCDATA)>
+<!ELEMENT section (#PCDATA)>
+<!ELEMENT memo (#PCDATA)>
+<!ELEMENT headline1 (#PCDATA)>
+<!ELEMENT headline2 (#PCDATA)>
+<!ELEMENT byline (#PCDATA)>
+<!ELEMENT lead (#PCDATA)>
+<!ELEMENT rest (#PCDATA)>
+<!ELEMENT graphics (#PCDATA)>
+<!ELEMENT keywords (#PCDATA)>
+<!ELEMENT caption (#PCDATA)>
+]>
+<article>
+<pubData>Something here</pubData>
+<pubArticleID>12345</pubArticleID>
+<pubDate>2001-04-01</pubDate>
+<pubName>XML.com</pubName>
+<section>Foo</section>
+<lead>Here's some leading text</lead>
+<rest>And here is the rest...</rest>
+</article>

example/article_internal_bad.xml

+<!DOCTYPE article [
+<!ELEMENT article (pubData*, pubArticleID*, pubDate+, pubName+, section+, memo*, headline1*, headline2*, byline*, lead*, rest*, graphics*, keywords*, caption*)>
+<!ELEMENT pubData (#PCDATA)>
+<!ELEMENT pubArticleID (#PCDATA)>
+<!ELEMENT pubDate (#PCDATA)>
+<!ELEMENT pubName (#PCDATA)>
+<!ELEMENT section (#PCDATA)>
+<!ELEMENT memo (#PCDATA)>
+<!ELEMENT headline1 (#PCDATA)>
+<!ELEMENT headline2 (#PCDATA)>
+<!ELEMENT byline (#PCDATA)>
+<!ELEMENT lead (#PCDATA)>
+<!ELEMENT rest (#PCDATA)>
+<!ELEMENT graphics (#PCDATA)>
+<!ELEMENT keywords (#PCDATA)>
+<!ELEMENT caption (#PCDATA)>
+]>
+<article>
+<pubData>Something here</pubData>
+<pubArticleID>12345</pubArticleID>
+<pub_date>2001-04-01</pub_date>
+<pubName>XML.com</pubName>
+<section>Foo</section>
+<lead>Here's some leading text</lead>
+<rest>And here is the rest...</rest>
+</article>
 use Test;
-BEGIN { plan tests=>8; }
+BEGIN { plan tests=>9; }
 END {ok(0) unless $loaded;}
 use XML::LibXML;
 $loaded = 1;
     ok( $itervar, 'testbtext' );
 
 }
+
+# test to make sure that multiple array findnodes() returns
+# don't segfault perl; it'll happen after the second one if it does
+for (0..3) {
+    my $doc = XML::LibXML->new->parse_string(
+'<?xml version="1.0" encoding="UTF-8"?>
+<?xsl-stylesheet type="text/xsl" href="a.xsl"?>
+<a />');
+    my @nds = $doc->findnodes("processing-instruction('xsl-stylesheet')");
+}
+
+ok(1);
 use Test;
-BEGIN { plan tests => 11 }
+BEGIN { plan tests => 13 }
 use XML::LibXML;
 ok(1);
 
 };
 ok($@);
 }
+
+{
+# validate a document with a <!DOCTYPE> declaration
+XML::LibXML->validation(1);
+my $xml = XML::LibXML->new->parse_file('example/article_internal.xml');
+ok($xml);
+}
+
+{
+# validate an invalid document with <!DOCTYPE declaration
+XML::LibXML->validation(1);
+eval {
+my $xml = XML::LibXML->new->parse_file('example/article_internal_bad.xml');
+ok(0);
+};
+ok($@);
+}