@@ -189,44 +189,52 @@ void git_repository_free(git_repository *repo)
189189 *
190190 * Open a repository object from its path
191191 */
192- static bool valid_repository_path ( git_buf * repository_path , git_buf * common_path )
192+ static int is_valid_repository_path ( bool * out , git_buf * repository_path , git_buf * common_path )
193193{
194+ int error ;
195+
196+ * out = false;
197+
194198 /* Check if we have a separate commondir (e.g. we have a
195199 * worktree) */
196200 if (git_path_contains_file (repository_path , GIT_COMMONDIR_FILE )) {
197201 git_buf common_link = GIT_BUF_INIT ;
198- git_buf_joinpath (& common_link , repository_path -> ptr , GIT_COMMONDIR_FILE );
199202
200- git_futils_readbuffer (& common_link , common_link .ptr );
201- git_buf_rtrim (& common_link );
203+ if ((error = git_buf_joinpath (& common_link , repository_path -> ptr , GIT_COMMONDIR_FILE )) < 0 ||
204+ (error = git_futils_readbuffer (& common_link , common_link .ptr )) < 0 )
205+ return error ;
202206
207+ git_buf_rtrim (& common_link );
203208 if (git_path_is_relative (common_link .ptr )) {
204- git_buf_joinpath (common_path , repository_path -> ptr , common_link .ptr );
209+ if ((error = git_buf_joinpath (common_path , repository_path -> ptr , common_link .ptr )) < 0 )
210+ return error ;
205211 } else {
206212 git_buf_swap (common_path , & common_link );
207213 }
208214
209215 git_buf_dispose (& common_link );
210216 }
211217 else {
212- git_buf_set (common_path , repository_path -> ptr , repository_path -> size );
218+ if ((error = git_buf_set (common_path , repository_path -> ptr , repository_path -> size )) < 0 )
219+ return error ;
213220 }
214221
215222 /* Make sure the commondir path always has a trailing * slash */
216223 if (git_buf_rfind (common_path , '/' ) != (ssize_t )common_path -> size - 1 )
217- git_buf_putc (common_path , '/' );
224+ if ((error = git_buf_putc (common_path , '/' )) < 0 )
225+ return error ;
218226
219227 /* Ensure HEAD file exists */
220228 if (git_path_contains_file (repository_path , GIT_HEAD_FILE ) == false)
221- return false;
222-
229+ return 0 ;
223230 /* Check files in common dir */
224231 if (git_path_contains_dir (common_path , GIT_OBJECTS_DIR ) == false)
225- return false ;
232+ return 0 ;
226233 if (git_path_contains_dir (common_path , GIT_REFS_DIR ) == false)
227- return false ;
234+ return 0 ;
228235
229- return true;
236+ * out = true;
237+ return 0 ;
230238}
231239
232240static git_repository * repository_alloc (void )
@@ -441,15 +449,15 @@ static int find_repo(
441449 uint32_t flags ,
442450 const char * ceiling_dirs )
443451{
444- int error ;
445452 git_buf path = GIT_BUF_INIT ;
446453 git_buf repo_link = GIT_BUF_INIT ;
447454 git_buf common_link = GIT_BUF_INIT ;
448455 struct stat st ;
449456 dev_t initial_device = 0 ;
450457 int min_iterations ;
451- bool in_dot_git ;
458+ bool in_dot_git , is_valid ;
452459 size_t ceiling_offset = 0 ;
460+ int error ;
453461
454462 git_buf_clear (gitdir_path );
455463
@@ -475,9 +483,8 @@ static int find_repo(
475483 for (;;) {
476484 if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT )) {
477485 if (!in_dot_git ) {
478- error = git_buf_joinpath (& path , path .ptr , DOT_GIT );
479- if (error < 0 )
480- break ;
486+ if ((error = git_buf_joinpath (& path , path .ptr , DOT_GIT )) < 0 )
487+ goto out ;
481488 }
482489 in_dot_git = !in_dot_git ;
483490 }
@@ -491,28 +498,33 @@ static int find_repo(
491498 break ;
492499
493500 if (S_ISDIR (st .st_mode )) {
494- if (valid_repository_path (& path , & common_link )) {
495- git_path_to_dir (& path );
496- git_buf_set (gitdir_path , path .ptr , path .size );
501+ if ((error = is_valid_repository_path (& is_valid , & path , & common_link )) < 0 )
502+ goto out ;
503+
504+ if (is_valid ) {
505+ if ((error = git_path_to_dir (& path )) < 0 ||
506+ (error = git_buf_set (gitdir_path , path .ptr , path .size )) < 0 )
507+ goto out ;
497508
498509 if (gitlink_path )
499- git_buf_attach (gitlink_path ,
500- git_worktree__read_link ( path . ptr , GIT_GITDIR_FILE ), 0 ) ;
510+ if (( error = git_buf_attach (gitlink_path , git_worktree__read_link ( path . ptr , GIT_GITDIR_FILE ), 0 )) < 0 )
511+ goto out ;
501512 if (commondir_path )
502513 git_buf_swap (& common_link , commondir_path );
503514
504515 break ;
505516 }
506- }
507- else if (S_ISREG ( st . st_mode ) && git__suffixcmp ( path .ptr , "/" DOT_GIT ) == 0 ) {
508- error = read_gitfile ( & repo_link , path . ptr );
509- if ( error < 0 )
510- break ;
511- if (valid_repository_path ( & repo_link , & common_link ) ) {
517+ } else if ( S_ISREG ( st . st_mode ) && git__suffixcmp ( path . ptr , "/" DOT_GIT ) == 0 ) {
518+ if (( error = read_gitfile ( & repo_link , path .ptr )) < 0 ||
519+ ( error = is_valid_repository_path ( & is_valid , & repo_link , & common_link )) < 0 )
520+ goto out ;
521+
522+ if (is_valid ) {
512523 git_buf_swap (gitdir_path , & repo_link );
513524
514525 if (gitlink_path )
515- error = git_buf_put (gitlink_path , path .ptr , path .size );
526+ if ((error = git_buf_put (gitlink_path , path .ptr , path .size )) < 0 )
527+ goto out ;
516528 if (commondir_path )
517529 git_buf_swap (& common_link , commondir_path );
518530 }
@@ -523,42 +535,37 @@ static int find_repo(
523535 /* Move up one directory. If we're in_dot_git, we'll search the
524536 * parent itself next. If we're !in_dot_git, we'll search .git
525537 * in the parent directory next (added at the top of the loop). */
526- if (git_path_dirname_r (& path , path .ptr ) < 0 ) {
527- error = -1 ;
528- break ;
529- }
538+ if ((error = git_path_dirname_r (& path , path .ptr )) < 0 )
539+ goto out ;
530540
531541 /* Once we've checked the directory (and .git if applicable),
532542 * find the ceiling for a search. */
533543 if (min_iterations && (-- min_iterations == 0 ))
534544 ceiling_offset = find_ceiling_dir_offset (path .ptr , ceiling_dirs );
535545
536546 /* Check if we should stop searching here. */
537- if (min_iterations == 0
538- && (path .ptr [ceiling_offset ] == 0
539- || (flags & GIT_REPOSITORY_OPEN_NO_SEARCH )))
547+ if (min_iterations == 0 &&
548+ (path .ptr [ceiling_offset ] == 0 || (flags & GIT_REPOSITORY_OPEN_NO_SEARCH )))
540549 break ;
541550 }
542551
543- if (! error && workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE )) {
552+ if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE )) {
544553 if (!git_buf_len (gitdir_path ))
545554 git_buf_clear (workdir_path );
546- else {
547- git_path_dirname_r (workdir_path , path .ptr );
548- git_path_to_dir (workdir_path );
549- }
550- if (git_buf_oom (workdir_path ))
551- return -1 ;
555+ else if ((error = git_path_dirname_r (workdir_path , path .ptr )) < 0 ||
556+ (error = git_path_to_dir (workdir_path )) < 0 )
557+ goto out ;
552558 }
553559
554560 /* If we didn't find the repository, and we don't have any other error
555561 * to report, report that. */
556- if (!git_buf_len (gitdir_path ) && !error ) {
557- git_error_set (GIT_ERROR_REPOSITORY ,
558- "could not find repository from '%s'" , start_path );
562+ if (!git_buf_len (gitdir_path )) {
563+ git_error_set (GIT_ERROR_REPOSITORY , "could not find repository from '%s'" , start_path );
559564 error = GIT_ENOTFOUND ;
565+ goto out ;
560566 }
561567
568+ out :
562569 git_buf_dispose (& path );
563570 git_buf_dispose (& repo_link );
564571 git_buf_dispose (& common_link );
@@ -569,14 +576,16 @@ int git_repository_open_bare(
569576 git_repository * * repo_ptr ,
570577 const char * bare_path )
571578{
572- int error ;
573579 git_buf path = GIT_BUF_INIT , common_path = GIT_BUF_INIT ;
574580 git_repository * repo = NULL ;
581+ bool is_valid ;
582+ int error ;
575583
576- if ((error = git_path_prettify_dir (& path , bare_path , NULL )) < 0 )
584+ if ((error = git_path_prettify_dir (& path , bare_path , NULL )) < 0 ||
585+ (error = is_valid_repository_path (& is_valid , & path , & common_path )) < 0 )
577586 return error ;
578587
579- if (!valid_repository_path ( & path , & common_path ) ) {
588+ if (!is_valid ) {
580589 git_buf_dispose (& path );
581590 git_buf_dispose (& common_path );
582591 git_error_set (GIT_ERROR_REPOSITORY , "path is not a repository: %s" , bare_path );
@@ -2055,6 +2064,7 @@ int git_repository_init_ext(
20552064 git_buf repo_path = GIT_BUF_INIT , wd_path = GIT_BUF_INIT ,
20562065 common_path = GIT_BUF_INIT , head_path = GIT_BUF_INIT ;
20572066 const char * wd ;
2067+ bool is_valid ;
20582068 int error ;
20592069
20602070 assert (out && given_repo && opts );
@@ -2066,7 +2076,10 @@ int git_repository_init_ext(
20662076
20672077 wd = (opts -> flags & GIT_REPOSITORY_INIT_BARE ) ? NULL : git_buf_cstr (& wd_path );
20682078
2069- if (valid_repository_path (& repo_path , & common_path )) {
2079+ if ((error = is_valid_repository_path (& is_valid , & repo_path , & common_path )) < 0 )
2080+ goto out ;
2081+
2082+ if (is_valid ) {
20702083 if ((opts -> flags & GIT_REPOSITORY_INIT_NO_REINIT ) != 0 ) {
20712084 git_error_set (GIT_ERROR_REPOSITORY ,
20722085 "attempt to reinitialize '%s'" , given_repo );
0 commit comments