Diff for /parser3/src/main/pa_xml_io.C between versions 1.18.10.1 and 1.36

version 1.18.10.1, 2005/08/05 13:03:03 version 1.36, 2019/11/05 19:25:51
Line 1 Line 1
 /** @file  /** @file
         Parser: plugins to xml library, controlling i/o; implementation          Parser: plugins to xml library, controlling i/o; implementation
   
         Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
Line 9 Line 9
   
 #ifdef XML  #ifdef XML
   
 static const char * const IDENT="$Date$";  volatile const char * IDENT_PA_XML_IO_C="$Id$" IDENT_PA_XML_IO_H;
   
 #include "libxslt/extensions.h"  #include "libxslt/extensions.h"
   
Line 17  static const char * const IDENT="$Date$" Line 17  static const char * const IDENT="$Date$"
 #include "pa_globals.h"  #include "pa_globals.h"
 #include "pa_request.h"  #include "pa_request.h"
   
 static Hash<pa_thread_t, HashStringBool*> xml_dependencies;  THREAD_LOCAL HashStringBool* xml_dependencies = NULL;
   
 static void add_dependency(const String::Body url) {   static void add_dependency(const String::Body url) { 
         pa_thread_t thread_id=pa_get_thread_id();          if(xml_dependencies) // do we need to monitor now?
         HashStringBool* urls;                  xml_dependencies->put(url, true);
         {  
                 SYNCHRONIZED;  
   
                 // try to get existing for this thread_id  
                 urls=xml_dependencies.get(thread_id);  
         }  
   
         if(urls) // do we need to monitor now?  
                 urls->put(url, true);  
 }  }
   
 void pa_xmlStartMonitoringDependencies() {   void pa_xmlStartMonitoringDependencies() { 
         pa_thread_t thread_id=pa_get_thread_id();          xml_dependencies=new HashStringBool;
         HashStringBool* urls=new HashStringBool;  
         {  
                 SYNCHRONIZED;  // find+fill blocked  
   
                 xml_dependencies.put(thread_id, urls);  
         }  
 }  }
   
 void pa_xmlStopMonitoringDependencies() {   void pa_xmlStopMonitoringDependencies() { 
         pa_thread_t thread_id=pa_get_thread_id();          xml_dependencies=NULL;
         {  
                 SYNCHRONIZED;  // find+fill blocked  
   
                 xml_dependencies.put(thread_id, 0);  
         }  
 }  }
   
 HashStringBool* pa_xmlGetDependencies() {  HashStringBool* pa_xmlGetDependencies() {
         pa_thread_t thread_id=pa_get_thread_id();          HashStringBool* result=xml_dependencies;
         {          xml_dependencies=NULL;
                 SYNCHRONIZED;  // find+remove blocked          return result;
   
                 HashStringBool* result=xml_dependencies.get(thread_id);  
                 xml_dependencies.remove(thread_id);  
                 return result;  
         }  
 }  }
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
 struct MemoryStream {  struct MemoryStream : public PA_Allocated {
         const char* m_buf;          const char* m_buf;
         size_t m_size;          size_t m_size;
         size_t m_position;          size_t m_position;
   
           MemoryStream(const char *a_buf) : m_buf(a_buf), m_size(strlen(m_buf)), m_position(0) {}
   
         int read(char* a_buffer, size_t a_size) {          int read(char* a_buffer, size_t a_size) {
                 size_t left=m_size-m_position;                  size_t left=m_size-m_position;
                 if(!left)                  if(!left)
Line 83  struct MemoryStream { Line 60  struct MemoryStream {
 };  };
 #endif  #endif
   
 static void *  static void * xmlFileOpen_ReadIntoStream (const char* do_not_store_filename, bool adjust_path_to_root_from_document_root=false) {
 xmlFileOpen_ReadIntoStream (const char* do_not_store_filename, bool adjust_path_to_root_from_document_root=false) {  
 #ifdef PA_SAFE_MODE  #ifdef PA_SAFE_MODE
 //copied from libxml/catalog.c  //copied from libxml/catalog.c
 #       define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"  #       define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
Line 94  xmlFileOpen_ReadIntoStream (const char* Line 70  xmlFileOpen_ReadIntoStream (const char*
 #endif  #endif
   
         Request& r=pa_thread_request();          Request& r=pa_thread_request();
         char adjust_buf[MAX_STRING];              char adjust_buf[MAX_STRING];
         if(adjust_path_to_root_from_document_root) {          if(adjust_path_to_root_from_document_root) {
                 const char* document_root=r.request_info.document_root;                  const char* document_root=r.request_info.document_root;
                 if(!document_root)                  if(!document_root)
Line 105  xmlFileOpen_ReadIntoStream (const char* Line 81  xmlFileOpen_ReadIntoStream (const char*
                 strcat(adjust_buf, &do_not_store_filename[16]);                  strcat(adjust_buf, &do_not_store_filename[16]);
                 do_not_store_filename=adjust_buf;                  do_not_store_filename=adjust_buf;
         } else          } else
                 if(strstr(do_not_store_filename, "file://"))                  if(!strstr(do_not_store_filename, "http://")) {
                         do_not_store_filename+=7/*strlen("file://")*/;                           if(strstr(do_not_store_filename, "file://")) {
                 else if(*do_not_store_filename && do_not_store_filename[1]!=':' && strstr(do_not_store_filename, "://"))  {                                  do_not_store_filename+=7 /*strlen("file://")*/;
                         pa_xmlStopMonitoringDependencies();  #ifdef WIN32
                         return 0; // plug out [do not handle other prefixes]                                  if(
                                           do_not_store_filename[0]=='/'
                                           && do_not_store_filename[1]
                                           && do_not_store_filename[2]==':'
                                           && do_not_store_filename[3]=='/'
                                   ) {
                                           // skip leading slash for absolute path file:///C:/path/to/file
                                           do_not_store_filename++;
                                   }
   #endif
                           } else if(*do_not_store_filename && do_not_store_filename[1]!=':' && strstr(do_not_store_filename, "://")) {
                                   pa_xmlStopMonitoringDependencies();
                                   return 0; // plug out [do not handle other prefixes]
                           }
                 }                  }
   
         const char* can_store_filename=pa_strdup(do_not_store_filename);          const char* can_store_filename=pa_strdup(do_not_store_filename);
Line 117  xmlFileOpen_ReadIntoStream (const char* Line 106  xmlFileOpen_ReadIntoStream (const char*
   
         const char *buf;          const char *buf;
         try {          try {
                 buf=file_read_text(r.charsets, *new String(can_store_filename));                  buf=file_load_text(r, *new String(can_store_filename), 
                           true /*fail_on_read_problem*/,
                           0 /*params*/,
                           false /*don't transcode result because it must be fit with @encoding value!*/);
         } catch(const Exception& e) {          } catch(const Exception& e) {
                 if(strcmp(e.type(), "file.missing")==0)                  if(strcmp(e.type(), "file.missing")==0)
                         return 0; // let the library try that and report an error properly                          return 0; // let the library try that and report an error properly
Line 126  xmlFileOpen_ReadIntoStream (const char* Line 118  xmlFileOpen_ReadIntoStream (const char*
         } catch(...) {          } catch(...) {
                 buf="xmlFileOpen_ReadIntoStream: unknown error";                  buf="xmlFileOpen_ReadIntoStream: unknown error";
         }          }
         MemoryStream* stream=new(UseGC) MemoryStream;          return (void *)new MemoryStream(buf);
         stream->m_buf=buf;  
         stream->m_size=strlen(buf);  
         return (void *)stream;  
 }  }
   
 static int  static int xmlFileMatchMonitor(const char* /*file_spec_cstr*/) {
 xmlFileMatchMonitor(const char* /*file_spec_cstr*/) {  
         return 1; // always intercept, causing xmlFileOpenMonitor to be called          return 1; // always intercept, causing xmlFileOpenMonitor to be called
 }  }
 static void *  
 xmlFileOpenMonitor(const char* filename) {  static void *xmlFileOpenMonitor(const char* filename) {
         return xmlFileOpen_ReadIntoStream(filename); // handles localfile case, else returns 0          return xmlFileOpen_ReadIntoStream(filename); // handles localfile case, else returns 0
 }  }
   
   
 /**  /**
  * xmlFileMatchWithLocalhostEqDocumentRoot:   * xmlFileMatchWithLocalhostEqDocumentRoot:
  * filename:  the URI for matching   * filename:  the URI for matching
Line 150  xmlFileOpenMonitor(const char* filename) Line 137  xmlFileOpenMonitor(const char* filename)
  *   *
  * Returns 1 if matches, 0 otherwise   * Returns 1 if matches, 0 otherwise
  */   */
 static int  static int xmlFileMatchLocalhost(const char* filename) {
 xmlFileMatchLocalhost(const char* filename) {          return !strncmp(filename, "http://localhost", 16);
         if (!strncmp(filename, "http://localhost", 16))  
                 return(1);  
         return(0);  
 }  }
   
 /**  /**
Line 165  xmlFileMatchLocalhost(const char* filena Line 149  xmlFileMatchLocalhost(const char* filena
  *   *
  * Returns an I/O context or NULL in case of error   * Returns an I/O context or NULL in case of error
  */   */
 static void *  static void *xmlFileOpenLocalhost(const char* filename) {
 xmlFileOpenLocalhost (const char* filename) {  
         return xmlFileOpen_ReadIntoStream(filename, true/*adjust path to root from document_root*/);          return xmlFileOpen_ReadIntoStream(filename, true/*adjust path to root from document_root*/);
 }  }
   
 static int  static int xmlFileMatchMethod(const char* filename) {
 xmlFileMatchMethod(const char* filename) {          return !strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/);
         if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))  
                 return(1);  
         return(0);  
 }  }
   
 /// parser://method/param/here -> ^MAIN:method[/params/here]  /// parser://method/param/here -> ^MAIN:method[/params/here]
 static void *  static void *xmlFileOpenMethod (const char* afilename) {
 xmlFileOpenMethod (const char* afilename) {  
         const char* buf;          const char* buf;
         try {          try {
                 Request& r=pa_thread_request();                  Request& r=pa_thread_request();
Line 192  xmlFileOpenMethod (const char* afilename Line 171  xmlFileOpenMethod (const char* afilename
                         param_body.append_know_length(s, strlen(s));                          param_body.append_know_length(s, strlen(s));
   
                 VString* vparam=new VString(*new String(param_body, String::L_TAINTED));                  VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
                 {                  Request::Execute_nonvirtual_method_result body=r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
                         Temp_lang temp_lang(r, String::L_XML); // default language: XML                  if(body.string) {
                         Request::Execute_nonvirtual_method_result body=                          buf=body.string->untaint_cstr(String::L_XML);
                                 r.execute_nonvirtual_method(r.main_class, *method, vparam, true);                  } else
                         if(body.string) {                          throw Exception(0, new String(afilename), "'%s' method not found in %s class", method_cstr, MAIN_CLASS_NAME);
                                 buf=body.string->cstr(String::L_UNSPECIFIED);  
                         } else  
                                 throw Exception(0,  
                                         new String(afilename),  
                                         "'%s' method not found in %s class",   
                                                         method_cstr, MAIN_CLASS_NAME);  
                 }  
         } catch(const Exception& e) {          } catch(const Exception& e) {
                 buf=e.comment();                  buf=e.comment();
         } catch(...) {          } catch(...) {
                 buf="xmlFileOpenLocalhost: unknown error";                  buf="xmlFileOpenLocalhost: unknown error";
         }          }
         MemoryStream* stream=new(UseGC) MemoryStream;          return (void *)new MemoryStream(buf);
         stream->m_buf=buf;  
         stream->m_size=strlen(buf);  
         return (void *)stream;  
 }  }
   
 /**  /**
Line 225  xmlFileOpenMethod (const char* afilename Line 194  xmlFileOpenMethod (const char* afilename
  *   *
  * Returns the number of bytes written   * Returns the number of bytes written
  */   */
 static int  static int pa_xmlFileReadMethod (void* context, char* buffer, int len){
 pa_xmlFileReadMethod (void * context, //< MemoryStream actually  
                                           char * buffer, int len)   
 {  
         MemoryStream& stream=*static_cast<MemoryStream*>(context);          MemoryStream& stream=*static_cast<MemoryStream*>(context);
   
         return stream.read(buffer, len);          return stream.read(buffer, len);
 }  }
   
 static int  static int pa_xmlFileCloseMethod (void* /*context*/) {
 pa_xmlFileCloseMethod (void * /*context*/) {  
         return 0;          return 0;
 }  }
   
   
   
 void pa_xml_io_init() {  void pa_xml_io_init() {
         // file open monitorer [for xslt cacher]          // file open monitorer [for xslt cacher]
         // safe mode checker, always fail match, but checks non-"://" there          // safe mode checker, always fail match, but checks non-"://" there
         xmlRegisterInputCallbacks(          xmlRegisterInputCallbacks(xmlFileMatchMonitor, xmlFileOpenMonitor, pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
                 xmlFileMatchMonitor, xmlFileOpenMonitor,  
                 pa_xmlFileReadMethod, pa_xmlFileCloseMethod);  
   
         // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc          // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
         xmlRegisterInputCallbacks(          xmlRegisterInputCallbacks(xmlFileMatchLocalhost, xmlFileOpenLocalhost, pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
                 xmlFileMatchLocalhost, xmlFileOpenLocalhost,  
                 pa_xmlFileReadMethod, pa_xmlFileCloseMethod);  
   
         // parser://method/param/here -> ^MAIN:method[/params/here]          // parser://method/param/here -> ^MAIN:method[/params/here]
         xmlRegisterInputCallbacks(          xmlRegisterInputCallbacks(xmlFileMatchMethod, xmlFileOpenMethod, pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
                 xmlFileMatchMethod, xmlFileOpenMethod,  
                 pa_xmlFileReadMethod, pa_xmlFileCloseMethod);  
 }  }
   
 #endif  #endif

Removed from v.1.18.10.1  
changed lines
  Added in v.1.36


E-mail: