已关闭
fix CVE-2025-26625 #24
Funda Wang创建于 1月2日关闭于 9 天前
fix CVE-2025-26625 #24
已关闭
Funda Wang创建于 1月2日关闭于 9 天前
已删除 :openEuler-24.03-LTS-Next合入到src-openeuler/git-lfsopenEuler-24.03-LTS-Next
4 个文件变更+9386-4
@@ -0,0 +1,757 @@
1+From 867aa58c816627cbe95f0e38de68daf8cf7cf730 Mon Sep 17 00:00:00 2001
2+From: =?UTF-8?q?Ond=C5=99ej=20Poho=C5=99elsk=C3=BD?= <opohorel@redhat.com>
3+Date: Thu, 7 Aug 2025 13:55:34 +0200
4+Subject: [PATCH] Use constant format string
5+ 
6+Resolves build failure with Golang-1.24<
7+---
8+ commands/command_clean.go | 2 +-
9+ commands/command_dedup.go | 2 +-
10+ commands/command_fsck.go | 4 ++--
11+ commands/command_logs.go | 6 +++---
12+ commands/command_migrate.go | 2 +-
13+ commands/command_migrate_export.go | 4 ++--
14+ commands/command_migrate_import.go | 20 ++++++++++----------
15+ commands/command_migrate_info.go | 6 +++---
16+ commands/command_pointer.go | 2 +-
17+ commands/command_smudge.go | 4 ++--
18+ creds/creds.go | 10 +++++-----
19+ errors/errors.go | 2 +-
20+ errors/types.go | 2 +-
21+ git/githistory/rewriter_test.go | 2 +-
22+ lfs/diff_index_scanner.go | 4 ++--
23+ lfs/gitfilter_smudge.go | 12 ++++++------
24+ lfshttp/certs.go | 12 ++++++------
25+ lfshttp/errors.go | 7 ++++++-
26+ lfshttp/lfshttp.go | 2 +-
27+ lfshttp/standalone/standalone.go | 8 ++++----
28+ ssh/connection.go | 2 +-
29+ t/git-lfs-test-server-api/main.go | 2 +-
30+ tasklog/simple_task.go | 2 +-
31+ tools/filetools.go | 4 ++--
32+ tq/basic_download.go | 4 ++--
33+ tq/basic_upload.go | 4 ++--
34+ tq/custom.go | 2 +-
35+ tq/ssh.go | 6 +++---
36+ tq/transfer_queue.go | 4 ++--
37+ tq/tus_upload.go | 4 ++--
38+ 30 files changed, 76 insertions(+), 71 deletions(-)
39+ 
40+diff --git a/commands/command_clean.go b/commands/command_clean.go
41+index 6b02d23c..8fa12d9b 100644
42+--- a/commands/command_clean.go
43++++ b/commands/command_clean.go
44+@@ -82,7 +82,7 @@ func clean(gf *lfs.GitFilter, to io.Writer, from io.Reader, fileName string, fil
45+ Panic(err, tr.Tr.Get("Unable to move %s to %s", tmpfile, mediafile))
46+ }
47+
48+- Debug(tr.Tr.Get("Writing %s", mediafile))
49++ Debug("%s", tr.Tr.Get("Writing %s", mediafile))
50+ }
51+
52+ _, err = lfs.EncodePointer(to, cleaned.Pointer)
53+diff --git a/commands/command_dedup.go b/commands/command_dedup.go
54+index 4d9688f2..2babff45 100644
55+--- a/commands/command_dedup.go
56++++ b/commands/command_dedup.go
57+@@ -129,7 +129,7 @@ func dedup(p *lfs.WrappedPointer) (success bool, err error) {
58+ if ok, err := tools.CloneFileByPath(dstFile, srcFile); err != nil {
59+ return false, err
60+ } else if !ok {
61+- return false, errors.Errorf(tr.Tr.Get("unknown clone file error"))
62++ return false, errors.Errorf("%s", tr.Tr.Get("unknown clone file error"))
63+ }
64+
65+ // Recover original state
66+diff --git a/commands/command_fsck.go b/commands/command_fsck.go
67+index c2332ef8..63756854 100644
68+--- a/commands/command_fsck.go
69++++ b/commands/command_fsck.go
70+@@ -170,7 +170,7 @@ func doFsckPointers(include, exclude string) []corruptPointer {
71+ var corruptPointers []corruptPointer
72+ gitscanner := lfs.NewGitScanner(cfg, func(p *lfs.WrappedPointer, err error) {
73+ if p != nil {
74+- Debug(tr.Tr.Get("Examining %v (%v)", p.Oid, p.Name))
75++ Debug("%s", tr.Tr.Get("Examining %v (%v)", p.Oid, p.Name))
76+ if !p.Canonical {
77+ cp := corruptPointer{
78+ blobOid: p.Sha1,
79+@@ -214,7 +214,7 @@ func doFsckPointers(include, exclude string) []corruptPointer {
80+ func fsckPointer(name, oid string, size int64) (bool, error) {
81+ path := cfg.Filesystem().ObjectPathname(oid)
82+
83+- Debug(tr.Tr.Get("Examining %v (%v)", name, path))
84++ Debug("%s", tr.Tr.Get("Examining %v (%v)", name, path))
85+
86+ f, err := os.Open(path)
87+ if pErr, pOk := err.(*os.PathError); pOk {
88+diff --git a/commands/command_logs.go b/commands/command_logs.go
89+index 89d738fe..aa781dfa 100644
90+--- a/commands/command_logs.go
91++++ b/commands/command_logs.go
92+@@ -37,7 +37,7 @@ func logsShowCommand(cmd *cobra.Command, args []string) {
93+ Exit(tr.Tr.Get("Error reading log: %s", name))
94+ }
95+
96+- Debug(tr.Tr.Get("Reading log: %s", name))
97++ Debug("%s", tr.Tr.Get("Reading log: %s", name))
98+ os.Stdout.Write(by)
99+ }
100+
101+@@ -51,8 +51,8 @@ func logsClearCommand(cmd *cobra.Command, args []string) {
102+ }
103+
104+ func logsBoomtownCommand(cmd *cobra.Command, args []string) {
105+- Debug(tr.Tr.Get("Sample debug message"))
106+- err := errors.Wrapf(errors.New(tr.Tr.Get("Sample wrapped error message")), tr.Tr.Get("Sample error message"))
107++ Debug("%s", tr.Tr.Get("Sample debug message"))
108++ err := errors.Wrapf(errors.New(tr.Tr.Get("Sample wrapped error message")), "%s", tr.Tr.Get("Sample error message"))
109+ Panic(err, tr.Tr.Get("Sample panic message"))
110+ }
111+
112+diff --git a/commands/command_migrate.go b/commands/command_migrate.go
113+index e638d0bf..b16680b5 100644
114+--- a/commands/command_migrate.go
115++++ b/commands/command_migrate.go
116+@@ -319,7 +319,7 @@ func currentRefToMigrate() (*git.Ref, error) {
117+ if current.Type == git.RefTypeOther ||
118+ current.Type == git.RefTypeRemoteBranch {
119+
120+- return nil, errors.Errorf(tr.Tr.Get("Cannot migrate non-local ref: %s", current.Name))
121++ return nil, errors.Errorf("%s", tr.Tr.Get("Cannot migrate non-local ref: %s", current.Name))
122+ }
123+ return current, nil
124+ }
125+diff --git a/commands/command_migrate_export.go b/commands/command_migrate_export.go
126+index 16c58653..484134b8 100644
127+--- a/commands/command_migrate_export.go
128++++ b/commands/command_migrate_export.go
129+@@ -35,7 +35,7 @@ func migrateExportCommand(cmd *cobra.Command, args []string) {
130+
131+ filter := rewriter.Filter()
132+ if len(filter.Include()) <= 0 {
133+- ExitWithError(errors.Errorf(tr.Tr.Get("One or more files must be specified with --include")))
134++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("One or more files must be specified with --include")))
135+ }
136+
137+ tracked := trackedFromExportFilter(filter)
138+@@ -116,7 +116,7 @@ func migrateExportCommand(cmd *cobra.Command, args []string) {
139+ }
140+ remoteURL := getAPIClient().Endpoints.RemoteEndpoint("download", remote).Url
141+ if remoteURL == "" && cmd.Flag("remote").Changed {
142+- ExitWithError(errors.Errorf(tr.Tr.Get("Invalid remote %s provided", remote)))
143++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Invalid remote %s provided", remote)))
144+ }
145+
146+ // If we have a valid remote, pre-download all objects using the Transfer Queue
147+diff --git a/commands/command_migrate_import.go b/commands/command_migrate_import.go
148+index 8b44b415..b03301f9 100644
149+--- a/commands/command_migrate_import.go
150++++ b/commands/command_migrate_import.go
151+@@ -44,11 +44,11 @@ func migrateImportCommand(cmd *cobra.Command, args []string) {
152+
153+ if migrateNoRewrite {
154+ if migrateFixup {
155+- ExitWithError(errors.Errorf(tr.Tr.Get("--no-rewrite and --fixup cannot be combined")))
156++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("--no-rewrite and --fixup cannot be combined")))
157+ }
158+
159+ if len(args) == 0 {
160+- ExitWithError(errors.Errorf(tr.Tr.Get("Expected one or more files with --no-rewrite")))
161++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Expected one or more files with --no-rewrite")))
162+ }
163+
164+ ref, err := git.CurrentRef()
165+@@ -66,21 +66,21 @@ func migrateImportCommand(cmd *cobra.Command, args []string) {
166+
167+ filter := git.GetAttributeFilter(cfg.LocalWorkingDir(), cfg.LocalGitDir())
168+ if len(filter.Include()) == 0 {
169+- ExitWithError(errors.Errorf(tr.Tr.Get("No Git LFS filters found in '.gitattributes'")))
170++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("No Git LFS filters found in '.gitattributes'")))
171+ }
172+
173+ gf := lfs.NewGitFilter(cfg)
174+
175+ for _, file := range args {
176+ if !filter.Allows(file) {
177+- ExitWithError(errors.Errorf(tr.Tr.Get("File %s did not match any Git LFS filters in '.gitattributes'", file)))
178++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("File %s did not match any Git LFS filters in '.gitattributes'", file)))
179+ }
180+ }
181+
182+ for _, file := range args {
183+ root, err = rewriteTree(gf, db, root, file)
184+ if err != nil {
185+- ExitWithError(errors.Wrapf(err, tr.Tr.Get("Could not rewrite %q", file)))
186++ ExitWithError(errors.Wrapf(err, "%s", tr.Tr.Get("Could not rewrite %q", file)))
187+ }
188+ }
189+
190+@@ -124,7 +124,7 @@ func migrateImportCommand(cmd *cobra.Command, args []string) {
191+ if migrateFixup {
192+ include, exclude := getIncludeExcludeArgs(cmd)
193+ if include != nil || exclude != nil {
194+- ExitWithError(errors.Errorf(tr.Tr.Get("Cannot use --fixup with --include, --exclude")))
195++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Cannot use --fixup with --include, --exclude")))
196+ }
197+ }
198+
199+@@ -142,7 +142,7 @@ func migrateImportCommand(cmd *cobra.Command, args []string) {
200+ if above > 0 {
201+ include, exclude := getIncludeExcludeArgs(cmd)
202+ if include != nil || exclude != nil || migrateFixup {
203+- ExitWithError(errors.Errorf(tr.Tr.Get("Cannot use --above with --include, --exclude, --fixup")))
204++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Cannot use --above with --include, --exclude, --fixup")))
205+ }
206+ }
207+
208+@@ -395,7 +395,7 @@ func rewriteTree(gf *lfs.GitFilter, db *gitobj.ObjectDatabase, root []byte, path
209+ // Try to replace this blob with a Git LFS pointer.
210+ index := findEntry(tree, splits[0])
211+ if index < 0 {
212+- return nil, errors.Errorf(tr.Tr.Get("unable to find entry %s in tree", splits[0]))
213++ return nil, errors.Errorf("%s", tr.Tr.Get("unable to find entry %s in tree", splits[0]))
214+ }
215+
216+ blobEntry := tree.Entries[index]
217+@@ -433,7 +433,7 @@ func rewriteTree(gf *lfs.GitFilter, db *gitobj.ObjectDatabase, root []byte, path
218+
219+ index := findEntry(tree, head)
220+ if index < 0 {
221+- return nil, errors.Errorf(tr.Tr.Get("unable to find entry %s in tree", head))
222++ return nil, errors.Errorf("%s", tr.Tr.Get("unable to find entry %s in tree", head))
223+ }
224+
225+ subtreeEntry := tree.Entries[index]
226+@@ -455,7 +455,7 @@ func rewriteTree(gf *lfs.GitFilter, db *gitobj.ObjectDatabase, root []byte, path
227+ return db.WriteTree(tree)
228+
229+ default:
230+- return nil, errors.Errorf(tr.Tr.Get("error parsing path %s", path))
231++ return nil, errors.Errorf("%s", tr.Tr.Get("error parsing path %s", path))
232+ }
233+ }
234+
235+diff --git a/commands/command_migrate_info.go b/commands/command_migrate_info.go
236+index bcbc18b2..c0368a6e 100644
237+--- a/commands/command_migrate_info.go
238++++ b/commands/command_migrate_info.go
239+@@ -96,17 +96,17 @@ func migrateInfoCommand(cmd *cobra.Command, args []string) {
240+ case "ignore":
241+ migrateInfoPointersMode = migrateInfoPointersIgnore
242+ default:
243+- ExitWithError(errors.Errorf(tr.Tr.Get("Unsupported --pointers option value")))
244++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Unsupported --pointers option value")))
245+ }
246+ }
247+
248+ if migrateFixup {
249+ include, exclude := getIncludeExcludeArgs(cmd)
250+ if include != nil || exclude != nil {
251+- ExitWithError(errors.Errorf(tr.Tr.Get("Cannot use --fixup with --include, --exclude")))
252++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Cannot use --fixup with --include, --exclude")))
253+ }
254+ if pointers.Changed && migrateInfoPointersMode != migrateInfoPointersIgnore {
255+- ExitWithError(errors.Errorf(tr.Tr.Get("Cannot use --fixup with --pointers=%s", pointers.Value.String())))
256++ ExitWithError(errors.Errorf("%s", tr.Tr.Get("Cannot use --fixup with --pointers=%s", pointers.Value.String())))
257+ }
258+ migrateInfoPointersMode = migrateInfoPointersIgnore
259+ }
260+diff --git a/commands/command_pointer.go b/commands/command_pointer.go
261+index a2a57da6..2177408d 100644
262+--- a/commands/command_pointer.go
263++++ b/commands/command_pointer.go
264+@@ -129,7 +129,7 @@ func pointerCommand(cmd *cobra.Command, args []string) {
265+ os.Exit(1)
266+ }
267+
268+- fmt.Fprintf(os.Stderr, buf.String())
269++ fmt.Fprintf(os.Stderr, "%s", buf.String())
270+ if comparing {
271+ compareOid, err = git.HashObject(bytes.NewReader(buf.Bytes()))
272+ if err != nil {
273+diff --git a/commands/command_smudge.go b/commands/command_smudge.go
274+index 0117b996..2b6297c8 100644
275+--- a/commands/command_smudge.go
276++++ b/commands/command_smudge.go
277+@@ -45,7 +45,7 @@ func delayedSmudge(gf *lfs.GitFilter, s *git.FilterProcessScanner, to io.Writer,
278+
279+ if n != 0 {
280+ return 0, false, nil, errors.NewNotAPointerError(errors.Errorf(
281+- tr.Tr.Get("Unable to parse pointer at: %q", filename),
282++ "%s", tr.Tr.Get("Unable to parse pointer at: %q", filename),
283+ ))
284+ }
285+ return 0, false, nil, nil
286+@@ -108,7 +108,7 @@ func smudge(gf *lfs.GitFilter, to io.Writer, from io.Reader, filename string, sk
287+
288+ if n != 0 {
289+ return 0, errors.NewNotAPointerError(errors.Errorf(
290+- tr.Tr.Get("Unable to parse pointer at: %q", filename),
291++ "%s", tr.Tr.Get("Unable to parse pointer at: %q", filename),
292+ ))
293+ }
294+ return 0, nil
295+diff --git a/creds/creds.go b/creds/creds.go
296+index 784c1b5f..d869dbca 100644
297+--- a/creds/creds.go
298++++ b/creds/creds.go
299+@@ -66,13 +66,13 @@ func (c Creds) buffer(protectProtocol bool) (*bytes.Buffer, error) {
300+ for k, v := range c {
301+ for _, item := range v {
302+ if strings.Contains(item, "\n") {
303+- return nil, errors.Errorf(tr.Tr.Get("credential value for %s contains newline: %q", k, item))
304++ return nil, errors.Errorf("%s", tr.Tr.Get("credential value for %s contains newline: %q", k, item))
305+ }
306+ if protectProtocol && strings.Contains(item, "\r") {
307+- return nil, errors.Errorf(tr.Tr.Get("credential value for %s contains carriage return: %q\nIf this is intended, set `credential.protectProtocol=false`", k, item))
308++ return nil, errors.Errorf("%s", tr.Tr.Get("credential value for %s contains carriage return: %q\nIf this is intended, set `credential.protectProtocol=false`", k, item))
309+ }
310+ if strings.Contains(item, string(rune(0))) {
311+- return nil, errors.Errorf(tr.Tr.Get("credential value for %s contains null byte: %q", k, item))
312++ return nil, errors.Errorf("%s", tr.Tr.Get("credential value for %s contains null byte: %q", k, item))
313+ }
314+
315+ buf.Write([]byte(k))
316+@@ -249,7 +249,7 @@ func (a *AskPassCredentialHelper) getValue(what Creds, valueType credValueType,
317+ case credValueTypePassword:
318+ valueString = "password"
319+ default:
320+- return "", errors.Errorf(tr.Tr.Get("Invalid Credential type queried from AskPass"))
321++ return "", errors.Errorf("%s", tr.Tr.Get("Invalid Credential type queried from AskPass"))
322+ }
323+
324+ // Return the existing credential if it was already provided, otherwise
325+@@ -274,7 +274,7 @@ func (a *AskPassCredentialHelper) getFromProgram(valueType credValueType, u *url
326+ case credValueTypePassword:
327+ valueString = "Password"
328+ default:
329+- return "", errors.Errorf(tr.Tr.Get("Invalid Credential type queried from AskPass"))
330++ return "", errors.Errorf("%s", tr.Tr.Get("Invalid Credential type queried from AskPass"))
331+ }
332+
333+ // 'cmd' will run the GIT_ASKPASS (or core.askpass) command prompting
334+diff --git a/errors/errors.go b/errors/errors.go
335+index dae33a81..c77b5e93 100644
336+--- a/errors/errors.go
337++++ b/errors/errors.go
338+@@ -114,7 +114,7 @@ func Combine(errs []error) error {
339+ }
340+ buf.WriteString(err.Error())
341+ }
342+- return fmt.Errorf(buf.String())
343++ return fmt.Errorf("%s", buf.String())
344+ }
345+
346+ func Cause(err error) error {
347+diff --git a/errors/types.go b/errors/types.go
348+index 041e4f39..b869b4ea 100644
349+--- a/errors/types.go
350++++ b/errors/types.go
351+@@ -386,7 +386,7 @@ func (e badPointerKeyError) BadPointerKeyError() bool {
352+ }
353+
354+ func NewBadPointerKeyError(expected, actual string) error {
355+- err := Errorf(tr.Tr.Get("Expected key %s, got %s", expected, actual))
356++ err := Errorf("%s", tr.Tr.Get("Expected key %s, got %s", expected, actual))
357+ return badPointerKeyError{expected, actual, newWrappedError(err, tr.Tr.Get("pointer parsing"))}
358+ }
359+
360+diff --git a/git/githistory/rewriter_test.go b/git/githistory/rewriter_test.go
361+index 98ce635c..b401e5f3 100644
362+--- a/git/githistory/rewriter_test.go
363++++ b/git/githistory/rewriter_test.go
364+@@ -377,7 +377,7 @@ func TestHistoryRewriterCallbacksSubtrees(t *testing.T) {
365+ }
366+
367+ func TestHistoryRewriterTreePreCallbackPropagatesErrors(t *testing.T) {
368+- expected := errors.Errorf("my error")
369++ expected := errors.Errorf("%s", "my error")
370+
371+ db := DatabaseFromFixture(t, "linear-history.git")
372+ r := NewRewriter(db)
373+diff --git a/lfs/diff_index_scanner.go b/lfs/diff_index_scanner.go
374+index 7ceaf4df..d7029423 100644
375+--- a/lfs/diff_index_scanner.go
376++++ b/lfs/diff_index_scanner.go
377+@@ -185,12 +185,12 @@ func (s *DiffIndexScanner) scan(line string) (*DiffIndexEntry, error) {
378+
379+ parts := strings.Split(line, "\t")
380+ if len(parts) < 2 {
381+- return nil, errors.Errorf(tr.Tr.Get("invalid line: %s", line))
382++ return nil, errors.Errorf("%s", tr.Tr.Get("invalid line: %s", line))
383+ }
384+
385+ desc := strings.Fields(parts[0])
386+ if len(desc) < 5 {
387+- return nil, errors.Errorf(tr.Tr.Get("invalid description: %s", parts[0]))
388++ return nil, errors.Errorf("%s", tr.Tr.Get("invalid description: %s", parts[0]))
389+ }
390+
391+ entry := &DiffIndexEntry{
392+diff --git a/lfs/gitfilter_smudge.go b/lfs/gitfilter_smudge.go
393+index 830e83c4..58049da1 100644
394+--- a/lfs/gitfilter_smudge.go
395++++ b/lfs/gitfilter_smudge.go
396+@@ -132,7 +132,7 @@ func (f *GitFilter) downloadFile(writer io.Writer, ptr *Pointer, workingfile, me
397+ }
398+ }
399+
400+- return 0, errors.Wrapf(multiErr, tr.Tr.Get("Error downloading %s (%s)", workingfile, ptr.Oid))
401++ return 0, errors.Wrapf(multiErr, "%s", tr.Tr.Get("Error downloading %s (%s)", workingfile, ptr.Oid))
402+ }
403+
404+ return f.readLocalFile(writer, ptr, mediafile, workingfile, nil)
405+@@ -163,7 +163,7 @@ func (f *GitFilter) downloadFileFallBack(writer io.Writer, ptr *Pointer, working
406+ multiErr = e
407+ }
408+ }
409+- wrappedError := errors.Wrapf(multiErr, tr.Tr.Get("Error downloading %s (%s)", workingfile, ptr.Oid))
410++ wrappedError := errors.Wrapf(multiErr, "%s", tr.Tr.Get("Error downloading %s (%s)", workingfile, ptr.Oid))
411+ if index >= len(remotes)-1 {
412+ return 0, wrappedError
413+ } else {
414+@@ -176,13 +176,13 @@ func (f *GitFilter) downloadFileFallBack(writer io.Writer, ptr *Pointer, working
415+ return f.readLocalFile(writer, ptr, mediafile, workingfile, nil)
416+ }
417+ }
418+- return 0, errors.Wrapf(errors.New("No known remotes"), tr.Tr.Get("Error downloading %s (%s)", workingfile, ptr.Oid))
419++ return 0, errors.Wrapf(errors.New("No known remotes"), "%s", tr.Tr.Get("Error downloading %s (%s)", workingfile, ptr.Oid))
420+ }
421+
422+ func (f *GitFilter) readLocalFile(writer io.Writer, ptr *Pointer, mediafile string, workingfile string, cb tools.CopyCallback) (int64, error) {
423+ reader, err := tools.RobustOpen(mediafile)
424+ if err != nil {
425+- return 0, errors.Wrapf(err, tr.Tr.Get("error opening media file"))
426++ return 0, errors.Wrapf(err, "%s", tr.Tr.Get("error opening media file"))
427+ }
428+ defer reader.Close()
429+
430+@@ -250,14 +250,14 @@ func (f *GitFilter) readLocalFile(writer io.Writer, ptr *Pointer, mediafile stri
431+ // setup reader
432+ reader, err = os.Open(response.file.Name())
433+ if err != nil {
434+- return 0, errors.Wrapf(err, tr.Tr.Get("Error opening smudged file: %s", err))
435++ return 0, errors.Wrapf(err, "%s", tr.Tr.Get("Error opening smudged file: %s", err))
436+ }
437+ defer reader.Close()
438+ }
439+
440+ n, err := tools.CopyWithCallback(writer, reader, ptr.Size, cb)
441+ if err != nil {
442+- return n, errors.Wrapf(err, tr.Tr.Get("Error reading from media file: %s", err))
443++ return n, errors.Wrapf(err, "%s", tr.Tr.Get("Error reading from media file: %s", err))
444+ }
445+
446+ return n, nil
447+diff --git a/lfshttp/certs.go b/lfshttp/certs.go
448+index c193aa59..68abcb42 100644
449+--- a/lfshttp/certs.go
450++++ b/lfshttp/certs.go
451+@@ -76,23 +76,23 @@ func getClientCertForHost(c *Client, host string) (*tls.Certificate, error) {
452+
453+ hostSslKey, err := tools.ExpandPath(hostSslKey, false)
454+ if err != nil {
455+- return nil, errors.Wrapf(err, tr.Tr.Get("Error resolving key path %q", hostSslKey))
456++ return nil, errors.Wrapf(err, "%s", tr.Tr.Get("Error resolving key path %q", hostSslKey))
457+ }
458+
459+ hostSslCert, err = tools.ExpandPath(hostSslCert, false)
460+ if err != nil {
461+- return nil, errors.Wrapf(err, tr.Tr.Get("Error resolving cert path %q", hostSslCert))
462++ return nil, errors.Wrapf(err, "%s", tr.Tr.Get("Error resolving cert path %q", hostSslCert))
463+ }
464+
465+ cert, err := os.ReadFile(hostSslCert)
466+ if err != nil {
467+ tracerx.Printf("Error reading client cert file %q: %v", hostSslCert, err)
468+- return nil, errors.Wrapf(err, tr.Tr.Get("Error reading client cert file %q", hostSslCert))
469++ return nil, errors.Wrapf(err, "%s", tr.Tr.Get("Error reading client cert file %q", hostSslCert))
470+ }
471+ key, err := os.ReadFile(hostSslKey)
472+ if err != nil {
473+ tracerx.Printf("Error reading client key file %q: %v", hostSslKey, err)
474+- return nil, errors.Wrapf(err, tr.Tr.Get("Error reading client key file %q", hostSslKey))
475++ return nil, errors.Wrapf(err, "%s", tr.Tr.Get("Error reading client key file %q", hostSslKey))
476+ }
477+
478+ block, _ := pem.Decode(key)
479+@@ -103,14 +103,14 @@ func getClientCertForHost(c *Client, host string) (*tls.Certificate, error) {
480+ key, err = decryptPEMBlock(c, block, hostSslKey, key)
481+ if err != nil {
482+ tracerx.Printf("Unable to decrypt client key file %q: %v", hostSslKey, err)
483+- return nil, errors.Wrapf(err, tr.Tr.Get("Error reading client key file %q (not a PKCS#1 file?)", hostSslKey))
484++ return nil, errors.Wrapf(err, "%s", tr.Tr.Get("Error reading client key file %q (not a PKCS#1 file?)", hostSslKey))
485+ }
486+ }
487+
488+ certobj, err := tls.X509KeyPair(cert, key)
489+ if err != nil {
490+ tracerx.Printf("Error reading client cert/key %v", err)
491+- return nil, errors.Wrapf(err, tr.Tr.Get("Error reading client cert/key"))
492++ return nil, errors.Wrapf(err, "%s", tr.Tr.Get("Error reading client cert/key"))
493+ }
494+ return &certobj, nil
495+ }
496+diff --git a/lfshttp/errors.go b/lfshttp/errors.go
497+index 15340061..bc1e13d6 100644
498+--- a/lfshttp/errors.go
499++++ b/lfshttp/errors.go
500+@@ -124,5 +124,10 @@ func defaultError(res *http.Response) error {
501+ msgFmt = tr.Tr.Get("Server error %%s from HTTP %d", res.StatusCode)
502+ }
503+
504+- return errors.Errorf(fmt.Sprintf(msgFmt), res.Request.URL)
505++ // Preserve exact original behavior but avoid format string warnings
506++ // Original was: errors.Errorf(fmt.Sprintf(msgFmt), res.Request.URL)
507++ // This is equivalent but avoids variable format strings
508++ urlStr := fmt.Sprintf("%v", res.Request.URL) // Convert URL to string safely
509++ finalMsg := strings.ReplaceAll(msgFmt, "%%s", urlStr) // Replace %%s with actual URL
510++ return errors.New(finalMsg)
511+ }
512+diff --git a/lfshttp/lfshttp.go b/lfshttp/lfshttp.go
513+index fa89714a..913442db 100644
514+--- a/lfshttp/lfshttp.go
515++++ b/lfshttp/lfshttp.go
516+@@ -84,7 +84,7 @@ func DecodeJSON(res *http.Response, obj interface{}) error {
517+ res.Body.Close()
518+
519+ if err != nil {
520+- return errors.Wrapf(err, tr.Tr.Get("Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL))
521++ return errors.Wrapf(err, "%s", tr.Tr.Get("Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL))
522+ }
523+
524+ return nil
525+diff --git a/lfshttp/standalone/standalone.go b/lfshttp/standalone/standalone.go
526+index 22a5902e..05b7a4b1 100644
527+--- a/lfshttp/standalone/standalone.go
528++++ b/lfshttp/standalone/standalone.go
529+@@ -256,7 +256,7 @@ func (h *fileHandler) upload(oid string, size int64, path string) (string, strin
530+ func (h *fileHandler) download(oid string, size int64) (string, string, error) {
531+ if !h.remoteConfig.LFSObjectExists(oid, size) {
532+ tracerx.Printf("missing object in %q (%s)", h.remotePath, oid)
533+- return oid, "", errors.Errorf(tr.Tr.Get("remote missing object %s", oid))
534++ return oid, "", errors.Errorf("%s", tr.Tr.Get("remote missing object %s", oid))
535+ }
536+
537+ src, err := h.remoteConfig.Filesystem().ObjectPath(oid)
538+@@ -290,13 +290,13 @@ func ProcessStandaloneData(cfg *config.Configuration, input *os.File, output *os
539+ for scanner.Scan() {
540+ var msg inputMessage
541+ if err := json.NewDecoder(strings.NewReader(scanner.Text())).Decode(&msg); err != nil {
542+- return errors.Wrapf(err, tr.Tr.Get("error decoding JSON"))
543++ return errors.Wrapf(err, "%s", tr.Tr.Get("error decoding JSON"))
544+ }
545+ if handler == nil {
546+ var err error
547+ handler, err = newHandler(cfg, output, &msg)
548+ if err != nil {
549+- err := errors.Wrapf(err, tr.Tr.Get("error creating handler"))
550++ err := errors.Wrapf(err, "%s", tr.Tr.Get("error creating handler"))
551+ errMsg := outputErrorMessage{
552+ Error: errorMessage{
553+ Message: err.Error(),
554+@@ -314,7 +314,7 @@ func ProcessStandaloneData(cfg *config.Configuration, input *os.File, output *os
555+ os.RemoveAll(handler.tempdir)
556+ }
557+ if err := scanner.Err(); err != nil {
558+- return errors.Wrapf(err, tr.Tr.Get("error reading input"))
559++ return errors.Wrapf(err, "%s", tr.Tr.Get("error reading input"))
560+ }
561+ return nil
562+ }
563+diff --git a/ssh/connection.go b/ssh/connection.go
564+index 83a4530c..f08165ae 100644
565+--- a/ssh/connection.go
566++++ b/ssh/connection.go
567+@@ -80,7 +80,7 @@ func startConnection(id int, osEnv config.Environment, gitEnv config.Environment
568+ r.Close()
569+ w.Close()
570+ cmd.Wait()
571+- err = errors.Combine([]error{err, fmt.Errorf(tr.Tr.Get("Failed to connect to remote SSH server: %s", cmd.Stderr))})
572++ err = errors.Combine([]error{err, fmt.Errorf("%s", tr.Tr.Get("Failed to connect to remote SSH server: %s", cmd.Stderr))})
573+ tracerx.Printf("pure SSH connection unsuccessful (#%d)", id)
574+ } else {
575+ tracerx.Printf("pure SSH connection successful (#%d)", id)
576+diff --git a/t/git-lfs-test-server-api/main.go b/t/git-lfs-test-server-api/main.go
577+index f897fd6e..6408fbdd 100644
578+--- a/t/git-lfs-test-server-api/main.go
579++++ b/t/git-lfs-test-server-api/main.go
580+@@ -74,7 +74,7 @@ func testServerApi(cmd *cobra.Command, args []string) {
581+
582+ manifest, err := buildManifest(repo)
583+ if err != nil {
584+- exit("error building tq.Manifest: " + err.Error())
585++ exit("error building tq.Manifest: %s", err.Error())
586+ }
587+
588+ var oidsExist, oidsMissing []TestObject
589+diff --git a/tasklog/simple_task.go b/tasklog/simple_task.go
590+index 207c5838..fb9c0988 100644
591+--- a/tasklog/simple_task.go
592++++ b/tasklog/simple_task.go
593+@@ -28,7 +28,7 @@ func NewSimpleTask() *SimpleTask {
594+
595+ // Log logs a string with no formatting verbs.
596+ func (s *SimpleTask) Log(str string) {
597+- s.Logf(str)
598++ s.Logf("%s", str)
599+ }
600+
601+ // Logf logs some formatted string, which is interpreted according to the rules
602+diff --git a/tools/filetools.go b/tools/filetools.go
603+index be97a800..05f56822 100644
604+--- a/tools/filetools.go
605++++ b/tools/filetools.go
606+@@ -181,14 +181,14 @@ func ExpandPath(path string, expand bool) (string, error) {
607+ }
608+
609+ if err != nil {
610+- return "", errors.Wrapf(err, tr.Tr.Get("could not find user %s", username))
611++ return "", errors.Wrapf(err, "%s", tr.Tr.Get("could not find user %s", username))
612+ }
613+
614+ homedir := who.HomeDir
615+ if expand {
616+ homedir, err = filepath.EvalSymlinks(homedir)
617+ if err != nil {
618+- return "", errors.Wrapf(err, tr.Tr.Get("cannot eval symlinks for %s", homedir))
619++ return "", errors.Wrapf(err, "%s", tr.Tr.Get("cannot eval symlinks for %s", homedir))
620+ }
621+ }
622+ return filepath.Join(homedir, path[len(username)+1:]), nil
623+diff --git a/tq/basic_download.go b/tq/basic_download.go
624+index 767ebaee..c2aae578 100644
625+--- a/tq/basic_download.go
626++++ b/tq/basic_download.go
627+@@ -118,7 +118,7 @@ func (a *basicDownloadAdapter) download(t *Transfer, cb ProgressCallback, authOk
628+ return err
629+ }
630+ if rel == nil {
631+- return errors.Errorf(tr.Tr.Get("Object %s not found on the server.", t.Oid))
632++ return errors.Errorf("%s", tr.Tr.Get("Object %s not found on the server.", t.Oid))
633+ }
634+
635+ req, err := a.newHTTPRequest("GET", rel)
636+@@ -243,7 +243,7 @@ func (a *basicDownloadAdapter) download(t *Transfer, cb ProgressCallback, authOk
637+ }
638+ written, err := tools.CopyWithCallback(dlFile, hasher, res.ContentLength, ccb)
639+ if err != nil {
640+- return errors.Wrapf(err, tr.Tr.Get("cannot write data to temporary file %q", dlfilename))
641++ return errors.Wrapf(err, "%s", tr.Tr.Get("cannot write data to temporary file %q", dlfilename))
642+ }
643+
644+ if actual := hasher.Hash(); actual != t.Oid {
645+diff --git a/tq/basic_upload.go b/tq/basic_upload.go
646+index 669a2015..b90278ad 100644
647+--- a/tq/basic_upload.go
648++++ b/tq/basic_upload.go
649+@@ -47,7 +47,7 @@ func (a *basicUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb Progres
650+ return err
651+ }
652+ if rel == nil {
653+- return errors.Errorf(tr.Tr.Get("No upload action for object: %s", t.Oid))
654++ return errors.Errorf("%s", tr.Tr.Get("No upload action for object: %s", t.Oid))
655+ }
656+
657+ req, err := a.newHTTPRequest("PUT", rel)
658+@@ -142,7 +142,7 @@ func (a *basicUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb Progres
659+ }
660+
661+ if res.StatusCode > 299 {
662+- return errors.Wrapf(nil, tr.Tr.Get("Invalid status for %s %s: %d",
663++ return errors.Wrapf(nil, "%s", tr.Tr.Get("Invalid status for %s %s: %d",
664+ req.Method,
665+ strings.SplitN(req.URL.String(), "?", 2)[0],
666+ res.StatusCode,
667+diff --git a/tq/custom.go b/tq/custom.go
668+index 060e77db..f479d3d7 100644
669+--- a/tq/custom.go
670++++ b/tq/custom.go
671+@@ -272,7 +272,7 @@ func (a *customAdapter) DoTransfer(ctx interface{}, t *Transfer, cb ProgressCall
672+ return err
673+ }
674+ if rel == nil && !a.standalone {
675+- return errors.Errorf(tr.Tr.Get("Object %s not found on the server.", t.Oid))
676++ return errors.Errorf("%s", tr.Tr.Get("Object %s not found on the server.", t.Oid))
677+ }
678+ var req *customAdapterTransferRequest
679+ if a.direction == Upload {
680+diff --git a/tq/ssh.go b/tq/ssh.go
681+index 79693495..235644ef 100644
682+--- a/tq/ssh.go
683++++ b/tq/ssh.go
684+@@ -194,7 +194,7 @@ func (a *SSHAdapter) download(t *Transfer, workerNum int, cb ProgressCallback) e
685+ return err
686+ }
687+ if rel == nil {
688+- return errors.Errorf(tr.Tr.Get("No download action for object: %s", t.Oid))
689++ return errors.Errorf("%s", tr.Tr.Get("No download action for object: %s", t.Oid))
690+ }
691+ // Reserve a temporary filename. We need to make sure nobody operates on the file simultaneously with us.
692+ f, err := tools.TempFile(a.tempDir(), t.Oid, a.fs)
693+@@ -267,7 +267,7 @@ func (a *SSHAdapter) doDownload(t *Transfer, workerNum int, f *os.File, cb Progr
694+ hasher := tools.NewHashingReader(data)
695+ written, err := tools.CopyWithCallback(f, hasher, t.Size, ccb)
696+ if err != nil {
697+- return errors.Wrapf(err, tr.Tr.Get("cannot write data to temporary file %q", dlfilename))
698++ return errors.Wrapf(err, "%s", tr.Tr.Get("cannot write data to temporary file %q", dlfilename))
699+ }
700+
701+ if actual := hasher.Hash(); actual != t.Oid {
702+@@ -346,7 +346,7 @@ func (a *SSHAdapter) upload(t *Transfer, workerNum int, cb ProgressCallback) err
703+ return err
704+ }
705+ if rel == nil {
706+- return errors.Errorf(tr.Tr.Get("No upload action for object: %s", t.Oid))
707++ return errors.Errorf("%s", tr.Tr.Get("No upload action for object: %s", t.Oid))
708+ }
709+
710+ f, err := os.OpenFile(t.Path, os.O_RDONLY, 0644)
711+diff --git a/tq/transfer_queue.go b/tq/transfer_queue.go
712+index ad779d34..26effe13 100644
713+--- a/tq/transfer_queue.go
714++++ b/tq/transfer_queue.go
715+@@ -648,7 +648,7 @@ func (q *TransferQueue) enqueueAndCollectRetriesFor(batch batch) (batch, error)
716+ // Transfer object, then we give up on the
717+ // transfer by telling the progress meter to
718+ // skip the number of bytes in "o".
719+- q.errorc <- errors.Errorf(tr.Tr.Get("[%v] The server returned an unknown OID.", o.Oid))
720++ q.errorc <- errors.Errorf("%s", tr.Tr.Get("[%v] The server returned an unknown OID.", o.Oid))
721+
722+ q.Skip(o.Size)
723+ q.wait.Done()
724+@@ -748,7 +748,7 @@ func (q *TransferQueue) partitionTransfers(transfers []*Transfer) (present []*Tr
725+ var err error
726+
727+ if t.Size < 0 {
728+- err = errors.Errorf(tr.Tr.Get("object %q has invalid size (got: %d)", t.Oid, t.Size))
729++ err = errors.Errorf("%s", tr.Tr.Get("object %q has invalid size (got: %d)", t.Oid, t.Size))
730+ } else {
731+ fd, serr := os.Stat(t.Path)
732+ if serr != nil {
733+diff --git a/tq/tus_upload.go b/tq/tus_upload.go
734+index 273cb7fc..27f47542 100644
735+--- a/tq/tus_upload.go
736++++ b/tq/tus_upload.go
737+@@ -34,7 +34,7 @@ func (a *tusUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb ProgressC
738+ return err
739+ }
740+ if rel == nil {
741+- return errors.Errorf(tr.Tr.Get("No upload action for object: %s", t.Oid))
742++ return errors.Errorf("%s", tr.Tr.Get("No upload action for object: %s", t.Oid))
743+ }
744+
745+ // Note not supporting the Creation extension since the batch API generates URLs
746+@@ -142,7 +142,7 @@ func (a *tusUploadAdapter) DoTransfer(ctx interface{}, t *Transfer, cb ProgressC
747+ }
748+
749+ if res.StatusCode > 299 {
750+- return errors.Wrapf(nil, tr.Tr.Get("Invalid status for %s %s: %d",
751++ return errors.Wrapf(nil, "%s", tr.Tr.Get("Invalid status for %s %s: %d",
752+ req.Method,
753+ strings.SplitN(req.URL.String(), "?", 2)[0],
754+ res.StatusCode,
755+--
756+2.50.1
757+ 
@@ -1,5 +1,5 @@
1---- Makefile.orig 2024-11-21 07:04:331+--- a/Makefile.orig 2024-11-21 07:04:33
2-+++ Makefile 2025-01-14 17:39:552++++ b/Makefile 2025-01-14 17:39:55
3@@ -28,7 +28,7 @@3@@ -28,7 +28,7 @@
4 # BUILTIN_LD_FLAGS are the internal flags used to pass to the linker. By default4 # BUILTIN_LD_FLAGS are the internal flags used to pass to the linker. By default
5 # the config.GitCommit variable is always set via this variable, and5 # the config.GitCommit variable is always set via this variable, and
@@ -4,7 +4,7 @@
4# https://github.com/git-lfs/git-lfs4# https://github.com/git-lfs/git-lfs
5Name: git-lfs5Name: git-lfs
6Version: 3.6.16Version: 3.6.1
7-Release: 17+Release: 2
8Summary: Git extension for versioning large files8Summary: Git extension for versioning large files
9 9 
10License: MIT and BSD and Apache-2.0 and MPL-2.010License: MIT and BSD and Apache-2.0 and MPL-2.0
@@ -12,6 +12,8 @@ URL: https://git-lfs.github.io/
12Source0: https://github.com/%{name}/%{name}/releases/download/v%{version}/%{name}-v%{version}.tar.gz12Source0: https://github.com/%{name}/%{name}/releases/download/v%{version}/%{name}-v%{version}.tar.gz
13Source1: vendor.tar.gz13Source1: vendor.tar.gz
14Patch6000: 0001-use-vendor-dir-for-build.patch14Patch6000: 0001-use-vendor-dir-for-build.patch
15+Patch6001: 0001-Use-constant-format-string.patch
16+Patch6002: git-lfs-3.6.1-cve-2025-26625.patch
15 17 
16%if %{with check}18%if %{with check}
17# Tests19# Tests
@@ -23,6 +25,8 @@ BuildRequires: git >= 1.8.5
23BuildRequires: golang, tar, which25BuildRequires: golang, tar, which
24 26 
25Requires: git-core >= 1.8.527Requires: git-core >= 1.8.5
28+Requires(post): /usr/bin/git
29+Requires(preun): /usr/bin/git
26 30 
27%description31%description
28Git Large File Storage (LFS) replaces large files such as audio samples,32Git Large File Storage (LFS) replaces large files such as audio samples,
@@ -31,7 +35,7 @@ storing the file contents on a remote server.
31 35 
32 36 
33%prep37%prep
34-%autosetup -p0 -n %{name}-%{version} -a 138+%autosetup -p1 -n %{name}-%{version} -a 1
35 39 
36cd ..40cd ..
37mv %{name}-%{version} %{name}41mv %{name}-%{version} %{name}
@@ -49,12 +53,23 @@ popd
49%install53%install
50install -Dpm0755 src/github.com/git-lfs/git-lfs/bin/git-lfs %{buildroot}%{_bindir}/%{name}54install -Dpm0755 src/github.com/git-lfs/git-lfs/bin/git-lfs %{buildroot}%{_bindir}/%{name}
51 55 
56+%post
57+git lfs install --system
58+ 
59+%preun
60+if [ $1 -eq 0 ] ; then
61+ git lfs uninstall --system
62+fi
63+ 
52 64 
53%files65%files
54%{_bindir}/%{name}66%{_bindir}/%{name}
55 67 
56 68 
57%changelog69%changelog
70+* Fri Jan 02 2026 Funda Wang <fundawang@yeah.net> - 3.6.1-2
71+- fix CVE-2025-26625 (patches from rhel)
72+ 
58* Sun Jan 19 2025 Funda Wang <fundawang@yeah.net> - 3.6.1-173* Sun Jan 19 2025 Funda Wang <fundawang@yeah.net> - 3.6.1-1
59- Upgrade to 3.6.174- Upgrade to 3.6.1
60 - fix CVE-2024-53263: Git LFS permits retrieval of credentials via crafted HTTP URLs75 - fix CVE-2024-53263: Git LFS permits retrieval of credentials via crafted HTTP URLs