Skip to content

Commit c5dd040

Browse files
committed
Use pathconf(), also check NAME_MAX
1 parent cc3f7bc commit c5dd040

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

src/config_rmw.c

+9
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,15 @@ parse_line_waste(st_waste *waste_curr, struct Canfigger *node,
275275
else if (p_state == -1)
276276
exit(p_state);
277277

278+
waste_curr->path_max =
279+
(waste_curr->removable == false) ? get_path_max(waste_curr->parent) : 0;
280+
waste_curr->name_max =
281+
(waste_curr->removable == false) ? get_name_max(waste_curr->parent) : 0;
282+
283+
//if (verbose)
284+
//printf("path_max: %ld; name_max %ld", waste_curr->path_max,
285+
//waste_curr->name_max);
286+
278287
waste_curr->is_btrfs = is_btrfs(waste_curr->parent);
279288

280289
// get device number to use later for rename

src/trashinfo.h

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
3131
typedef struct st_waste st_waste;
3232
struct st_waste
3333
{
34+
long path_max;
35+
long name_max;
3436
/** The parent directory, e.g. $HOME/.local/share/Trash */
3537
char *parent;
3638

src/utils.c

+103
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,98 @@ count_chars(const char c, const char *str)
495495
}
496496

497497

498+
static long
499+
get_pathconf_limit(const char *path, int name, long fallback,
500+
const char *limit_name)
501+
{
502+
if (!path)
503+
{
504+
fprintf(stderr, "Error: Path is NULL.\n");
505+
return -1;
506+
}
507+
508+
const char *actual_path =
509+
#ifdef TEST_LIB
510+
"/"
511+
#else
512+
path
513+
#endif
514+
;
515+
516+
long limit = pathconf(actual_path, name);
517+
if (limit == -1)
518+
{
519+
if (errno == 0)
520+
limit = fallback; // Use fallback if no limit is defined
521+
else
522+
{
523+
fprintf(stderr, "Error querying %s: ", limit_name);
524+
perror("pathconf");
525+
return -1;
526+
}
527+
}
528+
529+
return limit;
530+
}
531+
532+
533+
long
534+
get_name_max(const char *path)
535+
{
536+
return get_pathconf_limit(path, _PC_NAME_MAX, NAME_MAX, "NAME_MAX");
537+
}
538+
539+
540+
long
541+
get_path_max(const char *path)
542+
{
543+
return get_pathconf_limit(path, _PC_PATH_MAX, PATH_MAX, "PATH_MAX");
544+
}
545+
546+
int
547+
validate_path(const char *path)
548+
{
549+
if (!path)
550+
{
551+
fprintf(stderr, "Error: Path is NULL.\n");
552+
return -1; // Invalid input
553+
}
554+
555+
long path_max = get_path_max(path);
556+
long name_max = get_name_max(path);
557+
size_t path_len = strlen(path);
558+
if (path_len > (size_t) path_max)
559+
{
560+
fprintf(stderr, "Error: Path length (%zu) exceeds PATH_MAX (%ld).\n",
561+
path_len, path_max);
562+
return -1;
563+
}
564+
565+
// Check individual component lengths
566+
const char *start = path;
567+
while (*start)
568+
{
569+
const char *end = strchr(start, '/');
570+
size_t component_len = end ? (size_t) (end - start) : strlen(start);
571+
572+
if (component_len > (size_t) name_max)
573+
{
574+
fprintf(stderr,
575+
"Error: Path component '%.*s' exceeds NAME_MAX (%ld).\n",
576+
(int) component_len, start, name_max);
577+
return -1;
578+
}
579+
580+
if (!end)
581+
break;
582+
583+
start = end + 1;
584+
}
585+
586+
return 0;
587+
}
588+
589+
498590
///////////////////////////////////////////////////////////////////////
499591
#ifdef TEST_LIB
500592

@@ -723,6 +815,15 @@ test_count_chars(void)
723815
return;
724816
}
725817

818+
void
819+
test_validate_path(void)
820+
{
821+
assert(validate_path
822+
("/dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd/foo")
823+
!= 0);
824+
return;
825+
}
826+
726827

727828
int
728829
main()
@@ -756,6 +857,8 @@ main()
756857
free(escaped_path);
757858

758859
test_count_chars();
860+
861+
test_validate_path();
759862
return 0;
760863
}
761864
#endif

src/utils.h

+6
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,10 @@ bool is_dir_f(const char *pathname);
6464

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

67+
long get_path_max(const char *path);
68+
69+
long get_name_max(const char *path);
70+
71+
int validate_path(const char *path);
72+
6773
#endif

0 commit comments

Comments
 (0)