--- parser3/src/classes/file.C 2007/02/07 15:50:32 1.151 +++ parser3/src/classes/file.C 2007/08/20 10:02:51 1.159 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_FILE_C="$Date: 2007/02/07 15:50:32 $"; +static const char * const IDENT_FILE_C="$Date: 2007/08/20 10:02:51 $"; #include "pa_config_includes.h" @@ -119,14 +119,14 @@ static bool is_text_mode(const String& m 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& vfile_name=params.as_no_junction(1, "file name must not be code"); + Value& vfile_name=params.as_no_junction(1, FILE_NAME_MUST_NOT_BE_CODE); // save GET_SELF(r, VFile).save(r.absolute(vfile_name.as_string()), @@ -134,7 +134,7 @@ static void _save(Request& r, MethodPara } static void _delete(Request& r, MethodParams& params) { - Value& vfile_name=params.as_no_junction(0, "file name must not be code"); + Value& vfile_name=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE); // unlink file_delete(r.absolute(vfile_name.as_string())); @@ -182,8 +182,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", @@ -199,7 +197,7 @@ static void _load_pass_param( } static void _load(Request& r, MethodParams& params) { 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()); + 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; HashStringValue* third_param_hash=third_param?third_param->get_hash():0; @@ -226,7 +224,7 @@ static void _load(Request& r, MethodPara ); const char *user_file_name=params.count()>alt_filename_param_index? - params.as_string(alt_filename_param_index, "filename must be string").cstr() + params.as_string(alt_filename_param_index, FILE_NAME_MUST_BE_STRING).cstr() :lfile_name.cstr(String::L_FILE_SPEC); Value* vcontent_type=0; @@ -247,12 +245,12 @@ 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"); if(!is_text_mode(vmode_name.as_string())) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "only text mode is currently supported"); const char* user_file_name_cstr=r.absolute( - params.as_no_junction(1, "file name must not be code").as_string()).cstr(String::L_FILE_SPEC); + params.as_no_junction(1, FILE_NAME_MUST_NOT_BE_CODE).as_string()).cstr(String::L_FILE_SPEC); const String& content=params.as_string(2, "content must be string"); const char* content_cstr=content.cstr(String::L_UNSPECIFIED); // explode content, honor tainting changes @@ -264,7 +262,7 @@ static void _create(Request& r, MethodPa } static void _stat(Request& r, MethodParams& params) { - Value& vfile_name=params.as_no_junction(0, "file name must not be code"); + Value& vfile_name=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE); const String& lfile_name=vfile_name.as_string(); @@ -316,7 +314,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)); @@ -342,11 +340,18 @@ 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) { - Value& vfile_name=params.as_no_junction(0, "file name must not be code"); + Value& vfile_name=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE); const String& script_name=r.absolute(vfile_name.as_string()); @@ -412,7 +417,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"); } @@ -425,10 +430,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, "parameter 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"); + } + } } } } @@ -611,13 +630,17 @@ static void lock_execute_body(int , void info.r->write_assign_lang(info.r->process(*info.body_code)); }; static void _lock(Request& r, MethodParams& params) { - const String& file_spec=r.absolute(params.as_string(0, "file name must be string")); + const String& file_spec=r.absolute(params.as_string(0, FILE_NAME_MUST_BE_STRING)); Lock_execute_body_info info={ &r, ¶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) { @@ -636,7 +659,7 @@ static int lastposafter(const String& s, } static void _find(Request& r, MethodParams& params) { - const String& file_name=params.as_no_junction(0, "file name must not be code").as_string(); + const String& file_name=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE).as_string(); const String* file_spec; if(file_name.first_char()=='/') file_spec=&file_name; @@ -673,7 +696,7 @@ static void _find(Request& r, MethodPara } static void _dirname(Request& r, MethodParams& params) { - const String& file_spec=params.as_string(0, "file name must be string"); + const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); // /a/some.tar.gz > /a // /a/b/ > /a int afterslash=lastposafter(file_spec, 0, "/", 1, true); @@ -684,21 +707,21 @@ static void _dirname(Request& r, MethodP } static void _basename(Request& r, MethodParams& params) { - const String& file_spec=params.as_string(0, "file name must be string"); + const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); // /a/some.tar.gz > some.tar.gz int afterslash=lastposafter(file_spec, 0, "/", 1); r.write_assign_lang(file_spec.mid(afterslash, file_spec.length())); } static void _justname(Request& r, MethodParams& params) { - const String& file_spec=params.as_string(0, "file name must be string"); + const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); // /a/some.tar.gz > some.tar int afterslash=lastposafter(file_spec, 0, "/", 1); int afterdot=lastposafter(file_spec, afterslash, ".", 1); r.write_assign_lang(file_spec.mid(afterslash, afterdot!=afterslash?afterdot-1:file_spec.length())); } static void _justext(Request& r, MethodParams& params) { - const String& file_spec=params.as_string(0, "file name must be string"); + const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); // /a/some.tar.gz > gz int afterdot=lastposafter(file_spec, 0, ".", 1); if(afterdot>0) @@ -706,7 +729,7 @@ static void _justext(Request& r, MethodP } static void _fullpath(Request& r, MethodParams& params) { - const String& file_spec=params.as_string(0, "file name must be string"); + const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); const String* result; if(file_spec.first_char()=='/') result=&file_spec; @@ -752,7 +775,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; @@ -774,7 +797,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; @@ -807,7 +830,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"); } @@ -821,7 +844,7 @@ static void _sql(Request& r, MethodParam statement_string); if(!handlers.value) - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "produced no result"); @@ -855,7 +878,7 @@ static void _base64(Request& r, MethodPa } } else { // encode - const String& file_spec=params.as_string(0, "file name must be string"); + const String& file_spec=params.as_string(0, FILE_NAME_MUST_BE_STRING); const char* encoded=pa_base64_encode(r.absolute(file_spec)); r.write_assign_lang(*new String(encoded, 0, true/*once ?param=base64(something) was needed*/)); } @@ -866,10 +889,10 @@ static void _crc32(Request& r, MethodPar if(&r.get_self() == file_class) { // ^file:crc32[file-name] if(params.count()) { - const String& file_spec=params.as_string(0, "file name must be string"); + 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"); } @@ -928,10 +951,10 @@ static void _md5(Request& r, MethodParam if(&r.get_self() == file_class) { // ^file:md5[file-name] if(params.count()) { - const String& file_spec=params.as_string(0, "file name must be string"); + 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"); }