--- parser3/src/classes/op.C 2010/05/20 04:36:36 1.199 +++ parser3/src/classes/op.C 2010/11/15 23:31:08 1.205 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_OP_C="$Date: 2010/05/20 04:36:36 $"; +static const char * const IDENT_OP_C="$Date: 2010/11/15 23:31:08 $"; #include "classes.h" #include "pa_vmethod_frame.h" @@ -81,6 +81,7 @@ public: ULN("optimized-html", HTML|String::L_OPTIMIZE_BIT); ULN("regex", REGEX); ULN("parser-code", PARSER_CODE); + ULN("json", JSON); #undef ULN } } untaint_lang_name2enum; @@ -88,11 +89,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){ @@ -136,6 +145,13 @@ static void _taint(Request& r, MethodPar } } +static void _apply_taint(Request& r, MethodParams& params) { + String::Language lang=params.count()==1 ? String::L_AS_IS : get_untaint_lang(params, 0); + const String &sbody=params.as_string(params.count()-1, "body must be string"); + String::Body result_body=sbody.cstr_to_string_body_untaint(lang, 0, &r.charsets); + r.write_pass_lang(*new String(result_body, String::L_AS_IS)); +} + static void _process(Request& r, MethodParams& params) { Method* main_method; @@ -168,9 +184,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; @@ -192,9 +206,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? @@ -216,10 +228,10 @@ static void _process(Request& r, MethodP // after restoring current-request-lang // maybe-execute @main[] if(main_method) { - // temporarily set method_frame's self to target_self - Temp_method_frame_self tmfs(*r.get_method_frame(), *target_self); - // execute! - r.execute(*main_method->parser_code); + VMethodFrame frame(*main_method, r.get_method_frame()->caller(), *target_self); + frame.empty_params(); + r.op_call(frame); + r.write_pass_lang(frame.result()); } } @@ -286,7 +298,7 @@ static void _use(Request& r, MethodParam Value& vfile=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE); // _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)); + r.use_file(r.main_class, vfile.as_string(), r.get_method_filename(&r.get_method_frame()->caller()->method)); } static void set_skip(Request& r, Request::Skip askip) { @@ -886,7 +898,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); @@ -894,6 +907,9 @@ VClassMAIN::VClassMAIN(): VClass() { // ^taint[as-is|uri|sql|js|html|html-typo|regex|parser-code]{code} add_native_method("taint", Method::CT_ANY, _taint, 1, 2, Method::CO_WITHOUT_FRAME); + // ^apply-taint[untaint lang][string] + add_native_method("apply-taint", Method::CT_ANY, _apply_taint, 1, 2, Method::CO_WITHOUT_FRAME); + // ^process[code] add_native_method("process", Method::CT_ANY, _process, 1, 3);