Repository: gogs/gogs
File: internal/lfsutil/storage.go (Go)

Code before:
		if err != nil {
			_ = os.Remove(fpath)
		}
	}()

	err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm)
	if err != nil {
		return 0, errors.Wrap(err, "create directories")
	}

	w, err := os.OpenFile(fpath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o666)
	if err != nil {
		if os.IsExist(err) {
			// The file was already written by a previous upload (possibly for a
			// different repo). Since the OID is a content hash, the existing file
			// is guaranteed to have the correct content. Drain the reader and
			// return the existing file's size.
			_, _ = io.Copy(io.Discard, rc)
			fi, statErr := os.Stat(fpath)
			if statErr != nil {
				err = errors.Wrap(statErr, "stat existing file")
				return 0, err
			}
			err = nil
			return fi.Size(), nil
		}
		return 0, errors.Wrap(err, "create file")
	}
	defer w.Close()

	hash := sha256.New()
	written, err := io.Copy(w, io.TeeReader(rc, hash))
	if err != nil {
		return 0, errors.Wrap(err, "copy file")
	}

	if computed := hex.EncodeToString(hash.Sum(nil)); computed != string(oid) {
		err = ErrOIDMismatch
		return 0, err
	}
	return written, nil
}

func (s *LocalStorage) Download(oid OID, w io.Writer) error {
	fpath := s.storagePath(oid)
	if !osutil.IsFile(fpath) {
		return ErrObjectNotExist
	}

	r, err := os.Open(fpath)
	if err != nil {

Review comment (bug):
When `OpenFile` returns `EEXIST`, this code stats the existing path and returns its current size. If two uploads of the same OID race, request B can observe the file created by request A *before* A finishes writing, so `Stat` can return a partial size and B will create a DB record with the wrong `Size` (and downloads will send an incorrect Content-Length). Consider writing to a temp file and only atomically publishing the final object (e.g., link/rename into place) after hash verification, so an existing `fpath` is always complete.

Code after:
	defer rc.Close()

	if err := os.MkdirAll(dir, os.ModePerm); err != nil {
		return 0, errors.Wrap(err, "create directories")
	}

	// If the object file already exists, skip the upload and return the
	// existing file's size.
	if fi, err := os.Stat(fpath); err == nil {
		_, _ = io.Copy(io.Discard, rc)
		return fi.Size(), nil
	}

	// Write to a temp file and verify the content hash before publishing.
	// This ensures the final path always contains a complete, hash-verified
	// file, even when concurrent uploads of the same OID race.
	if err := os.MkdirAll(s.TempDir, os.ModePerm); err != nil {
		return 0, errors.Wrap(err, "create temp directory")
	}
	tmp, err := os.CreateTemp(s.TempDir, "upload-*")
	if err != nil {
		return 0, errors.Wrap(err, "create temp file")
	}
	tmpPath := tmp.Name()
	defer os.Remove(tmpPath)

	hash := sha256.New()
	written, err := io.Copy(tmp, io.TeeReader(rc, hash))
	if closeErr := tmp.Close(); err == nil && closeErr != nil {
		err = closeErr
	}
	if err != nil {
		return 0, errors.Wrap(err, "write object file")
	}

	if computed := hex.EncodeToString(hash.Sum(nil)); computed != string(oid) {
		return 0, ErrOIDMismatch
	}

	if err := os.Rename(tmpPath, fpath); err != nil && !os.IsExist(err) {
		return 0, errors.Wrap(err, "publish object file")
	}
	return written, nil
}

func (s *LocalStorage) Download(oid OID, w io.Writer) error {
	fpath := s.storagePath(oid)
	if !osutil.IsFile(fpath) {
		return ErrObjectNotExist
	}