From 9f01408ea7bb68684ec709fe1dabafd20254e055 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 30 Mar 2025 17:56:44 +0800 Subject: [PATCH] Avoid allocations by using unsafe strinng/bytes conversions --- git_hooks_handle_linux.go | 2 +- git_hooks_handle_other.go | 2 +- http_handle_repo_raw.go | 2 +- http_handle_repo_tree.go | 2 +- readme_to_html.go | 2 +- resources.go | 2 +- ssh_server.go | 4 ++-- unsafe.go | 20 ++++++++++++++++++++ diff --git a/git_hooks_handle_linux.go b/git_hooks_handle_linux.go index 40ba1aca00a95e6b8b0c64da2e2e72e3f0f624a0..36034f28afc3822d790207057b115a89bb4e52fa 100644 --- a/git_hooks_handle_linux.go +++ b/git_hooks_handle_linux.go @@ -76,7 +76,7 @@ } { var ok bool - packPass, ok = packPasses.Load(string(cookie)) + packPass, ok = packPasses.Load(bytesToString(cookie)) if !ok { if _, err = conn.Write([]byte{1}); err != nil { return diff --git a/git_hooks_handle_other.go b/git_hooks_handle_other.go index d4ee43adf7b8b2f029557075e096c66bec1c937c..02236c750256608104b405dd8047d815b7476166 100644 --- a/git_hooks_handle_other.go +++ b/git_hooks_handle_other.go @@ -54,7 +54,7 @@ } { var ok bool - packPass, ok = packPasses.Load(string(cookie)) + packPass, ok = packPasses.Load(bytesToString(cookie)) if !ok { if _, err = conn.Write([]byte{1}); err != nil { return diff --git a/http_handle_repo_raw.go b/http_handle_repo_raw.go index aab64b6ea6042be0b6af262feaf96cfa27354a72..1b4181b3c5b5ba41b7d546d161c9d5aefff908d4 100644 --- a/http_handle_repo_raw.go +++ b/http_handle_repo_raw.go @@ -33,7 +33,7 @@ return } refHashSlice = refHash[:] - cacheHandle := append(refHashSlice, []byte(pathSpec)...) //nolint:gocritic + cacheHandle := append(refHashSlice, stringToBytes(pathSpec)...) //nolint:gocritic if value, found := treeReadmeCache.Get(cacheHandle); found { params["files"] = value.DisplayTree diff --git a/http_handle_repo_tree.go b/http_handle_repo_tree.go index 1bb9940157319bded167ec30d79e451e8ff664d5..3c6e8df81810263cb3f631b15ab702d3fa89e486 100644 --- a/http_handle_repo_tree.go +++ b/http_handle_repo_tree.go @@ -39,7 +39,7 @@ return } refHashSlice = refHash[:] - cacheHandle := append(refHashSlice, []byte(pathSpec)...) //nolint:gocritic + cacheHandle := append(refHashSlice, stringToBytes(pathSpec)...) //nolint:gocritic if value, found := treeReadmeCache.Get(cacheHandle); found { params["files"] = value.DisplayTree diff --git a/readme_to_html.go b/readme_to_html.go index a7c7cb61cdb6e9c06c199833a2f257c1b5e42a7a..91312079ade129258c3e6ec662c94df3a6716516 100644 --- a/readme_to_html.go +++ b/readme_to_html.go @@ -37,7 +37,7 @@ if readmeFileContents, err = readmeFile.Contents(); err != nil { return "Error fetching README", escapeHTML("Unable to fetch contents of README: " + err.Error()) } - if err = markdownConverter.Convert([]byte(readmeFileContents), &readmeRenderedUnsafe); err != nil { + if err = markdownConverter.Convert(stringToBytes(readmeFileContents), &readmeRenderedUnsafe); err != nil { return "Error fetching README", escapeHTML("Unable to render README: " + err.Error()) } diff --git a/resources.go b/resources.go index df992ba643bd12f3f604119e75e06580cbcf9dd3..6d32136831da37796c480617210fbea5f4610850 100644 --- a/resources.go +++ b/resources.go @@ -67,7 +67,7 @@ if err != nil { return err } - _, err = templates.Parse(string(minified)) + _, err = templates.Parse(bytesToString(minified)) if err != nil { return err } diff --git a/ssh_server.go b/ssh_server.go index 56ed501a7996bd19201c141abd661e04d767b8f6..8fc39182905813a500ca1dea5077c4beef330981 100644 --- a/ssh_server.go +++ b/ssh_server.go @@ -36,7 +36,7 @@ return err } serverPubkey = hostKey.PublicKey() - serverPubkeyString = string(goSSH.MarshalAuthorizedKey(serverPubkey)) + serverPubkeyString = bytesToString(goSSH.MarshalAuthorizedKey(serverPubkey)) serverPubkeyFP = goSSH.FingerprintSHA256(serverPubkey) server = &gliderSSH.Server{ @@ -44,7 +44,7 @@ Handler: func(session gliderSSH.Session) { clientPubkey := session.PublicKey() var clientPubkeyStr string if clientPubkey != nil { - clientPubkeyStr = strings.TrimSuffix(string(goSSH.MarshalAuthorizedKey(clientPubkey)), "\n") + clientPubkeyStr = strings.TrimSuffix(bytesToString(goSSH.MarshalAuthorizedKey(clientPubkey)), "\n") } clog.Info("Incoming SSH: " + session.RemoteAddr().String() + " " + clientPubkeyStr + " " + session.RawCommand()) diff --git a/unsafe.go b/unsafe.go new file mode 100644 index 0000000000000000000000000000000000000000..418a910409520b0f4abcf2f11c87819412765843 --- /dev/null +++ b/unsafe.go @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: BSD-2-Clause +// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu + +package main + +import "unsafe" + +// stringToBytes converts a string to a byte slice without copying the string. +// Memory is borrowed from the string. +// The resulting byte slice must not be modified in any form. +func stringToBytes(s string) (bytes []byte) { + return unsafe.Slice(unsafe.StringData(s), len(s)) +} + +// bytesToString converts a byte slice to a string without copying the bytes. +// Memory is borrowed from the byte slice. +// The source byte slice must not be modified. +func bytesToString(b []byte) string { + return unsafe.String(&b[0], len(b)) +} -- 2.48.1