Re: [xml] Losing _private for external entities [Was: What is the _private field actually for?]



Hi Daniel,

  You can't change xmlCreateEntityParserCtxt() it's a public API.
The simplest is probably to embbed some of the code of
xmlCreateEntityParserCtxt into xmlParseCtxtExternalEntity, making sure
that _private is copied between xmlNewParserCtxt() and the
xmlLoadExternalEntity() . We don't use a base, so some of the code may
be simplified. If you don't feel okay hacking this I will, but you're in a better
position to test the change :-)

Here is a simple patch that works for me. Is the call to xmlBuildURI() still actually necessary?

Michael


Index: parser.c
===================================================================
RCS file: /cvs/gnome/libxml2/parser.c,v
retrieving revision 1.455
diff -u -r1.455 parser.c
--- parser.c    19 Sep 2006 12:44:35 -0000      1.455
+++ parser.c    3 Oct 2006 10:58:41 -0000
@@ -11047,6 +11047,9 @@
     int ret = 0;
     xmlChar start[4];
     xmlCharEncoding enc;
+    xmlParserInputPtr inputStream;
+    char *directory = NULL;
+    xmlChar *uri;

     if (ctx == NULL) return(-1);

@@ -11061,11 +11064,46 @@
     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
        return(-1);

-
-    ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
-    if (ctxt == NULL) return(-1);
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+       return(-1);
+    }
+
     ctxt->userData = ctxt;
     ctxt->_private = ctx->_private;
+
+    uri = xmlBuildURI(URL, NULL);
+
+    if (uri == NULL) {
+       inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
+       if (inputStream == NULL) {
+           xmlFreeParserCtxt(ctxt);
+           return(-1);
+       }
+
+       inputPush(ctxt, inputStream);
+
+       if ((ctxt->directory == NULL) && (directory == NULL))
+           directory = xmlParserGetDirectory((char *)URL);
+       if ((ctxt->directory == NULL) && (directory != NULL))
+           ctxt->directory = directory;
+    } else {
+       inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
+       if (inputStream == NULL) {
+           xmlFree(uri);
+           xmlFreeParserCtxt(ctxt);
+           return(-1);
+       }
+
+       inputPush(ctxt, inputStream);
+
+       if ((ctxt->directory == NULL) && (directory == NULL))
+           directory = xmlParserGetDirectory((char *)uri);
+       if ((ctxt->directory == NULL) && (directory != NULL))
+           ctxt->directory = directory;
+       xmlFree(uri);
+    }
+
     oldsax = ctxt->sax;
     ctxt->sax = ctx->sax;
     xmlDetectSAX2(ctxt);

Index: parser.c
===================================================================
RCS file: /cvs/gnome/libxml2/parser.c,v
retrieving revision 1.455
diff -u -r1.455 parser.c
--- parser.c    19 Sep 2006 12:44:35 -0000      1.455
+++ parser.c    3 Oct 2006 10:58:41 -0000
@@ -11047,6 +11047,9 @@
     int ret = 0;
     xmlChar start[4];
     xmlCharEncoding enc;
+    xmlParserInputPtr inputStream;
+    char *directory = NULL;
+    xmlChar *uri;
 
     if (ctx == NULL) return(-1);
 
@@ -11061,11 +11064,46 @@
     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
        return(-1);
 
-
-    ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
-    if (ctxt == NULL) return(-1);
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+       return(-1);
+    }
+    
     ctxt->userData = ctxt;
     ctxt->_private = ctx->_private;
+    
+    uri = xmlBuildURI(URL, NULL);
+
+    if (uri == NULL) {
+       inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
+       if (inputStream == NULL) {
+           xmlFreeParserCtxt(ctxt);
+           return(-1);
+       }
+
+       inputPush(ctxt, inputStream);
+
+       if ((ctxt->directory == NULL) && (directory == NULL))
+           directory = xmlParserGetDirectory((char *)URL);
+       if ((ctxt->directory == NULL) && (directory != NULL))
+           ctxt->directory = directory;
+    } else {
+       inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
+       if (inputStream == NULL) {
+           xmlFree(uri);
+           xmlFreeParserCtxt(ctxt);
+           return(-1);
+       }
+
+       inputPush(ctxt, inputStream);
+
+       if ((ctxt->directory == NULL) && (directory == NULL))
+           directory = xmlParserGetDirectory((char *)uri);
+       if ((ctxt->directory == NULL) && (directory != NULL))
+           ctxt->directory = directory;
+       xmlFree(uri);
+    }
+    
     oldsax = ctxt->sax;
     ctxt->sax = ctx->sax;
     xmlDetectSAX2(ctxt);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]