--- parser3/src/classes/op.C 2009/08/08 13:30:20 1.197 +++ parser3/src/classes/op.C 2010/07/05 05:54:46 1.201 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_OP_C="$Date: 2009/08/08 13:30:20 $"; +static const char * const IDENT_OP_C="$Date: 2010/07/05 05:54:46 $"; #include "classes.h" #include "pa_vmethod_frame.h" @@ -66,6 +66,7 @@ public: Untaint_lang_name2enum() { #define ULN(name, LANG) \ put(String::Body(name), (value_type)(String::L_##LANG)); + ULN("clean", CLEAN); ULN("as-is", AS_IS); ULN("optimized-as-is", AS_IS|String::L_OPTIMIZE_BIT); ULN("file-spec", FILE_SPEC); @@ -87,11 +88,19 @@ public: // methods static void _if(Request& r, MethodParams& params) { - bool condition=params.as_bool(0, "condition must be expression", r); - if(condition) - r.process_write(*params.get(1)); - else if(params.count()>2) - r.process_write(*params.get(2)); + size_t max_param=params.count()-1; + size_t i=0; + do { + bool condition=params.as_bool(i, "condition must be expression", r); + if(condition) { + r.process_write(*params.get(i+1)); + return; + } + i+=2; + } while (i < max_param); + + if(i == max_param) + r.process_write(*params.get(i)); } static String::Language get_untaint_lang(MethodParams& params, int index){ @@ -167,9 +176,7 @@ static void _process(Request& r, MethodP Value& voptions=params.as_no_junction(options_index, OPTIONS_MUST_NOT_BE_CODE); options=voptions.get_hash(); if(!options) - throw Exception(PARSER_RUNTIME, - 0, - "options must be hash"); + throw Exception(PARSER_RUNTIME, 0, OPTIONS_MUST_BE_HASH); } const String* main_alias=0; @@ -191,9 +198,7 @@ static void _process(Request& r, MethodP } if(valid_options!=options->count()) - throw Exception(PARSER_RUNTIME, - 0, - "called with invalid option"); + throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION); } uint processe_file_no=file_alias? @@ -283,7 +288,9 @@ static void _while(Request& r, MethodPar static void _use(Request& r, MethodParams& params) { Value& vfile=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE); - r.use_file(r.main_class, vfile.as_string()); + + // _use could be called from the parser3 method only, so caller is always defined + r.use_file(r.main_class, vfile.as_string(), r.get_method_filename(r.get_method_frame()->caller()->junction.method)); } static void set_skip(Request& r, Request::Skip askip) { @@ -883,7 +890,8 @@ VClassMAIN::VClassMAIN(): VClass() { // ^if(condition){code-when-true} // ^if(condition){code-when-true}{code-when-false} - add_native_method("if", Method::CT_ANY, _if, 2, 3, Method::CO_WITHOUT_FRAME); + // ^if(condition){code-when-true} (another condition){code-when-true} ... {code-when-false} + add_native_method("if", Method::CT_ANY, _if, 2, 10000, Method::CO_WITHOUT_FRAME); // ^untaint[as-is|uri|sql|js|html|html-typo|regex|parser-code]{code} add_native_method("untaint", Method::CT_ANY, _untaint, 1, 2, Method::CO_WITHOUT_FRAME);