diff --git a/Pal/lib/graphene/path.c b/Pal/lib/graphene/path.c index e5737ea9..867e85e9 100644 --- a/Pal/lib/graphene/path.c +++ b/Pal/lib/graphene/path.c @@ -36,17 +36,31 @@ static inline const char* find_next_slash(const char* path) { } /* - * Finds previous '/' in `path` (starting from `size` - 1) and returns offset to it. + * Finds previous '/' in `path` (starting from `offset` - 1). * If the last character is '/', then it is skipped (as a token can end with '/'). + * + * Returns whether '/' was found. + * Updates `*offset` to the index of the found '/' (or 0 if none was found). */ -static inline size_t find_prev_slash_offset(const char* path, size_t size) { - if (size && path[size - 1] == '/') { - size--; +static inline bool find_prev_slash_offset(const char* path, size_t* offset) { + size_t off = *offset; + + if (!off) { + return false; } - while (size && path[size - 1] != '/') { - size--; + + off--; // get offset to last character + + /* Skip trailing '/' if there is one */ + if (off && path[off] == '/') { + off--; } - return size; + while (off && path[off] != '/') { + off--; + } + + *offset = off; + return path[off] == '/'; } /* @@ -67,8 +81,8 @@ int get_norm_path(const char* path, char* buf, size_t* size_ptr) { size_t offset = 0, ret_size = 0; /* accounts for undiscardable bytes written to `buf` * i.e. `buf - ret_size` points to original `buf` */ - unsigned char need_slash = 0; // is '/' needed before next token - bool is_absolute_path = *path == '/'; + bool need_slash = false; // is '/' needed before next token + bool is_absolute_path = *path == '/'; /* handle an absolute path */ if (is_absolute_path) { @@ -88,8 +102,7 @@ int get_norm_path(const char* path, char* buf, size_t* size_ptr) { /* ".." */ if (offset) { /* eat up previously written token */ - offset = find_prev_slash_offset(buf, offset); - need_slash = 0; + need_slash = find_prev_slash_offset(buf, &offset); } else if (!is_absolute_path) { /* append undiscardable ".." since there is no previous token * but only if the path is not absolute */ @@ -103,7 +116,7 @@ int get_norm_path(const char* path, char* buf, size_t* size_ptr) { *buf++ = '.'; size -= need_slash + 2u; ret_size += need_slash + 2u; - need_slash = 1; + need_slash = true; } else { /* remaining case: offset == 0, path is absolute and ".." was just seen, * i.e. "/..", which is collapsed to "/", hence nothing needs to be done @@ -121,7 +134,7 @@ int get_norm_path(const char* path, char* buf, size_t* size_ptr) { } memcpy(buf + offset, path, len); offset += len; - need_slash = 1; + need_slash = true; } if (!*end) { break; diff --git a/Pal/regression/normalize_path.c b/Pal/regression/normalize_path.c index 6d29de2b..6fdd0e94 100644 --- a/Pal/regression/normalize_path.c +++ b/Pal/regression/normalize_path.c @@ -17,7 +17,7 @@ static const char* get_norm_path_cases[][2] = { {"/../../../../../a", "/a"}, {"/../a/../../b", "/b"}, {"/../..a/b", "/..a/b"}, - {" /a/..", "/"}, + {"/a/..", "/"}, {"/a/.", "/a"}, {"/.//a//./b", "/a/b"}, {"///////.////////////./", "/"}, @@ -38,11 +38,11 @@ static const char* get_base_name_cases[][2] = { {"a/b/c", "c"}, }; -#define ARR_LEN(x) (sizeof(x) / sizeof(x[0]) / sizeof(x[0][0])) +#define ARR_LEN(x) (sizeof(x) / sizeof((x)[0])) #define print_err(name, i, ...) \ do { \ - pal_printf("%s: case %lu (%s) ", name, i, cases[i][0]); \ + pal_printf("%s: case %lu (\"%s\") ", name, i, cases[i][0]); \ pal_printf(__VA_ARGS__); \ } while (0) @@ -69,7 +69,7 @@ static int run_test(void) { } if (strcmp(cases[i][1], buf) != 0) { - print_err(func_name, i, "returned: \"%s\", instead of: %s\n", buf, cases[i][1]); + print_err(func_name, i, "returned: \"%s\", instead of: \"%s\"\n", buf, cases[i][1]); return 1; } } @@ -80,6 +80,7 @@ int main(void) { cases = get_norm_path_cases; cases_len = ARR_LEN(get_norm_path_cases); func_to_test = get_norm_path; + func_name = "get_norm_path"; if (run_test()) { return 1; } @@ -87,6 +88,7 @@ int main(void) { cases = get_base_name_cases; cases_len = ARR_LEN(get_base_name_cases); func_to_test = get_base_name; + func_name = "get_base_name"; if (run_test()) { return 1; }