Repository: gofiber/fiber (go)

Issue:
🐛 [Bug]: EnvVar middleware parsing error
### Bug Description

```go
func TestEnvVarHandlerSpecialValue(t *testing.T) {
	os.Setenv("testEnvKey", "testBase64:TQ==")
	defer os.Unsetenv("testEnvKey")

	app := fiber.New()
	app.Use("/envvars", New())

	req, _ := http.NewRequest("GET", "http://localhost/envvars", nil)
	resp, err := app.Test(req)
	utils.AssertEqual(t, nil, err)

	respBody, err := ioutil.ReadAll(resp.Body)
	utils.AssertEqual(t, nil, err)

	var envVars EnvVar
	utils.AssertEqual(t, nil, json.Unmarshal(respBody, &envVars))
	val := envVars.Vars["testEnvKey"]
	utils.AssertEqual(t, "testBase64:TQ==", val)
}
```

```go
=== RUN   TestEnvVarHandlerSpecialValue
    envvar_test.go:124: 
        Test:       TestEnvVarHandlerSpecialValue
        Trace:      envvar_test.go:124
        Expect:     testBase64:TQ==     (string)
        Result:     testBase64:TQ       (string)
--- FAIL: TestEnvVarHandlerSpecialValue (0.00s)

FAIL
```


### How to Reproduce

Run the above test case.

### Expected Behavior

PASS

### Fiber Version

v2.37.0

### Code Snippet (optional)

_No response_

### Checklist:

- [X] I agree to follow Fiber's [Code of Conduct](https://github.com/gofiber/fiber/blob/master/.github/CODE_OF_CONDUCT.md).
- [X] I have checked for existing issues that describe my problem prior to opening this one.
- [X] I understand that improperly formatted bug reports may be closed without explanation.

Pull request:
🐛 Fix: EnvVar middleware parses base64 incorrectly
## Description

Fixes #2068

## Type of change

Please delete options that are not relevant.

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] This change requires a documentation update

## Checklist:

- [x] For new functionalities I follow the inspiration of the express js framework and built them similar in usage
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation - https://github.com/gofiber/docs for https://docs.gofiber.io/
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] If new dependencies exist, I have checked that they are really necessary and agreed with the maintainers/community (we want to have as few dependencies as possible)
- [x] I tried to make my code as fast as possible with as few allocations as possible
- [ ] For new code I have written benchmarks so that they can be analyzed and improved


Patch:
diff --git a/middleware/envvar/README.md b/middleware/envvar/README.md
index b9880e9c..a16923d0 100644
--- a/middleware/envvar/README.md
+++ b/middleware/envvar/README.md
@@ -44,10 +44,12 @@ app.Use("/expose/envvars", envvar.New())
 ### Custom Config
 
 ```go
-app.Use("/expose/envvars", envvar.New(envvar.Config{
-    ExportVars:  map[string]string{"testKey": "", "testDefaultKey": "testDefaultVal"},
-    ExcludeVars: map[string]string{"excludeKey": ""}}
-}))
+app.Use("/expose/envvars", envvar.New(
+	envvar.Config{
+		ExportVars:  map[string]string{"testKey": "", "testDefaultKey": "testDefaultVal"},
+		ExcludeVars: map[string]string{"excludeKey": ""},
+	}),
+)
 ```
 
 ### Response
@@ -57,10 +59,9 @@ Http response contract:
 {
   "vars": {
     "someEnvVariable": "someValue",
-    "anotherEnvVariable": "anotherValue",
+    "anotherEnvVariable": "anotherValue"
   }
 }
-
 ```
 
 ## Config
@@ -68,12 +69,11 @@ Http response contract:
 ```go
 // Config defines the config for middleware.
 type Config struct {
-    // ExportVars specifies the environment variables that should export
-    ExportVars map[string]string
-    // ExcludeVars specifies the environment variables that should not export
-    ExcludeVars map[string]string
+	// ExportVars specifies the environment variables that should export
+	ExportVars map[string]string
+	// ExcludeVars specifies the environment variables that should not export
+	ExcludeVars map[string]string
 }
-
 ```
 
 ## Default Config
diff --git a/middleware/envvar/envvar.go b/middleware/envvar/envvar.go
index 373eac50..c8ed80de 100644
--- a/middleware/envvar/envvar.go
+++ b/middleware/envvar/envvar.go
@@ -1,10 +1,10 @@
 package envvar
 
 import (
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/fiber/v2/utils"
 	"os"
 	"strings"
+
+	"github.com/gofiber/fiber/v2"
 )
 
 // Config defines the config for middleware.
@@ -39,14 +39,10 @@ func New(config ...Config) fiber.Handler {
 		envVar := newEnvVar(cfg)
 		varsByte, err := c.App().Config().JSONEncoder(envVar)
 		if err != nil {
-			c.Response().SetBodyRaw(utils.UnsafeBytes(err.Error()))
-			c.Response().SetStatusCode(fiber.StatusInternalServerError)
-			return nil
+			return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
 		}
-		c.Response().SetBodyRaw(varsByte)
-		c.Response().SetStatusCode(fiber.StatusOK)
-		c.Response().Header.Set("Content-Type", "application/json; charset=utf-8")
-		return nil
+		c.Set(fiber.HeaderContentType, fiber.MIMEApplicationJSONCharsetUTF8)
+		return c.Send(varsByte)
 	}
 }
 
@@ -62,7 +58,7 @@ func newEnvVar(cfg Config) *EnvVar {
 		}
 	} else {
 		for _, envVal := range os.Environ() {
-			keyVal := strings.Split(envVal, "=")
+			keyVal := strings.SplitN(envVal, "=", 2)
 			if _, exists := cfg.ExcludeVars[keyVal[0]]; !exists {
 				vars.set(keyVal[0], keyVal[1])
 			}
diff --git a/path.go b/path.go
index 2b9e0e45..27f09f5f 100644
--- a/path.go
+++ b/path.go
@@ -60,7 +60,7 @@ const (
 	paramConstraintDataSeparator byte = ','  // separator of datas of type constraint for a parameter
 )
 
-// parameter constraint types
+// TypeConstraint parameter constraint types
 type TypeConstraint int16
 
 type Constraint struct {
@@ -259,7 +259,7 @@ func (routeParser *routeParser) analyseParameterPart(pattern string) (string, *r
 	// Check has constraint
 	var constraints []*Constraint
 
-	if hasConstraint := (parameterConstraintStart != -1 && parameterConstraintEnd != -1); hasConstraint {
+	if hasConstraint := parameterConstraintStart != -1 && parameterConstraintEnd != -1; hasConstraint {
 		constraintString := pattern[parameterConstraintStart+1 : parameterConstraintEnd]
 		userConstraints := splitNonEscaped(constraintString, string(parameterConstraintSeparatorChars))
 		constraints = make([]*Constraint, 0, len(userConstraints))


Test patch:
diff --git a/hooks_test.go b/hooks_test.go
index 5a800920..5ed9d821 100644
--- a/hooks_test.go
+++ b/hooks_test.go
@@ -42,7 +42,8 @@ func Test_Hook_OnName(t *testing.T) {
 	defer bytebufferpool.Put(buf)
 
 	app.Hooks().OnName(func(r Route) error {
-		buf.WriteString(r.Name)
+		_, err := buf.WriteString(r.Name)
+		utils.AssertEqual(t, nil, err)
 
 		return nil
 	})
@@ -84,8 +85,8 @@ func Test_Hook_OnGroup(t *testing.T) {
 	defer bytebufferpool.Put(buf)
 
 	app.Hooks().OnGroup(func(g Group) error {
-		buf.WriteString(g.Prefix)
-
+		_, err := buf.WriteString(g.Prefix)
+		utils.AssertEqual(t, nil, err)
 		return nil
 	})
 
@@ -104,7 +105,8 @@ func Test_Hook_OnGroupName(t *testing.T) {
 	defer bytebufferpool.Put(buf)
 
 	app.Hooks().OnGroupName(func(g Group) error {
-		buf.WriteString(g.name)
+		_, err := buf.WriteString(g.name)
+		utils.AssertEqual(t, nil, err)
 
 		return nil
 	})
@@ -143,7 +145,8 @@ func Test_Hook_OnShutdown(t *testing.T) {
 	defer bytebufferpool.Put(buf)
 
 	app.Hooks().OnShutdown(func() error {
-		buf.WriteString("shutdowning")
+		_, err := buf.WriteString("shutdowning")
+		utils.AssertEqual(t, nil, err)
 
 		return nil
 	})
@@ -163,7 +166,8 @@ func Test_Hook_OnListen(t *testing.T) {
 	defer bytebufferpool.Put(buf)
 
 	app.Hooks().OnListen(func() error {
-		buf.WriteString("ready")
+		_, err := buf.WriteString("ready")
+		utils.AssertEqual(t, nil, err)
 
 		return nil
 	})
diff --git a/middleware/envvar/envvar_test.go b/middleware/envvar/envvar_test.go
index edb74d5f..6e90e99c 100644
--- a/middleware/envvar/envvar_test.go
+++ b/middleware/envvar/envvar_test.go
@@ -2,12 +2,13 @@ package envvar
 
 import (
 	"encoding/json"
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/fiber/v2/utils"
 	"io/ioutil"
 	"net/http"
 	"os"
 	"testing"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/fiber/v2/utils"
 )
 
 func TestEnvVarStructWithExportVarsExcludeVars(t *testing.T) {
@@ -102,3 +103,38 @@ func TestEnvVarHandlerMethod(t *testing.T) {
 	utils.AssertEqual(t, nil, err)
 	utils.AssertEqual(t, fiber.StatusMethodNotAllowed, resp.StatusCode)
 }
+
+func TestEnvVarHandlerSpecialValue(t *testing.T) {
+	testEnvKey := "testEnvKey"
+	fakeBase64 := "testBase64:TQ=="
+	os.Setenv(testEnvKey, fakeBase64)
+	defer os.Unsetenv(testEnvKey)
+
+	app := fiber.New()
+	app.Use("/envvars", New())
+	app.Use("/envvars/export", New(Config{ExportVars: map[string]string{testEnvKey: ""}}))
+
+	req, _ := http.NewRequest("GET", "http://localhost/envvars", nil)
+	resp, err := app.Test(req)
+	utils.AssertEqual(t, nil, err)
+
+	respBody, err := ioutil.ReadAll(resp.Body)
+	utils.AssertEqual(t, nil, err)
+
+	var envVars EnvVar
+	utils.AssertEqual(t, nil, json.Unmarshal(respBody, &envVars))
+	val := envVars.Vars[testEnvKey]
+	utils.AssertEqual(t, fakeBase64, val)
+
+	req, _ = http.NewRequest("GET", "http://localhost/envvars/export", nil)
+	resp, err = app.Test(req)
+	utils.AssertEqual(t, nil, err)
+
+	respBody, err = ioutil.ReadAll(resp.Body)
+	utils.AssertEqual(t, nil, err)
+
+	var envVarsExport EnvVar
+	utils.AssertEqual(t, nil, json.Unmarshal(respBody, &envVarsExport))
+	val = envVarsExport.Vars[testEnvKey]
+	utils.AssertEqual(t, fakeBase64, val)
+}