--- parser3/src/classes/op.C 2016/10/04 13:23:46 1.236 +++ parser3/src/classes/op.C 2016/11/01 23:10:40 1.243 @@ -18,7 +18,7 @@ #include "pa_vclass.h" #include "pa_charset.h" -volatile const char * IDENT_OP_C="$Id: op.C,v 1.236 2016/10/04 13:23:46 moko Exp $"; +volatile const char * IDENT_OP_C="$Id: op.C,v 1.243 2016/11/01 23:10:40 moko Exp $"; // defines @@ -86,14 +86,14 @@ static void _if(Request& r, MethodParams do { bool condition=params.as_bool(i, "condition must be expression", r); if(condition) { - r.process_write(*params.get(i+1)); + r.process_write(params[i+1]); return; } i+=2; } while (i < max_param); if(i == max_param) - r.process_write(*params.get(i)); + r.process_write(params[i]); } String::Language get_untaint_lang(const String& lang_name){ @@ -106,17 +106,19 @@ String::Language get_untaint_lang(const static void _untaint(Request& r, MethodParams& params) { String::Language lang; if(params.count()==1) - lang=String::L_AS_IS; // mark as simply 'as-is'. useful in html from sql + lang=String::L_AS_IS; // mark as simply 'as-is'. useful in html from sql else lang=get_untaint_lang(params.as_string(0, "lang must be string")); - { - Value& vbody=params.as_junction(params.count()-1, "body must be code"); - - Temp_lang temp_lang(r, lang); // set temporarily specified ^untaint[language; - Value& result=r.process(vbody); // process marking tainted with that lang - r.write_assign_lang(result); - } + Value& vbody=params.as_junction(params.count()-1, "body must be code"); + Value& result=r.process(vbody); + + if(const String* string=result.get_string()){ + String &untainted=*new String(); + string->append_to(untainted, lang); // mark all tainted to specified language + r.write(untainted); + } else + r.write(result); // this is not normal, just backward compatibility } static void _taint(Request& r, MethodParams& params) { @@ -130,7 +132,7 @@ static void _taint(Request& r, MethodPar Value& vbody=params.as_no_junction(params.count()-1, "body must not be code"); String result(vbody.as_string(), lang); // force result language to specified - r.write_assign_lang(result); + r.write(result); } } @@ -138,7 +140,7 @@ static void _apply_taint(Request& r, Met String::Language lang=params.count()==1 ? String::L_AS_IS : get_untaint_lang(params.as_string(0, "lang must be string")); const String &sbody=params.as_string(params.count()-1, "body must be string"); String::Body result_body=sbody.cstr_to_string_body_untaint(lang, r.connection(false), &r.charsets); - r.write_pass_lang(*new String(result_body, String::L_AS_IS)); + r.write(*new String(result_body, String::L_AS_IS)); } static void _process(Request& r, MethodParams& params) { @@ -161,8 +163,6 @@ static void _process(Request& r, MethodP if(!target_class) throw Exception(PARSER_RUNTIME, 0, "no target class"); - // temporary remove language change - Temp_lang temp_lang(r, String::L_PARSER_CODE); // temporary zero @main so to maybe-replace it in processed code Temp_method temp_method_main(*target_class, main_method_name, 0); @@ -208,7 +208,7 @@ static void _process(Request& r, MethodP Temp_class_replace class_replace(r, allow_class_replace); - r.use_buf(*target_class, source.untaint_cstr(String::L_AS_IS, r.connection(false)), main_alias, processe_file_no, line_no_alias_offset); + r.use_buf(*target_class, source.untaint_cstr(String::L_PARSER_CODE, r.connection(false)), main_alias, processe_file_no, line_no_alias_offset); // main_method main_method=target_class->get_method(main_method_name); @@ -218,8 +218,8 @@ static void _process(Request& r, MethodP if(main_method) { VMethodFrame frame(*main_method, r.get_method_frame()->caller(), *target_self); frame.empty_params(); - r.op_call(frame); - r.write_pass_lang(frame.result()); + r.call(frame); + r.write(frame.result()); } } @@ -243,7 +243,7 @@ static void _while(Request& r, MethodPar if(++endless_loop_count>=pa_loop_limit) // endless loop? throw Exception(PARSER_RUNTIME, 0, "endless loop detected"); - if(!r.process(vcondition, false/*don't intercept string*/).as_bool()) + if(!r.process(vcondition).as_bool()) break; Value& sv_processed=r.process(body_code); @@ -252,11 +252,11 @@ static void _while(Request& r, MethodPar const String* s_processed=sv_processed.get_string(); if(s_processed && !s_processed->is_empty()) { // we have body if(need_delim) // need delim & iteration produced string? - r.write_pass_lang(r.process(*delim_maybe_code)); + r.write(r.process(*delim_maybe_code)); else need_delim=true; } - r.write_pass_lang(sv_processed); + r.write(sv_processed); if(lskip==Request::SKIP_BREAK) break; @@ -266,7 +266,7 @@ static void _while(Request& r, MethodPar if(++endless_loop_count>=pa_loop_limit) // endless loop? throw Exception(PARSER_RUNTIME, 0, "endless loop detected"); - if(!r.process(vcondition, false/*don't intercept string*/).as_bool()) + if(!r.process(vcondition).as_bool()) break; r.process_write(body_code); @@ -349,11 +349,11 @@ static void _for(Request& r, MethodParam const String* s_processed=sv_processed.get_string(); if(s_processed && !s_processed->is_empty()) { // we have body if(need_delim) // need delim & iteration produced string? - r.write_pass_lang(r.process(*delim_maybe_code)); + r.write(r.process(*delim_maybe_code)); else need_delim=true; } - r.write_pass_lang(sv_processed); + r.write(sv_processed); if(lskip==Request::SKIP_BREAK) break; @@ -374,17 +374,16 @@ static void _for(Request& r, MethodParam static void _eval(Request& r, MethodParams& params) { Value& expr=params.as_junction(0, "need expression"); // evaluate expresion - Value& value_result=r.process(expr, - false/*don't intercept string*/).as_expr_result(); + Value& value_result=r.process(expr).as_expr_result(); if(params.count()>1) { const String& fmt=params.as_string(1, "fmt must be string").trim(); if(fmt.is_empty()){ - r.write_no_lang(value_result); + r.write(value_result); } else { - r.write_no_lang(String(format(value_result.as_double(), fmt.cstrm()))); + r.write(String(format(value_result.as_double(), fmt.cstrm()))); } } else - r.write_no_lang(value_result); + r.write(value_result); } static void _connect(Request& r, MethodParams& params) { @@ -450,9 +449,9 @@ static void _switch(Request& r, MethodPa Value& cases_code=params.as_junction(1, "switch cases must be code"); // execution of found ^case[...]{code} must be in context of ^switch[...]{code} // because of stacked WWrapper used there as wcontext - r.process(cases_code, true/*intercept_string*/); + r.process(cases_code); if(Value* selected_code=data->found? data->found: data->_default) - r.write_pass_lang(r.process(*selected_code)); + r.write(r.process(*selected_code)); } static void _case(Request& r, MethodParams& params) { @@ -734,7 +733,7 @@ static void _cache(Request& r, MethodPar Cache_scope* scope=static_cast(r.classes_conf.get(cache_data_name)); if(!scope) throw Exception(PARSER_RUNTIME, 0, "expire-time get without cache"); - r.write_no_lang(*new VDate((pa_time_t)scope->expires)); + r.write(*new VDate((pa_time_t)scope->expires)); return; } @@ -783,7 +782,7 @@ static void _cache(Request& r, MethodPar scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[] } else { // and it's not expired yet write it out - r.write_assign_lang(*cached.body); + r.write(*cached.body); // happy with it return; } @@ -795,7 +794,7 @@ static void _cache(Request& r, MethodPar const String* processed_body=locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec); if(processed_body){ // write it out - r.write_assign_lang(*processed_body); + r.write(*processed_body); // happy with it return; } else { @@ -809,9 +808,9 @@ static void _cache(Request& r, MethodPar // process without caching if(catch_code){ Try_catch_result result=try_catch(r, process_try_body_code, &body_code, catch_code); - r.write_assign_lang(result.processed_code); + r.write(result.processed_code); } else { - r.write_assign_lang(r.process_to_string(body_code)); + r.write(r.process_to_string(body_code)); } } @@ -840,13 +839,13 @@ static void _try_operator(Request& r, Me Value& finally_result=r.process(*finally_code); // no exception in try/catch or finally, writing processed body_code or catch_code - r.write_pass_lang(result.processed_code); + r.write(result.processed_code); // write out processed finally code - r.write_pass_lang(finally_result); + r.write(finally_result); } else { // no exception in try/catch, writing processed body_code or catch_code - r.write_pass_lang(result.processed_code); + r.write(result.processed_code); } } @@ -937,7 +936,7 @@ VClassMAIN::VClassMAIN(): VClass(MAIN_CL add_native_method("continue", Method::CT_ANY, _continue, 0, 1, Method::CO_WITHOUT_FRAME); // ^for[i](from-number;to-number-inclusive){code}[delim] - add_native_method("for", Method::CT_ANY, _for, 3+1, 3+1+1, Method::CO_WITHOUT_WCONTEXT); + add_native_method("for", Method::CT_ANY, _for, 3+1, 3+1+1); // ^eval(expr) // ^eval(expr)[format]