@@ -495,6 +495,98 @@ count_chars(const char c, const char *str)
495
495
}
496
496
497
497
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
+
498
590
///////////////////////////////////////////////////////////////////////
499
591
#ifdef TEST_LIB
500
592
@@ -723,6 +815,15 @@ test_count_chars(void)
723
815
return ;
724
816
}
725
817
818
+ void
819
+ test_validate_path (void )
820
+ {
821
+ assert (validate_path
822
+ ("/dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd/foo" )
823
+ != 0 );
824
+ return ;
825
+ }
826
+
726
827
727
828
int
728
829
main ()
@@ -756,6 +857,8 @@ main()
756
857
free (escaped_path );
757
858
758
859
test_count_chars ();
860
+
861
+ test_validate_path ();
759
862
return 0 ;
760
863
}
761
864
#endif
0 commit comments