--- parser3/src/classes/file.C 2007/02/28 19:08:46 1.153 +++ parser3/src/classes/file.C 2007/11/14 09:45:21 1.161 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_FILE_C="$Date: 2007/02/28 19:08:46 $"; +static const char * const IDENT_FILE_C="$Date: 2007/11/14 09:45:21 $"; #include "pa_config_includes.h" @@ -36,9 +36,6 @@ static const char * const IDENT_FILE_C=" #define NAME_NAME "name" -#define FILE_NAME_MUST_BE_STRING "file name must be string" -#define FILE_NAME_MUST_NOT_BE_CODE "file name must not be code" - // externs extern String sql_limit_name; @@ -117,18 +114,22 @@ static const String::Body cdate_name("cd // methods +static bool is_valid_mode (const String& mode) { + return (mode==TEXT_MODE_NAME || mode==BINARY_MODE_NAME); +} + static bool is_text_mode(const String& mode) { if(mode==TEXT_MODE_NAME) return true; if(mode==BINARY_MODE_NAME) return false; - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, &mode, "is invalid mode, must be either '"TEXT_MODE_NAME"' or '"BINARY_MODE_NAME"'"); } static void _save(Request& r, MethodParams& params) { - Value& vmode_name=params. as_no_junction(0, "mode must not be code"); + Value& vmode_name=params.as_no_junction(0, MODE_MUST_NOT_BE_CODE); Value& vfile_name=params.as_no_junction(1, FILE_NAME_MUST_NOT_BE_CODE); // save @@ -185,8 +186,6 @@ static void _copy(Request& r, MethodPara String from_spec = r.absolute(vfrom_file_name.as_string()); const String& to_spec = r.absolute(vto_file_name.as_string()); - // create_dir_for_file(to_spec); - file_write_action_under_lock( to_spec, "copy", @@ -201,7 +200,7 @@ static void _load_pass_param( dest->put(key, value); } static void _load(Request& r, MethodParams& params) { - Value& vmode_name=params. as_no_junction(0, "mode must not be code"); + Value& vmode_name=params.as_no_junction(0, MODE_MUST_NOT_BE_CODE); const String& lfile_name=r.absolute(params.as_no_junction(1, FILE_NAME_MUST_NOT_BE_CODE).as_string()); Value* third_param=params.count()>2?¶ms.as_no_junction(2, "filename or options must not be code") :0; @@ -248,9 +247,9 @@ static void _load(Request& r, MethodPara } static void _create(Request& r, MethodParams& params) { - Value& vmode_name=params. as_no_junction(0, "mode must not be code"); + Value& vmode_name=params.as_no_junction(0, MODE_MUST_NOT_BE_CODE); if(!is_text_mode(vmode_name.as_string())) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "only text mode is currently supported"); @@ -319,7 +318,7 @@ static void append_env_pair( // ignore, already processed } else { if(!is_safe_env_key(akey.cstr())) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, new String(akey, String::L_TAINTED), "not safe environment variable"); info->env->put(akey, avalue->as_string().cstr_to_string_body(String::L_UNSPECIFIED, 0, info->charsets)); @@ -345,6 +344,13 @@ static void pass_cgi_header_attribute( info->content_type=value; } } + +static void append_to_argv(Request& r, ArrayString& argv, const String* str){ + if( str->length() ){ + argv+=new String(str->cstr_to_string_body(String::L_UNSPECIFIED, 0, &r.charsets), String::L_AS_IS); + } +} + /// @todo fix `` in perl - they produced flipping consoles and no output to perl static void _exec_cgi(Request& r, MethodParams& params, bool cgi) { @@ -415,7 +421,7 @@ static void _exec_cgi(Request& r, Method if(VFile* vfile=static_cast(info.vstdin->as("file", false))) in->append_know_length((const char* )vfile->value_ptr(), vfile->value_size(), String::L_TAINTED); else - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, STDIN_EXEC_PARAM_NAME " parameter must be string or file"); } @@ -428,10 +434,24 @@ static void _exec_cgi(Request& r, Method // influence tainting // main target -- URLencoding of tainted pieces to String::L_URI lang Temp_client_charset temp(r.charsets, charset? *charset: r.charsets.source()); + for(size_t i=2; i 0) { - argv+=new String(param.cstr_to_string_body(String::L_UNSPECIFIED, 0, &r.charsets), String::L_AS_IS); + Value& param=params.as_no_junction(i, PARAM_MUST_NOT_BE_CODE); + if(param.is_defined()){ + if(param.is_string()){ + append_to_argv(r, argv, param.get_string()); + } else { + Table* table=param.get_table(); + if(table){ + for(size_t i=0; icount(); i++) { + append_to_argv(r, argv, table->get(i)->get(0)); + } + } else { + throw Exception(PARSER_RUNTIME, + 0, + "parameter must be string or table"); + } + } } } } @@ -620,7 +640,11 @@ static void _lock(Request& r, MethodPara ¶ms.as_junction(1, "body must be code") }; - file_write_action_under_lock(file_spec, "lock", lock_execute_body, &info); + file_write_action_under_lock( + file_spec, + "lock", + lock_execute_body, + &info); } static int lastposafter(const String& s, size_t after, const char* substr, size_t substr_size, bool beforelast=false) { @@ -755,7 +779,7 @@ public: bool add_column(SQL_Error& error, const char* /*str*/, size_t /*length*/) { if(got_columns++==3) { - error=SQL_Error("parser.runtime", "result must contain not more then 3 columns"); + error=SQL_Error(PARSER_RUNTIME, "result must contain not more then 3 columns"); return true; } return false; @@ -777,7 +801,7 @@ public: user_content_type=new String(str, length, true); break; default: - error=SQL_Error("parser.runtime", "result must not contain more then one row, three rows"); + error=SQL_Error(PARSER_RUNTIME, "result must not contain more then one row, three rows"); return true; } return false; @@ -799,7 +823,7 @@ static void _sql(Request& r, MethodParam if(params.count()>1) if(HashStringValue* options= - params.as_no_junction(1, "param must not be code").get_hash()) { + params.as_no_junction(1, PARAM_MUST_NOT_BE_CODE).get_hash()) { int valid_options=0; if(Value* vfilename=options->get(NAME_NAME)) { valid_options++; @@ -810,7 +834,7 @@ static void _sql(Request& r, MethodParam handlers.user_content_type=&vcontent_type->as_string(); } if(valid_options!=options->count()) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "called with invalid option"); } @@ -824,7 +848,7 @@ static void _sql(Request& r, MethodParam statement_string); if(!handlers.value) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "produced no result"); @@ -845,7 +869,7 @@ static void _base64(Request& r, MethodPa VFile& self=GET_SELF(r, VFile); if(params.count()) { // decode - const char* cstr=params.as_string(0, "parameter must be string").cstr(); + const char* cstr=params.as_string(0, PARAMETER_MUST_BE_STRING).cstr(); char* decoded_cstr=0; size_t decoded_size=0; pa_base64_decode(cstr, strlen(cstr), decoded_cstr, decoded_size); @@ -872,7 +896,7 @@ static void _crc32(Request& r, MethodPar const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); crc32=pa_crc32(r.absolute(file_spec)); } else { - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "file name must be defined"); } @@ -934,7 +958,7 @@ static void _md5(Request& r, MethodParam const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); md5=pa_md5(r.absolute(file_spec)); } else { - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "file name must be defined"); }