4545 #include < wintrust.h>
4646 #pragma comment (lib, "wintrust") // Link with the Wintrust.lib file.
4747#endif
48- #ifndef PATH_MAX
49- #define PATH_MAX MAX_PATH
50- #endif
5148#else /* _WIN32 */
5249 #include < dlfcn.h>
5350 #include < unistd.h>
@@ -177,7 +174,7 @@ namespace r1 {
177174 break ;
178175 case dl_buff_too_small:
179176 TBB_FPRINTF (stderr, " %s An internal buffer representing a path to dynamically loaded "
180- " module is small. Consider compiling with larger value for PATH_MAX macro. \n " ,
177+ " module is small.\n " ,
181178 prefix);
182179 break ;
183180 case dl_unload_fail:
@@ -340,12 +337,15 @@ namespace r1 {
340337 static std::once_flag init_dl_data_state;
341338
342339 static struct ap_data_t {
343- char _path[PATH_MAX+1 ];
340+ char *_path;
341+ std::size_t _capacity;
344342 std::size_t _len;
345343 } ap_data;
346344
347345 static void init_ap_data () {
348346 #if _WIN32
347+ ap_data._capacity = MAX_PATH;
348+ ap_data._path = (char *)calloc (ap_data._capacity , 1 );
349349 // Get handle of our DLL first.
350350 HMODULE handle;
351351 BOOL brc = GetModuleHandleEx (
@@ -356,30 +356,45 @@ namespace r1 {
356356 if ( !brc ) { // Error occurred.
357357 int err = GetLastError ();
358358 DYNAMIC_LINK_WARNING ( dl_sys_fail, " GetModuleHandleEx" , err );
359+ free (ap_data._path );
360+ ap_data._path = NULL ;
361+ ap_data._capacity = 0 ;
359362 return ;
360363 }
361364 // Now get path to our DLL.
362- DWORD drc = GetModuleFileName ( handle, ap_data._path , static_cast < DWORD >( PATH_MAX ) );
365+ DWORD drc = GetModuleFileName ( handle, ap_data._path , static_cast < DWORD >( ap_data. _capacity ) );
363366 if ( drc == 0 ) { // Error occurred.
364367 int err = GetLastError ();
365368 DYNAMIC_LINK_WARNING ( dl_sys_fail, " GetModuleFileName" , err );
369+ free (ap_data._path );
370+ ap_data._path = NULL ;
371+ ap_data._capacity = 0 ;
366372 return ;
367373 }
368- if ( drc >= PATH_MAX ) { // Buffer too short.
374+ if ( drc >= ap_data. _capacity ) { // Buffer too short.
369375 DYNAMIC_LINK_WARNING ( dl_buff_too_small );
376+ free (ap_data._path );
377+ ap_data._path = NULL ;
378+ ap_data._capacity = 0 ;
370379 return ;
371380 }
372381 // Find the position of the last backslash.
373382 char *backslash = std::strrchr ( ap_data._path , ' \\ ' );
374383
375384 if ( !backslash ) { // Backslash not found.
376385 __TBB_ASSERT_EX ( backslash != nullptr , " Unbelievable." );
386+ free (ap_data._path );
387+ ap_data._path = NULL ;
388+ ap_data._capacity = 0 ;
377389 return ;
378390 }
379391 __TBB_ASSERT_EX ( backslash >= ap_data._path , " Unbelievable." );
380392 ap_data._len = (std::size_t )(backslash - ap_data._path ) + 1 ;
381393 *(backslash+1 ) = 0 ;
382394 #else
395+ // Initial capacity, double until large enough
396+ ap_data._capacity = 4096 ;
397+ ap_data._path = (char *)calloc (ap_data._capacity , 1 );
383398 // There is an use case, when we want to find TBB library, not just some shared object
384399 // providing "dynamic_link" symbol (it can be shared object that directly includes
385400 // dynamic_link.cpp). For this case we use a public TBB symbol. Searching for public symbol
@@ -397,6 +412,9 @@ namespace r1 {
397412 if ( !res ) {
398413 char const * err = dlerror ();
399414 DYNAMIC_LINK_WARNING ( dl_sys_fail, " dladdr" , err );
415+ free (ap_data._path );
416+ ap_data._path = NULL ;
417+ ap_data._capacity = 0 ;
400418 return ;
401419 } else {
402420 __TBB_ASSERT_EX ( dlinfo.dli_fname !=nullptr , " Unbelievable." );
@@ -416,9 +434,14 @@ namespace r1 {
416434 ap_data._len = 0 ;
417435 } else {
418436 // The library path is relative so get the current working directory
419- if ( !getcwd ( ap_data._path , sizeof (ap_data._path )/sizeof (ap_data._path [0 ]) ) ) {
420- DYNAMIC_LINK_WARNING ( dl_buff_too_small );
421- return ;
437+ while ( !getcwd ( ap_data._path , ap_data._capacity ) ) {
438+ free (ap_data._path );
439+ ap_data._capacity *= 2 ;
440+ ap_data._path = (char *)calloc (ap_data._capacity , 1 );
441+ if (NULL == ap_data._path ) {
442+ DYNAMIC_LINK_WARNING ( dl_buff_too_small );
443+ return ;
444+ }
422445 }
423446 ap_data._len = std::strlen ( ap_data._path );
424447 ap_data._path [ap_data._len ++]=' /' ;
@@ -427,9 +450,12 @@ namespace r1 {
427450
428451 if ( fname_len>0 ) {
429452 ap_data._len += fname_len;
430- if ( ap_data._len >PATH_MAX ) {
453+ if ( ap_data._len >ap_data. _capacity ) {
431454 DYNAMIC_LINK_WARNING ( dl_buff_too_small );
432455 ap_data._len =0 ;
456+ free (ap_data._path );
457+ ap_data._path = NULL ;
458+ ap_data._capacity = 0 ;
433459 return ;
434460 }
435461 std::strncpy ( ap_data._path +rc, dlinfo.dli_fname , fname_len );
@@ -463,7 +489,9 @@ namespace r1 {
463489 if ( full_len < len ) {
464490 __TBB_ASSERT_EX ( ap_data._path [ap_data._len ] == 0 , nullptr );
465491 __TBB_ASSERT_EX ( std::strlen (ap_data._path ) == ap_data._len , nullptr );
466- std::strncpy ( path, ap_data._path , ap_data._len + 1 );
492+ // No need for strncpy, test above confirmed enough space
493+ // and do not need zero padding at the end.
494+ std::strcpy ( path, ap_data._path );
467495 __TBB_ASSERT_EX ( path[ap_data._len ] == 0 , nullptr );
468496 std::strncat ( path, name, len - ap_data._len );
469497 __TBB_ASSERT_EX ( std::strlen (path) == full_len, nullptr );
@@ -662,14 +690,17 @@ namespace r1 {
662690 * occurs, in which case the error is optionally reported.
663691 */
664692 bool has_valid_signature (const char * filepath, const std::size_t length) {
665- __TBB_ASSERT_EX (length <= PATH_MAX, " Too small buffer for path conversion " ) ;
666- wchar_t wfilepath[PATH_MAX] = { 0 } ;
693+ std:: size_t pathlen = strlen (filepath)+ 1 ;
694+ wchar_t * wfilepath = ( wchar_t *) calloc (pathlen, sizeof ( wchar_t )) ;
667695 {
668696 std::mbstate_t state{};
669697 const char * ansi_filepath = filepath; // mbsrtowcs moves original pointer
670698 const size_t num_converted = mbsrtowcs (wfilepath, &ansi_filepath, length, &state);
671- if (num_converted == std::size_t (-1 ))
699+ if (num_converted == std::size_t (-1 )) {
700+ free (wfilepath);
701+ wfilepath = NULL ;
672702 return false ;
703+ }
673704 }
674705 WINTRUST_FILE_INFO fdata;
675706 std::memset (&fdata, 0 , sizeof (fdata));
@@ -699,6 +730,8 @@ namespace r1 {
699730 pWVTData.dwStateAction = WTD_STATEACTION_CLOSE; // Release WVT state data
700731 (void )WinVerifyTrust (NULL , &pgActionID, &pWVTData);
701732
733+ free (wfilepath);
734+ wfilepath = NULL ;
702735 return ERROR_SUCCESS == rc;
703736 }
704737#endif // _WIN32 && !__TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION
@@ -710,42 +743,50 @@ namespace r1 {
710743 dynamic_link_handle library_handle = nullptr ;
711744#if __TBB_DYNAMIC_LOAD_ENABLED
712745 const char * path = library;
713- std::size_t const len = PATH_MAX + 1 ;
714- char absolute_path[ len ] = { 0 } ;
746+ std::size_t len = abs_path ( library, NULL , 1 ) ;
747+ char * absolute_path = ( char *) calloc (len, 1 ) ;
715748 std::size_t length = 0 ;
716749 const bool build_absolute_path = flags & DYNAMIC_LINK_BUILD_ABSOLUTE_PATH;
717750 if (build_absolute_path) {
718751 length = abs_path ( library, absolute_path, len );
719- if (length > len) {
720- DYNAMIC_LINK_WARNING ( dl_buff_too_small );
721- return nullptr ;
722- } else if (length == 0 ) {
752+ if (length == 0 ) {
723753 // length == 0 means failing of init_ap_data so the warning has already been issued.
754+ free (absolute_path);
755+ absolute_path = NULL ;
724756 return nullptr ;
725757 } else if (!file_exists (absolute_path)) {
726758 // Path to a file has been built manually. It is not proven to exist however.
727759 DYNAMIC_LINK_WARNING ( dl_lib_not_found, absolute_path, dlerror () );
760+ free (absolute_path);
761+ absolute_path = NULL ;
728762 return nullptr ;
729763 }
730764 path = absolute_path;
731765 }
732766#if _WIN32
733767#if !__TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION
734768 if (!build_absolute_path) { // Get the path if it is not yet built
735- length = get_module_path (absolute_path, len, library);
769+ length = get_module_path (absolute_path, ( unsigned ) len, library);
736770 if (length == 0 ) {
737771 DYNAMIC_LINK_WARNING ( dl_lib_not_found, path, dlerror () );
772+ free (absolute_path);
773+ absolute_path = NULL ;
738774 return library_handle;
739775 } else if (length >= len) { // The buffer length was insufficient
740776 DYNAMIC_LINK_WARNING ( dl_buff_too_small );
777+ free (absolute_path);
778+ absolute_path = NULL ;
741779 return library_handle;
742780 }
743781 length += 1 ; // Count terminating NULL character as part of string length
744782 path = absolute_path;
745783 }
746784
747- if (!has_valid_signature (path, length))
785+ if (!has_valid_signature (path, length)) {
786+ free (absolute_path);
787+ absolute_path = NULL ;
748788 return library_handle; // Warning (if any) has already been reported
789+ }
749790#endif /* !__TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION */
750791 // Prevent Windows from displaying silly message boxes if it fails to load library
751792 // (e.g. because of MS runtime problems - one of those crazy manifest related ones)
@@ -764,6 +805,8 @@ namespace r1 {
764805 }
765806 } else
766807 DYNAMIC_LINK_WARNING ( dl_lib_not_found, path, dlerror () );
808+ free (absolute_path);
809+ absolute_path = NULL ;
767810#endif /* __TBB_DYNAMIC_LOAD_ENABLED */
768811 return library_handle;
769812 }
0 commit comments