--- parser3/src/main/pa_common.C 2020/12/15 17:10:35 1.322 +++ parser3/src/main/pa_common.C 2024/09/11 21:07:36 1.331 @@ -1,8 +1,8 @@ /** @file Parser: commonly functions. - Copyright (c) 2000-2020 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2000-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "pa_common.h" @@ -12,7 +12,6 @@ #include "pa_charsets.h" #include "pa_http.h" #include "pa_request_charsets.h" -#include "pcre.h" #include "pa_request.h" #include "pa_idna.h" @@ -29,7 +28,7 @@ #define pa_mkdir(path, mode) mkdir(path, mode) #endif -volatile const char * IDENT_PA_COMMON_C="$Id: pa_common.C,v 1.322 2020/12/15 17:10:35 moko Exp $" IDENT_PA_COMMON_H IDENT_PA_HASH_H IDENT_PA_ARRAY_H IDENT_PA_STACK_H; +volatile const char * IDENT_PA_COMMON_C="$Id: pa_common.C,v 1.331 2024/09/11 21:07:36 moko Exp $" IDENT_PA_COMMON_H IDENT_PA_HASH_H IDENT_PA_ARRAY_H IDENT_PA_STACK_H; // some maybe-undefined constants @@ -116,7 +115,7 @@ struct File_read_action_info { static void file_read_action(struct stat& finfo, int f, const String& file_spec, void *context) { File_read_action_info& info = *static_cast(context); - size_t to_read_size = check_file_size(info.limit && info.limit < finfo.st_size ? info.limit : finfo.st_size, &file_spec); + size_t to_read_size = check_file_size(info.limit && info.limit < (size_t)finfo.st_size ? info.limit : (size_t)finfo.st_size, &file_spec); if(to_read_size) { if(info.offset) pa_lseek(f, info.offset, SEEK_SET); // seek never fails as POSIX allows the file offset to be set beyond the EOF @@ -286,11 +285,13 @@ bool file_read_action_under_lock(const S } void create_dir_for_file(const String& file_spec) { - size_t pos_after=1; - size_t pos_before; - while((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND) { - pa_mkdir(file_spec.mid(0, pos_before).taint_cstr(String::L_FILE_SPEC), 0775); - pos_after=pos_before+1; + const char *str=file_spec.taint_cstr(String::L_FILE_SPEC); + if(str[0]){ + const char *pos=str+1; + while((pos=strchr(pos,'/')) && pos[1]) { // to avoid trailing /, see #1166 + pa_mkdir(pa_strdup(str,pos-str), 0775); + pos++; + } } } @@ -564,15 +565,15 @@ const char* capitalize(const char* s){ return (const char*)result; } -char *str_lower(const char *s, size_t helper_length){ - char *result=pa_strdup(s, helper_length); +char *str_lower(const char *s, size_t length){ + char *result=pa_strdup(s, length); for(char* c=result; *c; c++) *c=(char)tolower((unsigned char)*c); return result; } -char *str_upper(const char *s, size_t helper_length){ - char *result=pa_strdup(s, helper_length); +char *str_upper(const char *s, size_t length){ + char *result=pa_strdup(s, length); for(char* c=result; *c; c++) *c=(char)toupper((unsigned char)*c); return result; @@ -652,6 +653,19 @@ char* rsplit(char* string, char delim) { return NULL; } +void pa_strncpy(char *dst, const char *src, size_t n){ + size_t left = n; + + if (left != 0 && src) { + while (--left != 0) { + if ((*dst++ = *src++) == '\0') + return; + } + } + if (n != 0) + *dst = '\0'; +} + #define STRCAT_STEP(str, len) if(str) { memcpy(ptr, str, len); ptr += len; } char *pa_strcat(const char *a, const char *b, const char *c) { @@ -748,19 +762,21 @@ const char* format(double value, const c if(fmt && strlen(fmt)){ switch(format_type(fmt)){ case FormatDouble: - size=snprintf(local_buf, sizeof(local_buf), fmt, value); - break; - case FormatInt: - size=snprintf(local_buf, sizeof(local_buf), fmt, (int)value); + size=snprintf(local_buf, sizeof(local_buf), fmt, value); break; case FormatUInt: - size=snprintf(local_buf, sizeof(local_buf), fmt, (uint)value); + if(value >= 0){ // on Apple M1 (uint) is 0 + size=snprintf(local_buf, sizeof(local_buf), fmt, clip2uint(value)); + break; + } + case FormatInt: + size=snprintf(local_buf, sizeof(local_buf), fmt, clip2int(value)); break; case FormatInvalid: throw Exception(PARSER_RUNTIME, 0, "Incorrect format string '%s' was specified.", fmt); } } else - size=snprintf(local_buf, sizeof(local_buf), "%d", (int)value); + return pa_itoa(clip2int(value)); if(size < 0 || size >= MAX_NUMBER-1){ // on win32 we manually reduce max size while printing throw Exception(PARSER_RUNTIME, 0, "Error occurred white executing snprintf with format string '%s'.", fmt); @@ -897,7 +913,7 @@ size_t strpos(const char *str, const cha return (p==0)?STRING_NOT_FOUND:p-str; } -int remove_crlf(char* start, char* end) { +size_t remove_crlf(char* start, char* end) { char* from=start; char* to=start; bool skip=false;