Skip to content

Commit

Permalink
Use pathconf(), also check NAME_MAX
Browse files Browse the repository at this point in the history
  • Loading branch information
andy5995 committed Dec 31, 2024
1 parent cc3f7bc commit c5dd040
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/config_rmw.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@ parse_line_waste(st_waste *waste_curr, struct Canfigger *node,
else if (p_state == -1)
exit(p_state);

waste_curr->path_max =
(waste_curr->removable == false) ? get_path_max(waste_curr->parent) : 0;
waste_curr->name_max =
(waste_curr->removable == false) ? get_name_max(waste_curr->parent) : 0;

//if (verbose)
//printf("path_max: %ld; name_max %ld", waste_curr->path_max,
//waste_curr->name_max);

waste_curr->is_btrfs = is_btrfs(waste_curr->parent);

// get device number to use later for rename
Expand Down
2 changes: 2 additions & 0 deletions src/trashinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
typedef struct st_waste st_waste;
struct st_waste
{
long path_max;
long name_max;
/** The parent directory, e.g. $HOME/.local/share/Trash */
char *parent;

Expand Down
103 changes: 103 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,98 @@ count_chars(const char c, const char *str)
}


static long
get_pathconf_limit(const char *path, int name, long fallback,
const char *limit_name)
{
if (!path)
{
fprintf(stderr, "Error: Path is NULL.\n");
return -1;
}

const char *actual_path =
#ifdef TEST_LIB
"/"
#else
path
#endif
;

long limit = pathconf(actual_path, name);
if (limit == -1)
{
if (errno == 0)
limit = fallback; // Use fallback if no limit is defined
else
{
fprintf(stderr, "Error querying %s: ", limit_name);
perror("pathconf");
return -1;
}
}

return limit;
}


long
get_name_max(const char *path)
{
return get_pathconf_limit(path, _PC_NAME_MAX, NAME_MAX, "NAME_MAX");
}


long
get_path_max(const char *path)
{
return get_pathconf_limit(path, _PC_PATH_MAX, PATH_MAX, "PATH_MAX");
}

int
validate_path(const char *path)
{
if (!path)
{
fprintf(stderr, "Error: Path is NULL.\n");
return -1; // Invalid input
}

long path_max = get_path_max(path);
long name_max = get_name_max(path);
size_t path_len = strlen(path);
if (path_len > (size_t) path_max)
{
fprintf(stderr, "Error: Path length (%zu) exceeds PATH_MAX (%ld).\n",
path_len, path_max);
return -1;
}

// Check individual component lengths
const char *start = path;
while (*start)
{
const char *end = strchr(start, '/');
size_t component_len = end ? (size_t) (end - start) : strlen(start);

if (component_len > (size_t) name_max)
{
fprintf(stderr,
"Error: Path component '%.*s' exceeds NAME_MAX (%ld).\n",
(int) component_len, start, name_max);
return -1;
}

if (!end)
break;

start = end + 1;
}

return 0;
}


///////////////////////////////////////////////////////////////////////
#ifdef TEST_LIB

Expand Down Expand Up @@ -723,6 +815,15 @@ test_count_chars(void)
return;
}

void
test_validate_path(void)
{
assert(validate_path
("/dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd/foo")
!= 0);
return;
}


int
main()
Expand Down Expand Up @@ -756,6 +857,8 @@ main()
free(escaped_path);

test_count_chars();

test_validate_path();
return 0;
}
#endif
6 changes: 6 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,10 @@ bool is_dir_f(const char *pathname);

int count_chars(const char c, const char *str);

long get_path_max(const char *path);

long get_name_max(const char *path);

int validate_path(const char *path);

#endif

0 comments on commit c5dd040

Please sign in to comment.