diff --git a/HISTORY b/HISTORY index a19ae18..5d1311d 100644 --- a/HISTORY +++ b/HISTORY @@ -1,4 +1,7 @@ +Version 1.64 2022-11-07 + * shared_func.[hc]: normalize_path use type string_t for general purpose + Version 1.63 2022-10-16 * sockopt.[hc]: getIpAndPort support ipv6 diff --git a/src/common_define.h b/src/common_define.h index af3693b..81892db 100644 --- a/src/common_define.h +++ b/src/common_define.h @@ -119,6 +119,11 @@ extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind); (strncasecmp(filename, FILE_RESOURCE_TAG_STR, \ FILE_RESOURCE_TAG_LEN) == 0) +#define IS_FILE_RESOURCE_EX(filename) \ + ((filename)->len >= FILE_RESOURCE_TAG_LEN && \ + memcmp((filename)->str, FILE_RESOURCE_TAG_STR, \ + FILE_RESOURCE_TAG_LEN) == 0) + #ifndef byte #define byte signed char #endif diff --git a/src/http_func.h b/src/http_func.h index 490a632..452860c 100644 --- a/src/http_func.h +++ b/src/http_func.h @@ -27,6 +27,10 @@ ((strncasecmp(str, "http://", 7) == 0) || \ (strncasecmp(str, "https://", 8) == 0)) +#define IS_URL_RESOURCE_EX(s) \ + ((s)->len >= 8 && ((memcmp((s)->str, "http://", 7) == 0) || \ + (memcmp((s)->str, "https://", 8) == 0))) + #ifdef __cplusplus extern "C" { #endif diff --git a/src/process_ctrl.c b/src/process_ctrl.c index a1047dd..c146e7e 100644 --- a/src/process_ctrl.c +++ b/src/process_ctrl.c @@ -278,6 +278,7 @@ int get_base_path_from_conf_file_ex(const char *filename, char *base_path, const int path_size, const int noent_log_level) { char *pBasePath; + string_t path_string; IniContext iniContext; int result; @@ -303,7 +304,8 @@ int get_base_path_from_conf_file_ex(const char *filename, char *base_path, break; } - normalize_path(NULL, pBasePath, base_path, path_size); + FC_SET_STRING(path_string, pBasePath); + normalize_path(NULL, &path_string, base_path, path_size); chopPath(base_path); if (!fileExists(base_path)) { diff --git a/src/shared_func.c b/src/shared_func.c index 229839d..2650b50 100644 --- a/src/shared_func.c +++ b/src/shared_func.c @@ -1195,8 +1195,8 @@ int fc_remove_redundant_slashes(const string_t *src, else { input.str = full_filename; - input.len = normalize_path(NULL, src->str, - full_filename, sizeof(full_filename)); + input.len = normalize_path(NULL, src, full_filename, + sizeof(full_filename)); } if (size <= input.len) @@ -3204,27 +3204,32 @@ char *format_http_date(time_t t, BufferInfo *buffer) return buffer->buff; } -int normalize_path(const char *from, const char *filename, +int normalize_path(const string_t *from, const string_t *filename, char *full_filename, const int size) { const char *start; const char *last; const char *end; - char cwd[PATH_MAX]; + char buff[PATH_MAX]; + string_t true_from; + string_t true_filename; int up_count; int path_len; int i; - if (IS_FILE_RESOURCE(filename)) { - filename = filename + FILE_RESOURCE_TAG_LEN; + if (IS_FILE_RESOURCE_EX(filename)) { + true_filename.str = filename->str + FILE_RESOURCE_TAG_LEN; + true_filename.len = filename->len - FILE_RESOURCE_TAG_LEN; + filename = &true_filename; } - if (*filename == '/') { - return snprintf(full_filename, size, "%s", filename); + if (*filename->str == '/') { + return snprintf(full_filename, size, "%.*s", + filename->len, filename->str); } if (from == NULL) { - if (getcwd(cwd, sizeof(cwd)) == NULL) { + if (getcwd(buff, sizeof(buff)) == NULL) { logError("file: "__FILE__", line: %d, " "call getcwd fail, errno: %d, error info: %s", __LINE__, errno, STRERROR(errno)); @@ -3232,32 +3237,35 @@ int normalize_path(const char *from, const char *filename, return 0; } - path_len = strlen(cwd); - if (cwd[path_len - 1] != '/') { - if ((path_len + 1) >= sizeof(cwd)) { + true_from.str = buff; + true_from.len = strlen(buff); + if (true_from.str[true_from.len - 1] != '/') { + if ((true_from.len + 1) > sizeof(buff)) { logError("file: "__FILE__", line: %d, " "cwd length is too long, exceeds %d", - __LINE__, (int)sizeof(cwd)); + __LINE__, (int)sizeof(buff)); *full_filename = '\0'; return 0; } - cwd[path_len] = '/'; - cwd[path_len + 1] = '\0'; + true_from.str[true_from.len++] = '/'; } - from = cwd; - } else if (IS_FILE_RESOURCE(from)) { - from = from + FILE_RESOURCE_TAG_LEN; + from = &true_from; + } else if (IS_FILE_RESOURCE_EX(from)) { + true_from.str = from->str + FILE_RESOURCE_TAG_LEN; + true_from.len = from->len - FILE_RESOURCE_TAG_LEN; + from = &true_from; } - last = strrchr(from, '/'); + last = fc_memrchr(from->str, '/', from->len); if (last != NULL) { - end = filename + strlen(filename); - if (memcmp(filename, "./", 2) == 0) { - start = filename + 2; + end = filename->str + filename->len; + if (filename->len >= 2 && memcmp(filename->str, "./", 2) == 0) { + start = filename->str + 2; } else { - start = filename; + start = filename->str; } + up_count = 0; while (start + 3 < end) { if (memcmp(start, "../", 3) != 0) { @@ -3268,97 +3276,30 @@ int normalize_path(const char *from, const char *filename, start += 3; } - path_len = last - from; + path_len = last - from->str; for (i=0; istr, '/', path_len); if (last == NULL) { logWarning("file: "__FILE__", line: %d, " - "too many ../ in the path resolve filename: %s, " - "from filename: %s", __LINE__, filename, from); + "too many ../ in the path resolve filename: %.*s, " + "from filename: %.*s", __LINE__, filename->len, + filename->str, from->len, from->str); break; } - path_len = last - from; + path_len = last - from->str; } - return snprintf(full_filename, size, "%.*s/%s", - path_len, from, start); + return snprintf(full_filename, size, "%.*s/%.*s", + path_len, from->str, (int)(end - start), start); } else { logWarning("file: "__FILE__", line: %d, " - "no \"/\" in the from filename: %s", - __LINE__, from); - return snprintf(full_filename, size, "%s", filename); + "no \"/\" in the from filename: %.*s", + __LINE__, from->len, from->str); + return snprintf(full_filename, size, "%.*s", + filename->len, filename->str); } } -int normalize_uri(const string_t *from, const char *uri, - char *dest, const int size) -{ -#define MAX_UP_PATH_COUNT 8 - const char *start; - const char *end; - const char *last; - string_t fpath; - string_t parts[MAX_UP_PATH_COUNT]; - int up_count; - int path_count; - int keep_count; - int len; - int i; - - if (*uri == '/') { - return snprintf(dest, size, "%s", uri); - } - - end = uri + strlen(uri); - if (memcmp(uri, "./", 2) == 0) { - start = uri + 2; - } else { - start = uri; - } - up_count = 0; - while (start + 3 < end) { - if (memcmp(start, "../", 3) != 0) { - break; - } - - ++up_count; - start += 3; - } - - last = fc_memrchr(from->str, '/', from->len); - if (last == NULL) { - logWarning("file: "__FILE__", line: %d, " - "no \"/\" in the from uri: %s", - __LINE__, from->str); - return snprintf(dest, size, "/%s", start); - } - - if (up_count == 0) { - return snprintf(dest, size, "%.*s/%s", - (int)(last - from->str), from->str, start); - } else { - fpath.str = (char *)from->str; - fpath.len = last - from->str; - path_count = split_string_ex(&fpath, '/', - parts, MAX_UP_PATH_COUNT, true); - keep_count = path_count - up_count; - if (keep_count < 0) { - logWarning("file: "__FILE__", line: %d, " - "uri: %s, contails too many \"../\"", - __LINE__, uri); - } - - len = 0; - for (i=0; ilen - FILE_RESOURCE_TAG_LEN), + filename->str + FILE_RESOURCE_TAG_LEN); } if (!is_url_from) { - return snprintf(full_filename, size, "%s", filename); + return snprintf(full_filename, size, "%.*s", + filename->len, filename->str); } if (is_url_filename) { - full_len = snprintf(full_filename, size, "%s", filename); + full_len = snprintf(full_filename, size, "%.*s", + filename->len, filename->str); if ((flags & NORMALIZE_FLAGS_URL_APPEND_PARAMS) == 0) { return full_len; } - from_ask = strchr(from + 8, '?'); + from_ask = memchr(from->str + 8, '?', from->len); } else { - base_end = strchr(from + 8, '/'); + base_end = memchr(from->str + 8, '/', from->len); if (base_end == NULL) { - return snprintf(full_filename, size, "%s%s%s", - from, (*filename == '/' ? "" : "/"), filename); + return snprintf(full_filename, size, "%.*s%s%.*s", + from->len, from->str, (*filename->str == '/' ? + "" : "/"), filename->len, filename->str); } - base_len = base_end - from; - from_ask = strchr(base_end + 1, '?'); + base_len = base_end - from->str; + from_ask = memchr(base_end + 1, '?', from->len - (base_len + 1)); from_uri.str = (char *)base_end; if (from_ask == NULL) { - from_uri.len = strlen(from_uri.str); + from_uri.len = from->len - base_len; } else { from_uri.len = from_ask - from_uri.str; } - full_len = snprintf(full_filename, size, "%.*s", base_len, from); - full_len = normalize_uri(&from_uri, filename, + full_len = snprintf(full_filename, size, "%.*s", base_len, from->str); + full_len += normalize_path(&from_uri, filename, full_filename + full_len, size - full_len); } if ((flags & NORMALIZE_FLAGS_URL_APPEND_PARAMS) != 0) { if (from_ask != NULL) { - dest_ask = strchr(filename, '?'); + dest_ask = memchr(filename->str, '?', filename->len); full_len += snprintf(full_filename + full_len, - size - full_len, "%c%s", (dest_ask == NULL ? - '?' : '&'), from_ask + 1); + size - full_len, "%c%.*s", (dest_ask == NULL ? + '?' : '&'), (int)((from->str + from->len) - + (from_ask + 1)), from_ask + 1); } } diff --git a/src/shared_func.h b/src/shared_func.h index b32e0ba..9fe4955 100644 --- a/src/shared_func.h +++ b/src/shared_func.h @@ -37,10 +37,6 @@ #define NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS \ (NORMALIZE_FLAGS_URL_ENABLED | NORMALIZE_FLAGS_URL_APPEND_PARAMS) -#define resolve_path(from, filename, full_filename, size) \ - normalize_path_ex(from, filename, full_filename, size, \ - NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS) - #define FC_SET_CLOEXEC(fd) \ if (g_set_cloexec) fd_set_cloexec(fd) @@ -1019,19 +1015,19 @@ char *format_http_date(time_t t, BufferInfo *buffer); * size: the max size of full_filename * return: length of the resolved full path */ -int normalize_path(const char *from, const char *filename, +int normalize_path(const string_t *from, const string_t *filename, char *full_filename, const int size); -/** return absolute uri (the second parameter) - * parameters: - * from: the input uri to get base path - * uri: the uri to resolve - * dest: store the resolved absolute uri - * size: the max size of dest - * return: length of the resolved uri -*/ -int normalize_uri(const string_t *from, const char *uri, - char *dest, const int size); +static inline int normalize_path1(const char *from, const char *filename, + char *full_filename, const int size) +{ + string_t from_string; + string_t filename_string; + + FC_SET_STRING(from_string, (char *)from); + FC_SET_STRING(filename_string, (char *)filename); + return normalize_path(&from_string, &filename_string, full_filename, size); +} /** return full path for the filename (the second parameter) * parameters: @@ -1044,9 +1040,20 @@ int normalize_uri(const string_t *from, const char *uri, * NORMALIZE_FLAGS_URL_APPEND_PARAMS: append params of from * return: length of the resolved full path */ -int normalize_path_ex(const char *from, const char *filename, +int normalize_path_ex(const string_t *from, const string_t *filename, char *full_filename, const int size, const int flags); +static inline int resolve_path(const char *from, const char *filename, + char *full_filename, const int size) +{ + string_t from_string; + string_t filename_string; + + FC_SET_STRING(from_string, (char *)from); + FC_SET_STRING(filename_string, (char *)filename); + return normalize_path_ex(&from_string, &filename_string, full_filename, + size, NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS); +} /** get gzip command full filename * return: the gzip command full filename diff --git a/src/tests/test_normalize_path.c b/src/tests/test_normalize_path.c index 5aa7d2a..9a40c25 100644 --- a/src/tests/test_normalize_path.c +++ b/src/tests/test_normalize_path.c @@ -27,8 +27,8 @@ int main(int argc, char *argv[]) { char full_filename[PATH_MAX]; - const char *from; - const char *filename; + string_t from; + string_t filename; int filename_len; int result; @@ -38,12 +38,14 @@ int main(int argc, char *argv[]) } log_init(); - from = argv[1]; - filename = argv[2]; - filename_len = normalize_path_ex(from, filename, + + FC_SET_STRING(from, argv[1]); + FC_SET_STRING(filename, argv[2]); + filename_len = normalize_path_ex(&from, &filename, full_filename, sizeof(full_filename), NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS); - printf("%s\n", full_filename); + printf("%s => {len1: %d, len2: %d}\n", full_filename, + (int)strlen(full_filename), filename_len); if (IS_URL_RESOURCE(full_filename)) { const int connect_timeout = 2;