Render and Bind panic on unexported nested interface fields

Abierto Apto para principiantes
#72 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
72/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
go
Área
api

Línea de trabajo

El pánico proviene de los dos recorridos recursivos en render.go, alrededor de la línea 82 para Render y la línea 114 para Bind, que llaman a f.Type().Implements(...) y luego a f.Interface() sin comprobar CanInterface(). Ejecuta los dos tests externos del issue, TestPrivateRenderer y TestPrivateBinder, para reproducir el pánico. Está terminado cuando ambos retornan sin entrar en pánico, el comportamiento elegido (omitir el campo no exportado o devolver un error) se aplica de forma consistente y está cubierto por un test.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Render and Bind panic when a payload has an unexported nested field whose type implements Renderer or Binder. This is a valid caller-defined struct; the API does not return an error.

Reproduced with Go 1.27.1 on Windows against current main (14f1cb3d5c2969d6e462632a205eacb6421eb4dc). The Renderer case also reproduces on v1.0.3. External-package test:

package render_test

import (
    "net/http"
    "net/http/httptest"
    "strings"
    "testing"

    "github.com/go-chi/render"
)

type childRenderer struct{}
func (childRenderer) Render(http.ResponseWriter, *http.Request) error { return nil }
type parentRenderer struct{ child childRenderer }
func (parentRenderer) Render(http.ResponseWriter, *http.Request) error { return nil }

type childBinder struct{}
func (childBinder) Bind(*http.Request) error { return nil }
type parentBinder struct{ child childBinder }
func (parentBinder) Bind(*http.Request) error { return nil }

func TestPrivateRenderer(t *testing.T) {
    r := httptest.NewRequest(http.MethodGet, "/", nil)
    w := httptest.NewRecorder()
    if err := render.Render(w, r, parentRenderer{}); err != nil { t.Fatal(err) }
}

func TestPrivateBinder(t *testing.T) {
    r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader("{}"))
    r.Header.Set("Content-Type", "application/json")
    if err := render.Bind(r, &parentBinder{}); err != nil { t.Fatal(err) }
}

Run either test individually; each panics with reflect.Value.Interface: cannot return value obtained from unexported field or method. Expected: Render/Bind should handle the payload without panicking, either by skipping inaccessible nested fields or by returning an error.

Both recursive loops check f.Type().Implements(...) and then call f.Interface() (render.go:82 and render.go:114). For a private field, f.CanInterface() is false even though its type implements the interface.

Lenguaje dominante
Go
Estrellas
341
Forks
68
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de go-chi/render

Todos los issues de go-chi/render

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.