--- parser3/src/main/pa_xml_io.C 2003/11/27 15:10:01 1.2 +++ parser3/src/main/pa_xml_io.C 2003/11/28 10:41:11 1.10 @@ -9,13 +9,53 @@ #ifdef XML -static const char * const IDENT="$Date: 2003/11/27 15:10:01 $"; +static const char * const IDENT="$Date: 2003/11/28 10:41:11 $"; #include "libxslt/extensions.h" #include "pa_globals.h" #include "pa_request.h" +#ifndef DOXYGEN +struct MemoryStream { + const char* m_buf; + size_t m_size; + size_t m_position; + + int read(char* a_buffer, size_t a_size) { + size_t left=m_size-m_position; + if(!left) + return 0; + + size_t to_read=min(a_size, left); + memcpy(a_buffer, m_buf, to_read); + m_position+=to_read; + return to_read; + } + +}; +#endif + + +#ifdef PA_SAFE_MODE +static int +xmlFileMatchSafeMode(const char* file_spec_cstr) { + if(strstr(filename, "://")) { + String* file_spec=new String(file_spec_cstr, true); + struct stat finfo; + if(stat(file_spec_cstr, &finfo)!=0) + throw Exception("file.missing", + file_spec, + "stat failed: %s (%d)", + strerror(errno), errno); + + check_safe_mode(finfo, file_spec, file_spec_cstr); + } + return 0; +} +#endif + + /** * xmlFileMatchWithLocalhostEqDocumentRoot: * filename: the URI for matching @@ -45,9 +85,8 @@ xmlFileMatchLocalhost(const char* filena */ static void * xmlFileOpenLocalhost (const char* filename) { - //_asm int 3; - FILE *fd; - const char* document_root=pa_thread_request().request_info.document_root; + Request& r=pa_thread_request(); + const char* document_root=r.request_info.document_root; if(!document_root) document_root="."; @@ -55,92 +94,50 @@ xmlFileOpenLocalhost (const char* filena path[0]=0; strcat(path, document_root); strcat(path, &filename[16]); - -#ifdef WIN32 - fd = fopen(path, "rb"); -#else - fd = fopen(path, "r"); -#endif /* WIN32 */ - return((void *) fd); -} -/** - * xmlFileRead: - * @context: the I/O context - * @buffer: where to drop data - * @len: number of bytes to write - * - * Read @len bytes to @buffer from the I/O channel. - * - * Returns the number of bytes written - */ -static int -pa_xmlFileRead (void * context, char * buffer, int len) { - return(fread(&buffer[0], 1, len, (FILE *) context)); -} + MemoryStream *stream=new(UseGC) MemoryStream; + stream->m_buf=file_read_text(r.charsets, *new String(filename), true); + stream->m_size=strlen(stream->m_buf); -/** - * xmlFileClose: - * @context: the I/O context - * - * Close an I/O channel - */ -static int -pa_xmlFileClose (void * context) { - return ( ( fclose((FILE *) context) == EOF ) ? -1 : 0 ); + return (void *)stream; } -////////////////////////// - -#ifndef DOXYGEN -struct MemoryStream { - const char* m_buf; - size_t m_size; - size_t m_position; - - int read(char* a_buffer, size_t a_size) { - size_t left=m_size-m_position; - if(!left) - return 0; - - size_t to_read=min(a_size, left); - memcpy(a_buffer, m_buf, to_read); - return to_read; - } - -}; -#endif - static int xmlFileMatchMethod(const char* filename) { - if (!strncmp(filename, "parser://", 7 /*strlen("parser://"), and check xmlFileOpenMethod*/)) + if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/)) return(1); return(0); } -/// parser://method/param/here -> ^/abc | ./abc +/// parser://method/param/here -> ^MAIN:method[/params/here] static void * xmlFileOpenMethod (const char* afilename) { - //_asm int 3; Request& r=pa_thread_request(); - char* s=pa_strdup(afilename+7 /*strlen("parser://")*/); + char* s=pa_strdup(afilename+9 /*strlen("parser://")*/); const char* method_cstr=lsplit(&s, '/'); const String* method=new String(method_cstr); + String::Body param_body("/"); + if(s) + param_body.append_know_length(s, strlen(s)); + + VString* vparam=new VString(*new String(param_body, String::L_TAINTED)); { Temp_lang temp_lang(r, String::L_XML); // default language: XML - // @todo: s=params - if(const String* body_string=r.execute_virtual_method(r.main_class, *method)) { + Request::Execute_nonvirtual_method_result body= + r.execute_nonvirtual_method(r.main_class, *method, vparam, true); + if(body.string) { MemoryStream *stream=new(UseGC) MemoryStream; - stream->m_buf=body_string->cstr(String::L_UNSPECIFIED); + stream->m_buf=body.string->cstr(String::L_UNSPECIFIED); stream->m_size=strlen(stream->m_buf); return (void*)stream; } } throw Exception(0, - method, - "not found (referred from parser://name/)"); + new String(afilename), + "'%s' method not found in %s class", + method_cstr, MAIN_CLASS_NAME); } static int @@ -152,12 +149,6 @@ pa_xmlFileReadMethod (void * context, // return stream.read(buffer, len); } -/** - * xmlFileClose: - * @context: the I/O context - * - * Close an I/O channel - */ static int pa_xmlFileCloseMethod (void * /*context*/) { return 0; @@ -166,12 +157,18 @@ pa_xmlFileCloseMethod (void * /*context* void pa_xml_io_init() { +#ifdef PA_SAFE_MODE + // safe mode checker, always fail match, but checks non-"://" there + xmlRegisterInputCallbacks( + xmlFileMatchSafeMode, 0, + 0, 0); +#endif // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc xmlRegisterInputCallbacks( xmlFileMatchLocalhost, xmlFileOpenLocalhost, - pa_xmlFileRead, pa_xmlFileClose); + pa_xmlFileReadMethod, pa_xmlFileCloseMethod); - // parser://method/param/here -> ^/abc | ./abc + // parser://method/param/here -> ^MAIN:method[/params/here] xmlRegisterInputCallbacks( xmlFileMatchMethod, xmlFileOpenMethod, pa_xmlFileReadMethod, pa_xmlFileCloseMethod);