--- parser3/src/classes/file.C 2024/09/28 14:37:53 1.281 +++ parser3/src/classes/file.C 2024/11/10 20:33:21 1.288 @@ -1,7 +1,7 @@ /** @file Parser: @b file parser class. - Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) Authors: Konstantin Morshnev , Alexandr Petrosian */ @@ -19,6 +19,7 @@ #include "pa_vdate.h" #include "pa_dir.h" #include "pa_vtable.h" +#include "pa_varray.h" #include "pa_charset.h" #include "pa_charsets.h" #include "pa_sql_connection.h" @@ -26,7 +27,7 @@ #include "pa_vregex.h" #include "pa_version.h" -volatile const char * IDENT_FILE_C="$Id: file.C,v 1.281 2024/09/28 14:37:53 moko Exp $"; +volatile const char * IDENT_FILE_C="$Id: file.C,v 1.288 2024/11/10 20:33:21 moko Exp $"; // defines @@ -56,7 +57,12 @@ public: } }; -Table file_list_table_template(new File_list_table_template_columns); +static Table &file_list_table_template(){ + static Table *singleton=NULL; + if(singleton==NULL) + singleton=new Table(new File_list_table_template_columns); + return *singleton; +} // class @@ -465,8 +471,7 @@ static void pass_cgi_header_attribute( } static void append_to_argv(Request& r, ArrayString& argv, const String* str){ - if(!str->is_empty()) - argv+=new String(str->cstr_to_string_body_untaint(String::L_AS_IS, r.connection(false), &r.charsets), String::L_AS_IS); + argv+=new String(str->cstr_to_string_body_untaint(String::L_AS_IS, r.connection(false), &r.charsets), String::L_AS_IS); } /// @todo fix `` in perl - they produced flipping consoles and no output to perl @@ -500,7 +505,7 @@ static void _exec_cgi(Request& r, Method ECSTR(QUERY_STRING, r.request_info.query_string); ECSTR(REQUEST_URI, r.request_info.uri); ECSTR(CONTENT_TYPE, r.request_info.content_type); - ECSTR(CONTENT_LENGTH, format(r.request_info.content_length, "%u")); + ECSTR(CONTENT_LENGTH, pa_uitoa(r.request_info.content_length)); // SCRIPT_* env.put("SCRIPT_NAME", script_name); @@ -545,18 +550,31 @@ static void _exec_cgi(Request& r, Method for(size_t i=param_index; icount(); j++) - append_to_argv(r, argv, table->get(j)->get(0)); - } else { - throw Exception(PARSER_RUNTIME, 0, "param must be string or table"); + if(const String *string=param.get_string()){ + append_to_argv(r, argv, string); + } else if(Table* table=param.get_table()){ + for(size_t j=0; jcount(); j++) + append_to_argv(r, argv, table->get(j)->get(0)); + } else if(VArray* array=dynamic_cast(¶m)){ + for(ArrayValue::Iterator i(array->array()); i; i.next()){ + if(i.value()){ + const String *string=i.value()->get_string(); + if(!string) + i.value()->bark("array element is '%s', it does not have string value"); + append_to_argv(r, argv, string); } } + } else { + throw Exception(PARSER_RUNTIME, 0, "param must be string or table or array of strings"); + } + } + + // remove trailing empty arguments for backward compatibility + for(ArrayString::ReverseIterator i(argv); i;){ + if(i.prev()->is_empty()){ // here for correct i.index() + argv.remove(i.index()); + } else { + break; } } } @@ -724,7 +742,7 @@ static void _list(Request& r, MethodPara const char* absolute_path_cstr=r.full_disk_path(relative_path.as_string()).taint_cstr(String::L_FILE_SPEC); Table::Action_options table_options; - Table& table=*new Table(file_list_table_template, table_options); + Table& table=*new Table(file_list_table_template(), table_options); const int ovector_size=(1/*match*/)*3; int ovector[ovector_size];