--- parser3/src/classes/file.C 2005/08/09 08:14:47 1.136 +++ parser3/src/classes/file.C 2005/11/22 11:31:58 1.140 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_FILE_C="$Date: 2005/08/09 08:14:47 $"; +static const char * const IDENT_FILE_C="$Date: 2005/11/22 11:31:58 $"; #include "pa_config_includes.h" @@ -171,11 +171,9 @@ static void _load(Request& r, MethodPara if(options) { options=new HashStringValue(*options); if(Value *voffset=(Value *)options->get(sql_offset_name)) { - options->remove(sql_offset_name); offset=r.process_to_value(*voffset).as_int(); } if(Value *vlimit=(Value *)options->get(sql_limit_name)) { - options->remove(sql_limit_name); limit=r.process_to_value(*vlimit).as_int(); } // no check on options count here, see file_read @@ -204,6 +202,25 @@ static void _load(Request& r, MethodPara file.headers->for_each(_load_pass_param, &self.fields()); } +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", + 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); + + 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 + + VString* vcontent_type=new VString(r.mime_type_of(user_file_name_cstr)); + + VFile& self=GET_SELF(r, VFile); + self.set(true/*tainted*/, content_cstr, strlen(content_cstr), user_file_name_cstr, vcontent_type); +} + static void _stat(Request& r, MethodParams& params) { Value& vfile_name=params.as_no_junction(0, "file name must not be code"); @@ -763,9 +780,30 @@ static void _sql(Request& r, MethodParam self.set(true/*tainted*/, handlers.value.str, handlers.value.length, user_file_name_cstr, vcontent_type); } +static void _base64(Request& r, MethodParams& params) { + VFile& self=GET_SELF(r, VFile); + if(params.count()) { + // decode + 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); + if(decoded_cstr && decoded_size) + self.set(true/*tainted*/, decoded_cstr, decoded_size); + } else { + // encode + const char* encoded=pa_base64_encode(self.value_ptr(), self.value_size()); + r.write_assign_lang(*new String(encoded, 0, true/*once ?param=base64(something) was needed*/)); + } +} + // constructor MFile::MFile(): Methoded("file") { + // ^create[text;user-name;string] + // ^create[binary;user-name;SOMEDAY SOMETHING] + add_native_method("create", Method::CT_DYNAMIC, _create, 3, 3); + // ^save[mode;file-name] add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2); @@ -820,4 +858,8 @@ MFile::MFile(): Methoded("file") { // ^file::sql[[alt_name]]{} add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2); + + // ^file.base64[] << encode + // ^file::base64[string] << decode + add_native_method("base64", Method::CT_DYNAMIC, _base64, 0, 1); }