--- parser3/src/main/pa_request.C 2024/05/11 19:20:41 1.420 +++ parser3/src/main/pa_request.C 2024/09/28 14:37:54 1.426 @@ -33,8 +33,9 @@ #include "pa_vmemory.h" #include "pa_vconsole.h" #include "pa_vdate.h" +#include "pa_varray.h" -volatile const char * IDENT_PA_REQUEST_C="$Id: pa_request.C,v 1.420 2024/05/11 19:20:41 moko Exp $" IDENT_PA_REQUEST_H IDENT_PA_REQUEST_CHARSETS_H IDENT_PA_REQUEST_INFO_H IDENT_PA_VCONSOLE_H; +volatile const char * IDENT_PA_REQUEST_C="$Id: pa_request.C,v 1.426 2024/09/28 14:37:54 moko Exp $" IDENT_PA_REQUEST_H IDENT_PA_REQUEST_CHARSETS_H IDENT_PA_REQUEST_INFO_H IDENT_PA_VCONSOLE_H; // consts @@ -43,7 +44,8 @@ volatile const char * IDENT_PA_REQUEST_C /// content type of response when no $MAIN:defaults.content-type defined const char* DEFAULT_CONTENT_TYPE="text/html"; -const uint LOOP_LIMIT=20000; +const uint LOOP_LIMIT=100000; +const uint ARRAY_LIMIT=1000000; const uint EXECUTE_RECOURSION_LIMIT=1000; const uint HTTPD_TIMEOUT=4; const size_t FILE_SIZE_LIMIT=512*1024*1024; @@ -76,6 +78,7 @@ const String exception_handled_part_name static const String origin_key(ORIGIN_KEY); int pa_loop_limit=LOOP_LIMIT; +int pa_array_limit=ARRAY_LIMIT; int pa_execute_recoursion_limit=EXECUTE_RECOURSION_LIMIT; int pa_httpd_timeout=HTTPD_TIMEOUT; size_t pa_file_size_limit=FILE_SIZE_LIMIT; @@ -101,6 +104,7 @@ static const String getter_protected_nam static const String locals_name("LOCALS"); static const String limits_name("LIMITS"); static const String loop_limit_name("max_loop"); +static const String array_limit_name("max_array_size"); static const String recoursion_limit_name("max_recoursion"); static const String file_size_limit_name("max_file_size"); static const String lock_wait_timeout_name("lock_wait_timeout"); @@ -245,6 +249,17 @@ VStateless_class& Request::get_class_ref return *result; } +bool Request::add_class(const char* atype, VStateless_class *aclass){ + if(!allow_class_replace){ + if(!classes().put_dont_replace(atype, aclass)) + return true; + if(strcmp(atype, VARRAY_TYPE)) + return false; + } + classes().put(atype, aclass); + return true; +} + static void load_charset(HashStringValue::key_type akey, HashStringValue::value_type avalue, Request_charsets* charsets) { pa_charsets.load_charset(*charsets, akey, avalue->as_string()); } @@ -328,6 +343,12 @@ void Request::configure_admin(VStateless if(pa_loop_limit==0) pa_loop_limit=INT_MAX; }, "LIMITS.%s must be int"); + pa_array_limit=ARRAY_LIMIT; + CONF_OPTION(limits, array_limit_name, { + pa_array_limit=option->as_int(); + if(pa_array_limit==0) pa_array_limit=INT_MAX; + }, "LIMITS.%s must be int"); + pa_execute_recoursion_limit=EXECUTE_RECOURSION_LIMIT; CONF_OPTION(limits, recoursion_limit_name, { pa_execute_recoursion_limit=option->as_int(); @@ -338,7 +359,7 @@ void Request::configure_admin(VStateless CONF_OPTION(limits, file_size_limit_name, { double limit=option->as_double(); if(limit >= (double)SSIZE_MAX) - throw Exception(PARSER_RUNTIME, 0, "$MAIN:LIMITS.%s must be less then %.15g", file_size_limit_name.cstr(), (double)SSIZE_MAX); + throw Exception(PARSER_RUNTIME, 0, "$MAIN:LIMITS.%s must be less than %.15g", file_size_limit_name.cstr(), (double)SSIZE_MAX); pa_file_size_limit=(size_t)limit; if(pa_file_size_limit==0) pa_file_size_limit=SSIZE_MAX; @@ -348,7 +369,7 @@ void Request::configure_admin(VStateless CONF_OPTION(limits, lock_wait_timeout_name, { double limit=option->as_double(); if(limit >= 3600*24) - throw Exception(PARSER_RUNTIME, 0, "$MAIN:LIMITS.%s must be less then %d", lock_wait_timeout_name.cstr(), 3600*24); + throw Exception(PARSER_RUNTIME, 0, "$MAIN:LIMITS.%s must be less than %d", lock_wait_timeout_name.cstr(), 3600*24); pa_lock_attempts=(unsigned int)(limit*2)+1; }, "LIMITS.%s must be number"); @@ -428,8 +449,8 @@ Table &Request::Exception_trace::table(R Operation::Origin origin=trace.origin(); if(origin.file_no) { *row+=new String(r.file_list[origin.file_no], String::L_TAINTED); // 'file' column - *row+=new String(String::Body::Format(1+origin.line), String::L_CLEAN); // 'lineno' column - *row+=new String(String::Body::Format(1+origin.col), String::L_CLEAN); // 'colno' column + *row+=new String(pa_uitoa(1+origin.line), String::L_CLEAN); // 'lineno' column + *row+=new String(pa_uitoa(1+origin.col), String::L_CLEAN); // 'colno' column } stack_trace+=row; } @@ -715,7 +736,7 @@ const String& Request::full_disk_path(co result << relative_name; return result; } - if(relative_name.pos("://")!=STRING_NOT_FOUND // something like "http://xxx" + if(relative_name.starts_with("http://") || relative_name.starts_with("parser://") #ifdef WIN32 || relative_name.pos(":")==1 // DRIVE: || relative_name.starts_with("\\\\") // UNC1 @@ -959,9 +980,8 @@ void Request::output_result(VFile* body_ VDate* vdate=0; if(Value* v=body_file->fields().get("mdate")) { - if(Value* vdatep=v->as(VDATE_TYPE)) - vdate=static_cast(vdatep); - else + vdate=dynamic_cast(v); + if(!vdate) throw Exception(PARSER_RUNTIME, 0, "mdate must be a date"); } if(!vdate)