nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: labstack/echo
Pull request #2385 (2023-01-27 20:59:37)

Return an empty string for ctx.path if there is no registered path
Proposed fix for https://github.com/labstack/echo/issues/2384

aldas: This will be probably release in next minor version with newer "context" timeout middleware

Patch:
diff --git a/router.go b/router.go
index 86a986a..597660d 100644
--- a/router.go
+++ b/router.go
@@ -524,7 +524,6 @@ func optionsMethodHandler(allowMethods string) func(c Context) error {
 // - Return it `Echo#ReleaseContext()`.
 func (r *Router) Find(method, path string, c Context) {
 	ctx := c.(*context)
-	ctx.path = path
 	currentNode := r.tree // Current node as root
 
 	var (


Test patch:
diff --git a/router_test.go b/router_test.go
index 825170a..619cce0 100644
--- a/router_test.go
+++ b/router_test.go
@@ -674,6 +674,18 @@ func TestRouterStatic(t *testing.T) {
 	assert.Equal(t, path, c.Get("path"))
 }
 
+func TestRouterNoRoutablePath(t *testing.T) {
+	e := New()
+	r := e.router
+	c := e.NewContext(nil, nil).(*context)
+
+	r.Find(http.MethodGet, "/notfound", c)
+	c.handler(c)
+
+	// No routable path, don't set Path.
+	assert.Equal(t, "", c.Path())
+}
+
 func TestRouterParam(t *testing.T) {
 	e := New()
 	r := e.router
Repository: labstack/echo
Pull request #2425 (2023-03-28 09:25:49)

add supprt for go1.20 http.rwUnwrapper
Support ResponseController for Go 1.20

aldas: @imxyb this looks OK but could you add one test for it.
imxyb: > @imxyb this looks OK but could you add one test for it.

done

Patch:
diff --git a/response.go b/response.go
index 84f7c9e..d9c9aa6 100644
--- a/response.go
+++ b/response.go
@@ -94,6 +94,13 @@ func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
 	return r.Writer.(http.Hijacker).Hijack()
 }
 
+// Unwrap returns the original http.ResponseWriter.
+// ResponseController can be used to access the original http.ResponseWriter.
+// See [https://go.dev/blog/go1.20]
+func (r *Response) Unwrap() http.ResponseWriter {
+	return r.Writer
+}
+
 func (r *Response) reset(w http.ResponseWriter) {
 	r.beforeFuncs = nil
 	r.afterFuncs = nil


Test patch:
diff --git a/response_test.go b/response_test.go
index d95e079..e4fd636 100644
--- a/response_test.go
+++ b/response_test.go
@@ -72,3 +72,11 @@ func TestResponse_ChangeStatusCodeBeforeWrite(t *testing.T) {
 
 	assert.Equal(t, http.StatusOK, rec.Code)
 }
+
+func TestResponse_Unwrap(t *testing.T) {
+	e := New()
+	rec := httptest.NewRecorder()
+	res := &Response{echo: e, Writer: rec}
+
+	assert.Equal(t, rec, res.Unwrap())
+}
Repository: labstack/echo
Pull request #2656 (2024-07-09 11:13:15)

bind: Maintain backwards compatibility for map[string]interface{} binding
This PR modifies the bindData function to preserve the pre v4.12.0 behavior for **map[string]interface{}** while supporting the new functionality:

- Single values are stored as strings
- Multiple values are stored as []string

This approach maintains compatibility with existing code that expects single string values, while allowing new code to take advantage of multiple values when present.

The change addresses the issue reported in https://github.com/labstack/echo/issues/2652, where the binding behavior for map[string]interface{} changed in v4.12.0, potentially breaking existing implementations.

Testing:
- Updated existing tests to reflect the new behavior

Please review and let me know if any further changes are needed.


Patch:
diff --git a/bind.go b/bind.go
index 507def3..877c0f5 100644
--- a/bind.go
+++ b/bind.go
@@ -159,6 +159,10 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
 		for k, v := range data {
 			if isElemString {
 				val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
+			} else if isElemInterface {
+				// To maintain backward compatibility, we always bind to the first string value
+				// and not the slice of strings when dealing with map[string]interface{}{}
+				val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v[0]))
 			} else {
 				val.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(v))
 			}


Test patch:
diff --git a/bind_test.go b/bind_test.go
index db7693c..fc0c005 100644
--- a/bind_test.go
+++ b/bind_test.go
@@ -497,8 +497,8 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
 		assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
 		assert.Equal(t,
 			map[string]interface{}{
-				"multiple": []string{"1", "2"},
-				"single":   []string{"3"},
+				"multiple": "1",
+				"single":   "3",
 			},
 			dest,
 		)
@@ -509,8 +509,8 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
 		assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
 		assert.Equal(t,
 			map[string]interface{}{
-				"multiple": []string{"1", "2"},
-				"single":   []string{"3"},
+				"multiple": "1",
+				"single":   "3",
 			},
 			dest,
 		)
Repository: labstack/echo
Pull request #1559 (2020-04-29 14:15:13)

Extend HTTPError to satisfy the Go 1.13 error wrapper interface
I don't see that this has been discussed before in the issues, so my apologies if this has been discussed and rejected for some reason.


Patch:
diff --git a/echo.go b/echo.go
index af93354..c7e4d6d 100644
--- a/echo.go
+++ b/echo.go
@@ -795,6 +795,11 @@ func (he *HTTPError) SetInternal(err error) *HTTPError {
 	return he
 }
 
+// Unwrap satisfies the Go 1.13 error wrapper interface.
+func (he *HTTPError) Unwrap() error {
+	return he.Internal
+}
+
 // WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.
 func WrapHandler(h http.Handler) HandlerFunc {
 	return func(c Context) error {


Test patch:
diff --git a/echo_go1.13_test.go b/echo_go1.13_test.go
new file mode 100644
index 0000000..3c488bc
--- /dev/null
+++ b/echo_go1.13_test.go
@@ -0,0 +1,28 @@
+// +build go1.13
+
+package echo
+
+import (
+	"errors"
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestHTTPError_Unwrap(t *testing.T) {
+	t.Run("non-internal", func(t *testing.T) {
+		err := NewHTTPError(http.StatusBadRequest, map[string]interface{}{
+			"code": 12,
+		})
+
+		assert.Nil(t, errors.Unwrap(err))
+	})
+	t.Run("internal", func(t *testing.T) {
+		err := NewHTTPError(http.StatusBadRequest, map[string]interface{}{
+			"code": 12,
+		})
+		err.SetInternal(errors.New("internal error"))
+		assert.Equal(t, "internal error", errors.Unwrap(err).Error())
+	})
+}
diff --git a/echo_test.go b/echo_test.go
index ddbc56f..b9c1778 100644
--- a/echo_test.go
+++ b/echo_test.go
@@ -549,7 +549,6 @@ func TestHTTPError(t *testing.T) {
 		})
 
 		assert.Equal(t, "code=400, message=map[code:12]", err.Error())
-
 	})
 	t.Run("internal", func(t *testing.T) {
 		err := NewHTTPError(http.StatusBadRequest, map[string]interface{}{
Repository: labstack/echo
Pull request #1666 (2020-11-05 02:39:59)

Fix DefaultHTTPErrorHandler with enabled debug (#1477)
This PR will correct the misbehaviour described in issue #1477. 

With enabled debug still the correct error will be returned and not overwritten.
Tests are added, where the now expected errors are shown


Patch:
diff --git a/echo.go b/echo.go
index 128f84f..29b88b7 100644
--- a/echo.go
+++ b/echo.go
@@ -362,10 +362,12 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
 	// Issue #1426
 	code := he.Code
 	message := he.Message
-	if e.Debug {
-		message = err.Error()
-	} else if m, ok := message.(string); ok {
-		message = Map{"message": m}
+	if m, ok := he.Message.(string); ok {
+		if e.Debug {
+			message = Map{"message": m, "error": err.Error()}
+		} else {
+			message = Map{"message": m}
+		}
 	}
 
 	// Send response


Test patch:
diff --git a/echo_test.go b/echo_test.go
index e1706ef..0368dbd 100644
--- a/echo_test.go
+++ b/echo_test.go
@@ -568,6 +568,49 @@ func TestHTTPError(t *testing.T) {
 	})
 }
 
+func TestDefaultHTTPErrorHandler(t *testing.T) {
+	e := New()
+	e.Debug = true
+	e.Any("/plain", func(c Context) error {
+		return errors.New("An error occurred")
+	})
+	e.Any("/badrequest", func(c Context) error {
+		return NewHTTPError(http.StatusBadRequest, "Invalid request")
+	})
+	e.Any("/servererror", func(c Context) error {
+		return NewHTTPError(http.StatusInternalServerError, map[string]interface{}{
+			"code":    33,
+			"message": "Something bad happened",
+			"error":   "stackinfo",
+		})
+	})
+	// With Debug=true plain response contains error message
+	c, b := request(http.MethodGet, "/plain", e)
+	assert.Equal(t, http.StatusInternalServerError, c)
+	assert.Equal(t, "{\n  \"error\": \"An error occurred\",\n  \"message\": \"Internal Server Error\"\n}\n", b)
+	// and special handling for HTTPError
+	c, b = request(http.MethodGet, "/badrequest", e)
+	assert.Equal(t, http.StatusBadRequest, c)
+	assert.Equal(t, "{\n  \"error\": \"code=400, message=Invalid request\",\n  \"message\": \"Invalid request\"\n}\n", b)
+	// complex errors are serialized to pretty JSON
+	c, b = request(http.MethodGet, "/servererror", e)
+	assert.Equal(t, http.StatusInternalServerError, c)
+	assert.Equal(t, "{\n  \"code\": 33,\n  \"error\": \"stackinfo\",\n  \"message\": \"Something bad happened\"\n}\n", b)
+
+	e.Debug = false
+	// With Debug=false the error response is shortened
+	c, b = request(http.MethodGet, "/plain", e)
+	assert.Equal(t, http.StatusInternalServerError, c)
+	assert.Equal(t, "{\"message\":\"Internal Server Error\"}\n", b)
+	c, b = request(http.MethodGet, "/badrequest", e)
+	assert.Equal(t, http.StatusBadRequest, c)
+	assert.Equal(t, "{\"message\":\"Invalid request\"}\n", b)
+	// No difference for error response with non plain string errors
+	c, b = request(http.MethodGet, "/servererror", e)
+	assert.Equal(t, http.StatusInternalServerError, c)
+	assert.Equal(t, "{\"code\":33,\"error\":\"stackinfo\",\"message\":\"Something bad happened\"}\n", b)
+}
+
 func TestEchoClose(t *testing.T) {
 	e := New()
 	errCh := make(chan error)
Repository: labstack/echo
Pull request #1671 (2020-11-06 14:33:57)

Fix Static files route not working
fix 404 error when using Static files route Echo.Static()

[related issue](https://github.com/labstack/echo/issues/1569)


Patch:
diff --git a/echo.go b/echo.go
index d284ff3..4b0c785 100644
--- a/echo.go
+++ b/echo.go
@@ -500,6 +500,7 @@ func (common) static(prefix, root string, get func(string, HandlerFunc, ...Middl
 		}
 		return c.File(name)
 	}
+	get(prefix, h)
 	if prefix == "/" {
 		return get(prefix+"*", h)
 	}


Test patch:
diff --git a/echo_test.go b/echo_test.go
index a6071e1..895ea18 100644
--- a/echo_test.go
+++ b/echo_test.go
@@ -102,6 +102,15 @@ func TestEchoStatic(t *testing.T) {
 			expectHeaderLocation: "/folder/",
 			expectBodyStartsWith: "",
 		},
+    {
+			name:                 "Directory Redirect with non-root path",
+			givenPrefix:          "/static",
+			givenRoot:            "_fixture",
+			whenURL:              "/static",
+			expectStatus:         http.StatusMovedPermanently,
+			expectHeaderLocation: "/static/",
+			expectBodyStartsWith: "",
+		},
 		{
 			name:                 "Directory with index.html",
 			givenPrefix:          "/",
@@ -161,6 +170,40 @@ func TestEchoStatic(t *testing.T) {
 	}
 }
 
+func TestEchoStaticRedirectIndex(t *testing.T) {
+	assert := assert.New(t)
+	e := New()
+
+	// HandlerFunc
+	e.Static("/static", "_fixture")
+
+	errCh := make(chan error)
+
+	go func() {
+		errCh <- e.Start("127.0.0.1:1323")
+	}()
+
+	time.Sleep(200 * time.Millisecond)
+
+	if resp, err := http.Get("http://127.0.0.1:1323/static"); err == nil {
+		defer resp.Body.Close()
+		assert.Equal(http.StatusOK, resp.StatusCode)
+
+		if body, err := ioutil.ReadAll(resp.Body); err == nil {
+			assert.Equal(true, strings.HasPrefix(string(body), "<!doctype html>"))
+		} else {
+			assert.Fail(err.Error())
+		}
+
+	} else {
+		assert.Fail(err.Error())
+	}
+
+	if err := e.Close(); err != nil {
+		t.Fatal(err)
+	}
+}
+
 func TestEchoFile(t *testing.T) {
 	e := New()
 	e.File("/walle", "_fixture/images/walle.png")
Repository: gkjohnson/three-mesh-bvh
Pull request #589 (2023-09-01 09:44:04)

Fix indirect raycast
**TODO**
- Benchmark w/ and w/o index condition


Patch:
diff --git a/src/utils/ThreeRayIntersectUtilities.js b/src/utils/ThreeRayIntersectUtilities.js
index 6f2c51d..24ccfd6 100644
--- a/src/utils/ThreeRayIntersectUtilities.js
+++ b/src/utils/ThreeRayIntersectUtilities.js
@@ -109,9 +109,18 @@ function checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b,
 function intersectTri( geo, side, ray, tri, intersections ) {
 
 	const triOffset = tri * 3;
-	const a = geo.index.getX( triOffset );
-	const b = geo.index.getX( triOffset + 1 );
-	const c = geo.index.getX( triOffset + 2 );
+	let a = triOffset + 0;
+	let b = triOffset + 1;
+	let c = triOffset + 2;
+
+	const index = geo.index;
+	if ( geo.index ) {
+
+		a = index.getX( a );
+		b = index.getX( b );
+		c = index.getX( c );
+
+	}
 
 	const { position, normal, uv, uv1 } = geo.attributes;
 	const intersection = checkBufferGeometryIntersection( ray, position, normal, uv, uv1, a, b, c, side );


Test patch:
diff --git a/test/MeshBVH.options.test.js b/test/MeshBVH.options.test.js
index 8cfb322..b6f0b59 100644
--- a/test/MeshBVH.options.test.js
+++ b/test/MeshBVH.options.test.js
@@ -7,6 +7,7 @@ import {
 import {
 	MeshBVH,
 	getBVHExtremes,
+	acceleratedRaycast,
 } from '../src/index.js';
 import { getMaxDepth } from './utils.js';
 
@@ -239,6 +240,23 @@ describe( 'Options', () => {
 
 		} );
 
+		it( 'should successfully raycast with no index buffer.', () => {
+
+			const geo = geometry.toNonIndexed();
+			const bvh = new MeshBVH( geo, { indirect: true } );
+			geo.boundsTree = bvh;
+			mesh.geometry = geo;
+			mesh.raycast = acceleratedRaycast;
+
+			const raycaster = new Raycaster();
+			raycaster.ray.origin.set( 0, 10, 0 );
+			raycaster.ray.direction.set( 0, - 1, 0 );
+
+			const results = raycaster.intersectObject( mesh );
+			expect( results.length ).toBeGreaterThan( 0 );
+
+		} );
+
 	} );
 
 	describe( 'strategy', () => {
Repository: gkjohnson/three-mesh-bvh
Pull request #664 (2024-05-14 10:43:07)

Fix indirect bvh serialization
Related to https://github.com/gkjohnson/three-mesh-bvh/issues/663#issuecomment-2108369387

Fix BVH failing when deserializing an indirect buffer. 


Patch:
diff --git a/src/core/MeshBVH.js b/src/core/MeshBVH.js
index e0d9e8e..e85a214 100644
--- a/src/core/MeshBVH.js
+++ b/src/core/MeshBVH.js
@@ -160,8 +160,7 @@ export class MeshBVH {
 
 		}
 
-		const { _indirectBuffer } = this;
-		this.resolveTriangleIndex = options.indirect ? i => _indirectBuffer[ i ] : i => i;
+		this.resolveTriangleIndex = this._indirectBuffer ? i => this._indirectBuffer[ i ] : i => i;
 
 	}
 


Test patch:
diff --git a/test/MeshBVH.serialize.test.js b/test/MeshBVH.serialize.test.js
index 382e876..15b55c1 100644
--- a/test/MeshBVH.serialize.test.js
+++ b/test/MeshBVH.serialize.test.js
@@ -140,4 +140,24 @@ describe( 'Serialization', () => {
 
 	} );
 
+	describe( 'indirect', () => {
+
+		it( 'should correctly deserialize the bvh.', () => {
+
+			const cloned = geometry.clone();
+			const bvh = new MeshBVH( geometry, { indirect: true } );
+			const serialized = MeshBVH.serialize( bvh );
+
+			const deserialized = MeshBVH.deserialize( serialized, cloned );
+			expect( deserialized.indirect ).toBe( true );
+			expect( () => {
+
+				deserialized.resolveTriangleIndex( 0 );
+
+			} ).not.toThrow();
+
+		} );
+
+	} );
+
 } );