@@ -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
727828int
728829main ()
@@ -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
0 commit comments