From 8e6f2c554b6f40b22ab12a7542b720a87771f47b Mon Sep 17 00:00:00 2001 From: blacktop Date: Thu, 12 Feb 2026 10:02:01 -0700 Subject: [PATCH] chore: modernize to 1.26 Refactor string concatenation to use strings.Builder for improved performance in multiple files --- cmd/ipsw/cmd/idev/idev_img_nonce.go | 10 +- cmd/ipsw/cmd/symbolicate.go | 5 +- cmd/ipsw/cmd/watch.go | 10 +- go.mod | 2 +- internal/ai/copilot/copilot.go | 2 +- internal/certs/certs.go | 8 +- internal/commands/ent/replacement.go | 7 +- internal/commands/extract/extract.go | 2 +- internal/commands/fw/trustcache.go | 12 +- internal/commands/macho/diff.go | 17 +-- internal/commands/watch/cache.go | 10 +- internal/demangle/ast.go | 42 ++++--- internal/demangle/demangle.go | 8 +- internal/download/dev_portal.go | 12 +- internal/download/iphonewiki.go | 16 +-- internal/download/pcc.go | 40 +++--- internal/download/pcc/pcc.go | 12 +- internal/utils/utils.go | 2 +- pkg/aea/aea.go | 21 ++-- pkg/appstore/app.go | 6 +- pkg/appstore/bundle.go | 42 +++---- pkg/appstore/cap.go | 6 +- pkg/appstore/cert.go | 18 +-- pkg/appstore/device.go | 18 +-- pkg/appstore/profile.go | 42 +++---- pkg/appstore/review.go | 6 +- pkg/bundle/bundle.go | 46 +++---- pkg/car/format.go | 72 +++++------ pkg/crashlog/ida.go | 4 +- pkg/crashlog/panic.go | 25 ++-- pkg/ctf/format.go | 11 +- pkg/dyld/format.go | 24 ++-- pkg/dyld/prebuilt_types.go | 162 ++++++++++++------------- pkg/emu/emu_string.go | 2 + pkg/img3/img3.go | 28 +++-- pkg/img4/manifest.go | 8 +- pkg/img4/recovery_test.go | 5 +- pkg/info/info.go | 70 +++++------ pkg/kernelcache/diff.go | 10 +- pkg/kernelcache/mig.go | 18 +-- pkg/lzma/lz_bin_tree.go | 6 +- pkg/lzma/lz_window.go | 2 +- pkg/lzma/lzma_encoder.go | 14 +-- pkg/lzma/lzma_len_coder.go | 4 +- pkg/lzma/lzma_lit_coder.go | 2 +- pkg/lzma/range_bit_tree_coder.go | 4 +- pkg/lzma/range_coder.go | 2 +- pkg/nskeyedarchiver/nskeyedarchiver.go | 6 +- pkg/ota/pbzx/extract.go | 12 +- pkg/ota/types/device_map.go | 7 +- pkg/plist/build_manifest.go | 44 +++---- pkg/plist/plist.go | 66 +++++----- pkg/plist/restore.go | 23 ++-- pkg/sep/sep.go | 20 +-- pkg/usb/afc/tree.go | 16 +-- pkg/usb/mcinstall/mcinstall.go | 27 +++-- pkg/wallpaper/mesu_test.go | 2 + 57 files changed, 557 insertions(+), 561 deletions(-) diff --git a/cmd/ipsw/cmd/idev/idev_img_nonce.go b/cmd/ipsw/cmd/idev/idev_img_nonce.go index ceae5b077..a90f6ac45 100644 --- a/cmd/ipsw/cmd/idev/idev_img_nonce.go +++ b/cmd/ipsw/cmd/idev/idev_img_nonce.go @@ -190,16 +190,16 @@ var nonceCmd = &cobra.Command{ fmt.Printf("%s %d\n", color.New(color.Faint, color.FgHiBlue).Sprintf("ApECID: "), personalID["UniqueChipID"]) } fmt.Println(color.New(color.Faint, color.FgHiBlue).Sprintf("Nonce:")) - var out string + var out strings.Builder for i, c := range nonce { if i > 0 && i%4 == 0 && i%24 != 0 { - out += color.New(color.Faint).Sprint("-") + out.WriteString(color.New(color.Faint).Sprint("-")) } else if i > 0 && i%24 == 0 { - out += "\n" + out.WriteString("\n") } - out += color.New(color.Bold).Sprintf("%c", c) + out.WriteString(color.New(color.Bold).Sprintf("%c", c)) } - fmt.Println(out) + fmt.Println(out.String()) } else { if asJSON { var out []byte diff --git a/cmd/ipsw/cmd/symbolicate.go b/cmd/ipsw/cmd/symbolicate.go index 2c6da9b74..78775083f 100644 --- a/cmd/ipsw/cmd/symbolicate.go +++ b/cmd/ipsw/cmd/symbolicate.go @@ -136,10 +136,7 @@ var symbolicateCmd = &cobra.Command{ demangleFlag := viper.GetBool("symbolicate.demangle") asHex := viper.GetBool("symbolicate.hex") peek := viper.GetBool("symbolicate.peek") - peekCount := viper.GetInt("symbolicate.peek-count") - if peekCount < 1 { - peekCount = 1 - } + peekCount := max(viper.GetInt("symbolicate.peek-count"), 1) pemDB := viper.GetString("symbolicate.pem-db") signaturesDir := viper.GetString("symbolicate.signatures") extrasDir := viper.GetString("symbolicate.extra") diff --git a/cmd/ipsw/cmd/watch.go b/cmd/ipsw/cmd/watch.go index ae6eb26cf..717bde1b5 100644 --- a/cmd/ipsw/cmd/watch.go +++ b/cmd/ipsw/cmd/watch.go @@ -55,15 +55,15 @@ func highlightHeader(re *regexp.Regexp, input string) string { if len(parts) == 0 { return colorHeader(input) } - highlighted := "" + var highlighted strings.Builder lastIndex := 0 for _, part := range parts { - highlighted += colorHeader(input[lastIndex:part[0]]) - highlighted += colorHighlight(input[part[0]:part[1]]) + highlighted.WriteString(colorHeader(input[lastIndex:part[0]])) + highlighted.WriteString(colorHighlight(input[part[0]:part[1]])) lastIndex = part[1] } - highlighted += colorHeader(input[lastIndex:]) - return highlighted + highlighted.WriteString(colorHeader(input[lastIndex:])) + return highlighted.String() } func init() { diff --git a/go.mod b/go.mod index 8ed143391..ad7e93d03 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,6 @@ require ( github.com/charmbracelet/bubbles v1.0.0 github.com/charmbracelet/bubbletea v1.3.10 github.com/charmbracelet/lipgloss v1.1.0 - github.com/cloudflare/circl v1.6.3 github.com/coder/acp-go-sdk v0.6.3 github.com/disintegration/imaging v1.6.2 github.com/docker/docker v28.5.2+incompatible @@ -130,6 +129,7 @@ require ( github.com/clipperhouse/displaywidth v0.9.0 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.5.0 // indirect + github.com/cloudflare/circl v1.6.3 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect diff --git a/internal/ai/copilot/copilot.go b/internal/ai/copilot/copilot.go index 376ab592d..d678e773a 100644 --- a/internal/ai/copilot/copilot.go +++ b/internal/ai/copilot/copilot.go @@ -101,7 +101,7 @@ type modelsResponse struct { Policy struct { State string `json:"state"` Terms string `json:"terms"` - } `json:"policy,omitempty"` + } `json:"policy"` } `json:"data"` Object string `json:"object"` } diff --git a/internal/certs/certs.go b/internal/certs/certs.go index 7244c5cee..f307e2124 100644 --- a/internal/certs/certs.go +++ b/internal/certs/certs.go @@ -263,17 +263,17 @@ func (ku ExtKeyUsage) String() string { } func ReprData(dat []byte, tabs, width int) string { - var out string + var out strings.Builder var parts []string for _, id := range dat { parts = append(parts, fmt.Sprintf("%02x", id)) if len(parts) == width { - out += fmt.Sprintf("%s%s\n", strings.Repeat("\t", tabs), strings.Join(parts, ":")+":") + out.WriteString(fmt.Sprintf("%s%s\n", strings.Repeat("\t", tabs), strings.Join(parts, ":")+":")) parts = []string{} } } if len(parts) > 0 { - out += strings.Repeat("\t", tabs) + strings.Join(parts, ":") + out.WriteString(strings.Repeat("\t", tabs) + strings.Join(parts, ":")) } - return out + return out.String() } diff --git a/internal/commands/ent/replacement.go b/internal/commands/ent/replacement.go index 67c35e7ab..2dd991b3e 100644 --- a/internal/commands/ent/replacement.go +++ b/internal/commands/ent/replacement.go @@ -142,12 +142,9 @@ func CompareVersionStrings(a, b string) int { aParts := parseVersionParts(a) bParts := parseVersionParts(b) - maxLen := len(aParts) - if len(bParts) > maxLen { - maxLen = len(bParts) - } + maxLen := max(len(bParts), len(aParts)) - for i := 0; i < maxLen; i++ { + for i := range maxLen { aVal := 0 bVal := 0 diff --git a/internal/commands/extract/extract.go b/internal/commands/extract/extract.go index 9dcf98407..a92ac4509 100644 --- a/internal/commands/extract/extract.go +++ b/internal/commands/extract/extract.go @@ -303,7 +303,7 @@ func ExtractFromDMG(ipswPath, dmgPath, destPath, pemDB string, pattern *regexp.R rel := strings.TrimPrefix(path, mountPoint) rel = strings.TrimPrefix(rel, string(os.PathSeparator)) rel = filepath.Clean(rel) - if pattern.MatchString(string(os.PathSeparator) + rel) || pattern.MatchString(rel) { + if pattern.MatchString(string(os.PathSeparator)+rel) || pattern.MatchString(rel) { fname := filepath.Join(destPath, rel) if err := os.MkdirAll(filepath.Dir(fname), 0o755); err != nil { return fmt.Errorf("failed to create directory %s: %v", filepath.Join(destPath, filepath.Dir(fname)), err) diff --git a/internal/commands/fw/trustcache.go b/internal/commands/fw/trustcache.go index 48db0f6ea..6f258840d 100644 --- a/internal/commands/fw/trustcache.go +++ b/internal/commands/fw/trustcache.go @@ -197,14 +197,14 @@ func (tc TrustCacheEntryV2) MarshalJSON() ([]byte, error) { } func (tc TrustCache) String() string { - var out string - out += fmt.Sprintf("UUID: %s\n", tc.UUID) - out += fmt.Sprintf("Version: %d\n", tc.Version) - out += fmt.Sprintf("NumEntries: %d\n", tc.NumEntries) + var out strings.Builder + out.WriteString(fmt.Sprintf("UUID: %s\n", tc.UUID)) + out.WriteString(fmt.Sprintf("Version: %d\n", tc.Version)) + out.WriteString(fmt.Sprintf("NumEntries: %d\n", tc.NumEntries)) for _, entry := range tc.Entries { - out += fmt.Sprintf(" %s\n", entry) + out.WriteString(fmt.Sprintf(" %s\n", entry)) } - return out + return out.String() } func ParseTrustCache(data []byte) (*TrustCache, error) { diff --git a/internal/commands/macho/diff.go b/internal/commands/macho/diff.go index 03d4ea7b6..0dfb2e811 100644 --- a/internal/commands/macho/diff.go +++ b/internal/commands/macho/diff.go @@ -163,19 +163,20 @@ func (i DiffInfo) Equal(x DiffInfo) bool { } func (i *DiffInfo) String() string { - out := i.Version + "\n" + var out strings.Builder + out.WriteString(i.Version + "\n") for _, sec := range i.Sections { - out += fmt.Sprintf(" %s: %#x\n", sec.Name, sec.Size) + out.WriteString(fmt.Sprintf(" %s: %#x\n", sec.Name, sec.Size)) } slices.Sort(i.Imports) for _, i := range i.Imports { - out += fmt.Sprintf(" - %s\n", i) + out.WriteString(fmt.Sprintf(" - %s\n", i)) } - out += fmt.Sprintf(" UUID: %s\n", i.UUID) - out += fmt.Sprintf(" Functions: %d\n", i.Functions) - out += fmt.Sprintf(" Symbols: %d\n", len(i.Symbols)) - out += fmt.Sprintf(" CStrings: %d\n", len(i.CStrings)) - return out + out.WriteString(fmt.Sprintf(" UUID: %s\n", i.UUID)) + out.WriteString(fmt.Sprintf(" Functions: %d\n", i.Functions)) + out.WriteString(fmt.Sprintf(" Symbols: %d\n", len(i.Symbols))) + out.WriteString(fmt.Sprintf(" CStrings: %d\n", len(i.CStrings))) + return out.String() } func (diff *MachoDiff) Generate(prev, next map[string]*DiffInfo, conf *DiffConfig) error { diff --git a/internal/commands/watch/cache.go b/internal/commands/watch/cache.go index cabf0b2fe..f87d14cb6 100644 --- a/internal/commands/watch/cache.go +++ b/internal/commands/watch/cache.go @@ -24,12 +24,12 @@ type FcsKey struct { IosBuild string `json:"ios_build,omitempty"` MacOsBuild string `json:"macos_build,omitempty"` VisionOsBuild string `json:"visionos_build,omitempty"` - UpdatedAt time.Time `json:"updated_at,omitempty"` + UpdatedAt time.Time `json:"updated_at"` } type FcsKeys struct { - Beta FcsKey `json:"beta,omitempty"` - RC FcsKey `json:"rc,omitempty"` - Release FcsKey `json:"release,omitempty"` + Beta FcsKey `json:"beta"` + RC FcsKey `json:"rc"` + Release FcsKey `json:"release"` } type CacheItem struct { @@ -37,7 +37,7 @@ type CacheItem struct { Commits Commits `json:"commits,omitempty"` Functions Function `json:"functions,omitempty"` URL string `json:"url,omitempty"` - FcsKeys FcsKeys `json:"fcs_keys,omitempty"` + FcsKeys FcsKeys `json:"fcs_keys"` } type Cache map[string]CacheItem diff --git a/internal/demangle/ast.go b/internal/demangle/ast.go index 1806f94b0..0c33651f3 100644 --- a/internal/demangle/ast.go +++ b/internal/demangle/ast.go @@ -492,12 +492,13 @@ func (qs *Qualifiers) GoString() string { } func (qs *Qualifiers) goString(indent int, field string) string { - quals := fmt.Sprintf("%*s%s", indent, "", field) + var quals strings.Builder + quals.WriteString(fmt.Sprintf("%*s%s", indent, "", field)) for _, q := range qs.Qualifiers { - quals += "\n" - quals += q.goString(indent+2, "") + quals.WriteString("\n") + quals.WriteString(q.goString(indent+2, "")) } - return quals + return quals.String() } // Qualifier is a single type qualifier. @@ -563,14 +564,15 @@ func (q *Qualifier) GoString() string { } func (q *Qualifier) goString(indent int, field string) string { - qs := fmt.Sprintf("%*s%s%s", indent, "", field, q.Name) + var qs strings.Builder + qs.WriteString(fmt.Sprintf("%*s%s%s", indent, "", field, q.Name)) if len(q.Exprs) > 0 { for i, e := range q.Exprs { - qs += "\n" - qs += e.goString(indent+2, fmt.Sprintf("%d: ", i)) + qs.WriteString("\n") + qs.WriteString(e.goString(indent+2, fmt.Sprintf("%d: ", i))) } } - return qs + return qs.String() } // TypeWithQualifiers is a type with standard qualifiers. @@ -1940,12 +1942,13 @@ func (ap *ArgumentPack) goString(indent int, field string) string { if len(ap.Args) == 0 { return fmt.Sprintf("%*s%sArgumentPack: nil", indent, "", field) } - s := fmt.Sprintf("%*s%sArgumentPack:", indent, "", field) + var s strings.Builder + s.WriteString(fmt.Sprintf("%*s%sArgumentPack:", indent, "", field)) for i, a := range ap.Args { - s += "\n" - s += a.goString(indent+2, fmt.Sprintf("%d: ", i)) + s.WriteString("\n") + s.WriteString(a.goString(indent+2, fmt.Sprintf("%d: ", i))) } - return s + return s.String() } // SizeofPack is the sizeof operator applied to an argument pack. @@ -3028,16 +3031,16 @@ func (so *Subobject) GoString() string { } func (so *Subobject) goString(indent int, field string) string { - var selectors string + var selectors strings.Builder for _, s := range so.Selectors { - selectors += fmt.Sprintf(" %d", s) + selectors.WriteString(fmt.Sprintf(" %d", s)) } return fmt.Sprintf("%*s%sSubobject:\n%s\n%s\n%*sOffset: %d\n%*sSelectors:%s\n%*sPastEnd: %t", indent, "", field, so.Type.goString(indent+2, "Type: "), so.SubExpr.goString(indent+2, "SubExpr: "), indent+2, "", so.Offset, - indent+2, "", selectors, + indent+2, "", selectors.String(), indent+2, "", so.PastEnd) } @@ -3445,12 +3448,13 @@ func (el *ExprList) goString(indent int, field string) string { if len(el.Exprs) == 0 { return fmt.Sprintf("%*s%sExprList: nil", indent, "", field) } - s := fmt.Sprintf("%*s%sExprList:", indent, "", field) + var s strings.Builder + s.WriteString(fmt.Sprintf("%*s%sExprList:", indent, "", field)) for i, e := range el.Exprs { - s += "\n" - s += e.goString(indent+2, fmt.Sprintf("%d: ", i)) + s.WriteString("\n") + s.WriteString(e.goString(indent+2, fmt.Sprintf("%d: ", i))) } - return s + return s.String() } // InitializerList is an initializer list: an optional type with a diff --git a/internal/demangle/demangle.go b/internal/demangle/demangle.go index c6899fa45..5279bc880 100644 --- a/internal/demangle/demangle.go +++ b/internal/demangle/demangle.go @@ -1130,11 +1130,11 @@ func (st *state) javaResource() AST { st.fail("not enough characters for java resource length") } str := st.str[:ln] - final := "" + var final strings.Builder st.advance(ln) for i := 0; i < len(str); i++ { if str[i] != '$' { - final += string(str[i]) + final.WriteString(string(str[i])) } else { if len(str) <= i+1 { st.failEarlier("java resource escape at end of string", 1) @@ -1148,10 +1148,10 @@ func (st *state) javaResource() AST { if !ok { st.failEarlier("unrecognized java resource escape", ln-i-1) } - final += r + final.WriteString(r) } } - return &Special{Prefix: "java resource ", Val: &Name{Name: final}} + return &Special{Prefix: "java resource ", Val: &Name{Name: final.String()}} } // ::= TV diff --git a/internal/download/dev_portal.go b/internal/download/dev_portal.go index a33608510..d6f7a354e 100644 --- a/internal/download/dev_portal.go +++ b/internal/download/dev_portal.go @@ -1029,11 +1029,11 @@ func (dp *DevPortal) verifyCode(codeType, code string, phoneID int) error { return fmt.Errorf("failed to deserialize response body JSON: %v", err) } if svcErr.HasError { - var errStr string + var errStr strings.Builder for _, svcErr := range svcErr.Errors { - errStr += fmt.Sprintf(": %s", svcErr.Message) + errStr.WriteString(fmt.Sprintf(": %s", svcErr.Message)) } - return fmt.Errorf("failed to verify code: response received %s%s", response.Status, errStr) + return fmt.Errorf("failed to verify code: response received %s%s", response.Status, errStr.String()) } } @@ -1072,11 +1072,11 @@ func (dp *DevPortal) trustSession() error { return fmt.Errorf("failed to deserialize response body JSON: %v", err) } if svcErr.HasError { - var errStr string + var errStr strings.Builder for _, svcErr := range svcErr.Errors { - errStr += fmt.Sprintf(": %s", svcErr.Message) + errStr.WriteString(fmt.Sprintf(": %s", svcErr.Message)) } - return fmt.Errorf("failed to update to trusted session: response received %s%s", response.Status, errStr) + return fmt.Errorf("failed to update to trusted session: response received %s%s", response.Status, errStr.String()) } } return fmt.Errorf("failed to update to trusted session: response received %s", response.Status) diff --git a/internal/download/iphonewiki.go b/internal/download/iphonewiki.go index 0397b046b..2057c9769 100644 --- a/internal/download/iphonewiki.go +++ b/internal/download/iphonewiki.go @@ -377,26 +377,26 @@ func stringToSlice(s string) []string { } func (k WikiFWKey) String() string { - var out string + var out strings.Builder for i, fn := range k.Filename { - out += fmt.Sprintf("‣ %s\n", fn) + out.WriteString(fmt.Sprintf("‣ %s\n", fn)) if len(k.Device) > 0 && len(k.Device[i]) > 0 { - out += fmt.Sprintf(" Device: %s\n", k.Device[i]) + out.WriteString(fmt.Sprintf(" Device: %s\n", k.Device[i])) } if len(k.Key) > 0 && len(k.Key[i]) > 0 { - out += fmt.Sprintf(" Key: %s\n", k.Key[i]) + out.WriteString(fmt.Sprintf(" Key: %s\n", k.Key[i])) } if len(k.Devkbag) > 0 && len(k.Devkbag[i]) > 0 { - out += fmt.Sprintf(" DevKBAG: %s\n", k.Devkbag[i]) + out.WriteString(fmt.Sprintf(" DevKBAG: %s\n", k.Devkbag[i])) } if len(k.Iv) > 0 && len(k.Iv[i]) > 0 { - out += fmt.Sprintf(" IV: %s\n", k.Iv[i]) + out.WriteString(fmt.Sprintf(" IV: %s\n", k.Iv[i])) } if len(k.Kbag) > 0 && len(k.Kbag[i]) > 0 { - out += fmt.Sprintf(" KBAG: %s\n", k.Kbag[i]) + out.WriteString(fmt.Sprintf(" KBAG: %s\n", k.Kbag[i])) } } - return out + return out.String() } func getWikiPage(page string, proxy string, insecure bool) (*wikiParseResults, error) { diff --git a/internal/download/pcc.go b/internal/download/pcc.go index 112edff1b..1f0a3e69d 100644 --- a/internal/download/pcc.go +++ b/internal/download/pcc.go @@ -102,42 +102,42 @@ func (a ByPccIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByPccIndex) Less(i, j int) bool { return a[i].Index > a[j].Index } func (r PCCRelease) String() string { - var out string - out += fmt.Sprintf("%d) %s\n", r.Index, colorHash(hex.EncodeToString(r.GetReleaseHash()))) - out += fmt.Sprintf(colorField("Type")+": %s\n", pcc.ATLogDataType(r.Type).String()) - out += fmt.Sprintf(colorField("Schema")+": %s\n", string(r.SchemaVersion.String())) - out += colorField("Assets\n") + var out strings.Builder + out.WriteString(fmt.Sprintf("%d) %s\n", r.Index, colorHash(hex.EncodeToString(r.GetReleaseHash())))) + out.WriteString(fmt.Sprintf(colorField("Type")+": %s\n", pcc.ATLogDataType(r.Type).String())) + out.WriteString(fmt.Sprintf(colorField("Schema")+": %s\n", string(r.SchemaVersion.String()))) + out.WriteString(colorField("Assets\n")) for _, asset := range r.GetAssets() { - out += fmt.Sprintf(" [%s]\n", colorTypeField(strings.TrimPrefix(asset.GetType().String(), "ASSET_TYPE_"))) - out += fmt.Sprintf(colorField(" Variant")+": %s\n", colorName(asset.GetVariant())) - out += fmt.Sprintf(colorField(" Digest")+": %s (%s)\n", colorHash(hex.EncodeToString(asset.Digest.GetValue())), strings.TrimPrefix(asset.Digest.GetDigestAlg().String(), "DIGEST_ALG_")) - out += fmt.Sprintf(colorField(" URL")+": %s\n", asset.GetUrl()) + out.WriteString(fmt.Sprintf(" [%s]\n", colorTypeField(strings.TrimPrefix(asset.GetType().String(), "ASSET_TYPE_")))) + out.WriteString(fmt.Sprintf(colorField(" Variant")+": %s\n", colorName(asset.GetVariant()))) + out.WriteString(fmt.Sprintf(colorField(" Digest")+": %s (%s)\n", colorHash(hex.EncodeToString(asset.Digest.GetValue())), strings.TrimPrefix(asset.Digest.GetDigestAlg().String(), "DIGEST_ALG_"))) + out.WriteString(fmt.Sprintf(colorField(" URL")+": %s\n", asset.GetUrl())) } - out += colorField("Tickets\n") + out.WriteString(colorField("Tickets\n")) hash := sha256.New() hash.Write(r.Ticket.ApTicket.Bytes) - out += fmt.Sprintf(colorField(" OS")+": %s\n", colorHash(hex.EncodeToString(hash.Sum(nil)))) - out += fmt.Sprintf(" [%s: %s]\n", colorCreateTime("created"), r.GetTimestamp().AsTime().Format("2006-01-02 15:04:05")) - out += fmt.Sprintf(" [%s: %s]\n", colorExpireTime("expires"), time.UnixMilli(r.ExpiryMS).Format("2006-01-02 15:04:05")) - out += colorField(" Cryptexes\n") + out.WriteString(fmt.Sprintf(colorField(" OS")+": %s\n", colorHash(hex.EncodeToString(hash.Sum(nil))))) + out.WriteString(fmt.Sprintf(" [%s: %s]\n", colorCreateTime("created"), r.GetTimestamp().AsTime().Format("2006-01-02 15:04:05"))) + out.WriteString(fmt.Sprintf(" [%s: %s]\n", colorExpireTime("expires"), time.UnixMilli(r.ExpiryMS).Format("2006-01-02 15:04:05"))) + out.WriteString(colorField(" Cryptexes\n")) for i, ct := range r.Ticket.CryptexTickets { hash.Reset() hash.Write(ct.Bytes) - out += fmt.Sprintf(" %d) %s\n", i, colorHash(hex.EncodeToString(hash.Sum(nil)))) + out.WriteString(fmt.Sprintf(" %d) %s\n", i, colorHash(hex.EncodeToString(hash.Sum(nil))))) } - out += colorField("DarwinInit:\n") + out.WriteString(colorField("DarwinInit:\n")) dat, _ := json.MarshalIndent(r.DarwinInit.AsMap(), "", " ") if color.NoColor { - out += string(dat) + out.WriteString(string(dat)) } else { var buf strings.Builder if err := quick.Highlight(&buf, string(dat)+"\n", "json", "terminal256", "nord"); err != nil { - out += string(dat) + out.WriteString(string(dat)) } else { - out += buf.String() + out.WriteString(buf.String()) } } - return out + return out.String() } func (r PCCRelease) Download(output, proxy string, insecure bool) error { diff --git a/internal/download/pcc/pcc.go b/internal/download/pcc/pcc.go index 7e068f50e..5e149134d 100644 --- a/internal/download/pcc/pcc.go +++ b/internal/download/pcc/pcc.go @@ -337,7 +337,7 @@ func file_ATResearcherApi_proto_init() { type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + GoPackagePath: reflect.TypeFor[x]().PkgPath(), RawDescriptor: file_ATResearcherApi_proto_rawDesc, NumEnums: 0, NumMessages: 3, @@ -966,7 +966,7 @@ func file_ATServiceApi_proto_init() { type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + GoPackagePath: reflect.TypeFor[x]().PkgPath(), RawDescriptor: file_ATServiceApi_proto_rawDesc, NumEnums: 1, NumMessages: 6, @@ -2586,7 +2586,7 @@ func file_AuditorApi_proto_init() { type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + GoPackagePath: reflect.TypeFor[x]().PkgPath(), RawDescriptor: file_AuditorApi_proto_rawDesc, NumEnums: 1, NumMessages: 17, @@ -3413,7 +3413,7 @@ func file_KtClientApi_proto_init() { type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + GoPackagePath: reflect.TypeFor[x]().PkgPath(), RawDescriptor: file_KtClientApi_proto_rawDesc, NumEnums: 0, NumMessages: 8, @@ -3918,7 +3918,7 @@ func file_ReleaseMetadata_proto_init() { type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + GoPackagePath: reflect.TypeFor[x]().PkgPath(), RawDescriptor: file_ReleaseMetadata_proto_rawDesc, NumEnums: 3, NumMessages: 3, @@ -5712,7 +5712,7 @@ func file_Transparency_proto_init() { type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + GoPackagePath: reflect.TypeFor[x]().PkgPath(), RawDescriptor: file_Transparency_proto_rawDesc, NumEnums: 8, NumMessages: 16, diff --git a/internal/utils/utils.go b/internal/utils/utils.go index ce42d77df..7b61f03ac 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -43,7 +43,7 @@ func (e *StopRetryingError) Error() string { // RetryWithResult will retry a function f a number of attempts with a sleep duration in between, returning the result if successful func RetryWithResult[T any](attempts int, sleep time.Duration, f func() (T, error)) (result T, err error) { - for i := 0; i < attempts; i++ { + for i := range attempts { if i > 0 { Indent(log.Debug, 2)(fmt.Sprintf("retrying after error: %s", err)) time.Sleep(sleep) diff --git a/pkg/aea/aea.go b/pkg/aea/aea.go index 0290889f3..c569c5c22 100644 --- a/pkg/aea/aea.go +++ b/pkg/aea/aea.go @@ -3,7 +3,9 @@ package aea import ( "bytes" "compress/gzip" + "crypto/ecdh" "crypto/ecdsa" + "crypto/hpke" "crypto/tls" "crypto/x509" _ "embed" @@ -20,7 +22,6 @@ import ( "strings" "github.com/blacktop/ipsw/internal/download" - "github.com/cloudflare/circl/hpke" ) //go:embed data/fcs-keys.gz @@ -192,25 +193,19 @@ func (md Metadata) DecryptFCS(pemData []byte, pemDB string, proxy string, insecu privKey = append(bytes.Repeat([]byte{0}, delta), privKey...) } - kemID := hpke.KEM_P256_HKDF_SHA256 - kdfID := hpke.KDF_HKDF_SHA256 - aeadID := hpke.AEAD_AES256GCM + kemID := hpke.DHKEM(ecdh.P256()) + kdfID := hpke.HKDFSHA256() + aeadID := hpke.AES256GCM() - suite := hpke.NewSuite(kemID, kdfID, aeadID) - - privateKey, err := kemID.Scheme().UnmarshalBinaryPrivateKey(privKey) + privateKey, err := kemID.NewPrivateKey(privKey) if err != nil { return nil, err } - recv, err := suite.NewReceiver(privateKey, nil) + recv, err := hpke.NewRecipient(encRequestData, privateKey, kdfID, aeadID, nil) if err != nil { return nil, err } - opener, err := recv.Setup(encRequestData) - if err != nil { - return nil, err - } - return opener.Open(wrappedKeyData, nil) + return recv.Open(nil, wrappedKeyData) } func Info(in string) (Metadata, error) { diff --git a/pkg/appstore/app.go b/pkg/appstore/app.go index 2ed0d7f93..29146e0d8 100644 --- a/pkg/appstore/app.go +++ b/pkg/appstore/app.go @@ -82,11 +82,11 @@ func (as *AppStore) GetApps() ([]App, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var apps AppsResponse diff --git a/pkg/appstore/bundle.go b/pkg/appstore/bundle.go index 42a678615..15e4651c3 100644 --- a/pkg/appstore/bundle.go +++ b/pkg/appstore/bundle.go @@ -103,11 +103,11 @@ func (as *AppStore) GetBundleIDs() ([]BundleID, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var bundles BundleIdsResponse @@ -148,11 +148,11 @@ func (as *AppStore) GetBundleID(id string) (*BundleID, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var bundle BundleIdResponse @@ -194,11 +194,11 @@ func (as *AppStore) GetBundleIDApp(id string) (*AppResponse, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var app AppResponse @@ -239,11 +239,11 @@ func (as *AppStore) GetBundleIDProfiles(id string) (*ProfileResponse, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var profile ProfileResponse @@ -284,11 +284,11 @@ func (as *AppStore) GetBundleIDCapabilities(id string) (*BundleIdCapabilitiesRes if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var caps BundleIdCapabilitiesResponse @@ -341,11 +341,11 @@ func (as *AppStore) RegisterBundleID(name, id string) (*BundleIdResponse, error) if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var bidResp BundleIdResponse @@ -387,11 +387,11 @@ func (as *AppStore) DeleteBundleID(id string) (*BundleIdResponse, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var bidResp BundleIdResponse diff --git a/pkg/appstore/cap.go b/pkg/appstore/cap.go index ce79c1fa1..fff418e7b 100644 --- a/pkg/appstore/cap.go +++ b/pkg/appstore/cap.go @@ -194,11 +194,11 @@ func (as *AppStore) EnableCapability(id, ctype string) (*BundleIdCapability, err if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var bcap BundleIdCapabilityResponse diff --git a/pkg/appstore/cert.go b/pkg/appstore/cert.go index da7c7b53f..2f6e1bfc7 100644 --- a/pkg/appstore/cert.go +++ b/pkg/appstore/cert.go @@ -142,11 +142,11 @@ func (as *AppStore) GetCertificates() ([]Certificate, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var certsResp CertificatesResponse @@ -206,11 +206,11 @@ func (as *AppStore) CreateCertificate(ctype string, csrData string) (*Certificat if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var cert CertificateResponse @@ -252,11 +252,11 @@ func (as *AppStore) RevokeCertificate(id string) error { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return fmt.Errorf("%s: %s", resp.Status, errOut) + return fmt.Errorf("%s: %s", resp.Status, errOut.String()) } return nil diff --git a/pkg/appstore/device.go b/pkg/appstore/device.go index 3a13a8571..a6da30bcd 100644 --- a/pkg/appstore/device.go +++ b/pkg/appstore/device.go @@ -81,11 +81,11 @@ func (as *AppStore) GetDevices() ([]Device, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var devicesResponseList DevicesResponse @@ -141,11 +141,11 @@ func (as *AppStore) RegisterDevice(name, platform, udid string) (*Device, error) if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var dev DeviceResponse @@ -210,11 +210,11 @@ func (as *AppStore) ModifyDevice(id, name, status string) (*Device, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var dev DeviceResponse diff --git a/pkg/appstore/profile.go b/pkg/appstore/profile.go index c84e24bf7..588e3fd6f 100644 --- a/pkg/appstore/profile.go +++ b/pkg/appstore/profile.go @@ -191,11 +191,11 @@ func (as *AppStore) GetProfiles() ([]Profile, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var profiles ProfilesResponse @@ -237,11 +237,11 @@ func (as *AppStore) GetProfile(id string) (*Profile, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var profile ProfileResponse @@ -282,11 +282,11 @@ func (as *AppStore) GetProfileBundleID(id string) (*BundleID, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var bundle BundleIdResponse @@ -327,11 +327,11 @@ func (as *AppStore) GetProfileDevices(id string) ([]Device, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var devices DevicesResponse @@ -372,11 +372,11 @@ func (as *AppStore) GetProfileCerts(id string) ([]Certificate, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var certs CertificatesResponse @@ -444,11 +444,11 @@ func (as *AppStore) CreateProfile(name string, ptype string, bundleID string, ce if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nil, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nil, fmt.Errorf("%s: %s", resp.Status, errOut) + return nil, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } var profileResponse ProfileResponse @@ -490,11 +490,11 @@ func (as *AppStore) DeleteProfile(id string) error { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return fmt.Errorf("%s: %s", resp.Status, errOut) + return fmt.Errorf("%s: %s", resp.Status, errOut.String()) } return nil diff --git a/pkg/appstore/review.go b/pkg/appstore/review.go index 243e40c43..5625372cf 100644 --- a/pkg/appstore/review.go +++ b/pkg/appstore/review.go @@ -97,11 +97,11 @@ func (as *AppStore) GetReviews(appID string) (ReviewsListResponse, error) { if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil { return nilResponse, fmt.Errorf("failed to JSON decode http response: %v", err) } - var errOut string + var errOut strings.Builder for idx, e := range eresp.Errors { - errOut += fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail) + errOut.WriteString(fmt.Sprintf("%s%s: %s (%s)\n", strings.Repeat("\t", idx), e.Code, e.Title, e.Detail)) } - return nilResponse, fmt.Errorf("%s: %s", resp.Status, errOut) + return nilResponse, fmt.Errorf("%s: %s", resp.Status, errOut.String()) } // For debugging, print the response body diff --git a/pkg/bundle/bundle.go b/pkg/bundle/bundle.go index 06609ec1a..fc5858f59 100644 --- a/pkg/bundle/bundle.go +++ b/pkg/bundle/bundle.go @@ -39,32 +39,33 @@ type Bundle struct { } func (b Bundle) String() string { - s := fmt.Sprintf("Bundle: %s\n", string(b.Magic[:])) - s += fmt.Sprintf(" Type: %d\n", b.Type) + var s strings.Builder + s.WriteString(fmt.Sprintf("Bundle: %s\n", string(b.Magic[:]))) + s.WriteString(fmt.Sprintf(" Type: %d\n", b.Type)) switch b.Type { case 3: - s += " Config:\n" - s += fmt.Sprintf(" Unk1: %d\n", b.Config.Unk1) - s += fmt.Sprintf(" Unk2: %d\n", b.Config.Unk2) - s += " Assets:\n" + s.WriteString(" Config:\n") + s.WriteString(fmt.Sprintf(" Unk1: %d\n", b.Config.Unk1)) + s.WriteString(fmt.Sprintf(" Unk2: %d\n", b.Config.Unk2)) + s.WriteString(" Assets:\n") for i, h := range b.Config.Assets { - s += fmt.Sprintf(" %3s) %-20s\n", fmt.Sprintf("%d", i+1), h) + s.WriteString(fmt.Sprintf(" %3s) %-20s\n", fmt.Sprintf("%d", i+1), h)) } - s += " TOC:\n" + s.WriteString(" TOC:\n") for _, t := range b.Config.TOC { - s += fmt.Sprintf(" %s\n", t) + s.WriteString(fmt.Sprintf(" %s\n", t)) } - s += "Compartments:\n" + s.WriteString("Compartments:\n") for _, f := range b.Files { - s += fmt.Sprintf("%s\n", f) + s.WriteString(fmt.Sprintf("%s\n", f)) } case 4: - s += " Ranges:\n" + s.WriteString(" Ranges:\n") for i, f := range b.TypeHeader.(Type4).Ranges { - s += fmt.Sprintf(" %3s) %s\n", fmt.Sprintf("%d", i+1), f) + s.WriteString(fmt.Sprintf(" %3s) %s\n", fmt.Sprintf("%d", i+1), f)) } } - return s + return s.String() } type Segment struct { @@ -98,34 +99,35 @@ func (f File) Segment(name string) *Segment { } func (f File) String() string { - s := fmt.Sprintf(" %s (%s)\n", f.Name, f.Type) + var s strings.Builder + s.WriteString(fmt.Sprintf(" %s (%s)\n", f.Name, f.Type)) for _, seg := range f.Segments { if seg.Size == 0 { continue } if seg.Name == "HEADER" { - s += fmt.Sprintf(" sz=0x%08x off=0x%08x-0x%08x __%s\n", seg.Size, seg.Offset, seg.Offset+seg.Size, seg.Name) + s.WriteString(fmt.Sprintf(" sz=0x%08x off=0x%08x-0x%08x __%s\n", seg.Size, seg.Offset, seg.Offset+seg.Size, seg.Name)) } } for _, sec := range f.Sections { if sec.Size == 0 { continue } - s += fmt.Sprintf(" sz=0x%08x off=0x%08x-0x%08x __%s\n", sec.Size, sec.Offset, sec.Offset+sec.Size, sec.Name) + s.WriteString(fmt.Sprintf(" sz=0x%08x off=0x%08x-0x%08x __%s\n", sec.Size, sec.Offset, sec.Offset+sec.Size, sec.Name)) } if len(f.Endpoints) > 0 { - s += " endpoints:\n" + s.WriteString(" endpoints:\n") for i, ep := range f.Endpoints { - s += fmt.Sprintf(" %3s) %s\n", fmt.Sprintf("%d", i+1), ep) + s.WriteString(fmt.Sprintf(" %3s) %s\n", fmt.Sprintf("%d", i+1), ep)) } } if len(f.Extra) > 0 { - s += " extra:\n" + s.WriteString(" extra:\n") for k, v := range f.Extra { - s += fmt.Sprintf(" %s: %v\n", k, v) + s.WriteString(fmt.Sprintf(" %s: %v\n", k, v)) } } - return s + return s.String() } type Type3 struct { diff --git a/pkg/car/format.go b/pkg/car/format.go index f9a4f6a04..b8d3d39f5 100644 --- a/pkg/car/format.go +++ b/pkg/car/format.go @@ -13,10 +13,10 @@ import ( ) func (a *Asset) String() string { - var out string - out += "Asset\n" + "=====\n" // title - out += "Header:\n" - out += fmt.Sprintf( + var out strings.Builder + out.WriteString("Asset\n" + "=====\n") // title + out.WriteString("Header:\n") + out.WriteString(fmt.Sprintf( " Version: %s"+ " CoreUI Version: %d\n"+ " Storage Version: %d\n"+ @@ -37,9 +37,9 @@ func (a *Asset) String() string { a.Header.SchemaVersion, a.Header.ColorSpaceID, a.Header.KeySemantics, - ) - out += "Metadata:\n" - out += fmt.Sprintf( + )) + out.WriteString("Metadata:\n") + out.WriteString(fmt.Sprintf( " Authoring Tool: %s"+ " Thinning Args: %s\n"+ " Deployment Platform: %s %s\n", @@ -47,17 +47,17 @@ func (a *Asset) String() string { strings.ReplaceAll(string(bytes.Trim(a.Metadata.ThinningArguments[:], "\x00")), "<", "\n <"), string(bytes.Trim(a.Metadata.DeploymentPlatform[:], "\x00")), string(bytes.Trim(a.Metadata.DeploymentPlatformVersion[:], "\x00")), - ) + )) if len(a.KeyFormat) > 0 { - out += "KeyFormats:\n" + out.WriteString("KeyFormats:\n") for _, k := range a.KeyFormat { - out += fmt.Sprintf(" - %s\n", k) + out.WriteString(fmt.Sprintf(" - %s\n", k)) } } if len(a.AppearanceDB) > 0 { - out += "Appearances:\n" + out.WriteString("Appearances:\n") for k, v := range a.AppearanceDB { - out += fmt.Sprintf(" %s: %d\n", k, v) + out.WriteString(fmt.Sprintf(" %s: %d\n", k, v)) } } // if len(a.FacetKeyDB) > 0 { @@ -70,62 +70,62 @@ func (a *Asset) String() string { // } // } if len(a.ColorDB) > 0 { - out += "Colors:\n" + out.WriteString("Colors:\n") for k, v := range a.ColorDB { if a.conf.Verbose { if tout, err := colorInTerminal(v); err == nil { - out += fmt.Sprintf("- %s:\n %s", k, tout) + out.WriteString(fmt.Sprintf("- %s:\n %s", k, tout)) } } else { - out += fmt.Sprintf(" %s: %#v\n", k, v) + out.WriteString(fmt.Sprintf(" %s: %#v\n", k, v)) } } } if len(a.Localizations) > 0 { - out += "Localizations:\n" + out.WriteString("Localizations:\n") for k, v := range a.Localizations { - out += fmt.Sprintf(" %s: %d\n", k, v) + out.WriteString(fmt.Sprintf(" %s: %d\n", k, v)) } } if len(a.ImageDB) > 0 { - out += "Assets:\n" + out.WriteString("Assets:\n") for _, ass := range a.ImageDB { - out += "-\n" - var asset string + out.WriteString("-\n") + var asset strings.Builder switch t := ass.Asset.(type) { case csiColor: if a.conf.Verbose { if tout, err := t.ToTerminal(); err == nil { - out += tout + out.WriteString(tout) } } - asset += fmt.Sprintf("Colorspace: %s\n", t.Info.ColorSpaceID()) + asset.WriteString(fmt.Sprintf("Colorspace: %s\n", t.Info.ColorSpaceID())) if len(t.Components) > 0 { - asset += "Components:\n" + asset.WriteString("Components:\n") for _, c := range t.Components { - asset += fmt.Sprintf(" - %v\n", c) + asset.WriteString(fmt.Sprintf(" - %v\n", c)) } } default: } - var attrs string + var attrs strings.Builder if len(ass.Attributes) > 0 { - attrs += "Attributes:\n" + attrs.WriteString("Attributes:\n") for _, kf := range a.KeyFormat { if value, ok := ass.Attributes[kf.String()]; ok { - attrs += fmt.Sprintf(" %-23s\t%d\n", kf.String()+":", value) + attrs.WriteString(fmt.Sprintf(" %-23s\t%d\n", kf.String()+":", value)) } } } - var rscs string + var rscs strings.Builder if len(ass.Resources) > 0 { - rscs += "Resources:\n" + rscs.WriteString("Resources:\n") for _, rsc := range ass.Resources { - rscs += fmt.Sprintf(" %s\n", rsc.ID) + rscs.WriteString(fmt.Sprintf(" %s\n", rsc.ID)) } } - out += fmt.Sprintf( + out.WriteString(fmt.Sprintf( "Name: %s\n"+ "Type: %s\n"+ "Size: %s\n"+ @@ -134,13 +134,13 @@ func (a *Asset) String() string { ass.Name, ass.Type, humanize.Bytes(uint64(ass.Size)), - asset, - attrs, - rscs, - ) + asset.String(), + attrs.String(), + rscs.String(), + )) } } - return out + return out.String() } // KeyFormatName converts renditionAttributeType to its Apple name diff --git a/pkg/crashlog/ida.go b/pkg/crashlog/ida.go index 71dfbd7af..c6498eb1b 100644 --- a/pkg/crashlog/ida.go +++ b/pkg/crashlog/ida.go @@ -4,7 +4,7 @@ import ( "fmt" "os" "path/filepath" - "sort" + "slices" "strings" "time" @@ -190,7 +190,7 @@ frames = [ for addr := range i.KernelSymbols { addrs = append(addrs, addr) } - sort.Slice(addrs, func(i, j int) bool { return addrs[i] < addrs[j] }) + slices.Sort(addrs) for _, addr := range addrs { sym := escapePyString(i.KernelSymbols[addr]) diff --git a/pkg/crashlog/panic.go b/pkg/crashlog/panic.go index fa6483540..a14e965c3 100644 --- a/pkg/crashlog/panic.go +++ b/pkg/crashlog/panic.go @@ -127,11 +127,11 @@ func (t TPIDRx_ELy) String() string { if len(t) == 0 { return "" } - var tpidrx string + var tpidrx strings.Builder for key, val := range t { - tpidrx += fmt.Sprintf(colorImage(" %-3s", key)+": %#016x\n", val) + tpidrx.WriteString(fmt.Sprintf(colorImage(" %-3s", key)+": %#016x\n", val)) } - return fmt.Sprintf(colorField("TPIDRx_ELy")+"\n%s\n", tpidrx) + return fmt.Sprintf(colorField("TPIDRx_ELy")+"\n%s\n", tpidrx.String()) } type Core struct { @@ -186,9 +186,10 @@ type PanickedThread struct { } func (p PanickedThread) String() string { - callstack := "\n" + var callstack strings.Builder + callstack.WriteString("\n") for _, state := range p.CallStack { - callstack += fmt.Sprintf(" %s\n", state) + callstack.WriteString(fmt.Sprintf(" %s\n", state)) } kexts := "" if len(p.Kexts) > 0 { @@ -197,7 +198,7 @@ func (p PanickedThread) String() string { for _, kext := range p.Kexts { kexts += fmt.Sprintf(" %s (%v) %s @ %s\n", kext.Name, kext.Version, kext.UUID, kext.Range) } - return fmt.Sprintf(colorField("Panicked Thread")+": %#016x, "+colorField("backtrace")+": %#016x, "+colorField("tid")+": %d%s%s", p.Address, p.Backtrace, p.TID, callstack, kexts) + return fmt.Sprintf(colorField("Panicked Thread")+": %#016x, "+colorField("backtrace")+": %#016x, "+colorField("tid")+": %d%s%s", p.Address, p.Backtrace, p.TID, callstack.String(), kexts) } type LastStartedKext struct { @@ -229,11 +230,11 @@ func (l LoadedKexts) String() string { if len(l) == 0 { return "" } - loadedKexts := "" + var loadedKexts strings.Builder for _, kext := range l { - loadedKexts += fmt.Sprintf(" %s\n", kext) + loadedKexts.WriteString(fmt.Sprintf(" %s\n", kext)) } - return fmt.Sprintf(colorField("Loaded Kexts:")+"\n%s\n", loadedKexts) + return fmt.Sprintf(colorField("Loaded Kexts:")+"\n%s\n", loadedKexts.String()) } type LoadedKext struct { @@ -836,9 +837,9 @@ func (p *Panic210) String() string { if ok { panic = colorField("Panic") + fmt.Sprintf("\n%s\n %s", start, rest) } - var cores string + var cores strings.Builder for _, core := range p.Cores { - cores += fmt.Sprintf("%s\n", core) + cores.WriteString(fmt.Sprintf("%s\n", core)) } return fmt.Sprintf( "%s\n\n"+ // panic @@ -909,7 +910,7 @@ func (p *Panic210) String() string { p.EpochTime, p.ZoneInfo, p.TPIDRx_ELy, - cores, + cores.String(), p.CompressorInfo, p.PanickedTask, p.PanickedThread, diff --git a/pkg/ctf/format.go b/pkg/ctf/format.go index 968a3644e..817984737 100644 --- a/pkg/ctf/format.go +++ b/pkg/ctf/format.go @@ -564,15 +564,16 @@ func (e *Enum) ParentID() int { } func (e *Enum) Type() string { return "enum " + e.name } func (e *Enum) String() string { - eout := fmt.Sprintf("enum %s {\n", e.name) + var eout strings.Builder + eout.WriteString(fmt.Sprintf("enum %s {\n", e.name)) for _, f := range e.Fields { - eout += fmt.Sprintf("\t%s = %d\n", + eout.WriteString(fmt.Sprintf("\t%s = %d\n", f.Name, f.Value, - ) + )) } - eout += "};" - return eout + eout.WriteString("};") + return eout.String() } func (e *Enum) Dump() string { var edump string diff --git a/pkg/dyld/format.go b/pkg/dyld/format.go index c4d388218..df330595b 100644 --- a/pkg/dyld/format.go +++ b/pkg/dyld/format.go @@ -532,11 +532,11 @@ func (f *File) getRosetta(uuid types.UUID) string { } func (f *File) getMappings(slideVersion uint32, verbose bool) string { - var output string + var output strings.Builder if f.Headers[f.UUID].SlideInfoOffsetUnused > 0 { for uuid, cacheMappings := range f.Mappings { - output += fmt.Sprintf("\n> SubCache %s", uuid) - output += cacheMappings.String() + output.WriteString(fmt.Sprintf("\n> SubCache %s", uuid)) + output.WriteString(cacheMappings.String()) } } else { // sort mappings map by address @@ -549,21 +549,21 @@ func (f *File) getMappings(slideVersion uint32, verbose bool) string { }) for _, uuid := range uuids { if uuid == f.symUUID { - output += fmt.Sprintf("\n> Cache (.symbols) UUID: %s\n\n", uuid) + output.WriteString(fmt.Sprintf("\n> Cache (.symbols) UUID: %s\n\n", uuid)) } else { ext, err := f.GetSubCacheExtensionFromUUID(uuid) if err != nil { - output += fmt.Sprintf("\n> Cache UUID: %s\n\n", uuid) + output.WriteString(fmt.Sprintf("\n> Cache UUID: %s\n\n", uuid)) } else { - output += fmt.Sprintf("\n> Cache (%s) UUID: %s\n\n", ext, uuid) + output.WriteString(fmt.Sprintf("\n> Cache (%s) UUID: %s\n\n", ext, uuid)) } } - output += "Mappings\n--------\n\n" - output += f.MappingsWithSlideInfo[uuid].String(slideVersion, verbose) - output += fmt.Sprintln() - output += f.getCodeSignature(uuid) - output += f.getRosetta(uuid) + output.WriteString("Mappings\n--------\n\n") + output.WriteString(f.MappingsWithSlideInfo[uuid].String(slideVersion, verbose)) + output.WriteString(fmt.Sprintln()) + output.WriteString(f.getCodeSignature(uuid)) + output.WriteString(f.getRosetta(uuid)) } } - return output + return output.String() } diff --git a/pkg/dyld/prebuilt_types.go b/pkg/dyld/prebuilt_types.go index 7c93f5134..526a77892 100644 --- a/pkg/dyld/prebuilt_types.go +++ b/pkg/dyld/prebuilt_types.go @@ -535,12 +535,12 @@ type ObjCBinaryInfo struct { } func (o ObjCBinaryInfo) String() string { - var out string - out += fmt.Sprintf(" __objc_imageinfo: %#08x\n", o.ImageInfoRuntimeOffset) - out += fmt.Sprintf(" __objc_selrefs: %#08x (count=%d)\n", o.SelRefsRuntimeOffset, o.SelRefsCount) - out += fmt.Sprintf(" __objc_classlist: %#08x (count=%d)\n", o.ClassListRuntimeOffset, o.ClassListCount) - out += fmt.Sprintf(" __objc_catlist: %#08x (count=%d)\n", o.CategoryListRuntimeOffset, o.CategoryCount) - out += fmt.Sprintf(" __objc_protolist: %#08x (count=%d)\n", o.ProtocolListRuntimeOffset, o.ProtocolListCount) + var out strings.Builder + out.WriteString(fmt.Sprintf(" __objc_imageinfo: %#08x\n", o.ImageInfoRuntimeOffset)) + out.WriteString(fmt.Sprintf(" __objc_selrefs: %#08x (count=%d)\n", o.SelRefsRuntimeOffset, o.SelRefsCount)) + out.WriteString(fmt.Sprintf(" __objc_classlist: %#08x (count=%d)\n", o.ClassListRuntimeOffset, o.ClassListCount)) + out.WriteString(fmt.Sprintf(" __objc_catlist: %#08x (count=%d)\n", o.CategoryListRuntimeOffset, o.CategoryCount)) + out.WriteString(fmt.Sprintf(" __objc_protolist: %#08x (count=%d)\n", o.ProtocolListRuntimeOffset, o.ProtocolListCount)) var flags []string if o.HasClassStableSwiftFixups { flags = append(flags, "class-stable-swift-fixups") @@ -564,12 +564,12 @@ func (o ObjCBinaryInfo) String() string { flags = append(flags, "protocol-method-lists-to-unique") } if len(flags) > 0 { - out += "\n flags:\n" + out.WriteString("\n flags:\n") for _, f := range flags { - out += fmt.Sprintf(" - %s\n", f) + out.WriteString(fmt.Sprintf(" - %s\n", f)) } } - return out + return out.String() } type PrebuiltLoader struct { @@ -601,48 +601,48 @@ func (pl PrebuiltLoader) GetFileOffset(vmoffset uint64) uint64 { return 0 } func (pl PrebuiltLoader) String(f *File) string { - var out string + var out strings.Builder if pl.Path != "" { - out += fmt.Sprintf("Path: %s\n", pl.Path) + out.WriteString(fmt.Sprintf("Path: %s\n", pl.Path)) } if pl.AltPath != "" { - out += fmt.Sprintf("AltPath: %s\n", pl.AltPath) + out.WriteString(fmt.Sprintf("AltPath: %s\n", pl.AltPath)) } if pl.Twin != "" { - out += fmt.Sprintf("Twin: %s\n", pl.Twin) + out.WriteString(fmt.Sprintf("Twin: %s\n", pl.Twin)) } - out += fmt.Sprintf("VM Size: %#x\n", pl.Header.VmSize) + out.WriteString(fmt.Sprintf("VM Size: %#x\n", pl.Header.VmSize)) if pl.Header.CodeSignature.Size > 0 { - out += fmt.Sprintf("CodeSignature: off=%#08x, sz=%#x\n", pl.Header.CodeSignature.FileOffset, pl.Header.CodeSignature.Size) + out.WriteString(fmt.Sprintf("CodeSignature: off=%#08x, sz=%#x\n", pl.Header.CodeSignature.FileOffset, pl.Header.CodeSignature.Size)) } if pl.FileValidation != nil { if pl.FileValidation.CheckCDHash { h := sha1.New() h.Write(pl.FileValidation.CDHash[:]) - out += fmt.Sprintf("CDHash: %x\n", h.Sum(nil)) + out.WriteString(fmt.Sprintf("CDHash: %x\n", h.Sum(nil))) } if pl.FileValidation.CheckInodeMtime { - out += fmt.Sprintf("slice-offset: %#x\n", pl.FileValidation.SliceOffset) - out += fmt.Sprintf("device-id: %#x\n", pl.FileValidation.DeviceID) - out += fmt.Sprintf("inode %#x\n", pl.FileValidation.Inode) - out += fmt.Sprintf("mod-time %#x\n", pl.FileValidation.Mtime) + out.WriteString(fmt.Sprintf("slice-offset: %#x\n", pl.FileValidation.SliceOffset)) + out.WriteString(fmt.Sprintf("device-id: %#x\n", pl.FileValidation.DeviceID)) + out.WriteString(fmt.Sprintf("inode %#x\n", pl.FileValidation.Inode)) + out.WriteString(fmt.Sprintf("mod-time %#x\n", pl.FileValidation.Mtime)) } // if !pl.FileValidation.UUID.IsNull() { // out += fmt.Sprintf("UUID: %s\n", pl.FileValidation.UUID) // } } - out += fmt.Sprintf("Loader: %s\n", pl.Loader) + out.WriteString(fmt.Sprintf("Loader: %s\n", pl.Loader)) if len(pl.Header.GetInfo()) > 0 { - out += fmt.Sprintf("Info: %s\n", pl.Header.GetInfo()) + out.WriteString(fmt.Sprintf("Info: %s\n", pl.Header.GetInfo())) } if pl.Header.ExportsTrieLoader.Size > 0 { - out += fmt.Sprintf("ExportsTrie: off=%#08x, sz=%#x\n", pl.GetFileOffset(pl.Header.ExportsTrieLoader.Offset), pl.Header.ExportsTrieLoader.Size) + out.WriteString(fmt.Sprintf("ExportsTrie: off=%#08x, sz=%#x\n", pl.GetFileOffset(pl.Header.ExportsTrieLoader.Offset), pl.Header.ExportsTrieLoader.Size)) } if pl.Header.FixupsLoadCommandOffset > 0 { - out += fmt.Sprintf("FixupsLoadCmd: off=%#08x\n", pl.Header.FixupsLoadCommandOffset) + out.WriteString(fmt.Sprintf("FixupsLoadCmd: off=%#08x\n", pl.Header.FixupsLoadCommandOffset)) } if len(pl.Regions) > 0 { - out += "\nRegions:\n\n" + out.WriteString("\nRegions:\n\n") tableString := &strings.Builder{} rdata := [][]string{} for _, rg := range pl.Regions { @@ -662,9 +662,9 @@ func (pl PrebuiltLoader) String(f *File) string { tbl.AppendBulk(rdata) tbl.SetAlignment(1) tbl.Render() - out += tableString.String() + out.WriteString(tableString.String()) } - out += "\nSections:\n" + out.WriteString("\nSections:\n") buf := &strings.Builder{} w := tabwriter.NewWriter(buf, 0, 0, 1, ' ', 0) for idx, off := range pl.Header.Sections.Offsets { @@ -674,43 +674,43 @@ func (pl PrebuiltLoader) String(f *File) string { fmt.Fprintf(w, " %s:\toff=%#x\tsz=%d\n", dyld_section_location_kind(idx), off, pl.Header.Sections.Sizes[idx]) } w.Flush() - out += buf.String() + out.WriteString(buf.String()) if len(pl.Dependents) > 0 { - out += "\nDependents:\n" + out.WriteString("\nDependents:\n") for _, dp := range pl.Dependents { - out += fmt.Sprintf(" %-10s) %s\n", dp.Kind, dp.Name) + out.WriteString(fmt.Sprintf(" %-10s) %s\n", dp.Kind, dp.Name)) } } if len(pl.BindTargets) > 0 { - out += "\nBindTargets:\n" + out.WriteString("\nBindTargets:\n") for _, bt := range pl.BindTargets { - out += fmt.Sprintf(" %s\n", bt.String(f)) + out.WriteString(fmt.Sprintf(" %s\n", bt.String(f))) } } if len(pl.OverrideBindTargets) > 0 { - out += "\nOverride BindTargets:\n" + out.WriteString("\nOverride BindTargets:\n") for _, bt := range pl.OverrideBindTargets { - out += fmt.Sprintf(" %s\n", bt.String(f)) + out.WriteString(fmt.Sprintf(" %s\n", bt.String(f))) } } if pl.ObjcFixupInfo != nil { - out += "\nObjC Fixup Info:\n" - out += fmt.Sprintln(pl.ObjcFixupInfo.String()) + out.WriteString("\nObjC Fixup Info:\n") + out.WriteString(fmt.Sprintln(pl.ObjcFixupInfo.String())) } if len(pl.ObjcCanonicalProtocolFixups) > 0 { - out += "ObjC Canonical ProtocolFixups:\n" + out.WriteString("ObjC Canonical ProtocolFixups:\n") for _, fixup := range pl.ObjcCanonicalProtocolFixups { - out += fmt.Sprintf(" %t\n", fixup) + out.WriteString(fmt.Sprintf(" %t\n", fixup)) } } if len(pl.ObjcSelectorFixups) > 0 { - out += "\nObjC SelectorFixups:\n" + out.WriteString("\nObjC SelectorFixups:\n") for _, bt := range pl.ObjcSelectorFixups { - out += fmt.Sprintf(" %s\n", bt.String(f)) + out.WriteString(fmt.Sprintf(" %s\n", bt.String(f))) } } - return out + return out.String() } type objCFlags uint32 @@ -766,115 +766,115 @@ func (pls PrebuiltLoaderSet) HasOptimizedSwift() bool { return (pls.SwiftForeignTypeConformanceTableOffset != 0) || (pls.SwiftMetadataConformanceTableOffset != 0) || (pls.SwiftTypeConformanceTableOffset != 0) } func (pls PrebuiltLoaderSet) String(f *File) string { - var out string - out += "PrebuiltLoaderSet:\n" - out += fmt.Sprintf(" Version: %x\n", pls.VersionHash) + var out strings.Builder + out.WriteString("PrebuiltLoaderSet:\n") + out.WriteString(fmt.Sprintf(" Version: %x\n", pls.VersionHash)) if !pls.DyldCacheUUID.IsNull() { - out += fmt.Sprintf(" DyldCacheUUID: %s\n", pls.DyldCacheUUID) + out.WriteString(fmt.Sprintf(" DyldCacheUUID: %s\n", pls.DyldCacheUUID)) } if len(pls.Loaders) > 0 { - out += "\nLoaders:\n" + out.WriteString("\nLoaders:\n") for _, pl := range pls.Loaders { if len(pls.Loaders) > 1 { - out += "---\n" + out.WriteString("---\n") } - out += pl.String(f) + out.WriteString(pl.String(f)) } } if pls.SelectorTable != nil { - out += "\nObjC Selector Table:\n" + out.WriteString("\nObjC Selector Table:\n") for _, bt := range pls.SelectorTable.Offsets { if bt.IsAbsolute() { continue } - out += fmt.Sprintf(" %s\n", bt.String(f)) + out.WriteString(fmt.Sprintf(" %s\n", bt.String(f))) } } if pls.ClassTable != nil { - out += "\nObjC Class Table:\n" + out.WriteString("\nObjC Class Table:\n") for idx, bt := range pls.ClassTable.Offsets { if bt.IsAbsolute() { continue } - out += fmt.Sprintf(" %s name\n", bt.String(f)) - out += fmt.Sprintf(" %s impl\n", pls.ClassTable.Classes[idx].String(f)) + out.WriteString(fmt.Sprintf(" %s name\n", bt.String(f))) + out.WriteString(fmt.Sprintf(" %s impl\n", pls.ClassTable.Classes[idx].String(f))) } } if pls.ProtocolTable != nil { - out += "\nObjC Protocol Table:\n" + out.WriteString("\nObjC Protocol Table:\n") for idx, bt := range pls.ProtocolTable.Offsets { if bt.IsAbsolute() { continue } - out += fmt.Sprintf(" %s name\n", bt.String(f)) - out += fmt.Sprintf(" %s impl\n", pls.ProtocolTable.Classes[idx].String(f)) + out.WriteString(fmt.Sprintf(" %s name\n", bt.String(f))) + out.WriteString(fmt.Sprintf(" %s impl\n", pls.ProtocolTable.Classes[idx].String(f))) } } if pls.HasOptimizedObjC() && pls.ObjcProtocolClassCacheOffset != 0 { - out += fmt.Sprintf("\nObjC Protocol Class Cache Address: %#x\n", f.Headers[f.UUID].SharedRegionStart+pls.ObjcProtocolClassCacheOffset) + out.WriteString(fmt.Sprintf("\nObjC Protocol Class Cache Address: %#x\n", f.Headers[f.UUID].SharedRegionStart+pls.ObjcProtocolClassCacheOffset)) } if len(pls.SwiftTypeProtocolTable) > 0 { - out += "\nSwift Type Protocol Table\n" - out += "-------------------------\n" + out.WriteString("\nSwift Type Protocol Table\n") + out.WriteString("-------------------------\n") pls.SwiftTypeProtocolTable.ForEachEntry(func(key SwiftTypeProtocolConformanceDiskLocationKey, values []SwiftTypeProtocolConformanceDiskLocation) { - out += fmt.Sprintf(" %s type descriptor\n", key.TypeDescriptor.String(f)) - out += fmt.Sprintf(" %s protocol\n", key.Protocol.String(f)) + out.WriteString(fmt.Sprintf(" %s type descriptor\n", key.TypeDescriptor.String(f))) + out.WriteString(fmt.Sprintf(" %s protocol\n", key.Protocol.String(f))) for _, v := range values { - out += fmt.Sprintf(" %s conformance\n", v.ProtocolConformance.String(f)) + out.WriteString(fmt.Sprintf(" %s conformance\n", v.ProtocolConformance.String(f))) } }) } if len(pls.SwiftMetadataProtocolTable) > 0 { - out += "\nSwift Metadata Protocol Table\n" - out += "-----------------------------\n" + out.WriteString("\nSwift Metadata Protocol Table\n") + out.WriteString("-----------------------------\n") pls.SwiftMetadataProtocolTable.ForEachEntry(func(key SwiftMetadataProtocolConformanceDiskLocationKey, values []SwiftMetadataProtocolConformanceDiskLocation) { - out += fmt.Sprintf(" %s metadata descriptor\n", key.MetadataDescriptor.String(f)) - out += fmt.Sprintf(" %s protocol\n", key.Protocol.String(f)) + out.WriteString(fmt.Sprintf(" %s metadata descriptor\n", key.MetadataDescriptor.String(f))) + out.WriteString(fmt.Sprintf(" %s protocol\n", key.Protocol.String(f))) for _, v := range values { - out += fmt.Sprintf(" %s conformance\n", v.ProtocolConformance.String(f)) + out.WriteString(fmt.Sprintf(" %s conformance\n", v.ProtocolConformance.String(f))) } }) } if len(pls.SwiftForeignTypeProtocolTable) > 0 { - out += "\nSwift Foreign Protocol Table\n" - out += "----------------------------\n" + out.WriteString("\nSwift Foreign Protocol Table\n") + out.WriteString("----------------------------\n") pls.SwiftForeignTypeProtocolTable.ForEachEntry(func(key SwiftForeignTypeProtocolConformanceDiskLocationKey, values []SwiftForeignTypeProtocolConformanceDiskLocation) { - out += fmt.Sprintf(" %s foreign descriptor\n", key.ForeignDescriptor.String(f)) - out += fmt.Sprintf(" %s protocol\n", key.Protocol.String(f)) + out.WriteString(fmt.Sprintf(" %s foreign descriptor\n", key.ForeignDescriptor.String(f))) + out.WriteString(fmt.Sprintf(" %s protocol\n", key.Protocol.String(f))) for _, v := range values { - out += fmt.Sprintf(" %s conformance\n", v.ProtocolConformance.String(f)) + out.WriteString(fmt.Sprintf(" %s conformance\n", v.ProtocolConformance.String(f))) } }) } if len(pls.MustBeMissingPaths) > 0 { - out += "\nMustBeMissing:\n" + out.WriteString("\nMustBeMissing:\n") for _, path := range pls.MustBeMissingPaths { - out += fmt.Sprintf(" %s\n", path) + out.WriteString(fmt.Sprintf(" %s\n", path)) } } if len(pls.Patches) > 0 { - out += "\nCache Overrides:\n" + out.WriteString("\nCache Overrides:\n") for _, patch := range pls.Patches { if len(pls.Patches) > 1 { - out += "---\n" + out.WriteString("---\n") } img := fmt.Sprintf("(index=%d)", patch.DylibIndex) if patch.DylibIndex < uint32(len(f.Images)) { img = f.Images[patch.DylibIndex].Name } - out += fmt.Sprintf(" cache-dylib: %s\n", img) - out += fmt.Sprintf(" dylib-offset: %#08x\n", patch.DylibVMOffset) + out.WriteString(fmt.Sprintf(" cache-dylib: %s\n", img)) + out.WriteString(fmt.Sprintf(" dylib-offset: %#08x\n", patch.DylibVMOffset)) if patch.PatchTo.LoaderRef().Index() < uint16(len(f.Images)) { img = f.Images[patch.PatchTo.LoaderRef().Index()].Name } else { img = patch.PatchTo.LoaderRef().String() } - out += fmt.Sprintf(" replace-loader: %s\n", img) - out += fmt.Sprintf(" replace-offset: %#08x\n", patch.PatchTo.Offset()) + out.WriteString(fmt.Sprintf(" replace-loader: %s\n", img)) + out.WriteString(fmt.Sprintf(" replace-offset: %#08x\n", patch.PatchTo.Offset())) } } - return out + return out.String() } type objCStringTable struct { diff --git a/pkg/emu/emu_string.go b/pkg/emu/emu_string.go index 40c2575bb..852727617 100644 --- a/pkg/emu/emu_string.go +++ b/pkg/emu/emu_string.go @@ -1,3 +1,5 @@ +//go:build unicorn + // Code generated by "stringer -type=interrupt,branchType,pstateMode -tags=unicorn -output emu_string.go"; DO NOT EDIT. package emu diff --git a/pkg/img3/img3.go b/pkg/img3/img3.go index 88828cdc7..1d4389211 100644 --- a/pkg/img3/img3.go +++ b/pkg/img3/img3.go @@ -7,6 +7,7 @@ import ( "encoding/binary" "fmt" "io" + "strings" "github.com/blacktop/ipsw/pkg/lzfse" ) @@ -582,7 +583,8 @@ func decryptKBAGWithKey(data, key []byte) ([]byte, error) { } func (i Img3) String() string { - iStr := fmt.Sprintf( + var iStr strings.Builder + iStr.WriteString(fmt.Sprintf( "[Img3 Info]\n"+ "===========\n"+ "Magic = %s\n"+ @@ -591,34 +593,34 @@ func (i Img3) String() string { "----\n", reverseBytes(i.Magic[:]), reverseBytes(i.Ident[:]), - ) + )) for _, tag := range i.Tags { magic := string(reverseBytes(tag.Magic[:])) switch magic { case "TYPE": - iStr += fmt.Sprintf("%s: %s\n", magic, reverseBytes(tag.Data[:])) + iStr.WriteString(fmt.Sprintf("%s: %s\n", magic, reverseBytes(tag.Data[:]))) case "DATA": - iStr += fmt.Sprintf("%s: %v (length: %d)\n", magic, tag.Data[0:15], len(tag.Data)) + iStr.WriteString(fmt.Sprintf("%s: %v (length: %d)\n", magic, tag.Data[0:15], len(tag.Data))) case "VERS": - iStr += fmt.Sprintf("%s: %s\n", magic, tag.Data) + iStr.WriteString(fmt.Sprintf("%s: %s\n", magic, tag.Data)) case "SEPO": - iStr += fmt.Sprintf("%s: %d\n", magic, binary.LittleEndian.Uint32(tag.Data)) + iStr.WriteString(fmt.Sprintf("%s: %d\n", magic, binary.LittleEndian.Uint32(tag.Data))) case "CHIP": - iStr += fmt.Sprintf("%s: 0x%x\n", magic, binary.LittleEndian.Uint32(tag.Data)) + iStr.WriteString(fmt.Sprintf("%s: 0x%x\n", magic, binary.LittleEndian.Uint32(tag.Data))) case "BORD": - iStr += fmt.Sprintf("%s: 0x%x\n", magic, binary.LittleEndian.Uint32(tag.Data)) + iStr.WriteString(fmt.Sprintf("%s: 0x%x\n", magic, binary.LittleEndian.Uint32(tag.Data))) case "KBAG": if kbag, err := ParseKBag(tag.Data); err == nil { - iStr += fmt.Sprintf("%s: CryptState=%d, AESType=0x%x, IV=%x, Key=%x\n", - magic, kbag.CryptState, kbag.AESType, kbag.IV, kbag.Key) + iStr.WriteString(fmt.Sprintf("%s: CryptState=%d, AESType=0x%x, IV=%x, Key=%x\n", + magic, kbag.CryptState, kbag.AESType, kbag.IV, kbag.Key)) } else { - iStr += fmt.Sprintf("%s: %v (parse error: %v)\n", magic, tag.Data, err) + iStr.WriteString(fmt.Sprintf("%s: %v (parse error: %v)\n", magic, tag.Data, err)) } default: - iStr += fmt.Sprintf("%s: %v\n", magic, tag.Data) + iStr.WriteString(fmt.Sprintf("%s: %v\n", magic, tag.Data)) } } - return iStr + return iStr.String() } func reverseBytes(a []byte) []byte { diff --git a/pkg/img4/manifest.go b/pkg/img4/manifest.go index d98584b84..506f9622a 100644 --- a/pkg/img4/manifest.go +++ b/pkg/img4/manifest.go @@ -1133,13 +1133,7 @@ func VerifyManifestDigests(im4m *Manifest, buildManifest *bm.BuildManifest, verb if name, exists := FourCCToComponent[fourCC]; exists { componentName = name // Check if this component was found in the BuildManifest - found := false - for _, foundComp := range foundComponents { - if foundComp == componentName { - found = true - break - } - } + found := slices.Contains(foundComponents, componentName) if !found { im4mOnlyImages = append(im4mOnlyImages, componentName) } diff --git a/pkg/img4/recovery_test.go b/pkg/img4/recovery_test.go index 3c2850028..61eb2fac3 100644 --- a/pkg/img4/recovery_test.go +++ b/pkg/img4/recovery_test.go @@ -3,6 +3,7 @@ package img4 import ( "bytes" "encoding/hex" + "maps" "testing" ) @@ -41,9 +42,7 @@ func TestRestoreInfoCreation(t *testing.T) { if tt.properties != nil { props := make(map[string]any) props["BNCN"] = tt.nonce - for k, v := range tt.properties { - props[k] = v - } + maps.Copy(props, tt.properties) restoreInfo = New(props) } else { restoreInfo = NewWithBootNonce(tt.nonce) diff --git a/pkg/info/info.go b/pkg/info/info.go index c7dc5a991..740b5b564 100644 --- a/pkg/info/info.go +++ b/pkg/info/info.go @@ -201,63 +201,63 @@ func getApFirmwareKey(device, build, filename string) (string, string, error) { } func (i *Info) String() string { - var iStr string + var iStr strings.Builder var verextra string if i.Plists.OTAInfo != nil { verextra = fmt.Sprintf(" %s", i.Plists.OTAInfo.MobileAssetProperties.ProductVersionExtra) } if i.Plists.BuildManifest != nil { - iStr += fmt.Sprintf( + iStr.WriteString(fmt.Sprintf( "Version = %s\n"+ "BuildVersion = %s\n"+ "OS Type = %s\n", i.Plists.BuildManifest.ProductVersion+verextra, i.Plists.BuildManifest.ProductBuildVersion, i.Plists.GetOSType(), - ) + )) } if i.Plists.Restore != nil { foundFS := false if fsDMG, err := i.GetFileSystemOsDmg(); err == nil { foundFS = true - iStr += fmt.Sprintf("FileSystem = %s\n", fsDMG) + iStr.WriteString(fmt.Sprintf("FileSystem = %s\n", fsDMG)) } if fsDMG, err := i.GetSystemOsDmg(); err == nil { - iStr += fmt.Sprintf("SystemOS = %s\n", fsDMG) + iStr.WriteString(fmt.Sprintf("SystemOS = %s\n", fsDMG)) } if fsDMG, err := i.GetAppOsDmg(); err == nil { - iStr += fmt.Sprintf("AppOS = %s\n", fsDMG) + iStr.WriteString(fmt.Sprintf("AppOS = %s\n", fsDMG)) } if fsDMG, err := i.GetExclaveOSDmg(); err == nil { - iStr += fmt.Sprintf("ExclaveOS = %s\n", fsDMG) + iStr.WriteString(fmt.Sprintf("ExclaveOS = %s\n", fsDMG)) } if ramDisk, err := i.GetRestoreRamDiskDmgs(); err == nil { - iStr += fmt.Sprintf("RestoreRamDisk = %s\n", ramDisk) + iStr.WriteString(fmt.Sprintf("RestoreRamDisk = %s\n", ramDisk)) } if !foundFS { if len(i.Plists.Restore.SystemRestoreImageFileSystems) > 0 { for file, fsType := range i.Plists.Restore.SystemRestoreImageFileSystems { - iStr += fmt.Sprintf("FileSystem = %s (Type: %s)\n", file, fsType) + iStr.WriteString(fmt.Sprintf("FileSystem = %s (Type: %s)\n", file, fsType)) } } } } if i.Plists.OTAInfo != nil { if len(i.Plists.OTAInfo.MobileAssetProperties.RestoreVersion) > 0 { - iStr += fmt.Sprintf("RestoreVersion = %s\n", i.Plists.OTAInfo.MobileAssetProperties.RestoreVersion) + iStr.WriteString(fmt.Sprintf("RestoreVersion = %s\n", i.Plists.OTAInfo.MobileAssetProperties.RestoreVersion)) } if len(i.Plists.OTAInfo.MobileAssetProperties.PrerequisiteBuild) > 0 { - iStr += fmt.Sprintf("PrereqBuild = %s\n", i.Plists.OTAInfo.MobileAssetProperties.PrerequisiteBuild) + iStr.WriteString(fmt.Sprintf("PrereqBuild = %s\n", i.Plists.OTAInfo.MobileAssetProperties.PrerequisiteBuild)) } if i.Plists.OTAInfo.MobileAssetProperties.SplatOnly { - iStr += "IsRSR = ✅\n" + iStr.WriteString("IsRSR = ✅\n") } } if len(i.DeviceTrees) > 0 { kcs := i.Plists.BuildManifest.GetKernelCaches() bls := i.Plists.BuildManifest.GetBootLoaders() - iStr += "\nDevices\n" - iStr += "-------\n" + iStr.WriteString("\nDevices\n") + iStr.WriteString("-------\n") for _, dtree := range i.DeviceTrees { dt, _ := dtree.Summary() prodName := dt.ProductName @@ -274,34 +274,34 @@ func (i *Info) String() string { prodName = dt.ProductType } } - iStr += fmt.Sprintf("\n%s\n", prodName) - iStr += fmt.Sprintf(" > %s_%s_%s\n", dt.ProductType, strings.ToUpper(dt.BoardConfig), i.Plists.BuildManifest.ProductBuildVersion) + iStr.WriteString(fmt.Sprintf("\n%s\n", prodName)) + iStr.WriteString(fmt.Sprintf(" > %s_%s_%s\n", dt.ProductType, strings.ToUpper(dt.BoardConfig), i.Plists.BuildManifest.ProductBuildVersion)) if !dt.Timestamp.IsZero() { - iStr += fmt.Sprintf(" - TimeStamp: %s\n", dt.Timestamp.Format("02 Jan 2006 15:04:05 MST")) + iStr.WriteString(fmt.Sprintf(" - TimeStamp: %s\n", dt.Timestamp.Format("02 Jan 2006 15:04:05 MST"))) } if len(kcs[strings.ToLower(dt.BoardConfig)]) > 0 { - iStr += fmt.Sprintf(" - KernelCache: %s\n", strings.Join(kcs[strings.ToLower(dt.BoardConfig)], ", ")) + iStr.WriteString(fmt.Sprintf(" - KernelCache: %s\n", strings.Join(kcs[strings.ToLower(dt.BoardConfig)], ", "))) } if cpu := i.GetCPU(dt.BoardConfig); len(cpu) > 0 { - iStr += fmt.Sprintf(" - %s\n", cpu) + iStr.WriteString(fmt.Sprintf(" - %s\n", cpu)) } if len(bls[strings.ToLower(dt.BoardConfig)]) > 0 { - iStr += " - BootLoaders\n" + iStr.WriteString(" - BootLoaders\n") for _, bl := range bls[strings.ToLower(dt.BoardConfig)] { - iStr += fmt.Sprintf(" * %s\n", filepath.Base(bl)) + iStr.WriteString(fmt.Sprintf(" * %s\n", filepath.Base(bl))) } } } } else { if i.Plists.BuildManifest != nil { - iStr += "\nDevices\n" - iStr += "-------\n" + iStr.WriteString("\nDevices\n") + iStr.WriteString("-------\n") for _, dev := range i.Plists.BuildManifest.SupportedProductTypes { - iStr += fmt.Sprintf(" > %s_%s\n", dev, i.Plists.BuildManifest.ProductBuildVersion) + iStr.WriteString(fmt.Sprintf(" > %s_%s\n", dev, i.Plists.BuildManifest.ProductBuildVersion)) } } } - return iStr + return iStr.String() } type InfoJSON struct { @@ -749,7 +749,7 @@ func (i *Info) GetKernelCacheForDevice(device string) []string { } func getAbbreviatedDevList(devices []string) string { - var devList string + var devList strings.Builder if len(devices) == 0 { return "" @@ -759,23 +759,23 @@ func getAbbreviatedDevList(devices []string) string { currentDev := devices[0] devPrefix := strings.Split(currentDev, ",")[0] - devList += currentDev + devList.WriteString(currentDev) for _, dev := range devices[1:] { if strings.HasPrefix(dev, devPrefix) { - devList += fmt.Sprintf("_%s", strings.Split(dev, ",")[1]) + devList.WriteString(fmt.Sprintf("_%s", strings.Split(dev, ",")[1])) } else { currentDev = dev devPrefix = strings.Split(currentDev, ",")[0] - devList += "_" + currentDev + devList.WriteString("_" + currentDev) } } - return devList + return devList.String() } func getAbbreviatedDevListFolder(devices []string) string { - var devList string + var devList strings.Builder if len(devices) == 0 { return "" @@ -787,19 +787,19 @@ func getAbbreviatedDevListFolder(devices []string) string { currentDev := devices[0] devPrefix := strings.Split(currentDev, ",")[0] - devList += currentDev + devList.WriteString(currentDev) for _, dev := range devices[1:] { if strings.HasPrefix(dev, devPrefix) { - devList += fmt.Sprintf("_%s", strings.Split(dev, ",")[1]) + devList.WriteString(fmt.Sprintf("_%s", strings.Split(dev, ",")[1])) } else { currentDev = dev devPrefix = strings.Split(currentDev, ",")[0] - devList += "_" + currentDev + devList.WriteString("_" + currentDev) } } - return devList + return devList.String() } // Parse parses plist files in a local ipsw file diff --git a/pkg/kernelcache/diff.go b/pkg/kernelcache/diff.go index 6e754fa13..88c6e7321 100644 --- a/pkg/kernelcache/diff.go +++ b/pkg/kernelcache/diff.go @@ -105,14 +105,14 @@ func InsertStringToFile(path, str string, index int) error { return err } - fileContent := "" + var fileContent strings.Builder for i, line := range lines { if i == index { - fileContent += str + fileContent.WriteString(str) } - fileContent += line - fileContent += "\n" + fileContent.WriteString(line) + fileContent.WriteString("\n") } - return os.WriteFile(path, []byte(fileContent), 0660) + return os.WriteFile(path, []byte(fileContent.String()), 0660) } diff --git a/pkg/kernelcache/mig.go b/pkg/kernelcache/mig.go index c7c7e5e0b..6021410b0 100644 --- a/pkg/kernelcache/mig.go +++ b/pkg/kernelcache/mig.go @@ -203,30 +203,30 @@ func (m MigKernSubsystem) LookupRoutineName(idx int) string { } func (m MigKernSubsystem) String() string { - var out string - out += fmt.Sprintf("%s: %s\t%s=%d %s=%d %s=%d\n", + var out strings.Builder + out.WriteString(fmt.Sprintf("%s: %s\t%s=%d %s=%d %s=%d\n", colorAddr("%#x", m.KServer), colorSubSystem(m.Start.String()), colorField("start"), m.Start, colorField("end"), m.End, colorField("max_sz"), m.Maxsize, - ) + )) for idx, r := range m.Routines { if r.KStubRoutine == 0 { continue // skip empty routines } - out += fmt.Sprintf(" %s: ", colorAddr("%#x", r.KStubRoutine)) - out += colorBold(m.LookupRoutineName(idx)) - out += fmt.Sprintf("\t%s=%02d %s=%#x %s=%02d %s=%d %s=%d %s=%d\n", + out.WriteString(fmt.Sprintf(" %s: ", colorAddr("%#x", r.KStubRoutine))) + out.WriteString(colorBold(m.LookupRoutineName(idx))) + out.WriteString(fmt.Sprintf("\t%s=%02d %s=%#x %s=%02d %s=%d %s=%d %s=%d\n", colorName("num"), idx+int(m.Start), colorName("impl"), r.ImplRoutine, colorName("argc"), r.ArgC, colorName("descr"), r.DescrCount, colorName("reply_descr"), r.ReplyDescrCount, colorName("max_reply_msg"), r.MaxReplyMsg, - ) + )) } - return out + return out.String() } func getMigInitFunc(m *macho.File) (*types.Function, error) { @@ -362,7 +362,7 @@ func getMigSubsystemPointers(m *macho.File, migEAddr uint64) ([]uint64, error) { var subsystems []uint64 - for i := uint64(0); i < maxEntries; i++ { + for i := range uint64(maxEntries) { ptr, err := m.GetPointerAtAddress(migEAddr + i*uint64(binary.Size(uint64(0)))) if err != nil { // If we fail on the very first entry, something is wrong with migEAddr. diff --git a/pkg/lzma/lz_bin_tree.go b/pkg/lzma/lz_bin_tree.go index 87fc93ca1..f03f9a02a 100644 --- a/pkg/lzma/lz_bin_tree.go +++ b/pkg/lzma/lz_bin_tree.go @@ -83,7 +83,7 @@ func newLzBinTree(r io.Reader, historySize, keepAddBufBefore, matchMaxLen, keepA } func normalizeLinks(items []uint32, numItems, subValue uint32) { - for i := uint32(0); i < numItems; i++ { + for i := range numItems { value := items[i] if value <= subValue { value = kEmptyHashValue @@ -253,7 +253,7 @@ func (bt *lzBinTree) getMatches(distances []uint32) uint32 { } func (bt *lzBinTree) skip(num uint32) { - for i := uint32(0); i < num; i++ { + for range num { var lenLimit uint32 if bt.iw.pos+bt.matchMaxLen <= bt.iw.streamPos { lenLimit = bt.matchMaxLen @@ -340,7 +340,7 @@ var crcTable []uint32 = make([]uint32, 256) // should be called in the encoder's contructor func initCrcTable() { - for i := uint32(0); i < 256; i++ { + for i := range uint32(256) { r := i for range 8 { if r&1 != 0 { diff --git a/pkg/lzma/lz_window.go b/pkg/lzma/lz_window.go index 2be2a33e1..1be6ec1c9 100644 --- a/pkg/lzma/lz_window.go +++ b/pkg/lzma/lz_window.go @@ -117,7 +117,7 @@ func (iw *lzInWindow) moveBlock() { offset-- } numBytes := iw.bufOffset + iw.streamPos - offset - for i := uint32(0); i < numBytes; i++ { + for i := range numBytes { iw.buf[i] = iw.buf[offset+i] } iw.bufOffset -= offset diff --git a/pkg/lzma/lzma_encoder.go b/pkg/lzma/lzma_encoder.go index 34c322f12..a4762116d 100644 --- a/pkg/lzma/lzma_encoder.go +++ b/pkg/lzma/lzma_encoder.go @@ -387,7 +387,7 @@ func (z *encoder) getOptimum(position uint32) (res uint32) { availableBytes = kMatchMaxLen } repMaxIndex := uint32(0) - for i := uint32(0); i < kNumRepDistances; i++ { + for i := range uint32(kNumRepDistances) { z.reps[i] = z.repDistances[i] z.repLens[i] = z.mf.iw.getMatchLen(0-1, z.reps[i], kMatchMaxLen) if z.repLens[i] > z.repLens[repMaxIndex] { @@ -452,7 +452,7 @@ DoWhile1: goto DoWhile1 } - for i := uint32(0); i < kNumRepDistances; i++ { + for i := range uint32(kNumRepDistances) { repLen := z.repLens[i] if repLen < 2 { continue @@ -655,7 +655,7 @@ DoWhile1: } startLen := uint32(2) - for repIndex := uint32(0); repIndex < kNumRepDistances; repIndex++ { + for repIndex := range uint32(kNumRepDistances) { lenTest := z.mf.iw.getMatchLen(0-1, z.reps[repIndex], availableBytes) if lenTest < 2 { continue @@ -802,7 +802,7 @@ func (z *encoder) fillDistancesPrices() { baseVal := (2 | posSlot&1) << footerBits tempPrices[i] = reverseGetPriceIndex(z.posCoders, baseVal-posSlot-1, footerBits, i-baseVal) } - for lenToPosState := uint32(0); lenToPosState < kNumLenToPosStates; lenToPosState++ { + for lenToPosState := range uint32(kNumLenToPosStates) { var posSlot uint32 st := lenToPosState << kNumPosSlotBits for posSlot = range z.distTableSize { @@ -824,7 +824,7 @@ func (z *encoder) fillDistancesPrices() { } func (z *encoder) fillAlignPrices() { - for i := uint32(0); i < kAlignTableSize; i++ { + for i := range uint32(kAlignTableSize) { z.alignPrices[i] = z.posAlignCoder.reverseGetPrice(i) } z.alignPriceCount = 0 @@ -1013,10 +1013,10 @@ func (z *encoder) encoder(r io.Reader, w io.Writer, size int64, level int) (err header := make([]byte, lzmaHeaderSize) header[0] = byte((z.cl.posStateBits*5+z.cl.litPosStateBits)*9 + z.cl.litContextBits) - for i := uint32(0); i < 4; i++ { + for i := range uint32(4) { header[i+1] = byte(z.cl.dictSize >> (8 * i)) } - for i := uint32(0); i < 8; i++ { + for i := range uint32(8) { header[i+lzmaPropSize] = byte(z.size >> (8 * i)) } n, err := w.Write(header) diff --git a/pkg/lzma/lzma_len_coder.go b/pkg/lzma/lzma_len_coder.go index fd36523ed..06701416e 100644 --- a/pkg/lzma/lzma_len_coder.go +++ b/pkg/lzma/lzma_len_coder.go @@ -18,7 +18,7 @@ func newLenCoder(numPosStates /*1 << pb*/ uint32) *lenCoder { midCoder: make([]*rangeBitTreeCoder, kNumPosStatesMax), highCoder: newRangeBitTreeCoder(kNumHighLenBits), } - for i := uint32(0); i < numPosStates; i++ { + for i := range numPosStates { lc.lowCoder[i] = newRangeBitTreeCoder(kNumLowLenBits) lc.midCoder[i] = newRangeBitTreeCoder(kNumMidLenBits) } @@ -101,7 +101,7 @@ func newLenPriceTableCoder(tableSize, numPosStates uint32) *lenPriceTableCoder { counters: make([]uint32, kNumPosStatesMax), tableSize: tableSize, } - for posState := uint32(0); posState < numPosStates; posState++ { + for posState := range numPosStates { pc.updateTable(posState) } return pc diff --git a/pkg/lzma/lzma_lit_coder.go b/pkg/lzma/lzma_lit_coder.go index ec614c7b9..2595a43a4 100644 --- a/pkg/lzma/lzma_lit_coder.go +++ b/pkg/lzma/lzma_lit_coder.go @@ -114,7 +114,7 @@ func newLitCoder(numPosBits, numPrevBits uint32) *litCoder { // numPosBits: numPosBits, posMask: (1 << numPosBits) - 1, } - for i := uint32(0); i < numStates; i++ { + for i := range numStates { lc.coders[i] = newLitSubCoder() } return lc diff --git a/pkg/lzma/range_bit_tree_coder.go b/pkg/lzma/range_bit_tree_coder.go index 4dc392169..e05ce1cab 100644 --- a/pkg/lzma/range_bit_tree_coder.go +++ b/pkg/lzma/range_bit_tree_coder.go @@ -41,7 +41,7 @@ func (rc *rangeBitTreeCoder) reverseDecode(rd *rangeDecoder) (res uint32) { func reverseDecodeIndex(rd *rangeDecoder, models []uint16, startIndex, numBitModels uint32) (res uint32) { index := uint32(1) res = 0 - for bitIndex := uint32(0); bitIndex < numBitModels; bitIndex++ { + for bitIndex := range numBitModels { bit := rd.decodeBit(models, startIndex+index) index <<= 1 index += bit @@ -108,7 +108,7 @@ func reverseGetPriceIndex(models []uint16, startIndex, numBitLevels, symbol uint func reverseEncodeIndex(re *rangeEncoder, models []uint16, startIndex, numBitLevels, symbol uint32) { m := uint32(1) - for i := uint32(0); i < numBitLevels; i++ { + for range numBitLevels { bit := symbol & 1 re.encode(models, startIndex+m, bit) m = m<<1 | bit diff --git a/pkg/lzma/range_coder.go b/pkg/lzma/range_coder.go index 35177df9d..75c77c17b 100644 --- a/pkg/lzma/range_coder.go +++ b/pkg/lzma/range_coder.go @@ -106,7 +106,7 @@ func (rd *rangeDecoder) decodeBit(probs []uint16, index uint32) (res uint32) { func initBitModels(length uint32) (probs []uint16) { probs = make([]uint16, length) val := uint16(kBitModelTotal) >> 1 - for i := uint32(0); i < length; i++ { + for i := range length { probs[i] = val // 1 << 10 } return diff --git a/pkg/nskeyedarchiver/nskeyedarchiver.go b/pkg/nskeyedarchiver/nskeyedarchiver.go index d63a1b101..095006066 100644 --- a/pkg/nskeyedarchiver/nskeyedarchiver.go +++ b/pkg/nskeyedarchiver/nskeyedarchiver.go @@ -316,7 +316,7 @@ func (p *NSKeyedArchiverParser) parseArray() ([]any, error) { // Parse the elements in the array array := make([]any, numElements) - for i := int64(0); i < numElements; i++ { + for i := range numElements { // Parse the element element, err := p.NextObject() if err != nil { @@ -340,7 +340,7 @@ func (p *NSKeyedArchiverParser) parseSet() (map[any]struct{}, error) { // Parse the elements in the set set := make(map[any]struct{}, numElements) - for i := int64(0); i < numElements; i++ { + for range numElements { // Parse the element element, err := p.NextObject() if err != nil { @@ -364,7 +364,7 @@ func (p *NSKeyedArchiverParser) parseDictionary() (map[string]any, error) { // Parse the key-value pairs in the dictionary dictionary := make(map[string]any, numPairs) - for i := int64(0); i < numPairs; i++ { + for range numPairs { // Parse the key key, err := p.parseASCIIString() if err != nil { diff --git a/pkg/ota/pbzx/extract.go b/pkg/ota/pbzx/extract.go index a3d27fad8..224681a52 100644 --- a/pkg/ota/pbzx/extract.go +++ b/pkg/ota/pbzx/extract.go @@ -25,11 +25,9 @@ func Extract(ctx context.Context, src io.Reader, dst io.Writer, numWorker int) e var wg1, wg2 sync.WaitGroup - wg1.Add(1) - go func() { - defer wg1.Done() + wg1.Go(func() { cancelIfError(read(ctx, src, inflateCh, writeCh)) - }() + }) if numWorker == 0 { numWorker = runtime.NumCPU() @@ -46,11 +44,9 @@ func Extract(ctx context.Context, src io.Reader, dst io.Writer, numWorker int) e }() } - wg2.Add(1) - go func() { - defer wg2.Done() + wg2.Go(func() { cancelIfError(write(ctx, writeCh, dst)) - }() + }) wg1.Wait() close(writeCh) diff --git a/pkg/ota/types/device_map.go b/pkg/ota/types/device_map.go index 280e2b751..831464db5 100644 --- a/pkg/ota/types/device_map.go +++ b/pkg/ota/types/device_map.go @@ -3,6 +3,7 @@ package types import ( "bytes" "fmt" + "strings" "github.com/blacktop/go-plist" ) @@ -159,11 +160,11 @@ func ParseDeviceMap(data []byte) (*DeviceMap, error) { } func (dm DeviceMap) String() string { - var out string + var out strings.Builder for boardconfig, device := range dm { - out += fmt.Sprintf("%s, board_config: %s\n", device, boardconfig) + out.WriteString(fmt.Sprintf("%s, board_config: %s\n", device, boardconfig)) } - return out + return out.String() } func (d Device) String() string { diff --git a/pkg/plist/build_manifest.go b/pkg/plist/build_manifest.go index 402067aeb..309aa6253 100644 --- a/pkg/plist/build_manifest.go +++ b/pkg/plist/build_manifest.go @@ -19,18 +19,18 @@ type BuildManifest struct { } func (b *BuildManifest) String() string { - var out string - out += "[BuildManifest]\n" - out += "===============\n" - out += fmt.Sprintf(" ManifestVersion: %d\n", b.ManifestVersion) - out += fmt.Sprintf(" ProductBuildVersion: %s\n", b.ProductBuildVersion) - out += fmt.Sprintf(" ProductVersion: %s\n", b.ProductVersion) - out += fmt.Sprintf(" SupportedProductTypes: %v\n", b.SupportedProductTypes) - out += " BuildIdentities:\n" + var out strings.Builder + out.WriteString("[BuildManifest]\n") + out.WriteString("===============\n") + out.WriteString(fmt.Sprintf(" ManifestVersion: %d\n", b.ManifestVersion)) + out.WriteString(fmt.Sprintf(" ProductBuildVersion: %s\n", b.ProductBuildVersion)) + out.WriteString(fmt.Sprintf(" ProductVersion: %s\n", b.ProductVersion)) + out.WriteString(fmt.Sprintf(" SupportedProductTypes: %v\n", b.SupportedProductTypes)) + out.WriteString(" BuildIdentities:\n") for _, bID := range b.BuildIdentities { - out += fmt.Sprintf(" -\n%s", bID.String()) + out.WriteString(fmt.Sprintf(" -\n%s", bID.String())) } - return out + return out.String() } type BuildIdentity struct { @@ -61,28 +61,28 @@ type BuildIdentity struct { } func (i BuildIdentity) String() string { - var out string + var out strings.Builder if len(i.ApProductMarketingVersion) > 0 { - out += fmt.Sprintf(" ProductMarketingVersion: %s\n", i.ApProductMarketingVersion) + out.WriteString(fmt.Sprintf(" ProductMarketingVersion: %s\n", i.ApProductMarketingVersion)) } if len(i.ApOSLongVersion) > 0 { - out += fmt.Sprintf(" Ap,OSLongVersion: %s\n", i.ApOSLongVersion) + out.WriteString(fmt.Sprintf(" Ap,OSLongVersion: %s\n", i.ApOSLongVersion)) } - out += fmt.Sprintf(" ApBoardID: %s\n", i.ApBoardID) - out += fmt.Sprintf(" ApBoardID: %s\n", i.ApBoardID) - out += fmt.Sprintf(" ApChipID: %s\n", i.ApChipID) - out += fmt.Sprintf(" ApSecurityDomain: %s\n", i.ApSecurityDomain) - out += fmt.Sprintf(" BbChipID: %s\n", i.BbChipID) - out += fmt.Sprintf(" Info:\n%s", i.Info.String()) - out += " Manifest:\n" + out.WriteString(fmt.Sprintf(" ApBoardID: %s\n", i.ApBoardID)) + out.WriteString(fmt.Sprintf(" ApBoardID: %s\n", i.ApBoardID)) + out.WriteString(fmt.Sprintf(" ApChipID: %s\n", i.ApChipID)) + out.WriteString(fmt.Sprintf(" ApSecurityDomain: %s\n", i.ApSecurityDomain)) + out.WriteString(fmt.Sprintf(" BbChipID: %s\n", i.BbChipID)) + out.WriteString(fmt.Sprintf(" Info:\n%s", i.Info.String())) + out.WriteString(" Manifest:\n") for k, v := range i.Manifest { if path, ok := v.Info["Path"]; ok { if len(path.(string)) > 0 { - out += fmt.Sprintf(" %-34s%s\n", k+":", v.String()) + out.WriteString(fmt.Sprintf(" %-34s%s\n", k+":", v.String())) } } } - return out + return out.String() } type IdentityInfo struct { diff --git a/pkg/plist/plist.go b/pkg/plist/plist.go index c8690679d..b7149143c 100644 --- a/pkg/plist/plist.go +++ b/pkg/plist/plist.go @@ -54,30 +54,30 @@ type AssetDataInfo struct { // AssetDataInfo Stringer func (a *AssetDataInfo) String() string { - var out string - out += "[AssetData/Info.plist]\n" - out += "======================\n" - out += fmt.Sprintf("Build: %s\n", a.Build) - out += fmt.Sprintf("DeviceClass: %s\n", a.DeviceClass) - out += fmt.Sprintf("HardwareModel: %s\n", a.HardwareModel) - out += fmt.Sprintf("MinimumSystemPartition: %d\n", a.MinimumSystemPartition) - out += fmt.Sprintf("PackageVersion: %s\n", a.PackageVersion) - out += fmt.Sprintf("ProductType: %s\n", a.ProductType) - out += fmt.Sprintf("ProductVersion: %s\n", a.ProductVersion) - out += fmt.Sprintf("RequiredSpace: %s\n", humanize.Bytes(uint64(a.RequiredSpace))) - out += fmt.Sprintf("ReserveFileAware: %v\n", a.ReserveFileAware) - out += fmt.Sprintf("SizeArchiveRoot: %s\n", humanize.Bytes(uint64(a.SizeArchiveRoot))) - out += fmt.Sprintf("SizePatchedBinaries: %s\n", humanize.Bytes(uint64(a.SizePatchedBinaries))) - out += fmt.Sprintf("SizePatchedBinaries-Snapshot: %s\n", humanize.Bytes(uint64(a.SizePatchedBinariesSnapshot))) + var out strings.Builder + out.WriteString("[AssetData/Info.plist]\n") + out.WriteString("======================\n") + out.WriteString(fmt.Sprintf("Build: %s\n", a.Build)) + out.WriteString(fmt.Sprintf("DeviceClass: %s\n", a.DeviceClass)) + out.WriteString(fmt.Sprintf("HardwareModel: %s\n", a.HardwareModel)) + out.WriteString(fmt.Sprintf("MinimumSystemPartition: %d\n", a.MinimumSystemPartition)) + out.WriteString(fmt.Sprintf("PackageVersion: %s\n", a.PackageVersion)) + out.WriteString(fmt.Sprintf("ProductType: %s\n", a.ProductType)) + out.WriteString(fmt.Sprintf("ProductVersion: %s\n", a.ProductVersion)) + out.WriteString(fmt.Sprintf("RequiredSpace: %s\n", humanize.Bytes(uint64(a.RequiredSpace)))) + out.WriteString(fmt.Sprintf("ReserveFileAware: %v\n", a.ReserveFileAware)) + out.WriteString(fmt.Sprintf("SizeArchiveRoot: %s\n", humanize.Bytes(uint64(a.SizeArchiveRoot)))) + out.WriteString(fmt.Sprintf("SizePatchedBinaries: %s\n", humanize.Bytes(uint64(a.SizePatchedBinaries)))) + out.WriteString(fmt.Sprintf("SizePatchedBinaries-Snapshot: %s\n", humanize.Bytes(uint64(a.SizePatchedBinariesSnapshot)))) if len(a.SystemUpdatePathMap) > 0 { - out += "SystemUpdatePathMap:\n" + out.WriteString("SystemUpdatePathMap:\n") for k, v := range a.SystemUpdatePathMap { - out += fmt.Sprintf(" - %s: %s\n", k, v) + out.WriteString(fmt.Sprintf(" - %s: %s\n", k, v)) } } - out += fmt.Sprintf("SystemVolumeSealingOverhead: %d\n", a.SystemVolumeSealingOverhead) - out += fmt.Sprintf("TargetUpdate: %s\n", a.TargetUpdate) - return out + out.WriteString(fmt.Sprintf("SystemVolumeSealingOverhead: %d\n", a.SystemVolumeSealingOverhead)) + out.WriteString(fmt.Sprintf("TargetUpdate: %s\n", a.TargetUpdate)) + return out.String() } // OTAInfo Info.plist object found in OTAs @@ -323,8 +323,8 @@ func (p *Plists) GetDeviceForBoardConfig(boardConfig string) *restoreDeviceMap { } func (i *Plists) String() string { - var iStr string - iStr += fmt.Sprintf( + var iStr strings.Builder + iStr.WriteString(fmt.Sprintf( "[Plists Info]\n"+ "===========\n"+ "Version = %s\n"+ @@ -333,18 +333,18 @@ func (i *Plists) String() string { i.BuildManifest.ProductVersion, i.BuildManifest.ProductBuildVersion, i.GetOSType(), - ) - iStr += "FileSystem = " + )) + iStr.WriteString("FileSystem = ") for file, fsType := range i.Restore.SystemRestoreImageFileSystems { - iStr += fmt.Sprintf("%s (Type: %s)\n", file, fsType) + iStr.WriteString(fmt.Sprintf("%s (Type: %s)\n", file, fsType)) } - iStr += "\nSupported Products:\n" + iStr.WriteString("\nSupported Products:\n") for _, prodType := range i.BuildManifest.SupportedProductTypes { - iStr += fmt.Sprintf(" - %s\n", prodType) + iStr.WriteString(fmt.Sprintf(" - %s\n", prodType)) } - iStr += "\nDeviceMap:\n" + iStr.WriteString("\nDeviceMap:\n") for _, device := range i.Restore.DeviceMap { - iStr += fmt.Sprintf( + iStr.WriteString(fmt.Sprintf( "BDID %d)\n"+ " - BoardConfig = %s\n"+ " - CPID = %d\n"+ @@ -357,12 +357,12 @@ func (i *Plists) String() string { device.Platform, device.SCEP, device.SDOM, - ) + )) } - iStr += "\nKernelCaches:\n" + iStr.WriteString("\nKernelCaches:\n") kcs := i.BuildManifest.GetKernelCaches() for key, value := range kcs { - iStr += fmt.Sprintf(" - BoardConfig: %s => %s\n", key, value) + iStr.WriteString(fmt.Sprintf(" - BoardConfig: %s => %s\n", key, value)) } - return iStr + return iStr.String() } diff --git a/pkg/plist/restore.go b/pkg/plist/restore.go index d34287ba2..9cfeb613a 100644 --- a/pkg/plist/restore.go +++ b/pkg/plist/restore.go @@ -3,6 +3,7 @@ package plist import ( "bytes" "fmt" + "strings" "github.com/blacktop/go-plist" ) @@ -46,25 +47,25 @@ func (dm *restoreDeviceMap) String() string { } func (r *Restore) String() string { - var out string - out += "[Restore]\n" - out += "=========\n" - out += fmt.Sprintf(" ProductBuildVersion: %s\n", r.ProductBuildVersion) - out += fmt.Sprintf(" ProductVersion: %s\n", r.ProductVersion) - out += fmt.Sprintf(" SupportedProductTypes: %v\n", r.SupportedProductTypes) + var out strings.Builder + out.WriteString("[Restore]\n") + out.WriteString("=========\n") + out.WriteString(fmt.Sprintf(" ProductBuildVersion: %s\n", r.ProductBuildVersion)) + out.WriteString(fmt.Sprintf(" ProductVersion: %s\n", r.ProductVersion)) + out.WriteString(fmt.Sprintf(" SupportedProductTypes: %v\n", r.SupportedProductTypes)) if len(r.DeviceMap) > 0 { - out += " DeviceMap:\n" + out.WriteString(" DeviceMap:\n") for _, dm := range r.DeviceMap { - out += fmt.Sprintf(" -\n%s", dm.String()) + out.WriteString(fmt.Sprintf(" -\n%s", dm.String())) } } if len(r.SystemRestoreImageFileSystems) > 0 { - out += " SystemRestoreImageFileSystems:\n" + out.WriteString(" SystemRestoreImageFileSystems:\n") for k, v := range r.SystemRestoreImageFileSystems { - out += fmt.Sprintf(" -\n %s: %s\n", k, v) + out.WriteString(fmt.Sprintf(" -\n %s: %s\n", k, v)) } } - return out + return out.String() } // ParseRestore parses the Restore.plist diff --git a/pkg/sep/sep.go b/pkg/sep/sep.go index b06101a8f..c3c7e4018 100644 --- a/pkg/sep/sep.go +++ b/pkg/sep/sep.go @@ -268,34 +268,34 @@ type Sep struct { } func (s Sep) String() string { - var out string - out += fmt.Sprintf( + var out strings.Builder + out.WriteString(fmt.Sprintf( "Legion: %s uuid=%s\n"+ "Kernel: start=%#x end=%#x\n"+ "%s: uuid=%s\n", s.Legion.Legion[:], s.Legion.UUID, s.Hdr.KernelTextOffset, s.Hdr.KernelTextOffset+s.Hdr.KernelDataOffset, s.SepOS.Name[:], s.SepOS.UUID, - ) + )) if len(s.Apps) > 0 { - out += "\n\nAPPS" + out.WriteString("\n\nAPPS") for _, app := range s.Apps { - out += fmt.Sprintf("\n\n%s\n", app) + out.WriteString(fmt.Sprintf("\n\n%s\n", app)) if m, err := macho.NewFile(bytes.NewReader(s.data[app.TextOffset:])); err == nil { - out += fmt.Sprintf("\n%s\n", m.FileTOC.String()) + out.WriteString(fmt.Sprintf("\n%s\n", m.FileTOC.String())) } } } if len(s.Libs) > 0 { - out += "\n\nLIBS" + out.WriteString("\n\nLIBS") for _, lib := range s.Libs { - out += fmt.Sprintf("\n\n%s\n", lib) + out.WriteString(fmt.Sprintf("\n\n%s\n", lib)) if m, err := macho.NewFile(bytes.NewReader(s.data[lib.TextOffset:])); err == nil { - out += fmt.Sprintf("\n%s\n", m.FileTOC.String()) + out.WriteString(fmt.Sprintf("\n%s\n", m.FileTOC.String())) } } } - return out + return out.String() } // Parse parses a SEP firmware image diff --git a/pkg/usb/afc/tree.go b/pkg/usb/afc/tree.go index 75e0178ec..6f97e12e1 100644 --- a/pkg/usb/afc/tree.go +++ b/pkg/usb/afc/tree.go @@ -130,12 +130,12 @@ func (p *printer) printText(text string, spaces []bool, last bool) string { indicator = lastItem } - var out string + var out strings.Builder lines := strings.Split(text, "\n") for i := range lines { text := lines[i] if i == 0 { - out += result + indicator + text + newLine + out.WriteString(result + indicator + text + newLine) continue } if last { @@ -143,21 +143,21 @@ func (p *printer) printText(text string, spaces []bool, last bool) string { } else { indicator = continueItem } - out += result + indicator + text + newLine + out.WriteString(result + indicator + text + newLine) } - return out + return out.String() } func (p *printer) printItems(t []Tree, spaces []bool) string { - var result string + var result strings.Builder for i, f := range t { last := i == len(t)-1 - result += p.printText(f.Text(), spaces, last) + result.WriteString(p.printText(f.Text(), spaces, last)) if len(f.Items()) > 0 { spacesChild := append(spaces, last) - result += p.printItems(f.Items(), spacesChild) + result.WriteString(p.printItems(f.Items(), spacesChild)) } } - return result + return result.String() } diff --git a/pkg/usb/mcinstall/mcinstall.go b/pkg/usb/mcinstall/mcinstall.go index 54be1affd..4a569a7ff 100644 --- a/pkg/usb/mcinstall/mcinstall.go +++ b/pkg/usb/mcinstall/mcinstall.go @@ -3,6 +3,7 @@ package mcinstall import ( "fmt" "os" + "strings" "github.com/blacktop/go-plist" "github.com/blacktop/ipsw/pkg/usb" @@ -45,21 +46,21 @@ type ProfileInfo struct { } func (p ProfileInfo) String() string { - var out string + var out strings.Builder for _, id := range p.IDs { - out += fmt.Sprintf(colorHeader("[ %s ]\n"), id) - out += colorHeader(" Manifest:\n") - out += fmt.Sprintf(colorFaint(" Description: ")+colorBold("%s\n"), p.Manifests[id].Description) - out += fmt.Sprintf(colorFaint(" Active: ")+colorBold("%t\n"), p.Manifests[id].IsActive) - out += colorHeader(" Metadata:\n") - out += fmt.Sprintf(colorFaint(" UUID: ")+colorBold("%s\n"), p.Metadatas[id].UUID) - out += fmt.Sprintf(colorFaint(" Version: ")+colorBold("%d\n"), p.Metadatas[id].Version) - out += fmt.Sprintf(colorFaint(" Name: ")+colorBold("%s\n"), p.Metadatas[id].Name) - out += fmt.Sprintf(colorFaint(" Description: ")+colorBold("%s\n"), p.Metadatas[id].Description) - out += fmt.Sprintf(colorFaint(" Organization: ")+colorBold("%s\n"), p.Metadatas[id].Organization) - out += fmt.Sprintf(colorFaint(" RemovalDisallowed: ")+colorBold("%t\n"), p.Metadatas[id].RemovalDisallowed) + out.WriteString(fmt.Sprintf(colorHeader("[ %s ]\n"), id)) + out.WriteString(colorHeader(" Manifest:\n")) + out.WriteString(fmt.Sprintf(colorFaint(" Description: ")+colorBold("%s\n"), p.Manifests[id].Description)) + out.WriteString(fmt.Sprintf(colorFaint(" Active: ")+colorBold("%t\n"), p.Manifests[id].IsActive)) + out.WriteString(colorHeader(" Metadata:\n")) + out.WriteString(fmt.Sprintf(colorFaint(" UUID: ")+colorBold("%s\n"), p.Metadatas[id].UUID)) + out.WriteString(fmt.Sprintf(colorFaint(" Version: ")+colorBold("%d\n"), p.Metadatas[id].Version)) + out.WriteString(fmt.Sprintf(colorFaint(" Name: ")+colorBold("%s\n"), p.Metadatas[id].Name)) + out.WriteString(fmt.Sprintf(colorFaint(" Description: ")+colorBold("%s\n"), p.Metadatas[id].Description)) + out.WriteString(fmt.Sprintf(colorFaint(" Organization: ")+colorBold("%s\n"), p.Metadatas[id].Organization)) + out.WriteString(fmt.Sprintf(colorFaint(" RemovalDisallowed: ")+colorBold("%t\n"), p.Metadatas[id].RemovalDisallowed)) } - return out + return out.String() } type ProfileMetadata struct { diff --git a/pkg/wallpaper/mesu_test.go b/pkg/wallpaper/mesu_test.go index f21124f85..742036271 100644 --- a/pkg/wallpaper/mesu_test.go +++ b/pkg/wallpaper/mesu_test.go @@ -1,3 +1,5 @@ +//go:build darwin && cgo && wallpaper + package wallpaper import (