Repository: go-gitea/gitea
File: services/pull/merge_prepare.go (Go)

Code before:
			log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err)
			return nil, nil, fmt.Errorf("unable to get sha of head branch in %v %w", pr, err)
		}
		if strings.TrimSpace(trackingCommitID) != expectedHeadCommitID {
			defer cancel()
			return nil, nil, ErrSHADoesNotMatch{
				GivenSHA:   expectedHeadCommitID,
				CurrentSHA: trackingCommitID,
			}
		}
	}

	mergeCtx.outbuf.Reset()
	mergeCtx.errbuf.Reset()
	if err := prepareTemporaryRepoForMerge(mergeCtx); err != nil {
		defer cancel()
		return nil, nil, err
	}

	mergeCtx.sig = doer.NewGitSig()
	mergeCtx.committer = mergeCtx.sig

	gitRepo, err := git.OpenRepository(ctx, mergeCtx.tmpBasePath)
	if err != nil {
		defer cancel()
		return nil, nil, fmt.Errorf("failed to open git repo %s: %w", mergeCtx.tmpBasePath, err)
	}
	defer gitRepo.Close()

	// Determine if we should sign
	sign, key, signer, _ := asymkey_service.SignMerge(ctx, mergeCtx.pr, mergeCtx.doer, gitRepo, "HEAD", trackingBranch)
	if sign {
		mergeCtx.signKey = key
		if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
			mergeCtx.committer = signer
		}
	}

	commitTimeStr := time.Now().Format(time.RFC3339)

	// Because this may call hooks we should pass in the environment
	mergeCtx.env = append(os.Environ(),
		"GIT_AUTHOR_NAME="+mergeCtx.sig.Name,
		"GIT_AUTHOR_EMAIL="+mergeCtx.sig.Email,
		"GIT_AUTHOR_DATE="+commitTimeStr,
		"GIT_COMMITTER_NAME="+mergeCtx.committer.Name,
		"GIT_COMMITTER_EMAIL="+mergeCtx.committer.Email,
		"GIT_COMMITTER_DATE="+commitTimeStr,
	)

	return mergeCtx, cancel, nil

Review comment (bug):
It incorrectly puts a server-side path (sensitive information) into error, then the error will be exposed to end users to lead to security problems.

Code after:
			log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err)
			return nil, nil, fmt.Errorf("unable to get sha of head branch in pr[%d]: %w", pr.ID, err)
		}
		if strings.TrimSpace(trackingCommitID) != expectedHeadCommitID {
			defer cancel()
			return nil, nil, ErrSHADoesNotMatch{
				GivenSHA:   expectedHeadCommitID,
				CurrentSHA: trackingCommitID,
			}
		}
	}

	mergeCtx.outbuf.Reset()
	mergeCtx.errbuf.Reset()
	if err := prepareTemporaryRepoForMerge(mergeCtx); err != nil {
		defer cancel()
		return nil, nil, err
	}

	mergeCtx.sig = doer.NewGitSig()
	mergeCtx.committer = mergeCtx.sig

	gitRepo, err := git.OpenRepository(ctx, mergeCtx.tmpBasePath)
	if err != nil {
		defer cancel()
		return nil, nil, fmt.Errorf("failed to open temp git repo for pr[%d]: %w", mergeCtx.pr.ID, err)
	}
	defer gitRepo.Close()

	// Determine if we should sign
	sign, key, signer, _ := asymkey_service.SignMerge(ctx, mergeCtx.pr, mergeCtx.doer, gitRepo, "HEAD", trackingBranch)
	if sign {
		mergeCtx.signKey = key
		if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
			mergeCtx.committer = signer
		}
	}

	commitTimeStr := time.Now().Format(time.RFC3339)

	// Because this may call hooks we should pass in the environment
	mergeCtx.env = append(os.Environ(),
		"GIT_AUTHOR_NAME="+mergeCtx.sig.Name,
		"GIT_AUTHOR_EMAIL="+mergeCtx.sig.Email,
		"GIT_AUTHOR_DATE="+commitTimeStr,
		"GIT_COMMITTER_NAME="+mergeCtx.committer.Name,
		"GIT_COMMITTER_EMAIL="+mergeCtx.committer.Email,
		"GIT_COMMITTER_DATE="+commitTimeStr,
	)

	return mergeCtx, cancel, nil