Skip to content
Merged
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
1 change: 1 addition & 0 deletions cmd/internal/migrations/lists.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ var Migrations = []Migration{
v3migrations.MigrateMiddlewareLocals,
v3migrations.MigrateFilesystemMiddleware,
v3migrations.MigrateLimiterConfig,
v3migrations.MigrateEncryptcookieConfig,
v3migrations.MigrateCacheConfig,
v3migrations.MigrateEnvVarConfig,
v3migrations.MigrateSessionConfig,
Expand Down
98 changes: 98 additions & 0 deletions cmd/internal/migrations/v3/encryptcookie_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package v3

import (
"fmt"
"regexp"
"strings"

semver "github.com/Masterminds/semver/v3"
"github.com/spf13/cobra"

"github.com/gofiber/cli/cmd/internal"
)

func MigrateEncryptcookieConfig(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
reConfig := regexp.MustCompile(`encryptcookie\.Config{`)

changed, err := internal.ChangeFileContent(cwd, func(content string) string {
matches := reConfig.FindAllStringIndex(content, -1)
if len(matches) == 0 {
return content
}

var b strings.Builder
last := 0
for _, m := range matches {
if _, err := b.WriteString(content[last:m[0]]); err != nil {
return content
}

start := m[0]
end := extractBlock(content, m[1], '{', '}')
cfg := content[start:end]
cfg = addEncryptcookieParam(cfg, "Encryptor")
cfg = addEncryptcookieParam(cfg, "Decryptor")

if _, err := b.WriteString(cfg); err != nil {
return content
}
last = end
}

if _, err := b.WriteString(content[last:]); err != nil {
return content
}
return b.String()
})
if err != nil {
return fmt.Errorf("failed to migrate encryptcookie configs: %w", err)
}
if !changed {
return nil
}

cmd.Println("Migrating encryptcookie middleware configs")
return nil
}

func addEncryptcookieParam(cfg, field string) string {
re := regexp.MustCompile(field + `:\s*func\s*\(([^)]*)\)`)
return re.ReplaceAllStringFunc(cfg, func(match string) string {
sub := re.FindStringSubmatch(match)
if len(sub) < 2 {
return match
}

params := sub[1]
trimmed := strings.TrimSpace(params)
if trimmed == "" {
return match
}

args := splitArgs(params)
var nonEmpty []string
for _, arg := range args {
if strings.TrimSpace(arg) != "" {
nonEmpty = append(nonEmpty, arg)
}
}

if len(nonEmpty) != 2 {
return match
}
Comment thread
gaby marked this conversation as resolved.
Comment on lines +72 to +82
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Skip inline parameters when comments present

The guard len(nonEmpty) != 2 relies on splitArgs returning exactly two entries, but splitArgs treats comment-only segments as arguments. If a user formats the Encryptor/Decryptor literal with inline comments (e.g., Encryptor: func( value string, // cookie value key string, )), splitArgs produces three entries (value string, the comment block, and key string) and the migration returns the original code without adding the new _ string parameter. Such signatures remain on the old two-argument form and will fail to compile after the middleware expects three parameters. Consider ignoring comment-only tokens (e.g., by stripping // and /* */ blocks) before the length check or by counting parameters syntactically rather than string splitting.

Useful? React with 👍 / 👎.


insertPos := 0
for insertPos < len(params) && (params[insertPos] == ' ' || params[insertPos] == '\t' || params[insertPos] == '\n') {
insertPos++
}

insertion := "_ string, "
Comment thread
gaby marked this conversation as resolved.
if idx := strings.LastIndex(params[:insertPos], "\n"); idx >= 0 {
indent := params[idx+1 : insertPos]
insertion = "_ string,\n" + indent
}

newParams := params[:insertPos] + insertion + params[insertPos:]
return strings.Replace(match, "("+params+")", "("+newParams+")", 1)
})
}
89 changes: 89 additions & 0 deletions cmd/internal/migrations/v3/encryptcookie_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package v3_test

import (
"bytes"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/gofiber/cli/cmd/internal/migrations/v3"
)

func Test_MigrateEncryptcookieConfig(t *testing.T) {
t.Parallel()

dir, err := os.MkdirTemp("", "mencryptcookie")
require.NoError(t, err)
defer func() { require.NoError(t, os.RemoveAll(dir)) }()

file := writeTempFile(t, dir, `package main
import (
"github.com/gofiber/fiber/v2/middleware/encryptcookie"
)
var _ = encryptcookie.New(encryptcookie.Config{
Encryptor: func(value, key string) (string, error) { return "", nil },
Decryptor: func(value string, key string) (string, error) { return "", nil },
})`)

var buf bytes.Buffer
cmd := newCmd(&buf)
require.NoError(t, v3.MigrateEncryptcookieConfig(cmd, dir, nil, nil))

content := readFile(t, file)
assert.Contains(t, content, "Encryptor: func(_ string, value, key string) (string, error)")
assert.Contains(t, content, "Decryptor: func(_ string, value string, key string) (string, error)")
assert.Contains(t, buf.String(), "Migrating encryptcookie middleware configs")
}

func Test_MigrateEncryptcookieConfig_MultiLine(t *testing.T) {
t.Parallel()

dir, err := os.MkdirTemp("", "mencryptcookieml")
require.NoError(t, err)
defer func() { require.NoError(t, os.RemoveAll(dir)) }()

file := writeTempFile(t, dir, `package main
import (
"github.com/gofiber/fiber/v2/middleware/encryptcookie"
)
var _ = encryptcookie.New(encryptcookie.Config{
Encryptor: func(
value string,
key string,
) (string, error) { return "", nil },
})`)

var buf bytes.Buffer
cmd := newCmd(&buf)
require.NoError(t, v3.MigrateEncryptcookieConfig(cmd, dir, nil, nil))

content := readFile(t, file)
assert.Contains(t, content, "\n\tEncryptor: func(\n\t\t_ string,\n\t\tvalue string,\n\t\tkey string,")
assert.Contains(t, buf.String(), "Migrating encryptcookie middleware configs")
}

func Test_MigrateEncryptcookieConfig_Idempotent(t *testing.T) {
t.Parallel()

dir, err := os.MkdirTemp("", "mencryptcookieidem")
require.NoError(t, err)
defer func() { require.NoError(t, os.RemoveAll(dir)) }()

file := writeTempFile(t, dir, `package main
import (
"github.com/gofiber/fiber/v2/middleware/encryptcookie"
)
var _ = encryptcookie.New(encryptcookie.Config{
Encryptor: func(value, key string) (string, error) { return "", nil },
})`)

var buf bytes.Buffer
cmd := newCmd(&buf)
require.NoError(t, v3.MigrateEncryptcookieConfig(cmd, dir, nil, nil))
first := readFile(t, file)
require.NoError(t, v3.MigrateEncryptcookieConfig(cmd, dir, nil, nil))
second := readFile(t, file)
assert.Equal(t, first, second)
}
Loading