--- parser3/src/include/pa_request.h 2009/05/04 09:26:08 1.192 +++ parser3/src/include/pa_request.h 2013/07/23 14:29:02 1.211 @@ -1,14 +1,14 @@ /** @file Parser: request class decl. - Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ #ifndef PA_REQUEST_H #define PA_REQUEST_H -static const char * const IDENT_REQUEST_H="$Date: 2009/05/04 09:26:08 $"; +#define IDENT_PA_REQUEST_H "$Id: pa_request.h,v 1.211 2013/07/23 14:29:02 moko Exp $" #include "pa_pool.h" #include "pa_hash.h" @@ -20,13 +20,10 @@ static const char * const IDENT_REQUEST_ #include "pa_sapi.h" #include "pa_vconsole.h" -#ifdef RESOURCES_DEBUG -#include -#endif - // consts const uint ANTI_ENDLESS_EXECUTE_RECOURSION=1000; +const uint ANTI_ENDLESS_JSON_STRING_RECOURSION=100; const size_t pseudo_file_no__process=1; // forwards @@ -118,10 +115,11 @@ private: ///@{ core data /// classes - HashStringValue fclasses; + HashString fclasses; /// already used files to avoid cyclic uses - Hash used_files; + HashString used_files; + HashString searched_along_class_path; /// list of all used files, Operation::file_no = index to it Array file_list; @@ -130,6 +128,8 @@ private: */ uint anti_endless_execute_recoursion; + uint anti_endless_json_string_recoursion; + ///@} /// execution stack @@ -152,6 +152,7 @@ public: /// interrupted flag, raised on signals [SIGPIPE] bool finterrupted; Skip fskip; + int fin_cycle; public: uint register_file(String::Body file_spec); @@ -181,13 +182,13 @@ public: #endif Request(SAPI_Info& asapi_info, Request_info& arequest_info, - String::Language adefault_lang, ///< all tainted data default untainting lang - bool status_allowed ///< status class allowed + String::Language adefault_lang ///< all tainted data default untainting lang ); ~Request(); /// global classes - HashStringValue& classes() { return fclasses; } + HashString& classes() { return fclasses; } + Value* get_class(const String& name); /** core request processing @@ -203,6 +204,8 @@ public: void execute(ArrayOperation& ops); // execute.C void op_call(VMethodFrame &frame); void op_call_write(VMethodFrame &frame); + Value& construct(Value &class_value, const Method &method); + /// execute ops with anti-recoursion check void recoursion_checked_execute(/*const String& name, */ArrayOperation& ops) { // anti_endless_execute_recoursion @@ -216,21 +219,41 @@ public: anti_endless_execute_recoursion--; } + uint json_string_recoursion_go_down(){ + if(++anti_endless_json_string_recoursion==ANTI_ENDLESS_JSON_STRING_RECOURSION){ + anti_endless_json_string_recoursion=0; + throw Exception(PARSER_RUNTIME, + 0, + "call canceled - endless json recursion detected"); + } + return anti_endless_json_string_recoursion; + } + + void json_string_recoursion_go_up(){ + if(anti_endless_json_string_recoursion) + anti_endless_json_string_recoursion--; + } + + /// + void use_file_directly(VStateless_class& aclass, + const String& file_spec, + bool fail_on_read_problem=true, + bool fail_on_file_absence=true); + /// compiles the file, maybe forcing it's class @a name and @a base_class. void use_file(VStateless_class& aclass, - const String& file_name, - const String* main_alias=0, - bool ignore_class_path=false, - bool fail_on_read_problem=true, - bool fail_on_file_absence=true); // pa_request.C + const String& file_name, + const String* use_filespec); + /// compiles a @a source buffer void use_buf(VStateless_class& aclass, const char* source, const String* main_alias, uint file_no, - int line_no_offset=0); // pa_request.C + int line_no_offset=0); /// processes any code-junction there may be inside of @a value + StringOrValue process_getter(Junction& junction); // execute.C StringOrValue process(Value& input_value, bool intercept_string=true); // execute.C void process_write(Value& input_value); // execute.C //@{ convinient helpers @@ -241,7 +264,8 @@ public: return process(input_value, intercept_string).as_value(); } //@} - + const String* get_method_filename(const Method* method); // execute.C + const String* get_used_filename(uint file_no); #define DEFINE_DUAL(modification) \ void write_##modification##_lang(StringOrValue dual) { \ @@ -291,6 +315,9 @@ public: /// returns an absolute @a path to relative @a name const String& absolute(const String& relative_name); + /// returns the mime type of 'user_file_name' + const String& mime_type_of(const String* file_name); + /// returns the mime type of 'user_file_name_cstr' const String& mime_type_of(const char* user_file_name_cstr); @@ -310,6 +337,9 @@ public: void set_skip(Skip askip) { fskip=askip; } Skip get_skip() { return fskip; } + void set_in_cycle(int adelta) { fin_cycle+=adelta; } + bool get_in_cycle() { return fin_cycle>0; } + public: /// info from web server @@ -335,7 +365,7 @@ public: VConsole& console; /// classes configured data - Hash classes_conf; + HashString classes_conf; public: // status read methods @@ -351,11 +381,15 @@ public: // status read methods } */ + /// public for ^reflection:copy[] + void put_element(Value& ncontext, const String& name, Value* value); + /// for @main[] const String* execute_virtual_method(Value& aself, const String& method_name); - /// for @postprocess[body] - StringOrValue execute_method(VMethodFrame& amethodFrame, const Method& method); + /// executes parser method, use op_call(frame) to execute native method + void execute_method(VMethodFrame& aframe); + //{ for @conf[filespec] and @auto[filespec] and parser://method/call const String* execute_method(Value& aself, const Method& method, Value* optional_param, @@ -401,7 +435,6 @@ private: // compile.C private: // execute.C - void put_element(Value& ncontext, const String& name, Value* value); Value& get_element(Value& ncontext, const String& name); private: // defaults @@ -450,6 +483,7 @@ class Request_context_saver { /// execution stack size_t stack; uint anti_endless_execute_recoursion; + uint anti_endless_json_string_recoursion; /// contexts VMethodFrame* method_frame; Value* rcontext; @@ -466,6 +500,7 @@ public: exception_trace_bottom(ar.exception_trace.bottom_index()), stack(ar.stack.top_index()), anti_endless_execute_recoursion(ar.anti_endless_execute_recoursion), + anti_endless_json_string_recoursion(ar.anti_endless_json_string_recoursion), method_frame(ar.method_frame), rcontext(ar.rcontext), wcontext(ar.wcontext), @@ -476,6 +511,7 @@ public: fr.exception_trace.set_bottom_index(exception_trace_bottom); fr.stack.set_top_index(stack); fr.anti_endless_execute_recoursion=anti_endless_execute_recoursion; + fr.anti_endless_json_string_recoursion=anti_endless_json_string_recoursion; fr.method_frame=method_frame, fr.rcontext=rcontext; fr.wcontext=wcontext; fr.flang=flang; fr.fconnection=fconnection; @@ -510,15 +546,20 @@ public: } }; +/// Auto-object used for break out of cycle check +class InCycle { + Request& frequest; +public: + InCycle(Request& arequest) : frequest(arequest) { + frequest.set_in_cycle(1); + } + ~InCycle() { + frequest.set_in_cycle(-1); + } +}; // defines for externs -#define CONTENT_TRANSFER_ENCODING_NAME "content-transfer-encoding" -#define CONTENT_DISPOSITION_NAME "content-disposition" -#define CONTENT_DISPOSITION_ATTACHMENT "attachment" -#define CONTENT_DISPOSITION_INLINE "inline" -#define CONTENT_DISPOSITION_FILENAME_NAME "filename" - #define EXCEPTION_HANDLED_PART_NAME "handled" @@ -528,12 +569,6 @@ extern const String main_method_name; extern const String auto_method_name; extern const String body_name; -extern const String content_transfer_encoding_name; -extern const String content_disposition_name; -extern const String content_disposition_attachment; -extern const String content_disposition_inline; -extern const String content_disposition_filename_name; - extern const String exception_type_part_name; extern const String exception_source_part_name; extern const String exception_comment_part_name;