Skip to content

perf: replace bytes.Buffer & strings.Builder with bytebufferpool #6086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cmd/docgen/docgen.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package main

import (
"bytes"
"log"
"os"
"reflect"
"regexp"
"strings"

"github.com/invopop/jsonschema"
"github.com/valyala/bytebufferpool"

"github.com/projectdiscovery/nuclei/v3/pkg/templates"
"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"
Expand Down Expand Up @@ -42,8 +42,9 @@ func main() {
}
jsonschemaData := r.Reflect(&templates.Template{})

var buf bytes.Buffer
encoder := json.NewEncoder(&buf)
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
encoder := json.NewEncoder(buf)
encoder.SetIndent("", " ")
_ = encoder.Encode(jsonschemaData)

Expand Down
7 changes: 4 additions & 3 deletions cmd/tmc/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"bytes"
"fmt"
"log"
"os"
Expand All @@ -24,6 +23,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"
"github.com/projectdiscovery/retryablehttp-go"
errorutil "github.com/projectdiscovery/utils/errors"
"github.com/valyala/bytebufferpool"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -379,8 +379,9 @@ func parseAndAddMaxRequests(catalog catalog.Catalog, path, data string) (string,
}
infoBlock.Info.Metadata["max-request"] = template.TotalRequests

var newInfoBlock bytes.Buffer
yamlEncoder := yaml.NewEncoder(&newInfoBlock)
newInfoBlock := bytebufferpool.Get()
defer bytebufferpool.Put(newInfoBlock)
yamlEncoder := yaml.NewEncoder(newInfoBlock)
yamlEncoder.SetIndent(yamlIndentSpaces)
err = yamlEncoder.Encode(infoBlock)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions internal/pdcp/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
unitutils "github.com/projectdiscovery/utils/unit"
updateutils "github.com/projectdiscovery/utils/update"
urlutil "github.com/projectdiscovery/utils/url"
"github.com/valyala/bytebufferpool"
)

const (
Expand Down Expand Up @@ -151,7 +152,8 @@ func (u *UploadWriter) autoCommit(ctx context.Context, r *io.PipeReader) {
}
}()
// temporary buffer to store the results
buff := &bytes.Buffer{}
buff := bytebufferpool.Get()
defer bytebufferpool.Put(buff)
ticker := time.NewTicker(flushTimer)
defer ticker.Stop()
for {
Expand Down Expand Up @@ -193,7 +195,7 @@ func (u *UploadWriter) autoCommit(ctx context.Context, r *io.PipeReader) {
}

// uploadChunk uploads a chunk of data to the server
func (u *UploadWriter) uploadChunk(buff *bytes.Buffer) error {
func (u *UploadWriter) uploadChunk(buff *bytebufferpool.ByteBuffer) error {
if err := u.upload(buff.Bytes()); err != nil {
return errorutil.NewWithErr(err).Msgf("could not upload chunk")
}
Expand Down
5 changes: 3 additions & 2 deletions internal/runner/healthcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import (
"fmt"
"net"
"runtime"
"strings"

"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
"github.com/projectdiscovery/nuclei/v3/pkg/types"
fileutil "github.com/projectdiscovery/utils/file"
"github.com/valyala/bytebufferpool"
)

// DoHealthCheck performs self-diagnostic checks
func DoHealthCheck(options *types.Options) string {
// RW permissions on config file
var test strings.Builder
test := bytebufferpool.Get()
defer bytebufferpool.Put(test)
test.WriteString(fmt.Sprintf("Version: %s\n", config.Version))
test.WriteString(fmt.Sprintf("Operating System: %s\n", runtime.GOOS))
test.WriteString(fmt.Sprintf("Architecture: %s\n", runtime.GOARCH))
Expand Down
7 changes: 4 additions & 3 deletions internal/runner/templates.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package runner

import (
"bytes"
"path/filepath"
"sort"
"strings"
Expand All @@ -11,6 +10,7 @@ import (
"github.com/logrusorgru/aurora"
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/loader"
"github.com/valyala/bytebufferpool"

"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/v3/pkg/templates"
Expand Down Expand Up @@ -108,9 +108,10 @@ func (r *Runner) listAvailableStoreTags(store *loader.Store) {
}

func (r *Runner) highlightTemplate(body *[]byte) ([]byte, error) {
var buf bytes.Buffer
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
// YAML lexer, true color terminal formatter and monokai style
err := quick.Highlight(&buf, string(*body), "yaml", "terminal16m", "monokai")
err := quick.Highlight(buf, string(*body), "yaml", "terminal16m", "monokai")
if err != nil {
return nil, err
}
Expand Down
5 changes: 4 additions & 1 deletion internal/server/dedupe.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/projectdiscovery/nuclei/v3/pkg/input/types"
mapsutil "github.com/projectdiscovery/utils/maps"
"github.com/valyala/bytebufferpool"
)

var dynamicHeaders = map[string]bool{
Expand Down Expand Up @@ -68,7 +69,9 @@ func hashRequest(req *types.RequestResponse) (string, error) {
return "", err
}

var hashContent strings.Builder
hashContent := bytebufferpool.Get()
defer bytebufferpool.Put(hashContent)

hashContent.WriteString(req.Request.Method)
hashContent.WriteString(normalizedURL)

Expand Down
5 changes: 3 additions & 2 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"html/template"
"net/http"
"net/url"
"strings"
"sync/atomic"
"time"

Expand All @@ -20,6 +19,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/output"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
"github.com/projectdiscovery/utils/env"
"github.com/valyala/bytebufferpool"
)

// DASTServer is a server that performs execution of fuzzing templates
Expand Down Expand Up @@ -98,7 +98,8 @@ func New(options *Options) (*DASTServer, error) {
}
server.scopeManager = scopeManager

var builder strings.Builder
builder := bytebufferpool.Get()
defer bytebufferpool.Put(builder)
gologger.Debug().Msgf("Using %d parallel tasks with %d buffer", maxWorkers, bufferSize)
if options.Token != "" {
builder.WriteString(" (with token)")
Expand Down
7 changes: 5 additions & 2 deletions lib/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/projectdiscovery/ratelimit"
"github.com/projectdiscovery/retryablehttp-go"
errorutil "github.com/projectdiscovery/utils/errors"
"github.com/valyala/bytebufferpool"
)

// NucleiSDKOptions contains options for nuclei SDK
Expand Down Expand Up @@ -188,9 +189,11 @@ func (e *NucleiEngine) SignTemplate(tmplSigner *signer.TemplateSigner, data []by
return data, err
}
_, content := signer.ExtractSignatureAndContent(data)
buff := bytes.NewBuffer(content)
buff := bytebufferpool.Get()
defer bytebufferpool.Put(buff)
buff.Write(content)
buff.WriteString("\n" + signatureData)
return buff.Bytes(), err
return buff.Bytes(), nil
}

func (e *NucleiEngine) closeInternal() {
Expand Down
5 changes: 3 additions & 2 deletions lib/sdk_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package nuclei
import (
"context"
"fmt"
"strings"
"sync"
"time"

"github.com/projectdiscovery/nuclei/v3/pkg/input"
"github.com/valyala/bytebufferpool"

"github.com/logrusorgru/aurora"
"github.com/pkg/errors"
Expand Down Expand Up @@ -51,7 +51,8 @@ func (e *NucleiEngine) applyRequiredDefaults(ctx context.Context) {
}
return
}
sb := strings.Builder{}
sb := bytebufferpool.Get()
defer bytebufferpool.Put(sb)
sb.WriteString(fmt.Sprintf("[%v] ", event.TemplateID))
if event.Matched != "" {
sb.WriteString(event.Matched)
Expand Down
5 changes: 3 additions & 2 deletions pkg/catalog/config/nucleiconfig.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package config

import (
"bytes"
"crypto/md5"
"fmt"
"log"
Expand All @@ -16,6 +15,7 @@ import (
errorutil "github.com/projectdiscovery/utils/errors"
fileutil "github.com/projectdiscovery/utils/file"
folderutil "github.com/projectdiscovery/utils/folder"
"github.com/valyala/bytebufferpool"
)

// DefaultConfig is the default nuclei configuration
Expand Down Expand Up @@ -292,7 +292,8 @@ func (c *Config) WriteTemplatesConfig() error {
// WriteTemplatesIndex writes the nuclei templates index file
func (c *Config) WriteTemplatesIndex(index map[string]string) error {
indexFile := c.GetTemplateIndexFilePath()
var buff bytes.Buffer
buff := bytebufferpool.Get()
defer bytebufferpool.Put(buff)
for k, v := range index {
_, _ = buff.WriteString(k + "," + v + "\n")
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/catalog/loader/ai_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/projectdiscovery/retryablehttp-go"
pdcpauth "github.com/projectdiscovery/utils/auth/pdcp"
errorutil "github.com/projectdiscovery/utils/errors"
"github.com/valyala/bytebufferpool"
)

const (
Expand Down Expand Up @@ -70,8 +71,9 @@ func getAIGeneratedTemplates(prompt string, options *types.Options) ([]string, e
if hasNoTargets && hasNoStdin {
// Display the template content with syntax highlighting
if !options.NoColor {
var buf bytes.Buffer
err = quick.Highlight(&buf, template, "yaml", "terminal16m", "monokai")
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
err = quick.Highlight(buf, template, "yaml", "terminal16m", "monokai")
if err == nil {
template = buf.String()
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/external/customtemplates/azure_blob.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package customtemplates

import (
"bytes"
"context"
"os"
"path/filepath"
Expand All @@ -13,6 +12,7 @@ import (
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
"github.com/projectdiscovery/nuclei/v3/pkg/types"
errorutil "github.com/projectdiscovery/utils/errors"
"github.com/valyala/bytebufferpool"
)

var _ Provider = &customTemplateAzureBlob{}
Expand Down Expand Up @@ -121,7 +121,8 @@ func downloadTemplate(client *azblob.Client, containerName string, path string,
return err
}

downloadedData := bytes.Buffer{}
downloadedData := bytebufferpool.Get()
defer bytebufferpool.Put(downloadedData)
retryReader := get.NewRetryReader(ctx, &azblob.RetryReaderOptions{})
_, err = downloadedData.ReadFrom(retryReader)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions pkg/fuzz/analyzers/time/time_delay.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import (
"errors"
"fmt"
"math"
"strings"

"github.com/valyala/bytebufferpool"
)

type timeDelayRequestSender func(delay int) (float64, error)
Expand Down Expand Up @@ -101,7 +102,8 @@ func checkTimingDependency(

result := regression.IsWithinConfidence(correlationErrorRange, 1.0, slopeErrorRange)
if result {
var resultReason strings.Builder
resultReason := bytebufferpool.Get()
defer bytebufferpool.Put(resultReason)
resultReason.WriteString(fmt.Sprintf(
"[time_delay] made %d requests (baseline: %.2fs) successfully, with a regression slope of %.2f and correlation %.2f",
requestsLimit,
Expand Down
5 changes: 3 additions & 2 deletions pkg/fuzz/component/body_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package component

import (
"bytes"
"io"
"mime/multipart"
"strings"
Expand All @@ -10,6 +9,7 @@ import (
"github.com/projectdiscovery/retryablehttp-go"
urlutil "github.com/projectdiscovery/utils/url"
"github.com/stretchr/testify/require"
"github.com/valyala/bytebufferpool"
)

func TestBodyComponent(t *testing.T) {
Expand Down Expand Up @@ -122,7 +122,8 @@ func TestBodyFormComponent(t *testing.T) {
}

func TestMultiPartFormComponent(t *testing.T) {
formData := &bytes.Buffer{}
formData := bytebufferpool.Get()
defer bytebufferpool.Put(formData)
writer := multipart.NewWriter(formData)

// Hypothetical form fields
Expand Down
9 changes: 6 additions & 3 deletions pkg/fuzz/dataformat/multipart.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/textproto"

mapsutil "github.com/projectdiscovery/utils/maps"
"github.com/valyala/bytebufferpool"
)

type MultiPartForm struct {
Expand Down Expand Up @@ -38,8 +39,9 @@ func (m *MultiPartForm) IsType(data string) bool {

// Encode encodes the data into MultiPartForm format
func (m *MultiPartForm) Encode(data KV) (string, error) {
var b bytes.Buffer
w := multipart.NewWriter(&b)
b := bytebufferpool.Get()
defer bytebufferpool.Put(b)
w := multipart.NewWriter(b)
if err := w.SetBoundary(m.boundary); err != nil {
return "", err
}
Expand Down Expand Up @@ -144,7 +146,8 @@ func (m *MultiPartForm) Decode(data string) (KV, error) {
}
defer file.Close()

buffer := new(bytes.Buffer)
buffer := bytebufferpool.Get()
defer bytebufferpool.Put(buffer)
if _, err := buffer.ReadFrom(file); err != nil {
return KV{}, err
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/fuzz/frequency/tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/bluele/gcache"
"github.com/projectdiscovery/gologger"
"github.com/valyala/bytebufferpool"
)

// Tracker implements a frequency tracker for a given input
Expand Down Expand Up @@ -121,7 +122,8 @@ func (t *Tracker) UnmarkParameter(parameter, target, template string) {
}

func getFrequencyKey(parameter, target, template string) string {
var sb strings.Builder
sb := bytebufferpool.Get()
defer bytebufferpool.Put(sb)
sb.WriteString(target)
sb.WriteString(":")
sb.WriteString(template)
Expand Down
Loading
Loading