Repository: labstack/echo (go)

Issue:
Parameterized routes return 404 after v4.1.13
### Issue Description

The latest release `v4.1.13` introduces a bug relat4ed to #1466 where parameterized routes sometimes return 404 for certain routes.

### Checklist

- [x] Dependencies installed
- [x] No typos
- [x] Searched existing issues and docs

### Expected behaviour

In the code shared below, if we access the route `/users/sharewithme/profile` or `/users/sharewithme/upload/self`, it's expected that the route would resolve correctly and not return 404 and the following code would return `sharewithme`; `sharewithme` and `self` respectively:

```go
// for route /users/sharewithme/profile
username := c.Param("username") // should return sharewithme

// for route /users/sharewithme/upload/self
username := c.Param("username")
type := c.Param("type")
```

### Actual behaviour

The routes mentioned above fail to resolve and instead return a 404

### Steps to reproduce

Run the code shared with the latest release and try the URLs mentioned above

### Working code to debug

```go
package main

import (
	"fmt"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"log"
	"net/http/httputil"
	"strings"
)

func main() {
	e := echo.New()

	RegisterAPIRoutes(e)

	e.Logger.Fatal(e.Start(":1234"))
}

func RegisterAPIRoutes(e *echo.Echo) {
	e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
		AllowOrigins:  []string{"*"},
		AllowMethods:  []string{echo.GET, echo.PUT, echo.POST, echo.DELETE},
		AllowHeaders:  []string{echo.HeaderContentType, echo.HeaderAuthorization},
		ExposeHeaders: []string{echo.HeaderAuthorization},
	}))

	e.POST("/users/signup", myFunc)
	e.POST("/users/signup/bulk", myFunc)
	e.POST("/users/signup/engcom", myFunc)
	e.POST("/users/surveysignup", myFunc)

	e.GET("/users/:username", myFunc)
	e.GET("/users/:username/likes/projects/ids", myFunc)
	e.GET("/users/:username/profile", myFunc)
	e.GET("/users/:username/uploads/:type", myFunc)

	e.GET("/interests/:name/users", myFunc)
	e.GET("/skills/:name/users", myFunc)
}

func myFunc(c echo.Context) error {
	var builder strings.Builder

	log.Println(c.Request())

	reqDump, _ := httputil.DumpRequest(c.Request(), true)

	builder.Write(reqDump)
	for _, name := range c.ParamNames() {
		builder.WriteString(fmt.Sprintf("Parameter: %s | Value: %s\n", name, c.Param(name)))
	}

	return c.String(200, builder.String())
}
```

### Version/commit
`v4.1.13`

Pull request description:
Parameterized routes sometimes return 404
Fixes #1479 

@vishr Please take a look at this when you have time. This is a followup from #1466 and could cause problems. Thanks!

Patch:
diff --git a/echo.go b/echo.go
index a6ac0fa..3869dc6 100644
--- a/echo.go
+++ b/echo.go
@@ -227,7 +227,7 @@ const (
 
 const (
 	// Version of Echo
-	Version = "4.1.13"
+	Version = "4.1.14"
 	website = "https://echo.labstack.com"
 	// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
 	banner = `
diff --git a/router.go b/router.go
index 0814597..9db9ea9 100644
--- a/router.go
+++ b/router.go
@@ -414,6 +414,10 @@ func (r *Router) Find(method, path string, c Context) {
 				if cn = nn.findChildByKind(pkind); cn != nil && strings.IndexByte(ns, '/') == -1 {
 					pvalues[len(cn.pnames)-1] = search
 					break
+				} else if cn != nil && strings.IndexByte(ns, '/') != 1 {
+					// If slash is present, it means that this is a parameterized route.
+					cn = cn.parent
+					goto Param
 				}
 				for {
 					np = nn.parent


Test patch:
diff --git a/router_test.go b/router_test.go
index 449af91..f47225d 100644
--- a/router_test.go
+++ b/router_test.go
@@ -1141,6 +1141,16 @@ func TestRouterParam1466(t *testing.T) {
 	r.Add(http.MethodGet, "/skills/:name/users", func(c Context) error {
 		return nil
 	})
+	// Additional routes for Issue 1479
+	r.Add(http.MethodGet, "/users/:username/likes/projects/ids", func(c Context) error {
+		return nil
+	})
+	r.Add(http.MethodGet, "/users/:username/profile", func(c Context) error {
+		return nil
+	})
+	r.Add(http.MethodGet, "/users/:username/uploads/:type", func(c Context) error {
+		return nil
+	})
 
 	c := e.NewContext(nil, nil).(*context)
 
@@ -1152,6 +1162,26 @@ func TestRouterParam1466(t *testing.T) {
 
 	r.Find(http.MethodGet, "/users/signup", c)
 	assert.Equal(t, "", c.Param("username"))
+	// Additional assertions for #1479
+	r.Find(http.MethodGet, "/users/sharewithme/likes/projects/ids", c)
+	assert.Equal(t, "sharewithme", c.Param("username"))
+
+	r.Find(http.MethodGet, "/users/ajitem/likes/projects/ids", c)
+	assert.Equal(t, "ajitem", c.Param("username"))
+
+	r.Find(http.MethodGet, "/users/sharewithme/profile", c)
+	assert.Equal(t, "sharewithme", c.Param("username"))
+
+	r.Find(http.MethodGet, "/users/ajitem/profile", c)
+	assert.Equal(t, "ajitem", c.Param("username"))
+
+	r.Find(http.MethodGet, "/users/sharewithme/uploads/self", c)
+	assert.Equal(t, "sharewithme", c.Param("username"))
+	assert.Equal(t, "self", c.Param("type"))
+
+	r.Find(http.MethodGet, "/users/ajitem/uploads/self", c)
+	assert.Equal(t, "ajitem", c.Param("username"))
+	assert.Equal(t, "self", c.Param("type"))
 }
 
 func benchmarkRouterRoutes(b *testing.B, routes []*Route) {