Skip to content

Commit

Permalink
Fix value method call on nil pointer (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Mar 6, 2024
1 parent 2d5f6b0 commit fbc1e0d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
16 changes: 12 additions & 4 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,15 @@ func (r *Reflector) reflectDefer(defName string, typeString refl.TypeString, rc
}

func (r *Reflector) checkTitle(v reflect.Value, s *Struct, schema *Schema) {
if vd, ok := v.Interface().(Described); ok {
if vd, ok := safeInterface(v).(Described); ok {
schema.WithDescription(vd.Description())
}

if s != nil && s.Description != nil {
schema.WithDescription(*s.Description)
}

if vt, ok := v.Interface().(Titled); ok {
if vt, ok := safeInterface(v).(Titled); ok {
schema.WithTitle(vt.Title())
}

Expand Down Expand Up @@ -532,7 +532,7 @@ func (r *Reflector) reflect(i interface{}, rc *ReflectContext, keepType bool, pa
}
}

if preparer, ok := v.Interface().(Preparer); ok {
if preparer, ok := safeInterface(v).(Preparer); ok {
err := preparer.PrepareJSONSchema(sp)

return schema, err
Expand All @@ -555,8 +555,16 @@ func checkTextMarshaler(t reflect.Type, schema *Schema) bool {
return false
}

func safeInterface(v reflect.Value) interface{} {
if v.Kind() == reflect.Ptr && !v.Elem().IsValid() {
v = reflect.New(v.Type())
}

return v.Interface()
}

func (r *Reflector) applySubSchemas(v reflect.Value, rc *ReflectContext, schema *Schema) error {
vi := v.Interface()
vi := safeInterface(v)

if e, ok := vi.(OneOfExposer); ok {
var schemas []SchemaOrBool
Expand Down
35 changes: 35 additions & 0 deletions reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1949,3 +1949,38 @@ func TestReflector_Reflect_ptrDefault(t *testing.T) {
"type":"object"
}`, s)
}

func TestReflector_Reflect_nilPreparer(t *testing.T) {
var o *Org

r := jsonschema.Reflector{}

s, err := r.Reflect(o)
require.NoError(t, err)
assertjson.EqMarshal(t, `{
"definitions":{
"JsonschemaGoTestEnumed":{"enum":["foo","bar"],"type":"string"},
"JsonschemaGoTestPerson":{
"title":"Person","required":["lastName"],
"properties":{
"birthDate":{"type":"string","format":"date"},
"createdAt":{"type":"string","format":"date-time"},
"date":{"type":"string","format":"date"},
"deathDate":{"type":["null","string"],"format":"date"},
"deletedAt":{"type":["null","string"],"format":"date-time"},
"enumed":{"$ref":"#/definitions/JsonschemaGoTestEnumed"},
"enumedPtr":{"$ref":"#/definitions/JsonschemaGoTestEnumed"},
"firstName":{"type":"string"},"height":{"type":"integer"},
"lastName":{"type":"string"},"meta":{},
"role":{"description":"The role of person.","type":"string"}
},
"type":"object"
}
},
"properties":{
"chiefOfMorale":{"$ref":"#/definitions/JsonschemaGoTestPerson"},
"employees":{"items":{"$ref":"#/definitions/JsonschemaGoTestPerson"},"type":"array"}
},
"type":"object"
}`, s)
}

0 comments on commit fbc1e0d

Please sign in to comment.